react-nomba-checkout-sdk
v2.0.6
Published
Nomba checkout sdk for react apps.
Readme
🚀 React Nomba Checkout SDK
The react-nomba-checkout-sdk is a lightweight React SDK designed to simplify payment processing and checkout integration using Nomba's secure and reliable infrastructure.
Built with ❤️ by Israel Itua
📦 Installation
You can install the SDK using npm or yarn:
npm install react-nomba-checkout-sdk
# or
yarn add react-nomba-checkout-sdk⚡ Quick Start (React)
Here's how to integrate the SDK into your React project:
import { useState } from 'react';
import {
useNombaCheckout,
InitializeNombaCheckout,
} from 'react-nomba-checkout-sdk';
import './App.css';
// Initialize Nomba Checkout on app load
InitializeNombaCheckout();
function App() {
const [isLoading, setIsLoading] = useState(false);
const handleCheckout = async () => {
setIsLoading(true);
const res = await useNombaCheckout({
accountId: 'your-account-id',
clientId: 'your-client-id',
order: {
callbackUrl: 'sample-url',
customerEmail: '[email protected]',
amount: '10.00',
currency: 'NGN',
orderMetaData: {
customMerchant: 'true',
},
splitRequest: {
splitType: 'PERCENTAGE',
splitList: [
{
accountId: 'your-account-id',
value: '65.45',
},
],
},
},
tokenizeCard: 'true',
onCreateOrder: (orderReference) => {
console.log('Function called after the order is created');
console.log({ orderReference });
setIsLoading(false);
},
onFailure: (err) => {
console.log('Function called if error occurs while creating order.');
console.log(err);
setIsLoading(false);
},
onClose: () => {
console.log('Function called when modal is closed.');
setIsLoading(false);
},
onPaymentSuccess: (successResponse) => {
console.log('Function called on payment success.');
console.log({ successResponse });
},
});
};
return (
<>
<h1>Pay with Nomba</h1>
<button onClick={handleCheckout}>
{isLoading ? 'Please wait...' : 'Pay with Nomba Checkout'}
</button>
</>
);
}
export default App;🔥 Next.js Integration (App Router)
For Next.js 13+ with App Router, follow this setup to ensure proper client-side rendering:
Step 1: Create the Checkout Component
Create components/NombaCheckoutButton.tsx:
'use client';
import { useState, useEffect } from 'react';
import {
useNombaCheckout,
InitializeNombaCheckout,
} from 'react-nomba-checkout-sdk';
export default function NombaCheckoutButton() {
const [isLoading, setIsLoading] = useState(false);
const [isInitialized, setIsInitialized] = useState(false);
useEffect(() => {
InitializeNombaCheckout();
setIsInitialized(true);
}, []);
const handleCheckout = async () => {
if (!isInitialized) {
console.log('SDK not initialized yet');
return;
}
setIsLoading(true);
const res = await useNombaCheckout({
accountId: 'your-account-id',
clientId: 'your-client-id',
order: {
callbackUrl: 'https://your-callback-url.com',
customerEmail: '[email protected]',
amount: '10.00',
currency: 'NGN',
orderMetaData: {
customMerchant: 'true',
},
splitRequest: {
splitType: 'PERCENTAGE',
splitList: [
{
accountId: 'your-account-id',
value: 65.45,
},
],
},
orderReference: 'your-order-reference',
customerId: '',
accountId: 'your-account-id',
},
tokenizeCard: true,
onCreateOrder: (orderReference) => {
console.log('Function called after the order is created');
console.log({ orderReference });
setIsLoading(false);
},
onFailure: (err) => {
console.log('Function called if error occurs while creating order.');
console.log(err);
setIsLoading(false);
},
onClose: () => {
console.log('Function called when modal is closed.');
setIsLoading(false);
return {};
},
onPaymentSuccess: (successResponse) => {
console.log('Function called on payment success.');
console.log({ successResponse });
return {};
},
});
};
return (
<>
<h1>Pay with Nomba</h1>
<button onClick={handleCheckout} disabled={!isInitialized}>
{isLoading ? 'Please wait...' : 'Pay with Nomba Checkout'}
</button>
</>
);
}Step 2: Use Dynamic Import in Your Page
Create or update your app/page.tsx:
'use client';
import dynamic from 'next/dynamic';
// Dynamically import the component with SSR disabled
const NombaCheckoutButton = dynamic(
() => import('@/components/NombaCheckoutButton'),
{ ssr: false }
);
export default function Home() {
return <NombaCheckoutButton />;
}Step 3: Configure Layout (Optional)
Update your app/layout.tsx if needed:
import type { Metadata } from 'next';
import { Geist, Geist_Mono } from 'next/font/google';
import './globals.css';
const geistSans = Geist({
variable: '--font-geist-sans',
subsets: ['latin'],
});
const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin'],
});
export const metadata: Metadata = {
title: 'Nomba Checkout Integration',
description: 'Payment processing with Nomba',
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang='en'>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
suppressHydrationWarning
>
{children}
</body>
</html>
);
}⚠️ Important Next.js Notes
- Always use dynamic import with
ssr: false- The SDK requires browser APIs and must be rendered client-side only - Initialize SDK in useEffect - Ensures proper initialization after component mounts
- Use 'use client' directive - Required for components using browser-specific features
- Check initialization state - Prevent checkout calls before SDK is ready
🔍 API Reference
InitializeNombaCheckout()
Initializes the SDK. Call once when your app loads (or in useEffect for Next.js).
InitializeNombaCheckout();useNombaCheckout(options)
Launches the Nomba checkout modal.
Options
| Parameter | Type | Required | Description |
| ------------------ | -------------- | -------- | ------------------------------ |
| accountId | string | Yes | Your Nomba account ID |
| clientId | string | Yes | Your Nomba client ID |
| order | object | Yes | Order details (see below) |
| tokenizeCard | boolean/string | No | Enable card tokenization |
| onCreateOrder | function | No | Callback after order creation |
| onFailure | function | No | Callback on error |
| onClose | function | No | Callback when modal closes |
| onPaymentSuccess | function | No | Callback on successful payment |
Order Object
| Field | Type | Required | Description |
| ---------------- | ------ | -------- | --------------------------- |
| callbackUrl | string | Yes | URL for payment callback |
| customerEmail | string | Yes | Customer's email address |
| amount | string | Yes | Payment amount |
| currency | string | Yes | Currency code (e.g., 'NGN') |
| orderReference | string | No | Your order reference |
| customerId | string | No | Customer identifier |
| accountId | string | No | Account ID for the order |
| orderMetaData | object | No | Additional metadata |
| splitRequest | object | No | Payment split configuration |
Split Request Object
| Field | Type | Required | Description |
| ----------- | ------ | -------- | ----------------------------- |
| splitType | string | Yes | 'PERCENTAGE' or 'FLAT' |
| splitList | array | Yes | Array of split configurations |
Split List Item
| Field | Type | Required | Description |
| ----------- | ------------- | -------- | --------------------------- |
| accountId | string | Yes | Account ID to receive split |
| value | number/string | Yes | Split amount or percentage |
📝 Example with All Options
const res = await useNombaCheckout({
accountId: 'acc_123456',
clientId: 'client_123456',
order: {
callbackUrl: 'https://yoursite.com/payment/callback',
customerEmail: '[email protected]',
amount: '5000.00',
currency: 'NGN',
orderReference: 'ORDER-2024-001',
customerId: 'CUST-001',
accountId: 'acc_123456',
orderMetaData: {
customMerchant: 'true',
productName: 'Premium Plan',
},
splitRequest: {
splitType: 'PERCENTAGE',
splitList: [
{
accountId: 'acc_partner_1',
value: 20,
},
{
accountId: 'acc_partner_2',
value: 15,
},
],
},
},
tokenizeCard: true,
onCreateOrder: (orderReference) => {
console.log('Order created:', orderReference);
},
onFailure: (error) => {
console.error('Payment failed:', error);
},
onClose: () => {
console.log('Checkout modal closed');
return {};
},
onPaymentSuccess: (response) => {
console.log('Payment successful:', response);
return {};
},
});🛠️ Troubleshooting
Next.js Hydration Errors
- Ensure you're using
dynamicimport withssr: false - Add
suppressHydrationWarningto your body tag in layout.tsx
SDK Not Initialized
- In Next.js, initialize the SDK in
useEffect - Check that the button is disabled until
isInitializedis true
Modal Not Opening
- Verify that
InitializeNombaCheckout()was called beforeuseNombaCheckout() - Check browser console for errors
👤 Author
Israel Itua
Frontend Engineer
GitHub
👥 Contributors
📄 License
MIT
🤝 Contributing
Contributions, issues, and feature requests are welcome!
