react-nomba-checkout-sdk 2.0.5 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +365 -63
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 🚀 React Nomba Checkout SDK
2
2
 
3
- The **`react-nomba-checkout-sdk`** is a lightweight React SDK designed to simplify payment processing and checkout integration using [Nomba's](https://nomba.com/) secure and reliable infrastructure.
3
+ The **react-nomba-checkout-sdk** is a lightweight React SDK designed to simplify payment processing and checkout integration using [Nomba's](https://nomba.com/) secure and reliable infrastructure.
4
4
 
5
5
  > Built with ❤️ by **Israel Itua**
6
6
 
@@ -18,15 +18,15 @@ yarn add react-nomba-checkout-sdk
18
18
 
19
19
  ---
20
20
 
21
- ## ⚡ Quick Start
21
+ ## ⚡ Quick Start (React)
22
22
 
23
- Heres how to integrate the SDK into your React project:
23
+ Here's how to integrate the SDK into your React project:
24
24
 
25
25
  ```jsx
26
26
  import { useState } from 'react';
27
27
  import {
28
- useNombaCheckout,
29
- InitializeNombaCheckout,
28
+ useNombaCheckout,
29
+ InitializeNombaCheckout,
30
30
  } from 'react-nomba-checkout-sdk';
31
31
  import './App.css';
32
32
 
@@ -34,59 +34,62 @@ import './App.css';
34
34
  InitializeNombaCheckout();
35
35
 
36
36
  function App() {
37
- const [isLoading, setIsLoading] = useState(false);
38
-
39
- const handleCheckout = async () => {
40
- setIsLoading(true);
41
-
42
- const res = await useNombaCheckout({
43
- accountId: 'your-account-id',
44
- clientId: 'your-client-id',
45
- order: {
46
- callbackUrl: 'sample-url',
47
- customerEmail: 'sample-email@gmail.com',
48
- amount: '10.00',
49
- currency: 'NGN',
50
- splitRequest: {
51
- splitType: 'PERCENTAGE',
52
- splitList: [
53
- {
54
- accountId: 'your-account-id',
55
- value: '65.45',
56
- },
57
- ],
58
- },
59
- },
60
- tokenizeCard: 'true',
61
- onCreateOrder: (orderReference) => {
62
- console.log('Function called after the order is created');
63
- console.log({ orderReference });
64
- setIsLoading(false);
65
- },
66
- onFailure: (err) => {
67
- console.log('Function called if error occurs while creating order.');
68
- console.log(err);
69
- setIsLoading(false);
70
- },
71
- onClose: () => {
72
- console.log('Function called when modal is closed.');
73
- setIsLoading(false);
74
- },
75
- onPaymentSuccess: (successResponse) => {
76
- console.log('Function called on payment success.');
77
- console.log({ successResponse });
78
- },
79
- });
80
- };
81
-
82
- return (
83
- <>
84
- <h1>Pay with Nomba</h1>
85
- <button onClick={handleCheckout}>
86
- {isLoading ? 'Please wait...' : 'Pay with Nomba Checkout'}
87
- </button>
88
- </>
89
- );
37
+ const [isLoading, setIsLoading] = useState(false);
38
+
39
+ const handleCheckout = async () => {
40
+ setIsLoading(true);
41
+
42
+ const res = await useNombaCheckout({
43
+ accountId: 'your-account-id',
44
+ clientId: 'your-client-id',
45
+ order: {
46
+ callbackUrl: 'sample-url',
47
+ customerEmail: 'sample-email@gmail.com',
48
+ amount: '10.00',
49
+ currency: 'NGN',
50
+ orderMetaData: {
51
+ customMerchant: 'true',
52
+ },
53
+ splitRequest: {
54
+ splitType: 'PERCENTAGE',
55
+ splitList: [
56
+ {
57
+ accountId: 'your-account-id',
58
+ value: '65.45',
59
+ },
60
+ ],
61
+ },
62
+ },
63
+ tokenizeCard: 'true',
64
+ onCreateOrder: (orderReference) => {
65
+ console.log('Function called after the order is created');
66
+ console.log({ orderReference });
67
+ setIsLoading(false);
68
+ },
69
+ onFailure: (err) => {
70
+ console.log('Function called if error occurs while creating order.');
71
+ console.log(err);
72
+ setIsLoading(false);
73
+ },
74
+ onClose: () => {
75
+ console.log('Function called when modal is closed.');
76
+ setIsLoading(false);
77
+ },
78
+ onPaymentSuccess: (successResponse) => {
79
+ console.log('Function called on payment success.');
80
+ console.log({ successResponse });
81
+ },
82
+ });
83
+ };
84
+
85
+ return (
86
+ <>
87
+ <h1>Pay with Nomba</h1>
88
+ <button onClick={handleCheckout}>
89
+ {isLoading ? 'Please wait...' : 'Pay with Nomba Checkout'}
90
+ </button>
91
+ </>
92
+ );
90
93
  }
91
94
 
92
95
  export default App;
@@ -94,17 +97,297 @@ export default App;
94
97
 
95
98
  ---
96
99
 
100
+ ## 🔥 Next.js Integration (App Router)
101
+
102
+ For Next.js 13+ with App Router, follow this setup to ensure proper client-side rendering:
103
+
104
+ ### Step 1: Create the Checkout Component
105
+
106
+ Create `components/NombaCheckoutButton.tsx`:
107
+
108
+ ```tsx
109
+ 'use client';
110
+
111
+ import { useState, useEffect } from 'react';
112
+ import {
113
+ useNombaCheckout,
114
+ InitializeNombaCheckout,
115
+ } from 'react-nomba-checkout-sdk';
116
+
117
+ export default function NombaCheckoutButton() {
118
+ const [isLoading, setIsLoading] = useState(false);
119
+ const [isInitialized, setIsInitialized] = useState(false);
120
+
121
+ useEffect(() => {
122
+ InitializeNombaCheckout();
123
+ setIsInitialized(true);
124
+ }, []);
125
+
126
+ const handleCheckout = async () => {
127
+ if (!isInitialized) {
128
+ console.log('SDK not initialized yet');
129
+ return;
130
+ }
131
+
132
+ setIsLoading(true);
133
+
134
+ const res = await useNombaCheckout({
135
+ accountId: 'your-account-id',
136
+ clientId: 'your-client-id',
137
+ order: {
138
+ callbackUrl: 'https://your-callback-url.com',
139
+ customerEmail: 'sample-email@gmail.com',
140
+ amount: '10.00',
141
+ currency: 'NGN',
142
+ orderMetaData: {
143
+ customMerchant: 'true',
144
+ },
145
+ splitRequest: {
146
+ splitType: 'PERCENTAGE',
147
+ splitList: [
148
+ {
149
+ accountId: 'your-account-id',
150
+ value: 65.45,
151
+ },
152
+ ],
153
+ },
154
+ orderReference: 'your-order-reference',
155
+ customerId: '',
156
+ accountId: 'your-account-id',
157
+ },
158
+ tokenizeCard: true,
159
+ onCreateOrder: (orderReference) => {
160
+ console.log('Function called after the order is created');
161
+ console.log({ orderReference });
162
+ setIsLoading(false);
163
+ },
164
+ onFailure: (err) => {
165
+ console.log('Function called if error occurs while creating order.');
166
+ console.log(err);
167
+ setIsLoading(false);
168
+ },
169
+ onClose: () => {
170
+ console.log('Function called when modal is closed.');
171
+ setIsLoading(false);
172
+ return {};
173
+ },
174
+ onPaymentSuccess: (successResponse) => {
175
+ console.log('Function called on payment success.');
176
+ console.log({ successResponse });
177
+ return {};
178
+ },
179
+ });
180
+ };
181
+
182
+ return (
183
+ <>
184
+ <h1>Pay with Nomba</h1>
185
+ <button onClick={handleCheckout} disabled={!isInitialized}>
186
+ {isLoading ? 'Please wait...' : 'Pay with Nomba Checkout'}
187
+ </button>
188
+ </>
189
+ );
190
+ }
191
+ ```
192
+
193
+ ### Step 2: Use Dynamic Import in Your Page
194
+
195
+ Create or update your `app/page.tsx`:
196
+
197
+ ```tsx
198
+ 'use client';
199
+
200
+ import dynamic from 'next/dynamic';
201
+
202
+ // Dynamically import the component with SSR disabled
203
+ const NombaCheckoutButton = dynamic(
204
+ () => import('@/components/NombaCheckoutButton'),
205
+ { ssr: false }
206
+ );
207
+
208
+ export default function Home() {
209
+ return <NombaCheckoutButton />;
210
+ }
211
+ ```
212
+
213
+ ### Step 3: Configure Layout (Optional)
214
+
215
+ Update your `app/layout.tsx` if needed:
216
+
217
+ ```tsx
218
+ import type { Metadata } from 'next';
219
+ import { Geist, Geist_Mono } from 'next/font/google';
220
+ import './globals.css';
221
+
222
+ const geistSans = Geist({
223
+ variable: '--font-geist-sans',
224
+ subsets: ['latin'],
225
+ });
226
+
227
+ const geistMono = Geist_Mono({
228
+ variable: '--font-geist-mono',
229
+ subsets: ['latin'],
230
+ });
231
+
232
+ export const metadata: Metadata = {
233
+ title: 'Nomba Checkout Integration',
234
+ description: 'Payment processing with Nomba',
235
+ };
236
+
237
+ export default function RootLayout({
238
+ children,
239
+ }: Readonly<{
240
+ children: React.ReactNode;
241
+ }>) {
242
+ return (
243
+ <html lang='en'>
244
+ <body
245
+ className={`${geistSans.variable} ${geistMono.variable} antialiased`}
246
+ suppressHydrationWarning
247
+ >
248
+ {children}
249
+ </body>
250
+ </html>
251
+ );
252
+ }
253
+ ```
254
+
255
+ ### ⚠️ Important Next.js Notes
256
+
257
+ - **Always use dynamic import with `ssr: false`** - The SDK requires browser APIs and must be rendered client-side only
258
+ - **Initialize SDK in useEffect** - Ensures proper initialization after component mounts
259
+ - **Use 'use client' directive** - Required for components using browser-specific features
260
+ - **Check initialization state** - Prevent checkout calls before SDK is ready
261
+
262
+ ---
263
+
97
264
  ## 🔍 API Reference
98
265
 
99
- ### `InitializeNombaCheckout()`
266
+ ### InitializeNombaCheckout()
267
+
268
+ Initializes the SDK. Call once when your app loads (or in useEffect for Next.js).
269
+
270
+ ```js
271
+ InitializeNombaCheckout();
272
+ ```
273
+
274
+ ---
275
+
276
+ ### useNombaCheckout(options)
277
+
278
+ Launches the Nomba checkout modal.
279
+
280
+ #### Options
100
281
 
101
- Initializes the SDK. Call once when your app loads.
282
+ | Parameter | Type | Required | Description |
283
+ | ------------------ | -------------- | -------- | ------------------------------ |
284
+ | `accountId` | string | Yes | Your Nomba account ID |
285
+ | `clientId` | string | Yes | Your Nomba client ID |
286
+ | `order` | object | Yes | Order details (see below) |
287
+ | `tokenizeCard` | boolean/string | No | Enable card tokenization |
288
+ | `onCreateOrder` | function | No | Callback after order creation |
289
+ | `onFailure` | function | No | Callback on error |
290
+ | `onClose` | function | No | Callback when modal closes |
291
+ | `onPaymentSuccess` | function | No | Callback on successful payment |
292
+
293
+ #### Order Object
294
+
295
+ | Field | Type | Required | Description |
296
+ | ---------------- | ------ | -------- | --------------------------- |
297
+ | `callbackUrl` | string | Yes | URL for payment callback |
298
+ | `customerEmail` | string | Yes | Customer's email address |
299
+ | `amount` | string | Yes | Payment amount |
300
+ | `currency` | string | Yes | Currency code (e.g., 'NGN') |
301
+ | `orderReference` | string | No | Your order reference |
302
+ | `customerId` | string | No | Customer identifier |
303
+ | `accountId` | string | No | Account ID for the order |
304
+ | `orderMetaData` | object | No | Additional metadata |
305
+ | `splitRequest` | object | No | Payment split configuration |
306
+
307
+ #### Split Request Object
308
+
309
+ | Field | Type | Required | Description |
310
+ | ----------- | ------ | -------- | ----------------------------- |
311
+ | `splitType` | string | Yes | 'PERCENTAGE' or 'FLAT' |
312
+ | `splitList` | array | Yes | Array of split configurations |
313
+
314
+ #### Split List Item
315
+
316
+ | Field | Type | Required | Description |
317
+ | ----------- | ------------- | -------- | --------------------------- |
318
+ | `accountId` | string | Yes | Account ID to receive split |
319
+ | `value` | number/string | Yes | Split amount or percentage |
102
320
 
103
321
  ---
104
322
 
105
- ### `useNombaCheckout(options)`
323
+ ## 📝 Example with All Options
106
324
 
107
- Launches the Nomba checkout modal. |
325
+ ```jsx
326
+ const res = await useNombaCheckout({
327
+ accountId: 'acc_123456',
328
+ clientId: 'client_123456',
329
+ order: {
330
+ callbackUrl: 'https://yoursite.com/payment/callback',
331
+ customerEmail: 'customer@example.com',
332
+ amount: '5000.00',
333
+ currency: 'NGN',
334
+ orderReference: 'ORDER-2024-001',
335
+ customerId: 'CUST-001',
336
+ accountId: 'acc_123456',
337
+ orderMetaData: {
338
+ customMerchant: 'true',
339
+ productName: 'Premium Plan',
340
+ },
341
+ splitRequest: {
342
+ splitType: 'PERCENTAGE',
343
+ splitList: [
344
+ {
345
+ accountId: 'acc_partner_1',
346
+ value: 20,
347
+ },
348
+ {
349
+ accountId: 'acc_partner_2',
350
+ value: 15,
351
+ },
352
+ ],
353
+ },
354
+ },
355
+ tokenizeCard: true,
356
+ onCreateOrder: (orderReference) => {
357
+ console.log('Order created:', orderReference);
358
+ },
359
+ onFailure: (error) => {
360
+ console.error('Payment failed:', error);
361
+ },
362
+ onClose: () => {
363
+ console.log('Checkout modal closed');
364
+ return {};
365
+ },
366
+ onPaymentSuccess: (response) => {
367
+ console.log('Payment successful:', response);
368
+ return {};
369
+ },
370
+ });
371
+ ```
372
+
373
+ ---
374
+
375
+ ## 🛠️ Troubleshooting
376
+
377
+ ### Next.js Hydration Errors
378
+
379
+ - Ensure you're using `dynamic` import with `ssr: false`
380
+ - Add `suppressHydrationWarning` to your body tag in layout.tsx
381
+
382
+ ### SDK Not Initialized
383
+
384
+ - In Next.js, initialize the SDK in `useEffect`
385
+ - Check that the button is disabled until `isInitialized` is true
386
+
387
+ ### Modal Not Opening
388
+
389
+ - Verify that `InitializeNombaCheckout()` was called before `useNombaCheckout()`
390
+ - Check browser console for errors
108
391
 
109
392
  ---
110
393
 
@@ -112,4 +395,23 @@ Launches the Nomba checkout modal. |
112
395
 
113
396
  **Israel Itua**
114
397
  Frontend Engineer
115
- [GitHub](https://github.com/the-israelItua/)
398
+ [GitHub](https://github.com/the-israelItua/)
399
+
400
+ ---
401
+
402
+ ## 👥 Contributors
403
+
404
+ - **Israel Itua** - Original Author - [GitHub](https://github.com/the-israelItua/)
405
+ - **Kelechi Uma** - Contributor - [GitHub](https://github.com/Kusjay)
406
+
407
+ ---
408
+
409
+ ## 📄 License
410
+
411
+ MIT
412
+
413
+ ---
414
+
415
+ ## 🤝 Contributing
416
+
417
+ Contributions, issues, and feature requests are welcome!
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-nomba-checkout-sdk",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",