@mbanq/core-sdk-js 1.0.0-alpha.5 → 1.0.0-alpha.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 CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  - ### Introduction
5
5
  - ### Installation
6
- - ### Authentication
6
+ - ### Quick Start
7
7
  - ### Setup
8
8
  - #### Axios Instance Logger
9
9
  - ### Middleware
@@ -11,37 +11,176 @@
11
11
  - #### Metrics Middleware
12
12
  - #### Custom Middleware
13
13
  - ### API Reference
14
- - #### Transfer Operations
15
- - #### GetTransfers
16
- - #### LogFail Transfer
17
- - #### MarkAsFail
18
- - #### MarkAsProcessing
19
- - #### MarkAsReturned
20
- - ### Custom API
21
- - #### Custom Get
22
- - #### Custom Create
23
- - #### Custom Update
14
+ - #### Payment Operations
15
+ - #### Create Payment
16
+ - #### Get Payment
17
+ - #### Update Payment
18
+ - #### List Payments
19
+ - #### Multi-Tenant Support
20
+ - ### Type Safety & Validation
24
21
  - ### Error Handling
25
22
  - ### Examples
26
23
 
27
24
  ## Introduction
28
- This library provides a set of JavaScript functions for interacting with our transfer management API. It simplifies the process of handling transfers and managing their statuses throughout their lifecycle.
25
+ This library provides a comprehensive JavaScript SDK for interacting with the Mbanq payment API. It offers type-safe payment operations with built-in validation, multi-tenant support, and a modern fluent API design.
29
26
  ## Installation
30
27
 
31
28
  ```bash
32
29
  npm install @mbanq/core-sdk-js
33
30
  ```
31
+
32
+ ## Quick Start
33
+
34
+ ```javascript
35
+ import { createClient } from '@mbanq/core-sdk-js';
36
+
37
+ // Initialize the client
38
+ const apiClient = createClient({
39
+ secret: 'your-api-secret',
40
+ signee: 'YOUR-SIGNEE',
41
+ baseUrl: 'https://api.cloud.mbanq.com',
42
+ tenantId: 'your-tenant-id'
43
+ });
44
+
45
+ // Create a payment
46
+ const payment = await apiClient.payment.create({
47
+ amount: 1000,
48
+ currency: 'USD',
49
+ paymentRail: 'ACH',
50
+ paymentType: 'CREDIT',
51
+ debtor: {
52
+ name: 'John Sender',
53
+ identifier: '123456789',
54
+ agent: {
55
+ name: 'First Bank',
56
+ identifier: '021000021'
57
+ }
58
+ },
59
+ creditor: {
60
+ name: 'Jane Receiver',
61
+ identifier: '987654321',
62
+ agent: {
63
+ name: 'Second Bank',
64
+ identifier: '121000248'
65
+ }
66
+ }
67
+ });
68
+
69
+ // List payments with filtering
70
+ const payments = await apiClient.payment.list()
71
+ .where('status').eq('DRAFT')
72
+ .where('paymentRail').eq('ACH')
73
+ .limit(10)
74
+ .execute();
75
+ ```
76
+
34
77
  ## Setup
