spaark-payapi-sdk 1.6.0 → 1.7.1
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.
- package/README.md +395 -73
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/react.js +2 -2
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +2 -2
- package/dist/react.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
# spaark-payapi-sdk
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for Pawapay Mobile Money API (V2). Simplifies integration with Mobile Money operators in Africa.
|
|
3
|
+
TypeScript SDK for Pawapay Mobile Money API (V2). Simplifies integration with Mobile Money operators in Africa (CEMAC region).
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/spaark-payapi-sdk)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Installation](#installation)
|
|
12
|
+
- [Quick Start](#quick-start)
|
|
13
|
+
- [Features](#features)
|
|
14
|
+
- [Project Architecture](#project-architecture)
|
|
15
|
+
- [Supported Providers](#supported-providers)
|
|
16
|
+
- [API Reference](#api-reference)
|
|
17
|
+
- [Initialization](#initialization)
|
|
18
|
+
- [Transactions](#transactions)
|
|
19
|
+
- [Toolkit](#toolkit)
|
|
20
|
+
- [Finances](#finances)
|
|
21
|
+
- [Webhooks](#webhooks)
|
|
22
|
+
- [Products](#products)
|
|
23
|
+
- [Utilities](#utilities)
|
|
24
|
+
- [React Components](#react-components)
|
|
25
|
+
- [Test Dashboard](#test-dashboard)
|
|
26
|
+
- [Finance Dashboard](#finance-dashboard)
|
|
27
|
+
- [TypeScript Types](#typescript-types)
|
|
28
|
+
- [Error Handling](#error-handling)
|
|
29
|
+
- [Environment Variables](#environment-variables)
|
|
30
|
+
- [Development](#development)
|
|
31
|
+
- [License](#license)
|
|
7
32
|
|
|
8
33
|
## Installation
|
|
9
34
|
|
|
@@ -24,7 +49,7 @@ The SDK includes React components built with shadcn/ui patterns. Install the req
|
|
|
24
49
|
|
|
25
50
|
```bash
|
|
26
51
|
# Core React dependencies
|
|
27
|
-
npm install react react-dom
|
|
52
|
+
npm install react react-dom axios
|
|
28
53
|
|
|
29
54
|
# shadcn/ui prerequisites (via shadcn CLI)
|
|
30
55
|
pnpm dlx shadcn@latest add button
|
|
@@ -34,7 +59,7 @@ pnpm dlx shadcn@latest add chart
|
|
|
34
59
|
pnpm dlx shadcn@latest add skeleton
|
|
35
60
|
pnpm dlx shadcn@latest add spinner
|
|
36
61
|
|
|
37
|
-
# Or install manually
|
|
62
|
+
# Or install manually (lucide-react is required for icons)
|
|
38
63
|
npm install lucide-react @radix-ui/react-tabs @radix-ui/react-select @radix-ui/react-dialog recharts @tanstack/react-table
|
|
39
64
|
|
|
40
65
|
# The following are bundled with the SDK (no need to install):
|
|
@@ -70,26 +95,94 @@ console.log(deposit.depositId, deposit.status);
|
|
|
70
95
|
|
|
71
96
|
## Features
|
|
72
97
|
|
|
73
|
-
|
|
74
|
-
- **
|
|
98
|
+
### Core SDK
|
|
99
|
+
- **Transactions**: Deposits, Payouts, Refunds, Payment Page, Polling
|
|
100
|
+
- **Toolkit**: Predict Provider, Active Configuration, Provider Availability, Public Keys
|
|
75
101
|
- **Finances**: Wallet Balances, Statement Generation
|
|
76
|
-
- **Webhooks**:
|
|
77
|
-
- **
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
- **
|
|
102
|
+
- **Webhooks**: HMAC-SHA256 signature verification, Event parsing
|
|
103
|
+
- **Products**: Product management with domain configuration
|
|
104
|
+
|
|
105
|
+
### React Components
|
|
106
|
+
- **Test Dashboard**: Interactive SDK testing UI with 4 modes and 6 tabs
|
|
107
|
+
- **Demo Mode**: Finance Dashboard with mock data (no API key required)
|
|
108
|
+
- **Demo Expert**: Test Dashboard with simulated API responses (no API key required)
|
|
109
|
+
- **Sandbox Mode**: Finance Dashboard connected to Pawapay sandbox API
|
|
110
|
+
- **Production Mode**: Finance Dashboard connected to Pawapay production API
|
|
111
|
+
- **Finance Dashboard**: Transaction analytics with charts and KPIs
|
|
112
|
+
- **Icons**: lucide-react icons throughout the UI
|
|
113
|
+
- **shadcn/ui Components**: Button, Tabs, Select, Card, Input, Table, Skeleton, Spinner
|
|
114
|
+
- **Charts**: Area, Bar, Pie charts with Recharts
|
|
81
115
|
- **i18n**: French/English support
|
|
82
116
|
|
|
117
|
+
### Developer Experience
|
|
118
|
+
- **Full TypeScript**: Complete type definitions with strict mode
|
|
119
|
+
- **Zod Validation**: Input validation for all requests
|
|
120
|
+
- **Retry Logic**: Exponential backoff with jitter
|
|
121
|
+
- **Logging**: Configurable log levels with sensitive data sanitization
|
|
122
|
+
- **Error Handling**: Typed errors with retryable flag
|
|
123
|
+
|
|
124
|
+
## Project Architecture
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
src/
|
|
128
|
+
├── sdk.ts # Main SpaarkPayApiSdk class
|
|
129
|
+
├── config.ts # Configuration validation (Zod)
|
|
130
|
+
├── index.ts # Main exports
|
|
131
|
+
├── react.tsx # React components entry point
|
|
132
|
+
│
|
|
133
|
+
├── modules/
|
|
134
|
+
│ ├── transactions.ts # Deposits, payouts, refunds, polling
|
|
135
|
+
│ ├── products.ts # Product management
|
|
136
|
+
│ ├── webhooks.ts # Signature verification, event parsing
|
|
137
|
+
│ ├── utils.ts # Helpers, availability, prediction
|
|
138
|
+
│ └── finances.ts # Wallet balances, statements
|
|
139
|
+
│
|
|
140
|
+
├── core/
|
|
141
|
+
│ ├── http-client.ts # Axios wrapper with interceptors
|
|
142
|
+
│ ├── retry.ts # Exponential backoff logic
|
|
143
|
+
│ ├── errors.ts # PawapayError class
|
|
144
|
+
│ └── logger.ts # Configurable logger
|
|
145
|
+
│
|
|
146
|
+
├── types/
|
|
147
|
+
│ ├── config.ts # SDK configuration types
|
|
148
|
+
│ ├── transactions.ts # Transaction types
|
|
149
|
+
│ ├── webhooks.ts # Webhook event types
|
|
150
|
+
│ ├── toolkit.ts # Toolkit types
|
|
151
|
+
│ ├── finances.ts # Finance types
|
|
152
|
+
│ └── products.ts # Product types
|
|
153
|
+
│
|
|
154
|
+
├── constants/
|
|
155
|
+
│ ├── correspondents.ts # Provider definitions & limits
|
|
156
|
+
│ └── errors.ts # Error code definitions
|
|
157
|
+
│
|
|
158
|
+
├── components/
|
|
159
|
+
│ └── SpaarkPaySdkFinanceDashboard.tsx
|
|
160
|
+
│
|
|
161
|
+
├── mocks/
|
|
162
|
+
│ └── webhook-generators.ts # Test webhook generation
|
|
163
|
+
│
|
|
164
|
+
└── lib/
|
|
165
|
+
└── utils.ts # Tailwind merge utility
|
|
166
|
+
```
|
|
167
|
+
|
|
83
168
|
## Supported Providers
|
|
84
169
|
|
|
85
|
-
| Provider | Country | Currency |
|
|
86
|
-
|
|
87
|
-
| `MTN_MOMO_CMR` | Cameroon | XAF |
|
|
88
|
-
| `ORANGE_CMR` | Cameroon | XAF |
|
|
89
|
-
| `MTN_MOMO_COG` | Congo | XAF |
|
|
90
|
-
| `AIRTEL_COG` | Congo | XAF |
|
|
91
|
-
| `MTN_MOMO_GAB` | Gabon | XAF |
|
|
92
|
-
| `AIRTEL_GAB` | Gabon | XAF |
|
|
170
|
+
| Provider | Country | Currency | Deposits | Payouts |
|
|
171
|
+
|----------|---------|----------|----------|---------|
|
|
172
|
+
| `MTN_MOMO_CMR` | Cameroon | XAF | 100 - 1,000,000 | 500 - 500,000 |
|
|
173
|
+
| `ORANGE_CMR` | Cameroon | XAF | 100 - 1,000,000 | 500 - 500,000 |
|
|
174
|
+
| `MTN_MOMO_COG` | Congo | XAF | 100 - 1,000,000 | 500 - 500,000 |
|
|
175
|
+
| `AIRTEL_COG` | Congo | XAF | 100 - 1,000,000 | 500 - 500,000 |
|
|
176
|
+
| `MTN_MOMO_GAB` | Gabon | XAF | 100 - 1,000,000 | 500 - 500,000 |
|
|
177
|
+
| `AIRTEL_GAB` | Gabon | XAF | 100 - 1,000,000 | 500 - 500,000 |
|
|
178
|
+
|
|
179
|
+
### Phone Number Formats
|
|
180
|
+
|
|
181
|
+
| Country | Format | Example |
|
|
182
|
+
|---------|--------|---------|
|
|
183
|
+
| Cameroon | `237XXXXXXXXX` | 237670000000 |
|
|
184
|
+
| Congo | `242XXXXXXXXX` | 242060000000 |
|
|
185
|
+
| Gabon | `241XXXXXXXX` | 24160000000 |
|
|
93
186
|
|
|
94
187
|
## API Reference
|
|
95
188
|
|
|
@@ -99,12 +192,16 @@ console.log(deposit.depositId, deposit.status);
|
|
|
99
192
|
import { SpaarkPayApiSdk } from 'spaark-payapi-sdk';
|
|
100
193
|
|
|
101
194
|
const sdk = new SpaarkPayApiSdk({
|
|
102
|
-
apiKey: process.env.PAWAPAY_API_KEY,
|
|
103
|
-
environment: 'sandbox',
|
|
104
|
-
timeout: 30000,
|
|
105
|
-
retries: 3,
|
|
106
|
-
logLevel: 'info',
|
|
195
|
+
apiKey: process.env.PAWAPAY_API_KEY, // Required
|
|
196
|
+
environment: 'sandbox', // 'sandbox' | 'production'
|
|
197
|
+
timeout: 30000, // Request timeout in ms (default: 30000)
|
|
198
|
+
retries: 3, // Retry attempts (default: 3)
|
|
199
|
+
logLevel: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'none'
|
|
107
200
|
});
|
|
201
|
+
|
|
202
|
+
// Runtime configuration
|
|
203
|
+
sdk.setLogLevel('debug');
|
|
204
|
+
sdk.setWebhookSecret('whsec_xxxxxxxxxxxx');
|
|
108
205
|
```
|
|
109
206
|
|
|
110
207
|
### Transactions
|
|
@@ -117,10 +214,10 @@ const deposit = await sdk.transactions.initiateDeposit({
|
|
|
117
214
|
currency: 'XAF',
|
|
118
215
|
provider: 'MTN_MOMO_CMR',
|
|
119
216
|
phoneNumber: '237670000000',
|
|
120
|
-
transactionId: sdk.utils.generateTransactionId(),
|
|
121
|
-
customerMessage: 'Payment description',
|
|
122
|
-
clientReferenceId: 'order-123',
|
|
123
|
-
metadata: [{ orderId: 'ORD-123' }],
|
|
217
|
+
transactionId: sdk.utils.generateTransactionId(), // UUID v4 required
|
|
218
|
+
customerMessage: 'Payment description', // 4-22 chars
|
|
219
|
+
clientReferenceId: 'order-123', // Optional
|
|
220
|
+
metadata: [{ orderId: 'ORD-123' }], // Optional
|
|
124
221
|
});
|
|
125
222
|
|
|
126
223
|
// Response
|
|
@@ -168,8 +265,8 @@ const status = await sdk.transactions.checkStatus('transaction-uuid');
|
|
|
168
265
|
|
|
169
266
|
```typescript
|
|
170
267
|
const result = await sdk.transactions.pollUntilComplete('transaction-uuid', {
|
|
171
|
-
interval: 5000, // Poll every 5 seconds
|
|
172
|
-
maxAttempts: 12, // Max 12 attempts (
|
|
268
|
+
interval: 5000, // Poll every 5 seconds (default)
|
|
269
|
+
maxAttempts: 12, // Max 12 attempts (default)
|
|
173
270
|
onStatusChange: (status) => console.log('Status:', status),
|
|
174
271
|
});
|
|
175
272
|
```
|
|
@@ -192,7 +289,7 @@ const page = await sdk.transactions.createPaymentPage({
|
|
|
192
289
|
returnUrl: 'https://yoursite.com/payment/complete',
|
|
193
290
|
phoneNumber: '237670000000', // Optional
|
|
194
291
|
amountDetails: { amount: 5000, currency: 'XAF' }, // Optional
|
|
195
|
-
language: 'FR', // Optional
|
|
292
|
+
language: 'FR', // Optional: 'FR' | 'EN'
|
|
196
293
|
country: 'CMR', // Optional
|
|
197
294
|
reason: 'Ticket purchase', // Optional
|
|
198
295
|
});
|
|
@@ -223,7 +320,7 @@ const prediction = await sdk.utils.predictProvider('+237 670 000 000');
|
|
|
223
320
|
```typescript
|
|
224
321
|
const availability = await sdk.utils.getProviderAvailability({
|
|
225
322
|
country: 'CMR', // Optional
|
|
226
|
-
operationType: 'DEPOSIT', // Optional
|
|
323
|
+
operationType: 'DEPOSIT', // Optional: 'DEPOSIT' | 'PAYOUT' | 'REFUND'
|
|
227
324
|
});
|
|
228
325
|
```
|
|
229
326
|
|
|
@@ -231,6 +328,7 @@ const availability = await sdk.utils.getProviderAvailability({
|
|
|
231
328
|
|
|
232
329
|
```typescript
|
|
233
330
|
const config = await sdk.utils.getActiveConfiguration();
|
|
331
|
+
// Returns company config, countries, providers, currencies, limits
|
|
234
332
|
```
|
|
235
333
|
|
|
236
334
|
#### Check MMO Availability
|
|
@@ -240,6 +338,13 @@ const status = await sdk.utils.checkMMOAvailability('MTN_MOMO_CMR');
|
|
|
240
338
|
// { correspondent: 'MTN_MOMO_CMR', available: true, degraded: false }
|
|
241
339
|
```
|
|
242
340
|
|
|
341
|
+
#### Get Public Keys
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
const keys = await sdk.utils.getPublicKeys();
|
|
345
|
+
// [{ id: 'key-001', key: 'MIIBIjANBgkqhkiG9w0BAQEFAA...' }]
|
|
346
|
+
```
|
|
347
|
+
|
|
243
348
|
### Finances
|
|
244
349
|
|
|
245
350
|
#### Wallet Balances
|
|
@@ -260,22 +365,51 @@ const statement = await sdk.finances.generateStatement({
|
|
|
260
365
|
compressed: true,
|
|
261
366
|
});
|
|
262
367
|
|
|
368
|
+
// Poll until complete
|
|
263
369
|
const result = await sdk.finances.pollStatementUntilComplete(statement.statementId);
|
|
264
370
|
console.log(result.downloadUrl);
|
|
265
371
|
```
|
|
266
372
|
|
|
267
373
|
### Webhooks
|
|
268
374
|
|
|
375
|
+
#### Setup
|
|
376
|
+
|
|
269
377
|
```typescript
|
|
270
|
-
// Set secret
|
|
378
|
+
// Set webhook secret
|
|
271
379
|
sdk.setWebhookSecret(process.env.PAWAPAY_WEBHOOK_SECRET);
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
#### Verify Signature
|
|
272
383
|
|
|
273
|
-
|
|
384
|
+
```typescript
|
|
274
385
|
const isValid = sdk.webhooks.verifySignature(body, signature);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### Parse Event
|
|
275
389
|
|
|
276
|
-
|
|
390
|
+
```typescript
|
|
277
391
|
const event = sdk.webhooks.parseEvent(body);
|
|
278
392
|
|
|
393
|
+
// Or verify + parse in one step
|
|
394
|
+
const event = sdk.webhooks.constructEvent(body, signature);
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
#### Event Types
|
|
398
|
+
|
|
399
|
+
| Event Type | Description |
|
|
400
|
+
|------------|-------------|
|
|
401
|
+
| `deposit.accepted` | Deposit request accepted |
|
|
402
|
+
| `deposit.completed` | Deposit completed successfully |
|
|
403
|
+
| `deposit.failed` | Deposit failed |
|
|
404
|
+
| `payout.accepted` | Payout request accepted |
|
|
405
|
+
| `payout.completed` | Payout completed successfully |
|
|
406
|
+
| `payout.failed` | Payout failed |
|
|
407
|
+
| `refund.completed` | Refund completed successfully |
|
|
408
|
+
| `refund.failed` | Refund failed |
|
|
409
|
+
|
|
410
|
+
#### Handle Events
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
279
413
|
switch (event.eventType) {
|
|
280
414
|
case 'deposit.completed':
|
|
281
415
|
console.log('Deposit completed:', event.data.depositId);
|
|
@@ -286,20 +420,54 @@ switch (event.eventType) {
|
|
|
286
420
|
case 'payout.completed':
|
|
287
421
|
console.log('Payout completed:', event.data.payoutId);
|
|
288
422
|
break;
|
|
423
|
+
case 'payout.failed':
|
|
424
|
+
console.log('Payout failed:', event.data.failureReason);
|
|
425
|
+
break;
|
|
289
426
|
}
|
|
290
427
|
```
|
|
291
428
|
|
|
429
|
+
### Products
|
|
430
|
+
|
|
431
|
+
Local product management (in-memory storage):
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
// Create product
|
|
435
|
+
const product = await sdk.products.create({
|
|
436
|
+
name: 'Premium Plan',
|
|
437
|
+
price: 10000,
|
|
438
|
+
currency: 'XAF',
|
|
439
|
+
description: 'Monthly subscription',
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// Get product
|
|
443
|
+
const product = await sdk.products.get('product-id');
|
|
444
|
+
|
|
445
|
+
// List products
|
|
446
|
+
const products = await sdk.products.list();
|
|
447
|
+
|
|
448
|
+
// Update product
|
|
449
|
+
await sdk.products.update('product-id', { price: 12000 });
|
|
450
|
+
|
|
451
|
+
// Delete product
|
|
452
|
+
await sdk.products.delete('product-id');
|
|
453
|
+
|
|
454
|
+
// Add/remove domains
|
|
455
|
+
await sdk.products.addDomain({ productId: 'product-id', domain: 'example.com' });
|
|
456
|
+
await sdk.products.removeDomain('product-id', 'example.com');
|
|
457
|
+
```
|
|
458
|
+
|
|
292
459
|
### Utilities
|
|
293
460
|
|
|
294
461
|
```typescript
|
|
295
|
-
// Generate UUID v4
|
|
462
|
+
// Generate UUID v4 transaction ID
|
|
296
463
|
const txId = sdk.utils.generateTransactionId();
|
|
297
464
|
|
|
298
|
-
// Validate transaction ID
|
|
465
|
+
// Validate transaction ID format
|
|
299
466
|
const isValid = sdk.utils.validateTransactionId(txId);
|
|
300
467
|
|
|
301
|
-
// Format phone number
|
|
468
|
+
// Format phone number for country
|
|
302
469
|
const phone = sdk.utils.formatPhoneNumber('670000000', 'CMR');
|
|
470
|
+
// '237670000000'
|
|
303
471
|
|
|
304
472
|
// Validate phone for provider
|
|
305
473
|
const isValid = sdk.utils.validatePhoneNumber('237670000000', 'MTN_MOMO_CMR');
|
|
@@ -307,10 +475,10 @@ const isValid = sdk.utils.validatePhoneNumber('237670000000', 'MTN_MOMO_CMR');
|
|
|
307
475
|
// Get provider info
|
|
308
476
|
const info = sdk.utils.getCorrespondentInfo('MTN_MOMO_CMR');
|
|
309
477
|
|
|
310
|
-
// Detect provider from phone
|
|
478
|
+
// Detect provider from phone number
|
|
311
479
|
const provider = sdk.utils.detectCorrespondent('237670000000');
|
|
312
480
|
|
|
313
|
-
// Get transaction limits
|
|
481
|
+
// Get transaction limits for provider
|
|
314
482
|
const limits = await sdk.utils.getTransactionLimits('MTN_MOMO_CMR');
|
|
315
483
|
```
|
|
316
484
|
|
|
@@ -318,27 +486,72 @@ const limits = await sdk.utils.getTransactionLimits('MTN_MOMO_CMR');
|
|
|
318
486
|
|
|
319
487
|
### Test Dashboard
|
|
320
488
|
|
|
489
|
+
Interactive testing UI with **4 operation modes** and 6 tabs (Deposit, Payout, Status, Toolkit, Finances, Webhooks).
|
|
490
|
+
|
|
491
|
+
#### Dashboard Modes
|
|
492
|
+
|
|
493
|
+
| Mode | Description | API Key Required |
|
|
494
|
+
|------|-------------|------------------|
|
|
495
|
+
| **Demo** | Finance Dashboard with mock/fake data | No |
|
|
496
|
+
| **Demo Expert** | Test Dashboard with simulated API responses | No |
|
|
497
|
+
| **Sandbox** | Finance Dashboard connected to Pawapay sandbox API | Yes |
|
|
498
|
+
| **Production** | Finance Dashboard connected to Pawapay production API | Yes |
|
|
499
|
+
|
|
321
500
|
```tsx
|
|
322
501
|
import { SpaarkPaySdkTestDashboard } from 'spaark-payapi-sdk/react';
|
|
323
502
|
|
|
324
503
|
export default function TestPage() {
|
|
325
504
|
return (
|
|
326
505
|
<SpaarkPaySdkTestDashboard
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
506
|
+
apiKey="pk_sandbox_xxx" // Optional: pre-configured API key
|
|
507
|
+
environment="sandbox" // 'sandbox' | 'production'
|
|
508
|
+
apiBasePath="/api/pawapay" // Backend proxy route
|
|
509
|
+
demoMode={false} // Start in demo mode (default: false)
|
|
330
510
|
onDepositComplete={(res) => console.log('Deposit:', res)}
|
|
331
511
|
onPayoutComplete={(res) => console.log('Payout:', res)}
|
|
332
512
|
onError={(err) => console.error(err)}
|
|
513
|
+
className="max-w-6xl mx-auto"
|
|
333
514
|
/>
|
|
334
515
|
);
|
|
335
516
|
}
|
|
336
517
|
```
|
|
337
518
|
|
|
338
|
-
|
|
519
|
+
**Mode Selection:**
|
|
520
|
+
- Without `apiKey` or `demoMode`: Shows mode selection screen
|
|
521
|
+
- With `demoMode={true}`: Starts directly in Demo mode
|
|
522
|
+
- With `apiKey` + `environment`: Starts in Sandbox or Production mode
|
|
523
|
+
|
|
524
|
+
#### Backend Proxy Setup (Next.js)
|
|
525
|
+
|
|
526
|
+
```typescript
|
|
527
|
+
// app/api/pawapay/deposit/route.ts
|
|
528
|
+
import { SpaarkPayApiSdk } from 'spaark-payapi-sdk';
|
|
529
|
+
|
|
530
|
+
export async function POST(request: Request) {
|
|
531
|
+
const body = await request.json();
|
|
532
|
+
|
|
533
|
+
const sdk = new SpaarkPayApiSdk({
|
|
534
|
+
apiKey: body.apiKey,
|
|
535
|
+
environment: body.environment,
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
const result = await sdk.transactions.initiateDeposit({
|
|
539
|
+
amount: body.amount,
|
|
540
|
+
currency: body.currency,
|
|
541
|
+
provider: body.provider,
|
|
542
|
+
phoneNumber: body.phoneNumber,
|
|
543
|
+
transactionId: body.transactionId,
|
|
544
|
+
customerMessage: body.customerMessage,
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
return Response.json(result);
|
|
548
|
+
}
|
|
549
|
+
```
|
|
339
550
|
|
|
340
551
|
### Finance Dashboard
|
|
341
552
|
|
|
553
|
+
Transaction analytics dashboard with KPI cards, filters, pagination, and charts.
|
|
554
|
+
|
|
342
555
|
```tsx
|
|
343
556
|
import {
|
|
344
557
|
SpaarkPaySdkFinanceDashboard,
|
|
@@ -356,7 +569,6 @@ const transactions: Transaction[] = [
|
|
|
356
569
|
phoneNumber: '237670000000',
|
|
357
570
|
createdAt: '2025-01-15T10:00:00Z',
|
|
358
571
|
},
|
|
359
|
-
// ... more transactions
|
|
360
572
|
];
|
|
361
573
|
|
|
362
574
|
export default function FinancePage() {
|
|
@@ -366,10 +578,10 @@ export default function FinancePage() {
|
|
|
366
578
|
title="My Finance Dashboard"
|
|
367
579
|
subtitle="Overview of your transactions"
|
|
368
580
|
locale="fr" // 'fr' | 'en'
|
|
369
|
-
onRefresh={() => fetchData()} // Refresh button
|
|
581
|
+
onRefresh={() => fetchData()} // Refresh button callback
|
|
370
582
|
onSettings={() => openSettings()} // Settings button (gear icon)
|
|
371
|
-
onAddTransaction={() => openForm()} // CTA when
|
|
372
|
-
onTransactionClick={(tx) => {}} //
|
|
583
|
+
onAddTransaction={() => openForm()} // CTA button when no transactions
|
|
584
|
+
onTransactionClick={(tx) => {}} // Table row click
|
|
373
585
|
onExpertModeClick={() => {}} // Expert mode button
|
|
374
586
|
showExpertMode={true}
|
|
375
587
|
isLoading={false}
|
|
@@ -392,17 +604,16 @@ export default function FinancePage() {
|
|
|
392
604
|
| `onTransactionClick` | `(tx) => void` | Table row click callback |
|
|
393
605
|
| `onExpertModeClick` | `() => void` | Expert mode button callback |
|
|
394
606
|
| `showExpertMode` | `boolean` | Show/hide expert mode button |
|
|
395
|
-
| `isLoading` | `boolean` | Show loading
|
|
607
|
+
| `isLoading` | `boolean` | Show loading skeletons |
|
|
396
608
|
|
|
397
609
|
**Features:**
|
|
398
610
|
|
|
399
611
|
**Dashboard Tab:**
|
|
400
|
-
- 8 KPI cards
|
|
401
|
-
- Row 1: Total Volume, Deposits, Payouts, Refunds
|
|
402
|
-
- Row 2: Pending, Completed, Failed, Cancelled
|
|
612
|
+
- 8 KPI cards: Total Volume, Deposits, Payouts, Refunds, Pending, Completed, Failed, Cancelled
|
|
403
613
|
- Search by transaction ID or phone number
|
|
404
|
-
- Dropdown filters
|
|
405
|
-
- Paginated transactions table with
|
|
614
|
+
- Dropdown filters for type and status
|
|
615
|
+
- Paginated transactions table with @tanstack/react-table
|
|
616
|
+
- Copy transaction ID button
|
|
406
617
|
- Empty state with CTA button
|
|
407
618
|
|
|
408
619
|
**Charts Tab:**
|
|
@@ -410,46 +621,73 @@ export default function FinancePage() {
|
|
|
410
621
|
- Bar Chart: Transaction amounts by type
|
|
411
622
|
- Pie Chart: Status distribution (donut style)
|
|
412
623
|
|
|
413
|
-
**UI Components (shadcn/ui style):**
|
|
414
|
-
- Button (default, outline, ghost, secondary variants)
|
|
415
|
-
- Tabs (Dashboard / Charts)
|
|
416
|
-
- Select with dropdown
|
|
417
|
-
- Card with header and content
|
|
418
|
-
- Input with search icon
|
|
419
|
-
- Spinner for loading states
|
|
420
|
-
|
|
421
|
-
**i18n:**
|
|
422
|
-
- French (default) and English support
|
|
423
|
-
- All labels, buttons, and chart legends translated
|
|
424
|
-
|
|
425
624
|
## TypeScript Types
|
|
426
625
|
|
|
427
626
|
```typescript
|
|
428
627
|
import type {
|
|
429
628
|
// SDK Config
|
|
430
629
|
SpaarkPayApiSdkConfig,
|
|
630
|
+
ResolvedConfig,
|
|
631
|
+
Environment,
|
|
632
|
+
LogLevel,
|
|
431
633
|
|
|
432
634
|
// Transactions
|
|
433
635
|
DepositRequest,
|
|
434
636
|
DepositResponse,
|
|
435
637
|
PayoutRequest,
|
|
436
638
|
PayoutResponse,
|
|
639
|
+
RefundRequest,
|
|
640
|
+
RefundResponse,
|
|
437
641
|
TransactionStatus,
|
|
438
642
|
TransactionStatusResponse,
|
|
643
|
+
PaymentPageRequest,
|
|
644
|
+
PaymentPageResponse,
|
|
645
|
+
PollOptions,
|
|
646
|
+
FailureReason,
|
|
647
|
+
DepositFailureCode,
|
|
648
|
+
PayoutFailureCode,
|
|
439
649
|
|
|
440
650
|
// Providers
|
|
441
651
|
Correspondent,
|
|
652
|
+
CorrespondentInfo,
|
|
653
|
+
TransactionLimits,
|
|
442
654
|
Currency,
|
|
443
655
|
|
|
656
|
+
// Webhooks
|
|
657
|
+
WebhookEventType,
|
|
658
|
+
PawapayWebhookEvent,
|
|
659
|
+
DepositCallbackData,
|
|
660
|
+
PayoutCallbackData,
|
|
661
|
+
|
|
662
|
+
// Toolkit
|
|
663
|
+
OperationType,
|
|
664
|
+
OperationStatus,
|
|
665
|
+
ProviderAvailability,
|
|
666
|
+
ActiveConfigResponse,
|
|
667
|
+
PredictProviderResponse,
|
|
668
|
+
PublicKeyResponse,
|
|
669
|
+
|
|
670
|
+
// Finances
|
|
671
|
+
WalletBalance,
|
|
672
|
+
StatementRequest,
|
|
673
|
+
StatementResponse,
|
|
674
|
+
StatementStatus,
|
|
675
|
+
|
|
676
|
+
// Products
|
|
677
|
+
Product,
|
|
678
|
+
ProductCreateRequest,
|
|
679
|
+
|
|
444
680
|
// React Components
|
|
445
681
|
Transaction,
|
|
446
682
|
TransactionType,
|
|
447
|
-
TransactionStatus,
|
|
448
683
|
SpaarkPaySdkFinanceDashboardProps,
|
|
449
684
|
SpaarkPaySdkTestDashboardProps,
|
|
450
685
|
} from 'spaark-payapi-sdk';
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
### Transaction Type (Finance Dashboard)
|
|
451
689
|
|
|
452
|
-
|
|
690
|
+
```typescript
|
|
453
691
|
type Transaction = {
|
|
454
692
|
id: string;
|
|
455
693
|
type: 'deposit' | 'payout' | 'refund';
|
|
@@ -474,22 +712,106 @@ try {
|
|
|
474
712
|
await sdk.transactions.initiateDeposit({ ... });
|
|
475
713
|
} catch (error) {
|
|
476
714
|
if (error instanceof PawapayError) {
|
|
477
|
-
console.log(error.code);
|
|
478
|
-
console.log(error.message);
|
|
479
|
-
console.log(error.retryable);
|
|
480
|
-
console.log(error.statusCode);
|
|
715
|
+
console.log(error.code); // Error code
|
|
716
|
+
console.log(error.message); // Human-readable message
|
|
717
|
+
console.log(error.retryable); // Whether to retry
|
|
718
|
+
console.log(error.statusCode); // HTTP status code
|
|
719
|
+
console.log(error.failureReason); // Pawapay failure reason
|
|
481
720
|
}
|
|
482
721
|
}
|
|
483
722
|
```
|
|
484
723
|
|
|
724
|
+
### Error Codes
|
|
725
|
+
|
|
726
|
+
| Code | Description | Retryable |
|
|
727
|
+
|------|-------------|-----------|
|
|
728
|
+
| `VALIDATION_ERROR` | Invalid input data | No |
|
|
729
|
+
| `INVALID_PHONE` | Invalid phone number format | No |
|
|
730
|
+
| `INSUFFICIENT_FUNDS` | Not enough balance | No |
|
|
731
|
+
| `AMOUNT_TOO_LOW` | Below minimum amount | No |
|
|
732
|
+
| `AMOUNT_TOO_HIGH` | Above maximum amount | No |
|
|
733
|
+
| `LIMIT_EXCEEDED` | Daily/monthly limit exceeded | No |
|
|
734
|
+
| `DUPLICATE` | Duplicate transaction ID | No |
|
|
735
|
+
| `MMO_UNAVAILABLE` | Provider is unavailable | Yes |
|
|
736
|
+
| `TIMEOUT` | Request timeout | Yes |
|
|
737
|
+
| `UNAUTHORIZED` | Invalid API key | No |
|
|
738
|
+
| `RATE_LIMITED` | Too many requests | Yes |
|
|
739
|
+
| `SERVER_ERROR` | Pawapay server error | Yes |
|
|
740
|
+
| `NETWORK_ERROR` | Network connectivity issue | Yes |
|
|
741
|
+
| `NOT_FOUND` | Transaction not found | No |
|
|
742
|
+
|
|
485
743
|
## Environment Variables
|
|
486
744
|
|
|
487
745
|
```bash
|
|
746
|
+
# Required
|
|
488
747
|
PAWAPAY_API_KEY=pk_sandbox_xxxxxxxxxxxx
|
|
489
|
-
|
|
490
|
-
|
|
748
|
+
|
|
749
|
+
# Optional
|
|
750
|
+
PAWAPAY_ENVIRONMENT=sandbox # 'sandbox' | 'production' (default: sandbox)
|
|
751
|
+
PAWAPAY_BASE_URL=https://custom.api.url # Custom API base URL
|
|
752
|
+
PAWAPAY_CALLBACK_URL=https://... # Default webhook callback URL
|
|
753
|
+
PAWAPAY_TIMEOUT=30000 # Request timeout in ms (default: 30000)
|
|
754
|
+
PAWAPAY_RETRIES=3 # Number of retries (default: 3)
|
|
755
|
+
PAWAPAY_LOG_LEVEL=info # 'debug' | 'info' | 'warn' | 'error' | 'none'
|
|
756
|
+
PAWAPAY_WEBHOOK_SECRET=whsec_xxx # Webhook signature secret
|
|
491
757
|
```
|
|
492
758
|
|
|
759
|
+
## Development
|
|
760
|
+
|
|
761
|
+
### Setup
|
|
762
|
+
|
|
763
|
+
```bash
|
|
764
|
+
# Clone repository
|
|
765
|
+
git clone https://github.com/confort-sept-inc/react-spaark-payapi-sdk.git
|
|
766
|
+
cd react-spaark-payapi-sdk
|
|
767
|
+
|
|
768
|
+
# Install dependencies
|
|
769
|
+
pnpm install
|
|
770
|
+
|
|
771
|
+
# Build
|
|
772
|
+
pnpm build
|
|
773
|
+
|
|
774
|
+
# Run tests
|
|
775
|
+
pnpm test
|
|
776
|
+
|
|
777
|
+
# Type check
|
|
778
|
+
pnpm typecheck
|
|
779
|
+
|
|
780
|
+
# Lint
|
|
781
|
+
pnpm lint
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
### Scripts
|
|
785
|
+
|
|
786
|
+
| Script | Description |
|
|
787
|
+
|--------|-------------|
|
|
788
|
+
| `pnpm build` | Build with tsup (ESM + CJS + types) |
|
|
789
|
+
| `pnpm dev` | Watch mode for development |
|
|
790
|
+
| `pnpm test` | Run Jest tests |
|
|
791
|
+
| `pnpm test:coverage` | Run tests with coverage |
|
|
792
|
+
| `pnpm typecheck` | TypeScript type checking |
|
|
793
|
+
| `pnpm lint` | ESLint |
|
|
794
|
+
| `pnpm release` | Build, version, and publish |
|
|
795
|
+
|
|
796
|
+
### Testing
|
|
797
|
+
|
|
798
|
+
```bash
|
|
799
|
+
# Run all tests
|
|
800
|
+
pnpm test
|
|
801
|
+
|
|
802
|
+
# Run with coverage (70% threshold)
|
|
803
|
+
pnpm test:coverage
|
|
804
|
+
|
|
805
|
+
# Run specific test file
|
|
806
|
+
pnpm test src/__tests__/sdk.test.ts
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
### Project Requirements
|
|
810
|
+
|
|
811
|
+
- Node.js >= 18.0.0
|
|
812
|
+
- TypeScript >= 5.3
|
|
813
|
+
- React 18 or 19 (for components)
|
|
814
|
+
|
|
493
815
|
## License
|
|
494
816
|
|
|
495
817
|
MIT
|