@tapsilat/tapsilat-js 2026.7.7 → 2026.10.26
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/CHANGELOG.md +9 -0
- package/README.md +217 -46
- package/dist/TapsilatSDK.d.ts +158 -40
- package/dist/TapsilatSDK.d.ts.map +1 -1
- package/dist/__mocks__/HttpClient.d.ts +1 -0
- package/dist/__mocks__/HttpClient.d.ts.map +1 -1
- package/dist/errors/TapsilatError.d.ts +12 -1
- package/dist/errors/TapsilatError.d.ts.map +1 -1
- package/dist/http/HttpClient.d.ts +19 -1
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/interceptors.d.ts.map +1 -1
- package/dist/index.cjs +1442 -128
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2029 -133
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1429 -129
- package/dist/index.js.map +1 -1
- package/dist/services/MarketplaceService.d.ts +59 -0
- package/dist/services/MarketplaceService.d.ts.map +1 -0
- package/dist/services/ServiceBase.d.ts +21 -0
- package/dist/services/ServiceBase.d.ts.map +1 -0
- package/dist/services/SubmerchantService.d.ts +31 -0
- package/dist/services/SubmerchantService.d.ts.map +1 -0
- package/dist/services/TokenizationService.d.ts +14 -0
- package/dist/services/TokenizationService.d.ts.map +1 -0
- package/dist/services/VposService.d.ts +26 -0
- package/dist/services/VposService.d.ts.map +1 -0
- package/dist/services/index.d.ts +6 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/types/elements.d.ts +144 -0
- package/dist/types/elements.d.ts.map +1 -0
- package/dist/types/index.d.ts +90 -44
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/panel.d.ts +839 -0
- package/dist/types/panel.d.ts.map +1 -0
- package/dist/utils/currency.d.ts +25 -0
- package/dist/utils/currency.d.ts.map +1 -0
- package/dist/utils/redact.d.ts +16 -0
- package/dist/utils/redact.d.ts.map +1 -0
- package/dist/utils/response.d.ts +12 -0
- package/dist/utils/response.d.ts.map +1 -1
- package/dist/utils/validators.d.ts +12 -0
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/verify.d.ts +31 -8
- package/dist/utils/verify.d.ts.map +1 -1
- package/dist/webhooks/OrderStatus.d.ts +98 -0
- package/dist/webhooks/OrderStatus.d.ts.map +1 -0
- package/dist/webhooks/WebhookEvent.d.ts +58 -0
- package/dist/webhooks/WebhookEvent.d.ts.map +1 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2026.10.26] - 2026-10-26
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `createElementsSession`, `getElementsSession` and `cancelElementsSession` for Tapsilat Elements sessions (`POST /elements/sessions`, `GET /elements/sessions/{id}`, `POST /elements/sessions/{id}/cancel`), with the `ElementsSessionCreateRequest`, `ElementsSessionCreateResponse`, `ElementsSession`, `ElementsCardSummary` and `ElementsSessionError` types and the `ElementsSessionPurpose`, `ElementsSessionStatus`, `ElementsTokenizeMode` and `ElementsCardBrand` constants. In Node.js the created session prints its `client_secret` as `[redacted]`; `JSON.stringify` keeps it.
|
|
14
|
+
- `TapsilatError.retryable`, set when the API error says the request can be retried.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Errors nested as `{"error": {"code", "message", "retryable"}}` set `message`, `apiCode` and `retryable` from that object instead of a message of `[object Object]`.
|
|
18
|
+
|
|
10
19
|
## [2025.12.5] - 2025-12-05
|
|
11
20
|
|
|
12
21
|
### Added
|
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ console.log("Order status:", status.status);
|
|
|
75
75
|
- Complete payment lifecycle management
|
|
76
76
|
- Multi-currency support (TRY, USD, EUR, GBP)
|
|
77
77
|
- Advanced filtering and pagination
|
|
78
|
+
- Tapsilat Elements sessions for the native Android and iOS card sheet
|
|
78
79
|
|
|
79
80
|
### Payment Term Management
|
|
80
81
|
- Create and manage installment plans
|
|
@@ -101,19 +102,7 @@ console.log("Order status:", status.status);
|
|
|
101
102
|
|
|
102
103
|
## SDK Compatibility
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
| Feature Category | JavaScript | Python | .NET |
|
|
107
|
-
|-----------------|------------|--------|------|
|
|
108
|
-
| Order Management | Yes | Yes | Yes |
|
|
109
|
-
| Payment Terms | Yes | Yes | Yes |
|
|
110
|
-
| System Utilities | Yes | Yes | Yes |
|
|
111
|
-
| Organization | Yes | Yes | Yes |
|
|
112
|
-
| GSM Validation | Yes | Yes | Yes |
|
|
113
|
-
| Installment Validation | Yes | Yes | Yes |
|
|
114
|
-
| Webhook Verification | Yes | No | No |
|
|
115
|
-
| TypeScript Support | Yes | No | Yes |
|
|
116
|
-
| Health Monitoring | Yes | No | No |
|
|
105
|
+
All Tapsilat SDKs (Go, JavaScript, Python, .NET, Kotlin, Rust, Swift and Zig) target the same panel REST API, so orders, payment terms, subscriptions, organization settings, submerchants, VPOS, card tokenization, card installments and the marketplace API behave the same in each. Webhook signature verification and the health check are additional helpers in this SDK.
|
|
117
106
|
|
|
118
107
|
---
|
|
119
108
|
|
|
@@ -152,7 +141,7 @@ console.log('Order status:', order.status);
|
|
|
152
141
|
#### Check Order Status
|
|
153
142
|
```typescript
|
|
154
143
|
const status = await tapsilat.getOrderStatus('order-reference-id');
|
|
155
|
-
if (status.status
|
|
144
|
+
if (OrderStatus.isPaid(status.status)) {
|
|
156
145
|
console.log('Payment successful!');
|
|
157
146
|
}
|
|
158
147
|
```
|
|
@@ -193,6 +182,22 @@ transactions.forEach(tx => {
|
|
|
193
182
|
});
|
|
194
183
|
```
|
|
195
184
|
|
|
185
|
+
#### Charge Order
|
|
186
|
+
```typescript
|
|
187
|
+
const chargeResult = await tapsilat.chargeOrder({
|
|
188
|
+
order_reference_id: 'order-reference-id'
|
|
189
|
+
});
|
|
190
|
+
console.log('Order charged:', chargeResult);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### Get Order Payments
|
|
194
|
+
`getAllOrdersPayments` is deprecated: the API has no route for it. List one order's payments with `getOrderPayments` and an order ID, reference ID or conversation ID.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const payments = await tapsilat.getOrderPayments({ order_reference_id: 'order-reference-id' });
|
|
198
|
+
console.log('Merchant net amount:', payments.total_merchant_net_amount);
|
|
199
|
+
```
|
|
200
|
+
|
|
196
201
|
#### Get Checkout URL
|
|
197
202
|
```typescript
|
|
198
203
|
const checkoutUrl = await tapsilat.getCheckoutUrl('order-reference-id');
|
|
@@ -225,55 +230,65 @@ console.log('Full refund processed:', fullRefund.amount);
|
|
|
225
230
|
### Webhook Handling
|
|
226
231
|
|
|
227
232
|
#### Verify Webhook Signature
|
|
233
|
+
Tapsilat signs every callback it sends to your callback URLs, and to an order's `payment_success_url` and `payment_failure_url`, with the webhook secret from the panel's callback settings. The `Tapsilat-Signature` header looks like `t=1726480000,v1=5257a8…`: `v1` is the hex HMAC-SHA256 of the timestamp, a dot and the raw body.
|
|
234
|
+
|
|
235
|
+
`verifyWebhook` checks it in constant time and rejects a timestamp more than 5 minutes from the server clock, so a captured callback cannot be replayed. Pass the raw body (a string or a `Buffer`), not re-encoded JSON. It resolves to `false` when the header is missing, malformed, stale or wrong.
|
|
228
236
|
```typescript
|
|
229
237
|
import express from 'express';
|
|
238
|
+
import { WebhookEvent, WEBHOOK_SIGNATURE_HEADER } from '@tapsilat/tapsilat-js';
|
|
230
239
|
|
|
231
240
|
const app = express();
|
|
232
|
-
app.use(express.raw({ type: 'application/json' }));
|
|
233
241
|
|
|
234
|
-
app.post('/webhooks/tapsilat', async (req, res) => {
|
|
235
|
-
const payload = req.body.toString();
|
|
236
|
-
const signature = req.headers['x-tapsilat-signature'];
|
|
237
|
-
|
|
242
|
+
app.post('/webhooks/tapsilat', express.raw({ type: '*/*' }), async (req, res) => {
|
|
238
243
|
const isValid = await tapsilat.verifyWebhook(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
process.env.
|
|
244
|
+
req.body, // the raw body as a Buffer
|
|
245
|
+
req.get(WEBHOOK_SIGNATURE_HEADER), // "Tapsilat-Signature"
|
|
246
|
+
process.env.TAPSILAT_WEBHOOK_SECRET!
|
|
242
247
|
);
|
|
243
|
-
|
|
244
248
|
if (!isValid) {
|
|
245
|
-
return res.
|
|
249
|
+
return res.sendStatus(400);
|
|
246
250
|
}
|
|
247
|
-
|
|
248
|
-
const event =
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
console.log('Order failed:', event.data.reference_id);
|
|
257
|
-
// Handle failed payment
|
|
258
|
-
break;
|
|
251
|
+
|
|
252
|
+
const event = WebhookEvent.fromPayload(req.body);
|
|
253
|
+
event.type; // "order_lite" (the default), "order", "order_payment_detail", ...
|
|
254
|
+
event.referenceId; // the order's reference ID, whatever the callback type
|
|
255
|
+
event.conversationId;
|
|
256
|
+
event.status; // e.g. "Paid", when the callback type carries a status
|
|
257
|
+
|
|
258
|
+
if (event.isPaid()) {
|
|
259
|
+
// fulfil the order
|
|
259
260
|
}
|
|
260
|
-
|
|
261
|
-
res.json({ received: true });
|
|
261
|
+
res.sendStatus(200);
|
|
262
262
|
});
|
|
263
263
|
```
|
|
264
264
|
|
|
265
|
+
A different tolerance in seconds can be passed as `{ tolerance }` in the fourth argument (`0` disables the timestamp check), and `{ now }` sets the Unix time to compare with. A bare hex HMAC of the body, with or without a `sha256=` prefix, is still accepted for signatures made the way earlier SDK versions documented.
|
|
266
|
+
|
|
267
|
+
#### Order Statuses
|
|
268
|
+
`OrderStatus` has the numeric status codes that callbacks carry, the names `getOrderStatus()` returns, and the groups most integrations need:
|
|
269
|
+
```typescript
|
|
270
|
+
import { OrderStatus } from '@tapsilat/tapsilat-js';
|
|
271
|
+
|
|
272
|
+
const { status } = await tapsilat.getOrderStatus(referenceId); // e.g. "Waiting for payment"
|
|
273
|
+
|
|
274
|
+
OrderStatus.isPaid(status); // Paid, Completed, Sub merchant payment approved
|
|
275
|
+
OrderStatus.isFailed(status); // Cancelled, Fraud, Rejected, Failure, Expired, Terminated
|
|
276
|
+
OrderStatus.isRefunded(status); // Refunded, Partially refunded
|
|
277
|
+
OrderStatus.code(status); // 7; also accepts "7" or 7
|
|
278
|
+
```
|
|
279
|
+
|
|
265
280
|
### Payment Term Management
|
|
266
281
|
|
|
267
282
|
#### Create Payment Term
|
|
268
283
|
```typescript
|
|
284
|
+
// order_id is the order's ID (order_id from createOrder), not its reference ID
|
|
269
285
|
const paymentTerm = await tapsilat.createOrderTerm({
|
|
270
|
-
order_id:
|
|
286
|
+
order_id: createdOrder.order_id,
|
|
271
287
|
term_reference_id: 'term-001',
|
|
272
288
|
amount: 250.00,
|
|
273
|
-
due_date: '2024-12-31',
|
|
289
|
+
due_date: '2024-12-31', // YYYY-MM-DD
|
|
274
290
|
term_sequence: 1,
|
|
275
291
|
required: true,
|
|
276
|
-
status: 'pending',
|
|
277
292
|
data: 'First installment'
|
|
278
293
|
});
|
|
279
294
|
console.log('Payment term created:', paymentTerm.term_reference_id);
|
|
@@ -281,11 +296,14 @@ console.log('Payment term created:', paymentTerm.term_reference_id);
|
|
|
281
296
|
|
|
282
297
|
#### Update Payment Term
|
|
283
298
|
```typescript
|
|
299
|
+
// The update replaces the term, so send every field rather than only the changed ones
|
|
284
300
|
const updatedTerm = await tapsilat.updateOrderTerm({
|
|
285
301
|
term_reference_id: 'term-001',
|
|
302
|
+
term_sequence: 1,
|
|
303
|
+
required: true,
|
|
286
304
|
amount: 275.00,
|
|
287
305
|
due_date: '2025-01-15',
|
|
288
|
-
status: '
|
|
306
|
+
status: 'pending'
|
|
289
307
|
});
|
|
290
308
|
console.log('Payment term updated:', updatedTerm.status);
|
|
291
309
|
```
|
|
@@ -293,6 +311,7 @@ console.log('Payment term updated:', updatedTerm.status);
|
|
|
293
311
|
#### Delete Payment Term
|
|
294
312
|
```typescript
|
|
295
313
|
const deletedTerm = await tapsilat.deleteOrderTerm({
|
|
314
|
+
order_id: createdOrder.order_id,
|
|
296
315
|
term_reference_id: 'term-001'
|
|
297
316
|
});
|
|
298
317
|
console.log('Payment term deleted:', deletedTerm.term_reference_id);
|
|
@@ -301,14 +320,16 @@ console.log('Payment term deleted:', deletedTerm.term_reference_id);
|
|
|
301
320
|
#### Refund Payment Term
|
|
302
321
|
```typescript
|
|
303
322
|
const termRefund = await tapsilat.refundOrderTerm({
|
|
304
|
-
term_id: 'term-
|
|
305
|
-
|
|
306
|
-
|
|
323
|
+
term_id: 'term-id', // the term's ID
|
|
324
|
+
reference_id: 'order-reference-id', // the order's reference ID
|
|
325
|
+
amount: 100.00
|
|
307
326
|
});
|
|
308
327
|
console.log('Term refund processed:', termRefund.refund_id);
|
|
309
328
|
```
|
|
310
329
|
|
|
311
330
|
#### Terminate Payment Term
|
|
331
|
+
`terminateOrderTerm` is deprecated: the API has no payment term termination route. Delete the term with `deleteOrderTerm`, or end the whole order with `terminateOrder`.
|
|
332
|
+
|
|
312
333
|
```typescript
|
|
313
334
|
const terminatedTerm = await tapsilat.terminateOrderTerm({
|
|
314
335
|
term_reference_id: 'term-001',
|
|
@@ -478,7 +499,21 @@ console.log('Organization Settings:', settings);
|
|
|
478
499
|
#### Get Currency Presets
|
|
479
500
|
```typescript
|
|
480
501
|
const presets = await tapsilat.getOrganizationCurrencyPresets();
|
|
481
|
-
console.log('Available currencies:', presets);
|
|
502
|
+
console.log('Available currencies:', presets.items);
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
#### Organization Management
|
|
506
|
+
```typescript
|
|
507
|
+
// Create Currency
|
|
508
|
+
const newCurrency = await tapsilat.createOrganizationCurrency({
|
|
509
|
+
currency_code: 'EUR'
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
// Get Partners
|
|
513
|
+
const partners = await tapsilat.getOrganizationPartners();
|
|
514
|
+
|
|
515
|
+
// Get Limits
|
|
516
|
+
const limits = await tapsilat.getOrganizationLimitsById('org-uuid', { currency: 'TRY' });
|
|
482
517
|
```
|
|
483
518
|
|
|
484
519
|
#### Get Suborganization Details
|
|
@@ -492,6 +527,7 @@ console.log('Suborganization Name:', suborg.name);
|
|
|
492
527
|
#### Get System Endpoints
|
|
493
528
|
```typescript
|
|
494
529
|
// Fetch various system configurations
|
|
530
|
+
const config = await tapsilat.getSystemConfig();
|
|
495
531
|
const errorCodes = await tapsilat.getSystemErrorCodes();
|
|
496
532
|
const productTypes = await tapsilat.getSystemProductTypes();
|
|
497
533
|
const transactionStatuses = await tapsilat.getSystemTransactionStatuses();
|
|
@@ -520,6 +556,141 @@ const updateResult = await tapsilat.orderRelatedUpdate(
|
|
|
520
556
|
console.log('Related order updated:', updateResult.success);
|
|
521
557
|
```
|
|
522
558
|
|
|
559
|
+
### Card Installments and Charging
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
const options = await tapsilat.getCardInstallments({
|
|
563
|
+
bin: '54066200',
|
|
564
|
+
amount: 100,
|
|
565
|
+
currency: 'TRY',
|
|
566
|
+
});
|
|
567
|
+
// options.installments lists each installment count with its commission rate and monthly payment
|
|
568
|
+
|
|
569
|
+
const table = await tapsilat.getInstallmentTable({ amount: 100, currency: 'TRY' });
|
|
570
|
+
// table.groups lists installment rows per bank card program
|
|
571
|
+
|
|
572
|
+
const charge = await tapsilat.chargeOrder({ order_reference_id: 'order-reference-id' });
|
|
573
|
+
if (!charge.isSuccess) {
|
|
574
|
+
// The request succeeded but the charge did not; inspect charge.errorCode and charge.message
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Submerchants, VPOS and Tokenization
|
|
579
|
+
|
|
580
|
+
Grouped services cover the remaining management APIs. Currency fields accept a currency UUID or an organization unit such as `TRY`; the server resolves units.
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
await tapsilat.submerchants.createSubmerchant({
|
|
584
|
+
locale: 'tr',
|
|
585
|
+
conversation_id: 'seller-1',
|
|
586
|
+
name: 'Example Ltd',
|
|
587
|
+
email: 'finance@example.test',
|
|
588
|
+
gsm_number: '905551112233',
|
|
589
|
+
sub_merchant_type: 'PRIVATE_COMPANY',
|
|
590
|
+
tax_number: '1234567890',
|
|
591
|
+
currency_id: 'TRY',
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
const posList = await tapsilat.vpos.listVpos({ page: 1, per_page: 20 });
|
|
595
|
+
const card = await tapsilat.tokenization.tokenizeCard({
|
|
596
|
+
card_number: '4111111111111111',
|
|
597
|
+
holder_name: 'John Doe',
|
|
598
|
+
expiry_month: '12',
|
|
599
|
+
expiry_year: '30',
|
|
600
|
+
cvv: '123',
|
|
601
|
+
user_id: 'customer-1',
|
|
602
|
+
});
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
`updateVpos` and `updateSubmerchant` replace the stored record: read it first and send every field back. For example, leaving out `failover` or `tls` stores `false`.
|
|
606
|
+
|
|
607
|
+
### Marketplace
|
|
608
|
+
|
|
609
|
+
`tapsilat.marketplace` uses the API version 2 routes, derived from your `baseURL`. Revisions are opaque strings: pass them back exactly as received.
|
|
610
|
+
|
|
611
|
+
```typescript
|
|
612
|
+
const payout = await tapsilat.marketplace.getMarketplacePayout(payoutId);
|
|
613
|
+
if (payout.eligibility_status === 'eligible' && payout.release_status === 'awaiting_approval') {
|
|
614
|
+
await tapsilat.marketplace.approveMarketplacePayouts({ ids: [payout.id!] });
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
await tapsilat.marketplace.runMarketplacePayoutOperation(payoutId, {
|
|
618
|
+
kind: 'update_item',
|
|
619
|
+
idempotency_key: 'booking-123-allocation-change-1',
|
|
620
|
+
revision: payout.revision!,
|
|
621
|
+
seller_reference: seller.routing_reference,
|
|
622
|
+
net_amount: '60.25',
|
|
623
|
+
});
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
Approval policies need a currency UUID; `createMarketplaceApprovalPolicy` and `updateMarketplaceApprovalPolicy` resolve units such as `TRY` for you, and `tapsilat.resolveCurrencyId('TRY')` exposes the same lookup.
|
|
627
|
+
|
|
628
|
+
### Tapsilat Elements Sessions
|
|
629
|
+
|
|
630
|
+
Tapsilat Elements is the native Android and iOS card sheet. Your backend creates a session with its secret API key and passes only the session's `client_secret` to the app, which opens the sheet with it. Card data goes from the sheet to Tapsilat encrypted and never reaches your backend.
|
|
631
|
+
|
|
632
|
+
#### Create an Elements Session
|
|
633
|
+
```typescript
|
|
634
|
+
import { ElementsSessionPurpose } from '@tapsilat/tapsilat-js';
|
|
635
|
+
|
|
636
|
+
const session = await tapsilat.createElementsSession({
|
|
637
|
+
purpose: ElementsSessionPurpose.PAY,
|
|
638
|
+
order_reference_id: order.reference_id,
|
|
639
|
+
save_card: true,
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
// Return session.id and session.client_secret to your app. Do not log or store the secret.
|
|
643
|
+
res.json({ id: session.id, client_secret: session.client_secret });
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
A `pay` session needs `order_reference_id`. A `tokenize` session saves a card for `user_id`, with `mode` set to `ElementsTokenizeMode.SECURE` (3D Secure), `HALF_SECURE` or `NON_SECURE`:
|
|
647
|
+
```typescript
|
|
648
|
+
import { ElementsSessionPurpose, ElementsTokenizeMode } from '@tapsilat/tapsilat-js';
|
|
649
|
+
|
|
650
|
+
const session = await tapsilat.createElementsSession({
|
|
651
|
+
purpose: ElementsSessionPurpose.TOKENIZE,
|
|
652
|
+
user_id: 'customer-1',
|
|
653
|
+
user_email: 'customer@example.test',
|
|
654
|
+
mode: ElementsTokenizeMode.SECURE,
|
|
655
|
+
});
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
#### Get the Session Outcome
|
|
659
|
+
Read the outcome on your backend before fulfilling, instead of trusting what the app reports:
|
|
660
|
+
```typescript
|
|
661
|
+
import { ElementsSessionStatus } from '@tapsilat/tapsilat-js';
|
|
662
|
+
|
|
663
|
+
const outcome = await tapsilat.getElementsSession(sessionId);
|
|
664
|
+
if (outcome.status === ElementsSessionStatus.SUCCEEDED) {
|
|
665
|
+
// fulfil the order; outcome.card holds the brand, last4 and expiry
|
|
666
|
+
} else if (outcome.status === ElementsSessionStatus.FAILED) {
|
|
667
|
+
// outcome.last_error?.code says why, for example "card_declined"
|
|
668
|
+
}
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
#### Cancel an Elements Session
|
|
672
|
+
```typescript
|
|
673
|
+
const canceled = await tapsilat.cancelElementsSession(sessionId);
|
|
674
|
+
```
|
|
675
|
+
This cancels a session that is still waiting for a card. A session that is confirming or has completed comes back unchanged, so check `canceled.status`.
|
|
676
|
+
|
|
677
|
+
The client secret is returned only by `createElementsSession`. In Node.js, `console.log` and `util.inspect` print it as `[redacted]`, and `JSON.stringify` keeps it so you can still send it to the app; a copy made with the spread operator prints it in full. `status`, `purpose` and `card.brand` are plain strings, so compare them with `ElementsSessionStatus`, `ElementsSessionPurpose` and `ElementsCardBrand`. Elements errors carry a stable `apiCode` (for example `elements_not_enabled` with HTTP 403, `session_not_found` with HTTP 404) and `retryable`, which is `true` for a temporary failure such as HTTP 503 `unavailable`:
|
|
678
|
+
```typescript
|
|
679
|
+
import { TapsilatError } from '@tapsilat/tapsilat-js';
|
|
680
|
+
|
|
681
|
+
try {
|
|
682
|
+
await tapsilat.getElementsSession(sessionId);
|
|
683
|
+
} catch (error) {
|
|
684
|
+
if (error instanceof TapsilatError && error.retryable) {
|
|
685
|
+
// try again later
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Error Details
|
|
691
|
+
|
|
692
|
+
Failed requests throw a `TapsilatError` (or a subclass). Besides `message` and `code`, it carries `statusCode`, the API's own `apiCode` and `apiStatus`, per-field validation `errors`, `retryable`, and the `rawBody`. Elements routes nest the error as `{"error": {"code": "...", "message": "...", "retryable": true}}`; `apiCode`, `message` and `retryable` are read from that object. Most "not found" errors arrive as HTTP 400, and rejected state changes (for example approving an ineligible payout) as HTTP 424. A successful status with an HTML body, which a deployment serving the panel UI returns for unknown routes, raises a `TapsilatError` with code `UNEXPECTED_RESPONSE`.
|
|
693
|
+
|
|
523
694
|
### Health Monitoring
|
|
524
695
|
|
|
525
696
|
#### API Health Check
|