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 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
  [![npm version](https://img.shields.io/npm/v/spaark-payapi-sdk.svg)](https://www.npmjs.com/package/spaark-payapi-sdk)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3+-blue.svg)](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
- - **Transactions**: Deposits, Payouts, Refunds, Payment Page
74
- - **Toolkit**: Predict Provider, Active Configuration, Provider Availability
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**: Signature verification, Event parsing
77
- - **React Components**: Test Dashboard + Finance Dashboard with Charts
78
- - **shadcn/ui**: Button, Tabs, Select, Card, Input components
79
- - **Charts**: Area, Bar, Pie charts with recharts
80
- - **Full TypeScript**: Complete type definitions
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', // 'sandbox' | 'production'
104
- timeout: 30000, // Optional: request timeout in ms
105
- retries: 3, // Optional: retry attempts
106
- logLevel: 'info', // Optional: 'debug' | 'info' | 'warn' | 'error' | 'none'
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', // 4-22 chars
122
- clientReferenceId: 'order-123', // Optional
123
- metadata: [{ orderId: 'ORD-123' }], // Optional
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 (1 minute)
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
- // Verify signature
384
+ ```typescript
274
385
  const isValid = sdk.webhooks.verifySignature(body, signature);
386
+ ```
387
+
388
+ #### Parse Event
275
389
 
276
- // Parse event
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
- environment="sandbox"
328
- apiBasePath="/api/pawapay"
329
- demoMode={false}
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
- Use `demoMode={true}` to test without API key.
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 empty
372
- onTransactionClick={(tx) => {}} // Row click
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 spinner |
607
+ | `isLoading` | `boolean` | Show loading skeletons |
396
608
 
397
609
  **Features:**
398
610
 
399
611
  **Dashboard Tab:**
400
- - 8 KPI cards in 2 rows:
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 (shadcn/ui Select) for type and status
405
- - Paginated transactions table with copy ID button
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
- // Transaction type for Finance Dashboard
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); // Error code
478
- console.log(error.message); // Human-readable message
479
- console.log(error.retryable); // Whether to retry
480
- console.log(error.statusCode); // HTTP status
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
- PAWAPAY_ENVIRONMENT=sandbox
490
- PAWAPAY_WEBHOOK_SECRET=whsec_xxxxxxxxxxxx
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