spaark-payapi-sdk 1.5.0 → 1.7.0

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
 
@@ -18,13 +43,24 @@ pnpm add spaark-payapi-sdk
18
43
  yarn add spaark-payapi-sdk
19
44
  ```
20
45
 
21
- ### For React Components
46
+ ### For React Components (shadcn/ui)
22
47
 
23
- The SDK includes React components that require additional peer dependencies:
48
+ The SDK includes React components built with shadcn/ui patterns. Install the required peer dependencies:
24
49
 
25
50
  ```bash
26
- # Required for React components
27
- npm install react react-dom lucide-react @radix-ui/react-tabs @radix-ui/react-select @radix-ui/react-dialog
51
+ # Core React dependencies
52
+ npm install react react-dom axios
53
+
54
+ # shadcn/ui prerequisites (via shadcn CLI)
55
+ pnpm dlx shadcn@latest add button
56
+ pnpm dlx shadcn@latest add tabs
57
+ pnpm dlx shadcn@latest add select
58
+ pnpm dlx shadcn@latest add chart
59
+ pnpm dlx shadcn@latest add skeleton
60
+ pnpm dlx shadcn@latest add spinner
61
+
62
+ # Or install manually (lucide-react is required for icons)
63
+ npm install lucide-react @radix-ui/react-tabs @radix-ui/react-select @radix-ui/react-dialog recharts @tanstack/react-table
28
64
 
29
65
  # The following are bundled with the SDK (no need to install):
30
66
  # - clsx
@@ -32,6 +68,8 @@ npm install react react-dom lucide-react @radix-ui/react-tabs @radix-ui/react-se
32
68
  # - class-variance-authority
33
69
  ```
34
70
 
71
+ > **Note**: The components use shadcn/ui styling conventions. Make sure your project has Tailwind CSS configured with the shadcn/ui theme variables.
72
+
35
73
  ## Quick Start
36
74
 
37
75
  ```typescript
@@ -57,24 +95,94 @@ console.log(deposit.depositId, deposit.status);
57
95
 
58
96
  ## Features
59
97
 
60
- - **Transactions**: Deposits, Payouts, Refunds, Payment Page
61
- - **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
62
101
  - **Finances**: Wallet Balances, Statement Generation
63
- - **Webhooks**: Signature verification, Event parsing
64
- - **React Components**: Test dashboard + Finance dashboard
65
- - **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
66
115
  - **i18n**: French/English support
67
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
+
68
168
  ## Supported Providers
69
169
 
70
- | Provider | Country | Currency |
71
- |----------|---------|----------|
72
- | `MTN_MOMO_CMR` | Cameroon | XAF |
73
- | `ORANGE_CMR` | Cameroon | XAF |
74
- | `MTN_MOMO_COG` | Congo | XAF |
75
- | `AIRTEL_COG` | Congo | XAF |
76
- | `MTN_MOMO_GAB` | Gabon | XAF |
77
- | `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 |
78
186
 
79
187
  ## API Reference
80
188
 
@@ -84,12 +192,16 @@ console.log(deposit.depositId, deposit.status);
84
192
  import { SpaarkPayApiSdk } from 'spaark-payapi-sdk';
85
193
 
86
194
  const sdk = new SpaarkPayApiSdk({
87
- apiKey: process.env.PAWAPAY_API_KEY,
88
- environment: 'sandbox', // 'sandbox' | 'production'
89
- timeout: 30000, // Optional: request timeout in ms
90
- retries: 3, // Optional: retry attempts
91
- 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'
92
200
  });
201
+
202
+ // Runtime configuration
203
+ sdk.setLogLevel('debug');
204
+ sdk.setWebhookSecret('whsec_xxxxxxxxxxxx');
93
205
  ```
94
206
 
95
207
  ### Transactions
@@ -102,10 +214,10 @@ const deposit = await sdk.transactions.initiateDeposit({
102
214
  currency: 'XAF',
103
215
  provider: 'MTN_MOMO_CMR',
104
216
  phoneNumber: '237670000000',
105
- transactionId: sdk.utils.generateTransactionId(),
106
- customerMessage: 'Payment description', // 4-22 chars
107
- clientReferenceId: 'order-123', // Optional
108
- 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
109
221
  });
110
222
 
111
223
  // Response