35
- Before using any of the library functions, you need to initialize the client with your API credentials:
78
+
79
+ ### Authentication Options
80
+
81
+ The SDK supports multiple authentication methods. Choose the one that fits your integration:
82
+
83
+ #### 1. JWT Token Authentication (Recommended)
84
+ Use your API secret and signee for JWT-based authentication:
85
+
86
+ ```javascript
87
+ const client = createClient({
88
+ secret: 'your-jwt-secret',
89
+ signee: 'YOUR-SIGNEE',
90
+ baseUrl: 'https://api.cloud.mbanq.com',
91
+ tenantId: 'your-tenant-id'
92
+ });
93
+ ```
94
+
95
+ #### 2. Bearer Token Authentication
96
+ If you already have a valid access token:
97
+
98
+ ```javascript
99
+ // With "Bearer " prefix (recommended)
100
+ const client = createClient({
101
+ bearerToken: 'Bearer your-access-token',
102
+ baseUrl: 'https://api.cloud.mbanq.com',
103
+ tenantId: 'your-tenant-id'
104
+ });
105
+
106
+ // Without "Bearer " prefix (automatically added)
107
+ const client = createClient({
108
+ bearerToken: 'your-access-token', // "Bearer " will be added automatically
109
+ baseUrl: 'https://api.cloud.mbanq.com',
110
+ tenantId: 'your-tenant-id'
111
+ });
112
+ ```
113
+
114
+ #### 3. OAuth Credential Authentication
115
+ For OAuth 2.0 password grant flow:
116
+
117
+ ```javascript
118
+ const client = createClient({
119
+ credential: {
120
+ client_id: 'your-client-id',
121
+ client_secret: 'your-client-secret',
122
+ username: 'your-username',
123
+ password: 'your-password',
124
+ grant_type: 'password'
125
+ },
126
+ baseUrl: 'https://api.cloud.mbanq.com',
127
+ tenantId: 'your-tenant-id'
128
+ });
129
+ ```
130
+
131
+ #### Authentication Priority
132
+ When multiple authentication methods are provided, the SDK uses them in this order:
133
+ 1. **`bearerToken`** - Takes highest priority if provided
134
+ 2. **`credential`** - OAuth flow is used if no bearerToken
135
+ 3. **`secret` + `signee`** - JWT authentication used as fallback
136
+
137
+ #### Additional Configuration Options
36
138
  ```javascript
37
- const coreSDK = createClient({
38
- secret: 'testing123',
39
- signee: 'TESTING',
40
- baseUrl: 'https://example.com',
41
- tenantId: 'testing'
139
+ const client = createClient({
140
+ // Choose one authentication method from above
141
+ secret: 'your-jwt-secret',
142
+ signee: 'YOUR-SIGNEE',
143
+
144
+ // Required configuration
145
+ baseUrl: 'https://api.cloud.mbanq.com',
146
+ tenantId: 'your-tenant-id',
147
+
148
+ // Optional configuration
149
+ traceId: 'custom-trace-id', // Custom request tracing identifier
150
+ axiosConfig: {
151
+ timeout: 30000, // Request timeout in milliseconds (default: 29000)
152
+ keepAlive: true, // HTTP keep-alive for connection reuse
153
+ headers: {
154
+ 'Custom-Header': 'custom-value' // Additional HTTP headers
155
+ }
156
+ }
42
157
  });
43
158
  ```
44
159
 
160
+ ### Security Best Practices
161
+
162
+ #### Credential Management
163
+ - **Never hardcode credentials** in your source code
164
+ - Use environment variables or secure credential management systems
165
+ - Rotate API secrets and tokens regularly
166
+ - Use the minimum required permissions for your integration
167
+
168
+ #### Environment Variables Example
169
+ ```javascript
170
+ const client = createClient({
171
+ secret: process.env.MBANQ_API_SECRET,
172
+ signee: process.env.MBANQ_API_SIGNEE,
173
+ baseUrl: process.env.MBANQ_API_URL,
174
+ tenantId: process.env.MBANQ_TENANT_ID
175
+ });
176
+ ```
177
+
178
+ #### Production Considerations
179
+ - Use HTTPS endpoints only (`https://`)
180
+ - Implement proper error handling to avoid credential leakage in logs
181
+ - Configure appropriate request timeouts
182
+ - Use connection pooling for high-volume applications
183
+
45
184
  ### Axios Instance Logger
46
185
  You can also configure an Axios instance logger to set up interceptors or other axios-specific configurations:
47
186
 
