clockpay-react
v1.1.5
Published
A type-safe, zero-config React SDK for accepting crypto payments with ClockPay.
Downloads
87
Readme
ClockPay React SDK
A type-safe, zero-config React SDK for accepting crypto payments with ClockPay.
Drop in a single <PaymentButton /> — it ships its own styles and wallet
providers, so there's nothing else to wire up.
- 🔌 Zero setup — no
WagmiProvider, noQueryClientProvider, no CSS import. - 🪙 Buyer picks coin & network — a selection screen fetches the coins and networks you support.
- 🎨 Themeable — a Stripe-style
appearanceobject controls colours, shape and type. - 🧩 Self-contained UI — scoped styles injected at runtime; works in any React app.
- 💳 Two payment flows — connect a wallet, or transfer to an address via QR.
- 🛡️ Type-safe — full TypeScript types for props, callbacks and responses.
Table of contents
- Installation
- Quick start
- How it works
- Order details (
meta) - Theming
- Handling results
- Framework notes
- API reference
- Supported networks
- Local development
- License
Installation
npm install clockpay-react
# or
yarn add clockpay-react
# or
pnpm add clockpay-reactThat's the only install you need. The SDK ships its entire web3 stack —
wagmi, viem, @wagmi/core, @web3modal/wagmi and @tanstack/react-query — as
regular dependencies, so your package manager pulls them in automatically. There's
nothing extra to add and no wagmi/Web3Modal setup to configure. The same single
command works on npm, yarn and pnpm alike.
The only requirement is that your app already has React 18 or newer (react and
react-dom), which are the SDK's only peer dependencies — every React app already
has these.
Quick start
import { PaymentButton } from 'clockpay-react';
export function Checkout() {
return (
<PaymentButton
publicKey="cpay_test_pk_..." // from your developer dashboard
amount={20000} // in the currency below
currency="ngn" // 'ngn' | 'usd'
reference="order_12345" // your own order reference
meta={{
title: 'Order #12345',
description: 'Two coffees and a croissant',
fullName: 'Paul Paito',
email: '[email protected]', // optional
phoneNumber: { code: '+234', number: '09012345678' }, // optional
}}
onSuccess={(data) => console.log('Payment confirmed', data)}
onError={(error) => console.error(error)}
/>
);
}That's it. The button opens a selection screen where the buyer picks a coin and
network, then a self-contained modal with both Connect to wallet and
Transfer (QR) flows, verifies the transaction on-chain, and calls your
onSuccess handler when payment is confirmed.
How it works
┌──────────────┐ click ┌──────────────────┐ ┌───────────────────────┐ confirm ┌───────────┐
│ PaymentButton │ ───────▶ │ Selection screen │ create │ Payment modal │ ────────▶ │ onSuccess │
│ (your page) │ │ • pick coin │ ──link▶ │ • Connect to wallet │ verify │ callback │
└──────────────┘ │ • pick network │ │ • Transfer (QR/addr) │ on-chain └───────────┘
└──────────────────┘ └───────────────────────┘- The buyer clicks the button. A selection screen opens and loads the coins you
support (
/wallet/client/checkout/coins); once a coin is picked it loads that coin's networks (/wallet/client/checkout/networks/{coinId}). - On Continue, the SDK generates a payment link
(
POST /payment/client/create-link) from youramount,currency,referenceandmeta, then initiates the checkout to get the deposit address, amount and network. - The payment modal opens with two tabs:
- Connect to wallet — pay directly via an injected or WalletConnect wallet.
- Transfer — scan the QR / copy the address, send manually, then paste the tx hash.
- The SDK verifies the transaction on-chain and calls
onSuccess/onError.
No server-side call or
clientSecretis required anymore — the SDK creates the payment link for you from the order details you pass to<PaymentButton />. YourpublicKeyis safe to ship to the browser; keep your secret key on the server.
Order details (meta)
The business supplies all order and buyer details up front — the buyer only picks a coin and network. These are sent when the payment link is generated:
<PaymentButton
publicKey="cpay_test_pk_..."
amount={20000}
currency="ngn" // 'ngn' | 'usd'
reference="order_12345" // your own reference for this order
meta={{
title: 'Order #12345', // required
description: 'Two coffees', // required
fullName: 'Paul Paito', // required
email: '[email protected]', // optional
customerId: 'cus_abc123', // optional
phoneNumber: { code: '+234', number: '09012345678' }, // optional
}}
/>| Field | Type | Required | Description |
|-------|------|----------|-------------|
| amount | number | Yes | Order amount, in currency. |
| currency | 'ngn' \| 'usd' | Yes | Fiat currency of amount. |
| reference | string | Yes | Your own reference for the order. |
| meta.title | string | Yes | Short order title shown to the buyer. |
| meta.description | string | Yes | Order description. |
| meta.fullName | string | Yes | Buyer's full name. |
| meta.email | string | No | Buyer email. |
| meta.customerId | string | No | Your id for the buyer. |
| meta.phoneNumber | { code: string; number: string } | No | Buyer phone number. |
Theming
Customize the button and modal with a Stripe-style appearance object:
<PaymentButton
publicKey="cpay_test_pk_..."
amount={20000}
currency="ngn"
reference="order_12345"
meta={{ title: 'Order #12345', description: 'Two coffees', fullName: 'Paul Paito' }}
appearance={{
variant: 'solid', // 'solid' | 'outline' (default: 'outline')
buttonColor: '#6C5CE7', // primary brand colour
buttonTextColor: '#ffffff',
borderRadius: 12, // number = pixels
fontFamily: 'Inter, sans-serif',
modalAccentColor: '#6C5CE7',
}}
/>You can also change the label:
<PaymentButton publicKey="..." amount={20000} currency="ngn" reference="order_12345"
meta={{ title: 'Order', description: '...', fullName: 'Paul Paito' }} label="Pay ₦20,000" />Handling results
<PaymentButton
publicKey="..."
amount={20000}
currency="ngn"
reference="order_12345"
meta={{ title: 'Order #12345', description: 'Two coffees', fullName: 'Paul Paito' }}
redirectUrl="https://yourstore.com/thank-you" // optional redirect after success
onSuccess={(data) => {
// data: { message: string }
toast.success(data.message);
}}
onError={(error) => {
// initiate or verify failed
toast.error(error.message);
}}
onClose={() => {
// modal closed (any outcome)
}}
/>Framework notes
Next.js (App Router). The SDK renders client-only UI, so use it inside a Client Component:
'use client';
import { PaymentButton } from 'clockpay-react';
export function Pay({ amount }: { amount: number }) {
return (
<PaymentButton
publicKey="..."
amount={amount}
currency="ngn"
reference="order_12345"
meta={{ title: 'Order', description: '...', fullName: 'Paul Paito' }}
/>
);
}Importing the package on the server is safe — no browser APIs run at import time; wallet/Web3 initialisation is lazy and only happens in the browser.
API reference
<PaymentButton />
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| publicKey | string | Yes | Public key from the developer dashboard. |
| amount | number | Yes | Order amount, in currency. |
| currency | 'ngn' \| 'usd' | Yes | Fiat currency of amount. |
| reference | string | Yes | Your own reference for the order. |
| meta | CheckoutMeta | Yes | Order/buyer details (see Order details). |
| appearance | ClockPayAppearance | No | Button/modal theming (see below). |
| label | ReactNode | No | Button label. Defaults to "Pay with Clockpay". |
| disabled | boolean | No | Disables the button. |
| redirectUrl | string | No | Where to send the buyer after a successful payment. |
| apiBaseUrl | string | No | Override the API gateway. By default it's selected from the key prefix: cpay_test_pk_ → dev gateway, cpay_live_pk_ → live gateway. |
| walletConnectProjectId | string | No | Your own WalletConnect project id. |
| onSuccess | (data: VerifyCryptoResponse) => void | No | Fired when payment is confirmed on-chain. |
| onError | (error: Error) => void | No | Fired if initiating or verifying fails. |
| onClose | () => void | No | Fired whenever the modal closes. |
ClockPayAppearance
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| variant | 'solid' \| 'outline' | 'outline' | Button fill style. |
| buttonColor | string | #27AAE1 | Primary brand colour. |
| buttonTextColor | string | brand / white | Button label colour. |
| borderRadius | string \| number | 8px | Corner radius (number = px). |
| fontFamily | string | inherit | Font for all SDK surfaces. |
| modalAccentColor | string | buttonColor | Accent used inside the modal. |
Exported types
import type {
PaymentButtonProps,
ClockPayAppearance,
CheckoutCurrency,
CheckoutMeta,
CheckoutPhoneNumber,
CheckoutData,
CheckoutResponse,
Coin,
CoinsResponse,
Network,
NetworksResponse,
CreateLinkPayload,
CreateLinkData,
CreateLinkResponse,
VerifyCryptoPayload,
VerifyCryptoResponse,
} from 'clockpay-react';Supported networks
The wallet-connect and verification flows support: Ethereum, Optimism,
BSC, Polygon, and Tron (transfer flow). The coins and networks offered on
the selection screen come from your account (/wallet/client/checkout/coins and
/wallet/client/checkout/networks/{coinId}); the buyer chooses which to pay with.
Local development
npm install
npm run dev # run the demo playground (Vite)
npm run typecheck # type-check the source
npm run lint # lint
npm run build # build the distributable library (tsup → dist/)License
MIT — see LICENSE.