@@ -153,8 +265,8 @@ const status = await sdk.transactions.checkStatus('transaction-uuid');
153
265
 
154
266
  ```typescript
155
267
  const result = await sdk.transactions.pollUntilComplete('transaction-uuid', {
156
- interval: 5000, // Poll every 5 seconds
157
- maxAttempts: 12, // Max 12 attempts (1 minute)
268
+ interval: 5000, // Poll every 5 seconds (default)
269
+ maxAttempts: 12, // Max 12 attempts (default)
158
270
  onStatusChange: (status) => console.log('Status:', status),
159
271
  });
160
272
  ```
@@ -177,7 +289,7 @@ const page = await sdk.transactions.createPaymentPage({
177
289
  returnUrl: 'https://yoursite.com/payment/complete',
178
290
  phoneNumber: '237670000000', // Optional
179
291
  amountDetails: { amount: 5000, currency: 'XAF' }, // Optional
180
- language: 'FR', // Optional
292
+ language: 'FR', // Optional: 'FR' | 'EN'
181
293
  country: 'CMR', // Optional
182
294
  reason: 'Ticket purchase', // Optional
183
295
  });
@@ -208,7 +320,7 @@ const prediction = await sdk.utils.predictProvider('+237 670 000 000');
208
320
  ```typescript
209
321
  const availability = await sdk.utils.getProviderAvailability({
210
322
  country: 'CMR', // Optional
211
- operationType: 'DEPOSIT', // Optional
323
+ operationType: 'DEPOSIT', // Optional: 'DEPOSIT' | 'PAYOUT' | 'REFUND'
212
324
  });
213
325
  ```
214
326
 