@@ -192,212 +331,328 @@ const client = createClient({
192
331
  ```
193
332
 
194
333
  ## API Reference
195
- ### Transfer Operations
196
- ### `GetTransfers(options)`
197
334
 
198
- Retrieves a list of transfers based on the provided options.
199
- #### Parameters:
335
+ ### Payment Operations
200
336
 
201
- - `options (Object)`
202
- - `transferStatus` (String, optional): Filter by transfer status
203
- - `executedAt` (Date): Filter executed transfers from this date
204
- - `queryLimit` (Date, optional): Number of results per page
205
- - `paymentType` (String): Filter by paymentType
206
- - `tenantId` (String, optional): Set tenant ID
337
+ #### Create Payment
207
338
 
208
- #### Returns:
339
+ Creates a new payment with comprehensive validation.
209
340
 
210
- - Promise`<Array>` of transfer objects
211
-
212
- #### Example:
213
341
  ```javascript
214
- const command = GetTransfers({
215
- transferStatus: 'EXECUTION_SCHEDULED',
216
- executedAt: '2025-01-22',
217
- paymentType: 'ACH',
218
- queryLimit: 200,
219
- tenantId: 'default'
342
+ const payment = await apiClient.payment.create({
343
+ // Required fields
344
+ amount: 1000,
345
+ currency: 'USD',
346
+ paymentRail: 'ACH', // ACH, WIRE, SWIFT, INTERNAL, FXPAY, CARD
347
+ paymentType: 'CREDIT', // CREDIT or DEBIT
348
+
349
+ // Originator (sender)
350
+ debtor: {
351
+ name: 'John Sender',
352
+ identifier: '123456789', // Account number
353
+ accountType: 'CHECKING', // Optional: CHECKING or SAVINGS
354
+ agent: {
355
+ name: 'First Bank',
356
+ identifier: '021000021' // Routing code
357
+ }
358
+ },
359
+
360
+ // Recipient (receiver)
361
+ creditor: {
362
+ name: 'Jane Receiver',
363
+ identifier: '987654321',
364
+ accountType: 'SAVINGS',
365
+ address: { // Required for WIRE transfers
366
+ streetAddress: '123 Main St',
367
+ city: 'New York',
368
+ state: 'NY',
369
+ country: 'US',
370
+ postalCode: '10001'
371
+ },
372
+ agent: {
373
+ name: 'Second Bank',
374
+ identifier: '121000248'
375
+ }
376
+ },
377
+
378
+ // Optional fields
379
+ clientId: 'client-123',
380
+ reference: ['Invoice-001', 'Payment-ABC'],
381
+ exchangeRate: 1.25,
382
+ chargeBearer: 'OUR', // For SWIFT: OUR, BEN, SHA
383
+ valueDate: '2025-01-15',
384
+ paymentRailMetaData: {
385
+ priority: 'high',
386
+ category: 'business'
387
+ }
220
388
  });
221
- await coreSDK.request(command);
222
389
  ```
223
- ### `LogFailTransfer(params)`
224
-
225
- Logs a failed transfer with the specified reason.
226
- #### Parameters:
227
- - `params (Object)`
228
- - `payload` (Transfer): The payload of transfer
229
- - `tanantId` (String): tenant ID
230
-
231
- #### Returns:
232
390
 
233
- - Promise`<Object>`
391
+ #### Get Payment
234
392
 
235
- ### `MarkAsFail(options)`
393
+ Retrieves a specific payment by ID.
236
394
 
237
- Marks a transfer as failed.
238
- #### Parameters:
239
-
240
- - `options`
241
- - `externalId`: (String)
242
- - `paymentType`: (String, optional)
243
- - `tenantId`: (String, optional)
395
+ ```javascript
396
+ const payment = await apiClient.payment.get('payment-456');
397
+ ```
244
398
 
245
- #### Returns:
399
+ #### Update Payment
246
400
 
247
- - Promise`<Object>`
248
- - `id`: (string)
249
- - `clientId`: (number)
250
- - `resourceId`: (number)
251
- - `resourceIdentifier`: (string)
401
+ Updates an existing payment. All fields are optional.
252
402
 
253
- ### `MarkAsProcessing(options)`
403
+ ```javascript
404
+ const updatedPayment = await apiClient.payment.update('payment-456', {
405
+ amount: 1500,
406
+ status: 'EXECUTION_SCHEDULED',
407
+ creditor: {
408
+ name: 'Updated Recipient Name'
409
+ },
410
+ errorCode: 'E001',
411
+ errorMessage: 'Insufficient funds',
412
+ exchangeRate: 1.30,
413
+ reference: ['Updated-Reference'],
414
+ paymentRailMetaData: {
415
+ updated: true
416
+ }
417
+ });
418
+ ```
254
419
 
255
- Marks a transfer as currently processing.
256
- #### Parameters:
420
+ #### List Payments
257
421
 
258
- - `options`
259
- - `externalId`: (string)
260
- - `fileUrl`: (string)
261
- - `paymentType`: (string)
262
- - `traceNumbers`: (Object)
263
- - `outgoingTransfer`: (string)
264
- - `tenantId`: (string, optional)
422
+ Retrieves payments with powerful filtering capabilities.
265
423
 
266
- #### Returns:
424
+ ```javascript
425
+ // Simple list
426
+ const payments = await apiClient.payment.list().execute();
427
+
428
+ // With filters and pagination
429
+ const payments = await apiClient.payment.list()
430
+ .where('status').eq('DRAFT')
431
+ .where('paymentRail').eq('ACH')
432
+ .where('paymentType').eq('CREDIT')
433
+ .where('originatorName').eq('John Doe')
434
+ .limit(50)
435
+ .offset(0)
436
+ .execute();
437
+
438
+ // Available filter fields
439
+ // originatorName, originatorAccount, originatorBankRoutingCode
440
+ // recipientName, recipientAccount, recipientBankRoutingCode
441
+ // reference, traceNumber, externalId, clientId
442
+ // dateFormat, locale, originatedBy, paymentRail, paymentType
443
+ // fromValueDate, toValueDate, fromExecuteDate, toExecuteDate
444
+ // status, fromReturnDate, toReturnDate, isSettlement, orderBy, sortOrder
445
+ ```
267
446
 
268
- - Promise`<Object>`
269
- - `id`: (string)
270
- - `clientId`: (number)
271
- - `resourceId`: (number)
272
- - `resourceIdentifier`: (string)
447
+ ### Multi-Tenant Support
273
448
 
274
- ### `MarkAsReturned(transferId)`
449
+ The SDK supports multi-tenant operations through tenant context.
275
450
 
276
- Marks a transfer as returned.
277
- #### Parameters:
451
+ #### Default Tenant Operations
452
+ Uses the `tenantId` from client configuration:
278
453
 
279
- - `options`
280
- - `paymentType`: (string)
281
- - `externalId`: (string)
282
- - `returnFileUrl`: (string)
283
- - `errorCode`: (string)
284
- - `errorMessage`: (string)
285
- - `returnDate`: (Date, optional)
286
- - `traceNumbers`: (Object)
287
- - `incomingReturnFile`?: (string, optional)
288
- - `outgoingReturnFile`: (string, optional)
289
- - `rawReturnDetails`: (any, optional)
290
- - `tenantId`: (string, optional)
454
+ ```javascript
455
+ const payment = await apiClient.payment.create(paymentData);
456
+ const payments = await apiClient.payment.list().execute();
457
+ ```
291
458
 
292
- #### Returns:
459
+ #### Tenant-Specific Operations
460
+ Override tenant for specific operations:
293
461
 
294
- - Promise`<Object>`
295
- - `id`: (string)
296
- - `clientId`: (number)
297
- - `resourceId`: (number)
298
- - `resourceIdentifier`: (string)
462
+ ```javascript
463
+ // Create payment for specific tenant
464
+ const payment = await apiClient.tenant('tenant-123').payment.create(paymentData);
299
465
 
300
- ### Custom API
301
- ### `Custom Get`
466
+ // Get payment from specific tenant
467
+ const payment = await apiClient.tenant('tenant-123').payment.get('payment-456');
302
468
 
303
- Retrieves any records based on the provided options.
469
+ // Update payment in specific tenant
470
+ await apiClient.tenant('tenant-123').payment.update('payment-456', updateData);
304
471
 
305
- #### Parameters:
472
+ // List payments from specific tenant with filters
473
+ const payments = await apiClient.tenant('tenant-123').payment.list()
474
+ .where('status').eq('DRAFT')
475
+ .limit(10)
476
+ .execute();
477
+ ```
306
478
 
307
- - `options (Object)`
308
- - `commandName` (String, optional): Set command name base on you want beside name CustomGet
309
- - `url` (String): The url that use to request to get something but not include baseURL
310
- - `tenantId` (String, optional): Set tenant ID
479
+ ## Type Safety & Validation
311
480
 
312
- #### Returns:
481
+ The SDK uses [Zod](https://zod.dev/) for runtime type validation and TypeScript for compile-time type safety.
313
482
 
314
- - Promise`<any>`
483
+ ### Supported Payment Rails
484
+ - `ACH` - Automated Clearing House
485
+ - `SAMEDAYACH` - Same Day ACH
486
+ - `WIRE` - Domestic Wire Transfer
487
+ - `SWIFT` - International Wire Transfer
488
+ - `INTERNAL` - Internal Transfer
489
+ - `FXPAY` - Foreign Exchange Payment
490
+ - `CARD` - Card Payment
315
491
 
316
- ### `Custom Create`
492
+ ### Payment Statuses
493
+ - `DRAFT`, `AML_SCREENING`, `AML_REJECTED`
494
+ - `EXECUTION_SCHEDULED`, `EXECUTION_PROCESSING`, `EXECUTION_SUCCESS`, `EXECUTION_FAILURE`
495
+ - `RETURNED`, `CANCELLED`, `COMPLIANCE_FAILURE`, `DELETED`, `UNKNOWN`
317
496
 
318
- Create any record or something based on the provided options.
497
+ ### Validation Features
498
+ - **Input Validation**: All create/update operations validate data structure
499
+ - **Response Validation**: API responses are validated before returning
500
+ - **Custom Rules**: WIRE transfers require recipient address with state/country
501
+ - **Type Safety**: Full TypeScript support with inferred types
319
502
 
320
- #### Parameters:
503
+ ## Error Handling
504
+ The library uses a consistent error handling pattern. All API calls may throw the following errors:
321
505
 
322
- - `options (Object)`
323
- - `data` (Object): any values that use to create somthing
324
- - `commandName` (String, optional): Set command name base on you want beside name CustomGet
325
- - `url` (String): The url that use to request to get something but not include baseURL
326
- - `tenantId` (String, optional): Set tenant ID
506
+ ### Error Types
507
+ - **`CommandError`**: Base error type with `code`, `message`, `statusCode`, and optional `requestId`
508
+ - **Authentication Errors**: Invalid or missing API credentials
509
+ - Invalid JWT secret/signee combination
510
+ - Expired or invalid bearer token
511
+ - OAuth credential authentication failure
512
+ - **Validation Errors**: Invalid parameters provided (uses Zod validation)
513
+ - **API Errors**: Server-side errors with specific error codes
514
+ - **Network Errors**: Network connectivity or timeout issues
515
+
516
+ ### Common Authentication Error Scenarios
517
+ - **Missing credentials**: No authentication method provided
518
+ - **Invalid JWT**: Incorrect secret or signee values
519
+ - **Expired token**: Bearer token has expired and needs refresh
520
+ - **OAuth failure**: Invalid username/password or client credentials
327
521
 
328
- #### Returns:
522
+ ## Examples
329
523
 
330
- - Promise`<any>`
524
+ ### Complete Payment Flow Example
331
525
 
332
- ### `Custom Update`
526
+ ```javascript
527
+ import { createClient } from '@mbanq/core-sdk-js';
333
528
 
334
- Update any record or something based on the provided options.
529
+ // Initialize the client
530
+ const apiClient = createClient({
531
+ secret: 'your-secret',
532
+ signee: 'YOUR-SIGNEE',
533
+ baseUrl: 'https://api.cloud.mbanq.com',
534
+ tenantId: 'your-tenant-id'
535
+ });
335
536
 
336
- #### Parameters:
537
+ // Create an ACH payment
538
+ const achPayment = await apiClient.payment.create({
539
+ amount: 1500,
540
+ currency: 'USD',
541
+ paymentRail: 'ACH',
542
+ paymentType: 'CREDIT',
543
+ debtor: {
544
+ name: 'Alice Corporation',
545
+ identifier: '111222333',
546
+ accountType: 'CHECKING',
547
+ agent: {
548
+ name: 'First National Bank',
549
+ identifier: '021000021'
550
+ }
551
+ },
552
+ creditor: {
553
+ name: 'Bob Enterprises',
554
+ identifier: '444555666',
555
+ accountType: 'CHECKING',
556
+ agent: {
557
+ name: 'Second Federal Bank',
558
+ identifier: '121000248'
559
+ }
560
+ },
561
+ clientId: 'client-abc123',
562
+ reference: ['Invoice-2025-001']
563
+ });
337
564
 
338
- - `options (Object)`
339
- - `update` (Object): any values that use to update somthing
340
- - `commandName` (String, optional): Set command name base on you want beside name CustomGet
341
- - `url` (String): The url that use to request to get something but not include baseURL
342
- - `tenantId` (String, optional): Set tenant ID
565
+ console.log('Created payment:', achPayment.id);
566
+
567
+ // Create an international WIRE payment
568
+ const wirePayment = await apiClient.payment.create({
569
+ amount: 5000,
570
+ currency: 'USD',
571
+ paymentRail: 'SWIFT',
572
+ paymentType: 'CREDIT',
573
+ debtor: {
574
+ name: 'US Company',
575
+ identifier: '123456789',
576
+ agent: {
577
+ name: 'Chase Bank',
578
+ identifier: 'CHASUS33XXX'
579
+ }
580
+ },
581
+ creditor: {
582
+ name: 'European Partner',
583
+ identifier: '987654321',
584
+ address: {
585
+ streetAddress: '123 Business Ave',
586
+ city: 'London',
587
+ state: 'England',
588
+ country: 'GB',
589
+ postalCode: 'SW1A 1AA'
590
+ },
591
+ agent: {
592
+ name: 'HSBC Bank',
593
+ identifier: 'HBUKGB4BXXX'
594
+ }
595
+ },
596
+ chargeBearer: 'OUR',
597
+ reference: ['Contract-2025-002'],
598
+ exchangeRate: 0.85
599
+ });
343
600
 
344
- #### Returns:
601
+ // Retrieve and monitor payments
602
+ const payment = await apiClient.payment.get(achPayment.id);
603
+ console.log('Payment status:', payment.status);
345
604
 
346
- - Promise`<any>`
605
+ // Update payment if needed
606
+ if (payment.status === 'DRAFT') {
607
+ await apiClient.payment.update(payment.id, {
608
+ status: 'EXECUTION_SCHEDULED',
609
+ reference: ['Updated-Reference']
610
+ });
611
+ }
347
612
 
348
- ## Error Handling
349
- The library uses a consistent error handling pattern. All API calls may throw the following errors:
613
+ // List recent payments with filters
614
+ const recentPayments = await apiClient.payment.list()
615
+ .where('status').eq('EXECUTION_SCHEDULED')
616
+ .where('paymentRail').eq('ACH')
617
+ .where('fromExecuteDate').eq('2025-01-01')
618
+ .where('toExecuteDate').eq('2025-01-31')
619
+ .limit(25)
620
+ .execute();
621
+
622
+ console.log(`Found ${recentPayments.length} scheduled ACH payments`);
623
+
624
+ // Multi-tenant example
625
+ const tenantPayment = await apiClient.tenant('different-tenant').payment.create({
626
+ amount: 750,
627
+ currency: 'USD',
628
+ paymentRail: 'INTERNAL',
629
+ paymentType: 'CREDIT',
630
+ debtor: { name: 'Internal Sender', identifier: '111111' },
631
+ creditor: { name: 'Internal Receiver', identifier: '222222' }
632
+ });
633
+ ```
350
634
 
351
- - `AuthenticationError`: Invalid or missing API credentials
352
- - `ValidationError`: Invalid parameters provided
353
- - `ApiError`: General API error with specific error code and message
354
- - `NetworkError`: Network-related issues
635
+ ### Error Handling Example
355
636
 
356
- ## Examples
357
- ### Complete Transfer Flow Example
358
637
  ```javascript
359
- // Initialize the client
360
- const coreSDK = createClient({ secret: 'testing123', signee: 'TESTING', baseUrl: 'https://example.com', tenantId: 'testing' });
361
-
362
- // Get schedule transfers
363
- const command = GetTransfers({
364
- transferStatus: 'EXECUTION_SCHEDULED',
365
- executedAt: '2025-01-22',
366
- paymentType: 'ACH',
367
- queryLimit: 200,
368
- tenantId: 'default'
369
- });
370
- const scheduleTransfers = await coreSDK.request(command);
371
-
372
- // Process each transfer
373
- for (const transfer of scheduleTransfers) {
374
- try {
375
- // Mark as processing
376
- const markProcessing = MarkAsProcessing({
377
- externalId: transfer.externalId,
378
- fileUrl: transfer.fileUrl,
379
- paymentType: 'ACH',
380
- traceNumbers: {
381
- outgoingTransfer: '123456'
382
- },
383
- tenantId: 'default'
384
- })
385
- await coreSDK.request(markProcessing);
386
-
387
- // Your processing logic here
388
-
389
- // If processing fails
390
- if (/* some condition */) {
391
- const markFail = MarkAsFail({
392
- externalId: transfer.externalId,
393
- errorMessage: 'error testing',
394
- paymentType: 'ACH',
395
- tenantId: 'default'
396
- })
397
- await coreSDK.request(markFail);
638
+ import { isCommandError } from '@mbanq/core-sdk-js';
639
+
640
+ try {
641
+ const payment = await apiClient.payment.create({
642
+ amount: -100, // Invalid: negative amount
643
+ currency: 'INVALID', // Invalid: not 3-character code
644
+ // Missing required fields
645
+ });
646
+ } catch (error) {
647
+ if (isCommandError(error)) {
648
+ console.error('Payment creation failed:');
649
+ console.error('Code:', error.code);
650
+ console.error('Message:', error.message);
651
+ if (error.requestId) {
652
+ console.error('Request ID:', error.requestId);
398
653
  }
399
- } catch (error) {
400
- console.error(`Error processing transfer ${transfer.id}:`, error);
654
+ } else {
655
+ console.error('Unexpected error:', error);
401
656
  }
402
657
  }
403
658
  ```