@clockpay/react-native
v1.0.4
Published
A type-safe React Native SDK for accepting crypto payments with ClockPay — a Stripe-style bottom-sheet payment modal.
Maintainers
Readme
ClockPay React Native SDK
A type-safe React Native SDK for accepting crypto payments with ClockPay. Drop in a
single <PaymentButton /> — it opens a Stripe-style bottom-sheet payment modal
that slides up from the bottom of the screen.
- 📱 Native bottom sheet — slides up with a dimmed backdrop and drag-to-dismiss.
- 🪙 Buyer picks coin & network — a selection sheet fetches the coins and networks you support.
- 🎨 Themeable — a Stripe-style
appearanceobject controls colours and shape. - 🔑 Env-aware — the API gateway is auto-selected from your key prefix.
- 👛 Wallet connect (optional) — connect a wallet in-sheet via WalletConnect. See Wallet connection.
- 🛡️ Type-safe — full TypeScript types for props, callbacks and responses.
Installation
npm install @clockpay/react-nativeInstall the required peer dependencies (native modules):
npm install react-native-svg react-native-qrcode-svg @react-native-clipboard/clipboard
cd ios && pod install # iOS onlyreact and react-native are also peer dependencies.
Quick start
import { PaymentButton } from '@clockpay/react-native';
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
}}
appearance={{ buttonColor: '#27AAE1', variant: 'outline' }}
onSuccess={(data) => console.log('Payment confirmed', data)}
onError={(error) => console.error(error)}
/>
);
}Pressing the button opens a selection sheet where the buyer picks a coin and
network. On continue, the SDK generates a payment link and presents the payment
sheet: a QR code + deposit address to transfer to, a countdown, then a screen to
paste the transaction hash for on-chain verification. onSuccess fires once the
payment is confirmed.
No
clientSecretor server-side call is required — the SDK creates the payment link from the order details you pass. YourpublicKeyis safe in the app; keep your secret key on the server.
Order details (meta)
The business supplies the order and buyer details up front — the buyer only picks a coin and network.
| 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. |
| 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
<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,
modalAccentColor: '#6C5CE7',
}}
/>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/sheet theming. |
| label | ReactNode | No | Button label. Defaults to "Pay with Clockpay". |
| disabled | boolean | No | Disables the button. |
| apiBaseUrl | string | No | Override the API gateway. By default it's selected from the key prefix: cpay_test_pk_ → dev, cpay_live_pk_ → live. |
| redirectUrl | string | No | Opened via Linking after a successful payment. |
| walletConnect | WalletConnectOptions | No | Enables in-sheet wallet connection. See Wallet connection. |
| onSuccess | (data: VerifyCryptoResponse) => void | No | Fired when payment is confirmed. |
| onError | (error: Error) => void | No | Fired if initiating or verifying fails. |
| onClose | () => void | No | Fired when the sheet 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 | number | 8 | Corner radius (dp). |
| fontFamily | string | system | Button label font. |
| modalAccentColor | string | buttonColor | Accent used inside the sheet. |
Wallet connection (optional)
The payment sheet's Connect tab can open a real WalletConnect session (via
Reown AppKit) so the buyer connects a wallet in-sheet.
It is opt-in: without the walletConnect prop the tab stays a non-interactive
placeholder and none of the packages below are needed.
Enable it by passing the prop — the ClockPay WalletConnect project id is built in, so an empty object is enough:
<PaymentButton
publicKey="cpay_test_pk_..."
amount={20000}
currency="ngn"
reference="order_12345"
meta={{ title: 'Order #12345', description: 'Two coffees', fullName: 'Paul Paito' }}
walletConnect={{
onConnect: (address) => console.log('connected', address), // optional
// metadata: { redirect: { native: 'yourapp://' } }, // optional override
}}
/>Setup
1. Install the wallet peer dependencies (⚠️ wagmi/viem must be v2, not v3):
npm install \
@reown/appkit-react-native @reown/appkit-wagmi-react-native \
wagmi@2 viem@2 @tanstack/react-query \
@walletconnect/react-native-compat \
@react-native-async-storage/async-storage \
@react-native-community/netinfo \
react-native-get-random-values
cd ios && pod install # iOS only2. Add the polyfills at the very top of your app entry (e.g. index.js), before
any other import:
import '@walletconnect/react-native-compat';
import 'react-native-get-random-values';3. Register a deep-link scheme matching metadata.redirect.native (default
clockpay://) so the wallet can return to your app — Info.plist +
AndroidManifest.xml for bare React Native, or scheme in app.json +
expo prebuild for Expo.
Requirements: React Native ≥ 0.81 (Reown AppKit v2), and a rebuilt custom dev client — wallet connection does not run in Expo Go. EVM chains only (Ethereum, Optimism, Arbitrum, BSC, Polygon).
Tapping the switch button opens the AppKit modal; once a wallet connects, the button
shows the connected address and onConnect fires. A WalletConnectProvider is also
exported if you prefer to own the wagmi/AppKit context yourself.
Supported networks
ETH, Optimism, BSC, Polygon, and Tron. The coins and networks offered on the
selection sheet come from your account (/wallet/checkout/coins and
/wallet/checkout/networks/{coinId}); the buyer chooses which to pay with.
Local development
npm install
npm run typecheck
npm run build # react-native-builder-bob → lib/License
MIT