@@ -216,6 +328,7 @@ const availability = await sdk.utils.getProviderAvailability({
216
328
 
217
329
  ```typescript
218
330
  const config = await sdk.utils.getActiveConfiguration();
331
+ // Returns company config, countries, providers, currencies, limits
219
332
  ```
220
333
 
221
334
  #### Check MMO Availability
@@ -225,6 +338,13 @@ const status = await sdk.utils.checkMMOAvailability('MTN_MOMO_CMR');
225
338
  // { correspondent: 'MTN_MOMO_CMR', available: true, degraded: false }
226
339
  ```
227
340
 
341
+ #### Get Public Keys
342
+
343
+ ```typescript
344
+ const keys = await sdk.utils.getPublicKeys();
345
+ // [{ id: 'key-001', key: 'MIIBIjANBgkqhkiG9w0BAQEFAA...' }]
346
+ ```
347
+
228
348
  ### Finances
229
349
 
230
350
  #### Wallet Balances
@@ -245,22 +365,51 @@ const statement = await sdk.finances.generateStatement({
245
365
  compressed: true,
246
366
  });
247
367
 
368
+ // Poll until complete
248
369
  const result = await sdk.finances.pollStatementUntilComplete(statement.statementId);
249
370
  console.log(result.downloadUrl);
250
371
  ```
251
372
 
252
373
  ### Webhooks
253
374
 
375
+ #### Setup
376
+
254
377
  ```typescript
255
- // Set secret
378
+ // Set webhook secret
256
379
  sdk.setWebhookSecret(process.env.PAWAPAY_WEBHOOK_SECRET);
380
+ ```
381
+
382
+ #### Verify Signature
257
383
 
258
- // Verify signature
384
+ ```typescript
259
385
  const isValid = sdk.webhooks.verifySignature(body, signature);
386
+ ```
387
+
388
+ #### Parse Event
260
389
 
261
- // Parse event
390
+ ```typescript
262
391
  const event = sdk.webhooks.parseEvent(body);
263
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
264
413
  switch (event.eventType) {
265
414
  case 'deposit.completed':
266
415
  console.log('Deposit completed:', event.data.depositId);
@@ -271,20 +420,54 @@ switch (event.eventType) {
271
420
  case 'payout.completed':
272
421
  console.log('Payout completed:', event.data.payoutId);
273
422
  break;
423
+ case 'payout.failed':
424
+ console.log('Payout failed:', event.data.failureReason);
425
+ break;
274
426
  }
275
427
  ```
276
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
+
277
459
  ### Utilities
278
460
 
279
461
  ```typescript
280
- // Generate UUID v4
462
+ // Generate UUID v4 transaction ID
281
463
  const txId = sdk.utils.generateTransactionId();
282
464
 
283
- // Validate transaction ID
465
+ // Validate transaction ID format
284
466
  const isValid = sdk.utils.validateTransactionId(txId);
285
467
 
286
- // Format phone number
468
+ // Format phone number for country
287
469
  const phone = sdk.utils.formatPhoneNumber('670000000', 'CMR');
470
+ // '237670000000'
288
471
 
289
472
  // Validate phone for provider
290
473
  const isValid = sdk.utils.validatePhoneNumber('237670000000', 'MTN_MOMO_CMR');
@@ -292,10 +475,10 @@ const isValid = sdk.utils.validatePhoneNumber('237670000000', 'MTN_MOMO_CMR');
292
475
  // Get provider info
293
476
  const info = sdk.utils.getCorrespondentInfo('MTN_MOMO_CMR');
294
477
 
295
- // Detect provider from phone
478
+ // Detect provider from phone number
296
479
  const provider = sdk.utils.detectCorrespondent('237670000000');
297
480
 
298
- // Get transaction limits
481
+ // Get transaction limits for provider
299
482
  const limits = await sdk.utils.getTransactionLimits('MTN_MOMO_CMR');
300
483
  ```
301
484
 
@@ -303,27 +486,72 @@ const limits = await sdk.utils.getTransactionLimits('MTN_MOMO_CMR');
303
486
 
304
487
  ### Test Dashboard
305
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
+
306
500
  ```tsx
307
501
  import { SpaarkPaySdkTestDashboard } from 'spaark-payapi-sdk/react';
308
502
 
309
503
  export default function TestPage() {
310
504
  return (
311
505
  <SpaarkPaySdkTestDashboard
312
- environment="sandbox"
313
- apiBasePath="/api/pawapay"
314
- 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)
315
510
  onDepositComplete={(res) => console.log('Deposit:', res)}
316
511
  onPayoutComplete={(res) => console.log('Payout:', res)}
317
512
  onError={(err) => console.error(err)}
513
+ className="max-w-6xl mx-auto"
318
514
  />
319
515
  );
320
516
  }
321
517
  ```
322
518
 
323
- 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
+ ```
324
550
 
325
551
  ### Finance Dashboard
326
552
 
553
+ Transaction analytics dashboard with KPI cards, filters, pagination, and charts.
554
+
327
555
  ```tsx
328
556
  import {
329
557
  SpaarkPaySdkFinanceDashboard,
@@ -341,54 +569,140 @@ const transactions: Transaction[] = [
341
569
  phoneNumber: '237670000000',
342
570
  createdAt: '2025-01-15T10:00:00Z',
343
571
  },
344
- // ... more transactions
345
572
  ];
346
573
 
347
574
  export default function FinancePage() {
348
575
  return (
349
576
  <SpaarkPaySdkFinanceDashboard
350
577
  transactions={transactions}
351
- title="My Finance Dashboard" // Customizable
352
- locale="fr" // 'fr' | 'en'
353
- onRefresh={() => fetchData()} // Refresh button handler
354
- onTransactionClick={(tx) => {}} // Row click handler
355
- onExpertModeClick={() => {}} // Expert mode button
356
- showExpertMode={true} // Show/hide expert button
357
- isLoading={false} // Loading state
578
+ title="My Finance Dashboard"
579
+ subtitle="Overview of your transactions"
580
+ locale="fr" // 'fr' | 'en'
581
+ onRefresh={() => fetchData()} // Refresh button callback
582
+ onSettings={() => openSettings()} // Settings button (gear icon)
583
+ onAddTransaction={() => openForm()} // CTA button when no transactions
584
+ onTransactionClick={(tx) => {}} // Table row click
585
+ onExpertModeClick={() => {}} // Expert mode button
586
+ showExpertMode={true}
587
+ isLoading={false}
358
588
  />
359
589
  );
360
590
  }
361
591
  ```
362
592
 
593
+ **Props:**
594
+
595
+ | Prop | Type | Description |
596
+ |------|------|-------------|
597
+ | `transactions` | `Transaction[]` | Array of transactions to display |
598
+ | `title` | `string` | Dashboard title (default: "Tableau de bord financier") |
599
+ | `subtitle` | `string` | Dashboard subtitle |
600
+ | `locale` | `'fr' \| 'en'` | Language (default: 'fr') |
601
+ | `onRefresh` | `() => void` | Refresh button callback |
602
+ | `onSettings` | `() => void` | Settings button callback (gear icon) |
603
+ | `onAddTransaction` | `() => void` | CTA button callback when no transactions |
604
+ | `onTransactionClick` | `(tx) => void` | Table row click callback |
605
+ | `onExpertModeClick` | `() => void` | Expert mode button callback |
606
+ | `showExpertMode` | `boolean` | Show/hide expert mode button |
607
+ | `isLoading` | `boolean` | Show loading skeletons |
608
+
363
609
  **Features:**
364
- - 5 KPI cards (Total Volume, Deposits, Payouts, Failed, Refunds)
610
+
611
+ **Dashboard Tab:**
612
+ - 8 KPI cards: Total Volume, Deposits, Payouts, Refunds, Pending, Completed, Failed, Cancelled
365
613
  - Search by transaction ID or phone number
366
- - Filter by type (deposit/payout/refund) and status
367
- - Paginated transactions table
368
- - Copy transaction ID to clipboard
369
- - i18n support (French/English)
370
- - Customizable title
371
- - Expert Mode button integration
614
+ - Dropdown filters for type and status
615
+ - Paginated transactions table with @tanstack/react-table
616
+ - Copy transaction ID button
617
+ - Empty state with CTA button
618
+
619
+ **Charts Tab:**
620
+ - Area Chart: Volume over time (deposits vs payouts)
621
+ - Bar Chart: Transaction amounts by type
622
+ - Pie Chart: Status distribution (donut style)
372
623
 
373
624
  ## TypeScript Types
374
625
 
375
626
  ```typescript
376
627
  import type {
628
+ // SDK Config
377
629
  SpaarkPayApiSdkConfig,
630
+ ResolvedConfig,
631
+ Environment,
632
+ LogLevel,
633
+
634
+ // Transactions
378
635
  DepositRequest,
379
636
  DepositResponse,
380
637
  PayoutRequest,
381
638
  PayoutResponse,
639
+ RefundRequest,
640
+ RefundResponse,
382
641
  TransactionStatus,
383
642
  TransactionStatusResponse,
643
+ PaymentPageRequest,
644
+ PaymentPageResponse,
645
+ PollOptions,
646
+ FailureReason,
647
+ DepositFailureCode,
648
+ PayoutFailureCode,
649
+
650
+ // Providers
384
651
  Correspondent,
652
+ CorrespondentInfo,
653
+ TransactionLimits,
385
654
  Currency,
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
+
680
+ // React Components
386
681
  Transaction,
387
682
  TransactionType,
388
- // ... and more
683
+ SpaarkPaySdkFinanceDashboardProps,
684
+ SpaarkPaySdkTestDashboardProps,
389
685
  } from 'spaark-payapi-sdk';
390
686
  ```
391
687
 
688
+ ### Transaction Type (Finance Dashboard)
689
+
690
+ ```typescript
691
+ type Transaction = {
692
+ id: string;
693
+ type: 'deposit' | 'payout' | 'refund';
694
+ amount: number;
695
+ currency: string;
696
+ status: 'ACCEPTED' | 'PENDING' | 'ENQUEUED' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'CANCELLED' | 'REJECTED';
697
+ provider: Correspondent;
698
+ phoneNumber: string;
699
+ description?: string;
700
+ createdAt: string;
701
+ updatedAt?: string;
702
+ failureReason?: string;
703
+ };
704
+ ```
705
+
392
706
  ## Error Handling
393
707
 
394
708
  ```typescript
@@ -398,22 +712,106 @@ try {
398
712
  await sdk.transactions.initiateDeposit({ ... });
399
713
  } catch (error) {
400
714
  if (error instanceof PawapayError) {
401
- console.log(error.code); // Error code
402
- console.log(error.message); // Human-readable message
403
- console.log(error.retryable); // Whether to retry
404
- 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
405
720
  }
406
721
  }
407
722
  ```
408
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
+
409
743
  ## Environment Variables
410
744
 
411
745
  ```bash
746
+ # Required
412
747
  PAWAPAY_API_KEY=pk_sandbox_xxxxxxxxxxxx
413
- PAWAPAY_ENVIRONMENT=sandbox
414
- 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
757
+ ```
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
415
782
  ```
416
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
+
417
815
  ## License
418
816
 
419
817
  MIT