monime-package 1.0.5 → 1.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.
- package/README.md +664 -142
- package/dist/index.d.mts +191 -0
- package/dist/index.d.ts +191 -0
- package/dist/index.js +189 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +189 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Official, lightweight TypeScript SDK for Monime. It provides a typed client for
|
|
|
5
5
|
|
|
6
6
|

|
|
7
7
|

|
|
8
|
-

|
|
9
9
|

|
|
10
10
|

|
|
11
11
|
|
|
@@ -19,19 +19,23 @@ Package: `monime-package`
|
|
|
19
19
|
- **[Installation](#installation)**
|
|
20
20
|
- **[Environment Variables](#environment-variables)**
|
|
21
21
|
- **[Quick Start](#quick-start)**
|
|
22
|
-
- **[
|
|
22
|
+
- **[API Reference](#api-reference)**
|
|
23
|
+
- **[Financial Accounts](#financial-accounts)**
|
|
24
|
+
- **[Internal Transfers](#internal-transfers)**
|
|
25
|
+
- **[Payment Codes](#payment-codes)**
|
|
26
|
+
- **[Payouts](#payouts)**
|
|
27
|
+
- **[Financial Transactions](#financial-transactions)**
|
|
28
|
+
- **[Checkout Sessions](#checkout-sessions)**
|
|
23
29
|
- **[Configuration](#configuration)**
|
|
24
|
-
- **[Examples](#examples)**
|
|
30
|
+
- **[Complete Examples](#complete-examples)**
|
|
31
|
+
- **[TypeScript Types](#typescript-types)**
|
|
25
32
|
- **[Idempotency](#idempotency)**
|
|
26
33
|
- **[Pagination](#pagination)**
|
|
27
34
|
- **[Migration from Old Helpers](#migration-from-old-helpers)**
|
|
28
|
-
- **[Folder Structure](#folder-structure)**
|
|
29
35
|
- **[Error Handling](#error-handling)**
|
|
30
36
|
- **[Security](#security)**
|
|
31
|
-
- **[Versioning](#versioning)**
|
|
32
|
-
- **[Support](#support)**
|
|
33
|
-
- **[Return Types (Appendix)](#return-types-appendix)**
|
|
34
37
|
- **[Contributing](#contributing)**
|
|
38
|
+
- **[Support](#support)**
|
|
35
39
|
- **[License](#license)**
|
|
36
40
|
|
|
37
41
|
---
|
|
@@ -42,6 +46,10 @@ Package: `monime-package`
|
|
|
42
46
|
- **Predictable** return shape: `{ success, data?, error? }`
|
|
43
47
|
- **Client-based** auth: set credentials once per instance
|
|
44
48
|
- **Minimal deps** (`axios`) and small surface area
|
|
49
|
+
- **Full API coverage** for all Monime endpoints
|
|
50
|
+
- **Mobile Money support** (Africell, Orange, etc.)
|
|
51
|
+
- **Bank transfers** and digital wallet integrations
|
|
52
|
+
- **Checkout sessions** for hosted payment pages
|
|
45
53
|
|
|
46
54
|
---
|
|
47
55
|
|
|
@@ -95,7 +103,7 @@ import { createClient, type DestinationOption } from "monime-package";
|
|
|
95
103
|
|
|
96
104
|
---
|
|
97
105
|
|
|
98
|
-
##
|
|
106
|
+
## API Reference
|
|
99
107
|
|
|
100
108
|
All methods return the same envelope:
|
|
101
109
|
|
|
@@ -107,33 +115,84 @@ type Result<T> = {
|
|
|
107
115
|
};
|
|
108
116
|
```
|
|
109
117
|
|
|
110
|
-
The client exposes namespaced APIs under `client.<module
|
|
118
|
+
The client exposes namespaced APIs under `client.<module>`. Below is the complete API reference:
|
|
119
|
+
|
|
120
|
+
### Financial Accounts
|
|
111
121
|
|
|
112
|
-
|
|
122
|
+
Manage digital wallets and financial accounts.
|
|
113
123
|
|
|
114
124
|
```ts
|
|
125
|
+
// Create a new financial account
|
|
115
126
|
client.financialAccount.create(name: string): Promise<Result<CreateFinancialAccount>>
|
|
127
|
+
|
|
128
|
+
// Get account details by ID
|
|
116
129
|
client.financialAccount.get(financialAccountId: string): Promise<Result<GetFinancialAccount>>
|
|
130
|
+
|
|
131
|
+
// List all financial accounts
|
|
117
132
|
client.financialAccount.getAll(): Promise<Result<AllFinancialAccount>>
|
|
118
133
|
```
|
|
119
134
|
|
|
120
|
-
|
|
135
|
+
**Parameters:**
|
|
136
|
+
- `name`: Account name (required)
|
|
137
|
+
- `financialAccountId`: Unique account identifier (required)
|
|
121
138
|
|
|
139
|
+
**Example:**
|
|
122
140
|
```ts
|
|
141
|
+
// Create account
|
|
142
|
+
const account = await client.financialAccount.create("My Wallet");
|
|
143
|
+
if (account.success) {
|
|
144
|
+
console.log("Account ID:", account.data.result.id);
|
|
145
|
+
console.log("Balance:", account.data.result.balance.available.value);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Get account details
|
|
149
|
+
const details = await client.financialAccount.get("fa-123456");
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Internal Transfers
|
|
153
|
+
|
|
154
|
+
Transfer funds between your financial accounts.
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
// Create internal transfer
|
|
123
158
|
client.internalTransfer.create(
|
|
124
159
|
sourceAccount: string,
|
|
125
160
|
destinationAccount: string,
|
|
126
161
|
amount: number,
|
|
127
162
|
): Promise<Result<CreateInternalTransfer>>
|
|
128
163
|
|
|
164
|
+
// Get transfer details
|
|
129
165
|
client.internalTransfer.get(internalTransferId: string): Promise<Result<InternalTransfer>>
|
|
166
|
+
|
|
167
|
+
// List all transfers
|
|
130
168
|
client.internalTransfer.getAll(): Promise<Result<AllInternalTransfers>>
|
|
169
|
+
|
|
170
|
+
// Cancel/delete a transfer
|
|
131
171
|
client.internalTransfer.delete(internalTransferId: string): Promise<{ success: boolean; error?: Error }>
|
|
132
172
|
```
|
|
133
173
|
|
|
134
|
-
|
|
174
|
+
**Parameters:**
|
|
175
|
+
- `sourceAccount`: Source financial account ID (required)
|
|
176
|
+
- `destinationAccount`: Destination financial account ID (required)
|
|
177
|
+
- `amount`: Transfer amount in SLE (required, must be > 0)
|
|
178
|
+
- `internalTransferId`: Transfer ID for get/delete operations (required)
|
|
179
|
+
|
|
180
|
+
**Example:**
|
|
181
|
+
```ts
|
|
182
|
+
// Transfer 1000 SLE between accounts
|
|
183
|
+
const transfer = await client.internalTransfer.create("fa-source", "fa-dest", 1000);
|
|
184
|
+
if (transfer.success) {
|
|
185
|
+
console.log("Transfer ID:", transfer.data.result.id);
|
|
186
|
+
console.log("Status:", transfer.data.result.status);
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Payment Codes
|
|
191
|
+
|
|
192
|
+
Generate USSD payment codes for mobile money transactions.
|
|
135
193
|
|
|
136
194
|
```ts
|
|
195
|
+
// Create payment code
|
|
137
196
|
client.paymentCode.create(
|
|
138
197
|
paymentName: string,
|
|
139
198
|
amount: number,
|
|
@@ -142,34 +201,182 @@ client.paymentCode.create(
|
|
|
142
201
|
phoneNumber: string,
|
|
143
202
|
): Promise<Result<CreatePaymentCode>>
|
|
144
203
|
|
|
145
|
-
|
|
146
|
-
client.paymentCode.getAll(): Promise<Result<GetAllPaymentCode>>
|
|
204
|
+
// Get payment code details
|
|
147
205
|
client.paymentCode.get(paymentCodeId: string): Promise<Result<GetOne>>
|
|
206
|
+
|
|
207
|
+
// List all payment codes
|
|
208
|
+
client.paymentCode.getAll(): Promise<Result<GetAllPaymentCode>>
|
|
209
|
+
|
|
210
|
+
// Delete payment code
|
|
211
|
+
client.paymentCode.delete(paymentCodeId: string): Promise<{ success: boolean; error?: Error }>
|
|
148
212
|
```
|
|
149
213
|
|
|
150
|
-
|
|
214
|
+
**Parameters:**
|
|
215
|
+
- `paymentName`: Description for the payment (required)
|
|
216
|
+
- `amount`: Payment amount in SLE (required, must be > 0)
|
|
217
|
+
- `financialAccount`: Target financial account ID (required)
|
|
218
|
+
- `username`: Customer name (required)
|
|
219
|
+
- `phoneNumber`: Authorized phone number (required)
|
|
220
|
+
- `paymentCodeId`: Payment code ID for get/delete operations (required)
|
|
151
221
|
|
|
222
|
+
**Example:**
|
|
152
223
|
```ts
|
|
153
|
-
|
|
224
|
+
// Create USSD payment code
|
|
225
|
+
const paymentCode = await client.paymentCode.create(
|
|
226
|
+
"Order #12345",
|
|
227
|
+
5000, // 50.00 SLE
|
|
228
|
+
"fa-123456",
|
|
229
|
+
"John Doe",
|
|
230
|
+
"0771234567"
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
if (paymentCode.success) {
|
|
234
|
+
console.log("USSD Code:", paymentCode.data.result.ussdCode);
|
|
235
|
+
console.log("Expires at:", paymentCode.data.result.expireTime);
|
|
236
|
+
}
|
|
237
|
+
```
|
|
154
238
|
|
|
239
|
+
### Payouts
|
|
240
|
+
|
|
241
|
+
Send money to mobile money providers, banks, or wallets.
|
|
242
|
+
|
|
243
|
+
```ts
|
|
244
|
+
// Create payout
|
|
155
245
|
client.payout.create(
|
|
156
246
|
amount: number,
|
|
157
247
|
destination: DestinationOption,
|
|
158
248
|
sourceAccount: string,
|
|
159
249
|
): Promise<Result<CreatePayout>>
|
|
160
250
|
|
|
251
|
+
// List all payouts
|
|
161
252
|
client.payout.get(): Promise<Result<GetAll>>
|
|
253
|
+
|
|
254
|
+
// Get specific payout
|
|
162
255
|
client.payout.getOne(payoutId: string): Promise<Result<GetOnePayout>>
|
|
256
|
+
|
|
257
|
+
// Cancel payout
|
|
163
258
|
client.payout.delete(payoutId: string): Promise<{ success: boolean; error?: Error }>
|
|
164
259
|
```
|
|
165
260
|
|
|
166
|
-
|
|
261
|
+
**Destination Types:**
|
|
262
|
+
```ts
|
|
263
|
+
type DestinationOption =
|
|
264
|
+
| { type: "momo"; providerId: "m17" | "m18"; phoneNumber: string }
|
|
265
|
+
| { type: "bank"; providerId: "b01" | "b02" | "b03"; accountNumber: string }
|
|
266
|
+
| { type: "wallet"; providerId: "w01" | "w02"; walletId: string };
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**Parameters:**
|
|
270
|
+
- `amount`: Payout amount in SLE (required, must be > 0)
|
|
271
|
+
- `destination`: Payout destination (required)
|
|
272
|
+
- `sourceAccount`: Source financial account ID (required)
|
|
273
|
+
- `payoutId`: Payout ID for get/delete operations (required)
|
|
274
|
+
|
|
275
|
+
**Example:**
|
|
276
|
+
```ts
|
|
277
|
+
// Mobile money payout
|
|
278
|
+
const mobileMoneyPayout = await client.payout.create(
|
|
279
|
+
10000, // 100.00 SLE
|
|
280
|
+
{ type: "momo", providerId: "m17", phoneNumber: "0771234567" },
|
|
281
|
+
"fa-123456"
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
// Bank transfer payout
|
|
285
|
+
const bankPayout = await client.payout.create(
|
|
286
|
+
50000, // 500.00 SLE
|
|
287
|
+
{ type: "bank", providerId: "b01", accountNumber: "1234567890" },
|
|
288
|
+
"fa-123456"
|
|
289
|
+
);
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Financial Transactions
|
|
293
|
+
|
|
294
|
+
Query transaction history and details.
|
|
167
295
|
|
|
168
296
|
```ts
|
|
297
|
+
// Get transaction details
|
|
169
298
|
client.financialTransaction.get(transactionId: string): Promise<Result<GetTransaction>>
|
|
299
|
+
|
|
300
|
+
// List all transactions
|
|
170
301
|
client.financialTransaction.getAll(): Promise<Result<AllTransaction>>
|
|
171
302
|
```
|
|
172
303
|
|
|
304
|
+
**Parameters:**
|
|
305
|
+
- `transactionId`: Transaction ID (required)
|
|
306
|
+
|
|
307
|
+
**Example:**
|
|
308
|
+
```ts
|
|
309
|
+
// Get all transactions
|
|
310
|
+
const transactions = await client.financialTransaction.getAll();
|
|
311
|
+
if (transactions.success) {
|
|
312
|
+
transactions.data.result.forEach(tx => {
|
|
313
|
+
console.log(`${tx.type}: ${tx.amount.value} ${tx.amount.currency}`);
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Checkout Sessions
|
|
319
|
+
|
|
320
|
+
Create hosted payment pages for seamless customer payments.
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
// Create checkout session
|
|
324
|
+
client.checkoutSession.create(
|
|
325
|
+
name: string,
|
|
326
|
+
amount: number,
|
|
327
|
+
quantity: number,
|
|
328
|
+
successUrl: string,
|
|
329
|
+
cancelUrl: string,
|
|
330
|
+
description?: string,
|
|
331
|
+
financialAccountId?: string,
|
|
332
|
+
primaryColor?: string,
|
|
333
|
+
images?: string[],
|
|
334
|
+
): Promise<Result<CreateCheckout>>
|
|
335
|
+
|
|
336
|
+
// List all checkout sessions
|
|
337
|
+
client.checkoutSession.get(): Promise<Result<AllCheckout>>
|
|
338
|
+
|
|
339
|
+
// Get specific checkout session
|
|
340
|
+
client.checkoutSession.getOne(checkoutId: string): Promise<Result<OneCheckout>>
|
|
341
|
+
|
|
342
|
+
// Delete checkout session
|
|
343
|
+
client.checkoutSession.delete(checkoutId: string): Promise<{ success: boolean; error?: Error }>
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Parameters:**
|
|
347
|
+
- `name`: Product/service name (required)
|
|
348
|
+
- `amount`: Price per item in SLE (required)
|
|
349
|
+
- `quantity`: Number of items (required)
|
|
350
|
+
- `successUrl`: Redirect URL after successful payment (required)
|
|
351
|
+
- `cancelUrl`: Redirect URL when payment is cancelled (required)
|
|
352
|
+
- `description`: Product description (optional)
|
|
353
|
+
- `financialAccountId`: Target account for payments (optional)
|
|
354
|
+
- `primaryColor`: Brand color in hex format (optional)
|
|
355
|
+
- `images`: Product image URLs (optional)
|
|
356
|
+
- `checkoutId`: Checkout session ID for get/delete operations (required)
|
|
357
|
+
|
|
358
|
+
**Example:**
|
|
359
|
+
```ts
|
|
360
|
+
// Create checkout for e-commerce
|
|
361
|
+
const checkout = await client.checkoutSession.create(
|
|
362
|
+
"Premium Subscription",
|
|
363
|
+
2500, // 25.00 SLE per month
|
|
364
|
+
1,
|
|
365
|
+
"https://myapp.com/success",
|
|
366
|
+
"https://myapp.com/cancel",
|
|
367
|
+
"Monthly premium subscription",
|
|
368
|
+
"fa-123456",
|
|
369
|
+
"#3B82F6", // Blue color
|
|
370
|
+
["https://myapp.com/images/premium.jpg"]
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
if (checkout.success) {
|
|
374
|
+
// Redirect customer to checkout page
|
|
375
|
+
console.log("Checkout URL:", checkout.data.result.redirectUrl);
|
|
376
|
+
console.log("Order Number:", checkout.data.result.orderNumber);
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
173
380
|
---
|
|
174
381
|
|
|
175
382
|
## Configuration
|
|
@@ -188,93 +395,206 @@ type ClientOptions = {
|
|
|
188
395
|
|
|
189
396
|
---
|
|
190
397
|
|
|
191
|
-
## Examples
|
|
398
|
+
## Complete Examples
|
|
192
399
|
|
|
193
|
-
|
|
400
|
+
Here are comprehensive examples showing real-world usage patterns:
|
|
194
401
|
|
|
195
|
-
|
|
196
|
-
const account = await client.financialAccount.create("App Wallet");
|
|
197
|
-
if (!account.success) throw account.error;
|
|
198
|
-
console.log(account.data);
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### Get account details
|
|
402
|
+
### Complete E-commerce Integration
|
|
202
403
|
|
|
203
404
|
```ts
|
|
204
|
-
|
|
205
|
-
console.log(details);
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### List financial accounts
|
|
405
|
+
import { createClient, type DestinationOption } from "monime-package";
|
|
209
406
|
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
407
|
+
// Initialize client
|
|
408
|
+
const client = createClient({
|
|
409
|
+
monimeSpaceId: process.env.MONIME_SPACE_ID!,
|
|
410
|
+
accessToken: process.env.MONIME_ACCESS_TOKEN!,
|
|
411
|
+
});
|
|
214
412
|
|
|
215
|
-
|
|
413
|
+
// Create business account
|
|
414
|
+
const businessAccount = await client.financialAccount.create("E-commerce Store");
|
|
415
|
+
if (!businessAccount.success) {
|
|
416
|
+
throw new Error(`Failed to create account: ${businessAccount.error?.message}`);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const accountId = businessAccount.data!.result.id;
|
|
420
|
+
console.log(`Created account: ${accountId}`);
|
|
421
|
+
console.log(`Balance: ${businessAccount.data!.result.balance.available.value} SLE`);
|
|
422
|
+
|
|
423
|
+
// Create checkout session for customer
|
|
424
|
+
const checkout = await client.checkoutSession.create(
|
|
425
|
+
"Digital Camera",
|
|
426
|
+
45000, // 450.00 SLE
|
|
427
|
+
1,
|
|
428
|
+
"https://store.com/success",
|
|
429
|
+
"https://store.com/cancel",
|
|
430
|
+
"Professional DSLR Camera with lens kit",
|
|
431
|
+
accountId,
|
|
432
|
+
"#2563EB", // Brand blue
|
|
433
|
+
["https://store.com/camera.jpg"]
|
|
434
|
+
);
|
|
216
435
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
436
|
+
if (checkout.success) {
|
|
437
|
+
console.log(`Checkout created: ${checkout.data!.result.id}`);
|
|
438
|
+
console.log(`Payment URL: ${checkout.data!.result.redirectUrl}`);
|
|
439
|
+
console.log(`Order: ${checkout.data!.result.orderNumber}`);
|
|
440
|
+
}
|
|
221
441
|
```
|
|
222
442
|
|
|
223
|
-
### Payment
|
|
443
|
+
### Payment Processing Workflow
|
|
224
444
|
|
|
225
445
|
```ts
|
|
226
|
-
//
|
|
227
|
-
const
|
|
228
|
-
"
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
"
|
|
232
|
-
"0771234567"
|
|
446
|
+
// 1. Generate USSD payment code for customer
|
|
447
|
+
const paymentCode = await client.paymentCode.create(
|
|
448
|
+
"Invoice #INV-2024-001",
|
|
449
|
+
15000, // 150.00 SLE
|
|
450
|
+
accountId,
|
|
451
|
+
"Customer Name",
|
|
452
|
+
"0771234567"
|
|
233
453
|
);
|
|
234
|
-
if (!code.success) console.error(code.error);
|
|
235
|
-
else console.log("Payment code:", code.data);
|
|
236
454
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
455
|
+
if (paymentCode.success) {
|
|
456
|
+
console.log(`USSD Code: ${paymentCode.data!.result.ussdCode}`);
|
|
457
|
+
console.log(`Expires: ${paymentCode.data!.result.expireTime}`);
|
|
458
|
+
|
|
459
|
+
// Send USSD code to customer via SMS/email
|
|
460
|
+
await sendToCustomer(paymentCode.data!.result.ussdCode);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// 2. Monitor payment status
|
|
464
|
+
const checkPaymentStatus = async (codeId: string) => {
|
|
465
|
+
const status = await client.paymentCode.get(codeId);
|
|
466
|
+
if (status.success) {
|
|
467
|
+
console.log(`Payment Status: ${status.data!.result.status}`);
|
|
468
|
+
return status.data!.result.status === 'completed';
|
|
469
|
+
}
|
|
470
|
+
return false;
|
|
471
|
+
};
|
|
242
472
|
|
|
243
|
-
//
|
|
244
|
-
const
|
|
245
|
-
|
|
473
|
+
// 3. Process payout to supplier after payment received
|
|
474
|
+
const paySupplier = async () => {
|
|
475
|
+
const payout = await client.payout.create(
|
|
476
|
+
8000, // 80.00 SLE to supplier
|
|
477
|
+
{
|
|
478
|
+
type: "momo",
|
|
479
|
+
providerId: "m17",
|
|
480
|
+
phoneNumber: "0779876543"
|
|
481
|
+
},
|
|
482
|
+
accountId
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
if (payout.success) {
|
|
486
|
+
console.log(`Payout ID: ${payout.data!.result.id}`);
|
|
487
|
+
console.log(`Status: ${payout.data!.result.status}`);
|
|
488
|
+
console.log(`Fees: ${payout.data!.result.fees.map(f => `${f.code}: ${f.amount.value}`)}`);
|
|
489
|
+
}
|
|
490
|
+
};
|
|
246
491
|
```
|
|
247
492
|
|
|
248
|
-
###
|
|
493
|
+
### Multi-Account Management
|
|
249
494
|
|
|
250
495
|
```ts
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
//
|
|
264
|
-
|
|
496
|
+
// Create multiple accounts for different purposes
|
|
497
|
+
const accounts = await Promise.all([
|
|
498
|
+
client.financialAccount.create("Sales Revenue"),
|
|
499
|
+
client.financialAccount.create("Operating Expenses"),
|
|
500
|
+
client.financialAccount.create("Tax Reserve"),
|
|
501
|
+
]);
|
|
502
|
+
|
|
503
|
+
// Check if all accounts were created successfully
|
|
504
|
+
if (accounts.every(acc => acc.success)) {
|
|
505
|
+
const [salesAccount, expensesAccount, taxAccount] = accounts.map(acc => acc.data!.result.id);
|
|
506
|
+
|
|
507
|
+
// Distribute revenue: 70% operations, 30% tax reserve
|
|
508
|
+
const revenue = 100000; // 1000.00 SLE
|
|
509
|
+
|
|
510
|
+
const transfers = await Promise.all([
|
|
511
|
+
client.internalTransfer.create(salesAccount, expensesAccount, revenue * 0.7),
|
|
512
|
+
client.internalTransfer.create(salesAccount, taxAccount, revenue * 0.3),
|
|
513
|
+
]);
|
|
514
|
+
|
|
515
|
+
transfers.forEach((transfer, index) => {
|
|
516
|
+
const purpose = index === 0 ? 'operations' : 'tax reserve';
|
|
517
|
+
if (transfer.success) {
|
|
518
|
+
console.log(`${purpose} transfer: ${transfer.data!.result.id}`);
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
```
|
|
265
523
|
|
|
266
|
-
|
|
267
|
-
const single = await client.payout.getOne("payout-id");
|
|
524
|
+
### Transaction Monitoring & Reporting
|
|
268
525
|
|
|
269
|
-
|
|
270
|
-
|
|
526
|
+
```ts
|
|
527
|
+
// Get all transactions for reporting
|
|
528
|
+
const transactions = await client.financialTransaction.getAll();
|
|
529
|
+
|
|
530
|
+
if (transactions.success) {
|
|
531
|
+
const txs = transactions.data!.result;
|
|
532
|
+
|
|
533
|
+
// Group transactions by type
|
|
534
|
+
const summary = txs.reduce((acc, tx) => {
|
|
535
|
+
acc[tx.type] = (acc[tx.type] || 0) + tx.amount.value;
|
|
536
|
+
return acc;
|
|
537
|
+
}, {} as Record<string, number>);
|
|
538
|
+
|
|
539
|
+
console.log('Transaction Summary:', summary);
|
|
540
|
+
|
|
541
|
+
// Find large transactions (> 50,000 SLE)
|
|
542
|
+
const largeTransactions = txs.filter(tx => Math.abs(tx.amount.value) > 50000);
|
|
543
|
+
console.log(`Large transactions: ${largeTransactions.length}`);
|
|
544
|
+
|
|
545
|
+
// Check account balances after transactions
|
|
546
|
+
const accountIds = [...new Set(txs.map(tx => tx.financialAccount.id))];
|
|
547
|
+
|
|
548
|
+
for (const accountId of accountIds) {
|
|
549
|
+
const account = await client.financialAccount.get(accountId);
|
|
550
|
+
if (account.success) {
|
|
551
|
+
console.log(`Account ${accountId}: ${account.data!.result.balance.available.value} SLE`);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
271
555
|
```
|
|
272
556
|
|
|
273
|
-
###
|
|
557
|
+
### Error Handling Best Practices
|
|
274
558
|
|
|
275
559
|
```ts
|
|
276
|
-
|
|
277
|
-
const
|
|
560
|
+
// Robust error handling with retries
|
|
561
|
+
const createTransferWithRetry = async (
|
|
562
|
+
sourceAccount: string,
|
|
563
|
+
destinationAccount: string,
|
|
564
|
+
amount: number,
|
|
565
|
+
maxRetries = 3
|
|
566
|
+
) => {
|
|
567
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
568
|
+
const transfer = await client.internalTransfer.create(sourceAccount, destinationAccount, amount);
|
|
569
|
+
|
|
570
|
+
if (transfer.success) {
|
|
571
|
+
return transfer;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Log the error
|
|
575
|
+
console.error(`Transfer attempt ${attempt} failed:`, transfer.error?.message);
|
|
576
|
+
|
|
577
|
+
// Don't retry on validation errors
|
|
578
|
+
if (transfer.error?.message?.includes('validation')) {
|
|
579
|
+
throw transfer.error;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Wait before retrying (exponential backoff)
|
|
583
|
+
if (attempt < maxRetries) {
|
|
584
|
+
await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
throw new Error(`Transfer failed after ${maxRetries} attempts`);
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
// Usage
|
|
592
|
+
try {
|
|
593
|
+
const transfer = await createTransferWithRetry("fa-source", "fa-dest", 10000);
|
|
594
|
+
console.log("Transfer successful:", transfer.data!.result.id);
|
|
595
|
+
} catch (error) {
|
|
596
|
+
console.error("Transfer failed permanently:", error.message);
|
|
597
|
+
}
|
|
278
598
|
```
|
|
279
599
|
|
|
280
600
|
---
|
|
@@ -309,38 +629,6 @@ await client.financialAccount.create("name");
|
|
|
309
629
|
|
|
310
630
|
---
|
|
311
631
|
|
|
312
|
-
## Folder Structure
|
|
313
|
-
|
|
314
|
-
```
|
|
315
|
-
.
|
|
316
|
-
├── LICENSE
|
|
317
|
-
├── README.md
|
|
318
|
-
├── package.json
|
|
319
|
-
├── tsconfig.json
|
|
320
|
-
├── tsup.config.ts
|
|
321
|
-
├── src
|
|
322
|
-
│ ├── index.ts # entry point (exports createClient, types)
|
|
323
|
-
│ ├── client.ts # MonimeClient with namespaced modules
|
|
324
|
-
│ └── modules/
|
|
325
|
-
│ ├── financialAccount/
|
|
326
|
-
│ │ ├── financialAccount.ts
|
|
327
|
-
│ │ └── index.ts
|
|
328
|
-
│ ├── financialTransaction/
|
|
329
|
-
│ │ ├── financialTransaction.ts
|
|
330
|
-
│ │ └── index.ts
|
|
331
|
-
│ ├── internalTransfer/
|
|
332
|
-
│ │ ├── internalTransfer.ts
|
|
333
|
-
│ │ └── index.ts
|
|
334
|
-
│ ├── paymentCode/
|
|
335
|
-
│ │ ├── paymentCode.ts
|
|
336
|
-
│ │ └── index.ts
|
|
337
|
-
│ ├── payout/
|
|
338
|
-
│ │ ├── payout.ts
|
|
339
|
-
│ │ └── index.ts
|
|
340
|
-
│ └── types.ts
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
---
|
|
344
632
|
|
|
345
633
|
## Error Handling
|
|
346
634
|
|
|
@@ -368,67 +656,301 @@ This project follows semantic versioning (SemVer). See releases for notable chan
|
|
|
368
656
|
- File issues and feature requests at the repository: `https://github.com/Walon-Foundation/monime-package/issues`.
|
|
369
657
|
- For production incidents, rotate credentials if you suspect exposure.
|
|
370
658
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
## Return Types (Appendix)
|
|
659
|
+
## TypeScript Types
|
|
374
660
|
|
|
375
|
-
All result payload types are exported from the package
|
|
661
|
+
All result payload types are exported from the package for complete type safety:
|
|
376
662
|
|
|
377
663
|
```ts
|
|
378
664
|
import type {
|
|
379
|
-
//
|
|
665
|
+
// Core types
|
|
666
|
+
ClientOptions,
|
|
667
|
+
|
|
668
|
+
// Financial Account types
|
|
380
669
|
CreateFinancialAccount,
|
|
381
670
|
GetFinancialAccount,
|
|
382
671
|
AllFinancialAccount,
|
|
383
672
|
|
|
384
|
-
// Internal Transfer
|
|
673
|
+
// Internal Transfer types
|
|
385
674
|
CreateInternalTransfer,
|
|
386
675
|
InternalTransfer,
|
|
387
676
|
AllInternalTransfers,
|
|
388
677
|
|
|
389
|
-
// Payment Code
|
|
678
|
+
// Payment Code types
|
|
390
679
|
CreatePaymentCode,
|
|
391
680
|
GetAllPaymentCode,
|
|
392
681
|
GetOne,
|
|
393
682
|
|
|
394
|
-
// Payout
|
|
683
|
+
// Payout types
|
|
395
684
|
DestinationOption,
|
|
396
685
|
CreatePayout,
|
|
397
686
|
GetAll,
|
|
398
687
|
GetOnePayout,
|
|
399
688
|
|
|
400
|
-
// Financial Transaction
|
|
689
|
+
// Financial Transaction types
|
|
401
690
|
GetTransaction,
|
|
402
691
|
AllTransaction,
|
|
692
|
+
|
|
693
|
+
// Checkout Session types
|
|
694
|
+
CreateCheckout,
|
|
695
|
+
AllCheckout,
|
|
696
|
+
OneCheckout,
|
|
403
697
|
} from "monime-package";
|
|
404
698
|
```
|
|
405
699
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
700
|
+
### Core Type Definitions
|
|
701
|
+
|
|
702
|
+
#### Result Envelope
|
|
703
|
+
All API responses follow this consistent pattern:
|
|
704
|
+
```ts
|
|
705
|
+
type Result<T> = {
|
|
706
|
+
success: boolean;
|
|
707
|
+
data?: T;
|
|
708
|
+
error?: Error;
|
|
709
|
+
};
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
#### Client Configuration
|
|
713
|
+
```ts
|
|
714
|
+
type ClientOptions = {
|
|
715
|
+
monimeSpaceId: string; // Your Monime Space ID
|
|
716
|
+
accessToken: string; // Your API access token
|
|
717
|
+
};
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
#### Destination Options for Payouts
|
|
721
|
+
```ts
|
|
722
|
+
type DestinationOption =
|
|
723
|
+
| {
|
|
724
|
+
type: "momo";
|
|
725
|
+
providerId: "m17" | "m18"; // MTN, Orange Money
|
|
726
|
+
phoneNumber: string;
|
|
727
|
+
}
|
|
728
|
+
| {
|
|
729
|
+
type: "bank";
|
|
730
|
+
providerId: "b01" | "b02" | "b03"; // Bank codes
|
|
731
|
+
accountNumber: string;
|
|
732
|
+
}
|
|
733
|
+
| {
|
|
734
|
+
type: "wallet";
|
|
735
|
+
providerId: "w01" | "w02"; // Wallet provider codes
|
|
736
|
+
walletId: string;
|
|
737
|
+
};
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
### Response Type Details
|
|
741
|
+
|
|
742
|
+
#### Financial Account Types
|
|
743
|
+
```ts
|
|
744
|
+
// Account creation/retrieval response
|
|
745
|
+
interface CreateFinancialAccount {
|
|
746
|
+
success: boolean;
|
|
747
|
+
messages: string[];
|
|
748
|
+
result: {
|
|
749
|
+
id: string; // Unique account ID
|
|
750
|
+
uvan: string; // Internal identifier
|
|
751
|
+
name: string; // Account name
|
|
752
|
+
currency: string; // Always "SLE" (Sierra Leone)
|
|
753
|
+
reference: string; // Account reference
|
|
754
|
+
description: string; // Account description
|
|
755
|
+
balance: {
|
|
756
|
+
available: {
|
|
757
|
+
currency: string;
|
|
758
|
+
value: number; // Balance in cents (SLE)
|
|
759
|
+
};
|
|
760
|
+
};
|
|
761
|
+
createTime: string; // ISO timestamp
|
|
762
|
+
updateTime: string; // ISO timestamp
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
#### Internal Transfer Types
|
|
768
|
+
```ts
|
|
769
|
+
interface CreateInternalTransfer {
|
|
770
|
+
success: boolean;
|
|
771
|
+
messages: string[];
|
|
772
|
+
result: {
|
|
773
|
+
id: string; // Transfer ID
|
|
774
|
+
status: string; // Transfer status
|
|
775
|
+
amount: {
|
|
776
|
+
currency: string;
|
|
777
|
+
value: number; // Amount in cents
|
|
778
|
+
};
|
|
779
|
+
sourceFinancialAccount: { id: string };
|
|
780
|
+
destinationFinancialAccount: { id: string };
|
|
781
|
+
financialTransactionReference: string;
|
|
782
|
+
description: string;
|
|
783
|
+
failureDetail: {
|
|
784
|
+
code: string;
|
|
785
|
+
message: string;
|
|
786
|
+
};
|
|
787
|
+
ownershipGraph: {
|
|
788
|
+
owner: {
|
|
789
|
+
id: string;
|
|
790
|
+
type: string;
|
|
791
|
+
owner: {
|
|
792
|
+
id: string;
|
|
793
|
+
type: string;
|
|
794
|
+
};
|
|
795
|
+
};
|
|
796
|
+
};
|
|
797
|
+
createTime: string;
|
|
798
|
+
updateTime: string;
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
```
|
|
410
802
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
803
|
+
#### Payment Code Types
|
|
804
|
+
```ts
|
|
805
|
+
interface CreatePaymentCode {
|
|
806
|
+
success: boolean;
|
|
807
|
+
messages: string[];
|
|
808
|
+
result: {
|
|
809
|
+
id: string;
|
|
810
|
+
mode: string; // "recurrent"
|
|
811
|
+
status: string; // Payment status
|
|
812
|
+
name: string; // Payment name
|
|
813
|
+
amount: {
|
|
814
|
+
currency: string;
|
|
815
|
+
value: number; // Amount in cents
|
|
816
|
+
};
|
|
817
|
+
enable: boolean;
|
|
818
|
+
expireTime: string; // ISO timestamp
|
|
819
|
+
customer: { name: string };
|
|
820
|
+
ussdCode: string; // USSD code for payment
|
|
821
|
+
reference: string;
|
|
822
|
+
authorizedProviders: string[];
|
|
823
|
+
authorizedPhoneNumber: string;
|
|
824
|
+
recurrentPaymentTarget: {
|
|
825
|
+
expectedPaymentCount: number;
|
|
826
|
+
expectedPaymentTotal: {
|
|
827
|
+
currency: string;
|
|
828
|
+
value: number;
|
|
829
|
+
};
|
|
830
|
+
};
|
|
831
|
+
financialAccountId: string;
|
|
832
|
+
processedPaymentData: {
|
|
833
|
+
amount: { currency: string; value: number };
|
|
834
|
+
orderId: string;
|
|
835
|
+
paymentId: string;
|
|
836
|
+
orderNumber: string;
|
|
837
|
+
channelData: {
|
|
838
|
+
providerId: string;
|
|
839
|
+
accountId: string;
|
|
840
|
+
reference: string;
|
|
841
|
+
};
|
|
842
|
+
financialTransactionReference: string;
|
|
843
|
+
};
|
|
844
|
+
createTime: string;
|
|
845
|
+
updateTime: string;
|
|
846
|
+
ownershipGraph: OwnershipGraph;
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
```
|
|
415
850
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
851
|
+
#### Checkout Session Types
|
|
852
|
+
```ts
|
|
853
|
+
interface CreateCheckout {
|
|
854
|
+
success: boolean;
|
|
855
|
+
messages: string[];
|
|
856
|
+
result: {
|
|
857
|
+
id: string;
|
|
858
|
+
status: string;
|
|
859
|
+
name: string;
|
|
860
|
+
orderNumber: string; // Generated order number
|
|
861
|
+
reference: string;
|
|
862
|
+
description: string;
|
|
863
|
+
redirectUrl: string; // Checkout page URL
|
|
864
|
+
cancelUrl: string;
|
|
865
|
+
successUrl: string;
|
|
866
|
+
lineItems: {
|
|
867
|
+
data: Array<{
|
|
868
|
+
type: string;
|
|
869
|
+
id: string;
|
|
870
|
+
name: string;
|
|
871
|
+
price: { currency: string; value: number };
|
|
872
|
+
quantity: number;
|
|
873
|
+
reference: string;
|
|
874
|
+
description: string;
|
|
875
|
+
images: string[];
|
|
876
|
+
}>;
|
|
877
|
+
};
|
|
878
|
+
financialAccountId: string;
|
|
879
|
+
brandingOptions: {
|
|
880
|
+
primaryColor: string;
|
|
881
|
+
};
|
|
882
|
+
expireTime: string;
|
|
883
|
+
createTime: string;
|
|
884
|
+
ownershipGraph: OwnershipGraph;
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
```
|
|
420
888
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
889
|
+
#### Common Types
|
|
890
|
+
```ts
|
|
891
|
+
// Pagination for list responses
|
|
892
|
+
interface Pagination {
|
|
893
|
+
count: number; // Total count
|
|
894
|
+
next: string; // Next page URL/cursor
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// Ownership information
|
|
898
|
+
interface OwnershipGraph {
|
|
899
|
+
owner: {
|
|
900
|
+
id: string;
|
|
901
|
+
type: string;
|
|
902
|
+
owner: {
|
|
903
|
+
id: string;
|
|
904
|
+
type: string;
|
|
905
|
+
};
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// Amount representation
|
|
910
|
+
interface Amount {
|
|
911
|
+
currency: string; // Always "SLE"
|
|
912
|
+
value: number; // Amount in cents (multiply by 100 for SLE)
|
|
913
|
+
}
|
|
914
|
+
```
|
|
426
915
|
|
|
427
|
-
|
|
428
|
-
- `GetTransaction`: details for a transaction (amount, reference, ownershipGraph, ...)
|
|
429
|
-
- `AllTransaction`: list of transactions with pagination
|
|
916
|
+
### Type Usage Examples
|
|
430
917
|
|
|
431
|
-
|
|
918
|
+
```ts
|
|
919
|
+
// Type-safe account creation
|
|
920
|
+
const createAccountTyped = async (name: string): Promise<CreateFinancialAccount | null> => {
|
|
921
|
+
const result = await client.financialAccount.create(name);
|
|
922
|
+
return result.success ? result.data! : null;
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
// Type-safe payout with validation
|
|
926
|
+
const createMobileMoneyPayout = async (
|
|
927
|
+
amount: number,
|
|
928
|
+
phoneNumber: string,
|
|
929
|
+
sourceAccount: string
|
|
930
|
+
): Promise<CreatePayout | null> => {
|
|
931
|
+
const destination: DestinationOption = {
|
|
932
|
+
type: "momo",
|
|
933
|
+
providerId: "m17",
|
|
934
|
+
phoneNumber,
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
const result = await client.payout.create(amount, destination, sourceAccount);
|
|
938
|
+
return result.success ? result.data! : null;
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
// Type-safe transaction processing
|
|
942
|
+
const processTransactions = async (): Promise<void> => {
|
|
943
|
+
const txResult = await client.financialTransaction.getAll();
|
|
944
|
+
|
|
945
|
+
if (txResult.success && txResult.data) {
|
|
946
|
+
const transactions: AllTransaction = txResult.data;
|
|
947
|
+
|
|
948
|
+
transactions.result.forEach((tx: GetTransaction['result']) => {
|
|
949
|
+
console.log(`Transaction ${tx.id}: ${tx.amount.value / 100} ${tx.amount.currency}`);
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
```
|
|
432
954
|
|
|
433
955
|
---
|
|
434
956
|
|