@delopay/sdk 0.1.6 → 0.2.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/dist/index.js CHANGED
@@ -1,10 +1,3 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
1
  // src/error.ts
9
2
  var DelopayError = class extends Error {
10
3
  constructor(message, options) {
@@ -14,11 +7,19 @@ var DelopayError = class extends Error {
14
7
  this.status = options.status;
15
8
  this.code = options.code;
16
9
  this.type = options.type;
10
+ if (options.requestId !== void 0) this.requestId = options.requestId;
11
+ if (options.rawBody !== void 0) this.rawBody = options.rawBody;
17
12
  }
18
13
  };
19
14
  var DelopayAuthenticationError = class extends DelopayError {
20
- constructor(message = "Invalid API key") {
21
- super(message, { status: 401, code: "AUTH_01", type: "authentication_error" });
15
+ constructor(message = "Invalid API key", options) {
16
+ super(message, {
17
+ status: 401,
18
+ code: "AUTH_01",
19
+ type: "authentication_error",
20
+ requestId: options?.requestId,
21
+ rawBody: options?.rawBody
22
+ });
22
23
  Object.setPrototypeOf(this, new.target.prototype);
23
24
  this.name = "DelopayAuthenticationError";
24
25
  }
@@ -39,13 +40,13 @@ var Admin = class {
39
40
  return this.request("POST", "/admin/tenant_signup", { body: params });
40
41
  }
41
42
  // --- Advanced operations (Task 4.10) ---
42
- /** Set signup settings. `POST /admin/signup_settings` */
43
+ /** Set signup settings. `POST /admin/settings/signup` */
43
44
  async setSignupSettings(params) {
44
- return this.request("POST", "/admin/signup_settings", { body: params });
45
+ return this.request("POST", "/admin/settings/signup", { body: params });
45
46
  }
46
- /** Get signup settings. `GET /admin/signup_settings` */
47
+ /** Get signup settings. `GET /admin/settings/signup` */
47
48
  async getSignupSettings() {
48
- return this.request("GET", "/admin/signup_settings");
49
+ return this.request("GET", "/admin/settings/signup");
49
50
  }
50
51
  /** Onboard a merchant. `POST /admin/onboard_merchant` */
51
52
  async onboardMerchant(params) {
@@ -64,7 +65,7 @@ var AdminPortal = class {
64
65
  });
65
66
  }
66
67
  async getCustomer(customerId) {
67
- return this.request("GET", `/admin-portal/customers/${customerId}`);
68
+ return this.request("GET", `/admin-portal/customers/${encodeURIComponent(customerId)}`);
68
69
  }
69
70
  async listTransactions(params) {
70
71
  return this.request("GET", "/admin-portal/transactions", {
@@ -104,7 +105,7 @@ var ApiKeys = class {
104
105
  * ```
105
106
  */
106
107
  async create(merchantId, params) {
107
- return this.request("POST", `/api_keys/${merchantId}`, { body: params });
108
+ return this.request("POST", `/api_keys/${encodeURIComponent(merchantId)}`, { body: params });
108
109
  }
109
110
  /**
110
111
  * Retrieve metadata about an API key (does not return the plaintext secret).
@@ -114,7 +115,10 @@ var ApiKeys = class {
114
115
  * @returns The API key metadata.
115
116
  */
116
117
  async retrieve(merchantId, keyId) {
117
- return this.request("GET", `/api_keys/${merchantId}/${keyId}`);
118
+ return this.request(
119
+ "GET",
120
+ `/api_keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`
121
+ );
118
122
  }
119
123
  /**
120
124
  * Update an API key's name or expiry.
@@ -125,7 +129,11 @@ var ApiKeys = class {
125
129
  * @returns The updated API key metadata.
126
130
  */
127
131
  async update(merchantId, keyId, params) {
128
- return this.request("POST", `/api_keys/${merchantId}/${keyId}`, { body: params });
132
+ return this.request(
133
+ "POST",
134
+ `/api_keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,
135
+ { body: params }
136
+ );
129
137
  }
130
138
  /**
131
139
  * Revoke an API key, immediately invalidating it.
@@ -135,7 +143,10 @@ var ApiKeys = class {
135
143
  * @returns Revocation confirmation.
136
144
  */
137
145
  async revoke(merchantId, keyId) {
138
- return this.request("DELETE", `/api_keys/${merchantId}/${keyId}`);
146
+ return this.request(
147
+ "DELETE",
148
+ `/api_keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`
149
+ );
139
150
  }
140
151
  /**
141
152
  * List all API keys for a merchant.
@@ -144,7 +155,7 @@ var ApiKeys = class {
144
155
  * @returns Array of API key metadata objects.
145
156
  */
146
157
  async list(merchantId) {
147
- return this.request("GET", `/api_keys/${merchantId}/list`);
158
+ return this.request("GET", `/api_keys/${encodeURIComponent(merchantId)}/list`);
148
159
  }
149
160
  };
150
161
 
@@ -159,7 +170,7 @@ var AuditLogs = class {
159
170
  });
160
171
  }
161
172
  async retrieve(logId) {
162
- return this.request("GET", `/admin-portal/audit/${logId}`);
173
+ return this.request("GET", `/admin-portal/audit/${encodeURIComponent(logId)}`);
163
174
  }
164
175
  };
165
176
 
@@ -172,27 +183,39 @@ var Authentication = class {
172
183
  return this.request("POST", "/authentication", { body: params });
173
184
  }
174
185
  async checkEligibility(authId) {
175
- return this.request("POST", `/authentication/${authId}/eligibility`);
186
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/eligibility`);
176
187
  }
177
188
  async authenticate(authId, params) {
178
- return this.request("POST", `/authentication/${authId}/authenticate`, { body: params });
189
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/authenticate`, {
190
+ body: params
191
+ });
179
192
  }
180
193
  async sync(authId, params) {
181
- return this.request("POST", `/authentication/${authId}/sync`, { body: params });
194
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/sync`, {
195
+ body: params
196
+ });
182
197
  }
183
198
  /** Redirect after authentication. `POST /authentication/{authId}/redirect` */
184
199
  async redirect(authId, params) {
185
- return this.request("POST", `/authentication/${authId}/redirect`, { body: params });
200
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/redirect`, {
201
+ body: params
202
+ });
186
203
  }
187
204
  /** Enable authn methods token. `POST /authentication/{authId}/enabled_authn_methods_token` */
188
205
  async enabledAuthnMethodsToken(authId, params) {
189
- return this.request("POST", `/authentication/${authId}/enabled_authn_methods_token`, {
190
- body: params
191
- });
206
+ return this.request(
207
+ "POST",
208
+ `/authentication/${encodeURIComponent(authId)}/enabled_authn_methods_token`,
209
+ {
210
+ body: params
211
+ }
212
+ );
192
213
  }
193
214
  /** Submit eligibility check. `POST /authentication/{authId}/eligibility-check` */
194
215
  async eligibilityCheck(authId, params) {
195
- return this.request("POST", `/authentication/${authId}/eligibility-check`, { body: params });
216
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/eligibility-check`, {
217
+ body: params
218
+ });
196
219
  }
197
220
  };
198
221
 
@@ -209,7 +232,11 @@ var BillingAllocations = class {
209
232
  * @returns The allocation transfer result.
210
233
  */
211
234
  async transferIn(merchantId, params) {
212
- return this.request("POST", `/billing/${merchantId}/allocations/transfer-in`, { body: params });
235
+ return this.request(
236
+ "POST",
237
+ `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-in`,
238
+ { body: params }
239
+ );
213
240
  }
214
241
  /**
215
242
  * Transfer funds from a shop's allocation back to the host merchant treasury.
@@ -219,9 +246,13 @@ var BillingAllocations = class {
219
246
  * @returns The allocation transfer result.
220
247
  */
221
248
  async transferOut(merchantId, params) {
222
- return this.request("POST", `/billing/${merchantId}/allocations/transfer-out`, {
223
- body: params
224
- });
249
+ return this.request(
250
+ "POST",
251
+ `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-out`,
252
+ {
253
+ body: params
254
+ }
255
+ );
225
256
  }
226
257
  /**
227
258
  * List all shop balance allocations for a merchant.
@@ -230,7 +261,7 @@ var BillingAllocations = class {
230
261
  * @returns List of shop allocations.
231
262
  */
232
263
  async list(merchantId) {
233
- return this.request("GET", `/billing/${merchantId}/allocations`);
264
+ return this.request("GET", `/billing/${encodeURIComponent(merchantId)}/allocations`);
234
265
  }
235
266
  /**
236
267
  * Get the balance allocation for a specific shop.
@@ -240,7 +271,10 @@ var BillingAllocations = class {
240
271
  * @returns The shop's balance allocation.
241
272
  */
242
273
  async get(merchantId, profileId) {
243
- return this.request("GET", `/billing/${merchantId}/allocations/${profileId}`);
274
+ return this.request(
275
+ "GET",
276
+ `/billing/${encodeURIComponent(merchantId)}/allocations/${encodeURIComponent(profileId)}`
277
+ );
244
278
  }
245
279
  };
246
280
  var Billing = class {
@@ -261,7 +295,7 @@ var Billing = class {
261
295
  * ```
262
296
  */
263
297
  async getProfile(merchantId) {
264
- return this.request("GET", `/billing/${merchantId}`);
298
+ return this.request("GET", `/billing/${encodeURIComponent(merchantId)}`);
265
299
  }
266
300
  /**
267
301
  * Start a Stripe SetupIntent flow to collect a payment card for auto-recharge.
@@ -271,7 +305,9 @@ var Billing = class {
271
305
  * @returns The Stripe client secret needed to render the card element.
272
306
  */
273
307
  async setup(merchantId, params) {
274
- return this.request("POST", `/billing/${merchantId}/setup`, { body: params });
308
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/setup`, {
309
+ body: params
310
+ });
275
311
  }
276
312
  /**
277
313
  * Confirm card setup after the Stripe SetupIntent completes on the frontend.
@@ -281,7 +317,9 @@ var Billing = class {
281
317
  * @returns The updated billing profile.
282
318
  */
283
319
  async completeSetup(merchantId, params) {
284
- return this.request("POST", `/billing/${merchantId}/setup/complete`, { body: params });
320
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/setup/complete`, {
321
+ body: params
322
+ });
285
323
  }
286
324
  /**
287
325
  * Manually top up a merchant's prepaid balance by charging their saved card.
@@ -291,7 +329,9 @@ var Billing = class {
291
329
  * @returns The top-up result.
292
330
  */
293
331
  async topup(merchantId, params) {
294
- return this.request("POST", `/billing/${merchantId}/topup`, { body: params });
332
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/topup`, {
333
+ body: params
334
+ });
295
335
  }
296
336
  /**
297
337
  * List the balance ledger (credits and debits) for a merchant.
@@ -301,7 +341,7 @@ var Billing = class {
301
341
  * @returns The ledger entries.
302
342
  */
303
343
  async listLedger(merchantId, params) {
304
- return this.request("GET", `/billing/${merchantId}/ledger`, {
344
+ return this.request("GET", `/billing/${encodeURIComponent(merchantId)}/ledger`, {
305
345
  query: params
306
346
  });
307
347
  }
@@ -313,7 +353,9 @@ var Billing = class {
313
353
  * @returns The updated billing profile.
314
354
  */
315
355
  async updateAutoRecharge(merchantId, params) {
316
- return this.request("PATCH", `/billing/${merchantId}/auto-recharge`, { body: params });
356
+ return this.request("PATCH", `/billing/${encodeURIComponent(merchantId)}/auto-recharge`, {
357
+ body: params
358
+ });
317
359
  }
318
360
  /**
319
361
  * Admin: manually credit a merchant's balance (e.g. promotional credit).
@@ -323,7 +365,9 @@ var Billing = class {
323
365
  * @returns The adjustment result.
324
366
  */
325
367
  async adminCredit(merchantId, params) {
326
- return this.request("POST", `/billing/${merchantId}/admin/credit`, { body: params });
368
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/admin/credit`, {
369
+ body: params
370
+ });
327
371
  }
328
372
  /**
329
373
  * Admin: manually debit a merchant's balance.
@@ -333,7 +377,9 @@ var Billing = class {
333
377
  * @returns The adjustment result.
334
378
  */
335
379
  async adminDebit(merchantId, params) {
336
- return this.request("POST", `/billing/${merchantId}/admin/debit`, { body: params });
380
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/admin/debit`, {
381
+ body: params
382
+ });
337
383
  }
338
384
  };
339
385
 
@@ -367,7 +413,7 @@ var CardIssuers = class {
367
413
  return this.request("POST", "/card_issuers", { body: params });
368
414
  }
369
415
  async update(issuerId, params) {
370
- return this.request("PUT", `/card_issuers/${issuerId}`, { body: params });
416
+ return this.request("PUT", `/card_issuers/${encodeURIComponent(issuerId)}`, { body: params });
371
417
  }
372
418
  async list() {
373
419
  return this.request("GET", "/card_issuers");
@@ -380,21 +426,33 @@ var Connectors = class {
380
426
  this.request = request;
381
427
  }
382
428
  async create(accountId, params) {
383
- return this.request("POST", `/account/${accountId}/connectors`, { body: params });
429
+ return this.request("POST", `/account/${encodeURIComponent(accountId)}/connectors`, {
430
+ body: params
431
+ });
384
432
  }
385
433
  async retrieve(accountId, connectorId) {
386
- return this.request("GET", `/account/${accountId}/connectors/${connectorId}`);
434
+ return this.request(
435
+ "GET",
436
+ `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`
437
+ );
387
438
  }
388
439
  async list(accountId) {
389
- return this.request("GET", `/account/${accountId}/connectors`);
440
+ return this.request("GET", `/account/${encodeURIComponent(accountId)}/connectors`);
390
441
  }
391
442
  async update(accountId, connectorId, params) {
392
- return this.request("POST", `/account/${accountId}/connectors/${connectorId}`, {
393
- body: params
394
- });
443
+ return this.request(
444
+ "POST",
445
+ `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,
446
+ {
447
+ body: params
448
+ }
449
+ );
395
450
  }
396
451
  async delete(accountId, connectorId) {
397
- return this.request("DELETE", `/account/${accountId}/connectors/${connectorId}`);
452
+ return this.request(
453
+ "DELETE",
454
+ `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`
455
+ );
398
456
  }
399
457
  // --- Advanced operations (Task 4.8) ---
400
458
  /** Verify connector credentials. `POST /account/connectors/verify` */
@@ -403,11 +461,17 @@ var Connectors = class {
403
461
  }
404
462
  /** Register a webhook for a connector. `POST /account/{merchantId}/connectors/webhooks/{connectorId}` */
405
463
  async registerWebhook(merchantId, connectorId) {
406
- return this.request("POST", `/account/${merchantId}/connectors/webhooks/${connectorId}`);
464
+ return this.request(
465
+ "POST",
466
+ `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`
467
+ );
407
468
  }
408
469
  /** Get a webhook for a connector. `GET /account/{merchantId}/connectors/webhooks/{connectorId}` */
409
470
  async getWebhook(merchantId, connectorId) {
410
- return this.request("GET", `/account/${merchantId}/connectors/webhooks/${connectorId}`);
471
+ return this.request(
472
+ "GET",
473
+ `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`
474
+ );
411
475
  }
412
476
  /** List available payment methods. `GET /account/payment_methods` */
413
477
  async listPaymentMethods() {
@@ -449,7 +513,7 @@ var Customers = class {
449
513
  * ```
450
514
  */
451
515
  async retrieve(customerId) {
452
- return this.request("GET", `/customers/${customerId}`);
516
+ return this.request("GET", `/customers/${encodeURIComponent(customerId)}`);
453
517
  }
454
518
  /**
455
519
  * Update an existing customer's details.
@@ -459,7 +523,7 @@ var Customers = class {
459
523
  * @returns The updated customer.
460
524
  */
461
525
  async update(customerId, params) {
462
- return this.request("POST", `/customers/${customerId}`, { body: params });
526
+ return this.request("POST", `/customers/${encodeURIComponent(customerId)}`, { body: params });
463
527
  }
464
528
  /**
465
529
  * Delete a customer and all their saved payment methods.
@@ -468,7 +532,7 @@ var Customers = class {
468
532
  * @returns The deleted customer object.
469
533
  */
470
534
  async delete(customerId) {
471
- return this.request("DELETE", `/customers/${customerId}`);
535
+ return this.request("DELETE", `/customers/${encodeURIComponent(customerId)}`);
472
536
  }
473
537
  /**
474
538
  * List customers, optionally filtered by email.
@@ -490,7 +554,7 @@ var Customers = class {
490
554
  }
491
555
  /** List mandates for a customer. `GET /customers/{customerId}/mandates` */
492
556
  async listMandates(customerId) {
493
- return this.request("GET", `/customers/${customerId}/mandates`);
557
+ return this.request("GET", `/customers/${encodeURIComponent(customerId)}/mandates`);
494
558
  }
495
559
  };
496
560
 
@@ -506,7 +570,7 @@ var Disputes = class {
506
570
  * @returns The dispute.
507
571
  */
508
572
  async retrieve(disputeId) {
509
- return this.request("GET", `/disputes/${disputeId}`);
573
+ return this.request("GET", `/disputes/${encodeURIComponent(disputeId)}`);
510
574
  }
511
575
  /**
512
576
  * List disputes, optionally filtered by status, stage, or date range.
@@ -526,7 +590,7 @@ var Disputes = class {
526
590
  * @returns The updated dispute.
527
591
  */
528
592
  async accept(disputeId) {
529
- return this.request("POST", `/disputes/accept/${disputeId}`);
593
+ return this.request("POST", `/disputes/accept/${encodeURIComponent(disputeId)}`);
530
594
  }
531
595
  /**
532
596
  * Submit evidence to challenge a dispute.
@@ -552,7 +616,7 @@ var Disputes = class {
552
616
  * @returns The submitted evidence.
553
617
  */
554
618
  async retrieveEvidence(disputeId) {
555
- return this.request("GET", `/disputes/evidence/${disputeId}`);
619
+ return this.request("GET", `/disputes/evidence/${encodeURIComponent(disputeId)}`);
556
620
  }
557
621
  /**
558
622
  * Delete submitted evidence for a dispute.
@@ -586,9 +650,17 @@ var Disputes = class {
586
650
  async aggregateByProfile(params) {
587
651
  return this.request("GET", "/disputes/profile/aggregate", { query: params });
588
652
  }
589
- /** Fetch dispute from connector. `POST /disputes/{disputeId}/fetch_from_connector` */
590
- async fetchFromConnector(disputeId) {
591
- return this.request("POST", `/disputes/${disputeId}/fetch_from_connector`);
653
+ /**
654
+ * Fetch the latest dispute state from the connector (gateway).
655
+ * `GET /disputes/{connectorId}/fetch`
656
+ *
657
+ * Note: the path parameter is the **connector dispute id** on the gateway, not the
658
+ * Delopay dispute id. Method is GET (not POST) and this method signature was
659
+ * previously wrong — callers depending on the old `POST /disputes/{id}/fetch_from_connector`
660
+ * path were silently hitting 404s.
661
+ */
662
+ async fetchFromConnector(connectorId) {
663
+ return this.request("GET", `/disputes/${encodeURIComponent(connectorId)}/fetch`);
592
664
  }
593
665
  };
594
666
 
@@ -619,7 +691,7 @@ var EphemeralKeys = class {
619
691
  * @returns The deleted key object.
620
692
  */
621
693
  async delete(keyId) {
622
- return this.request("DELETE", `/ephemeral_keys/${keyId}`);
694
+ return this.request("DELETE", `/ephemeral_keys/${encodeURIComponent(keyId)}`);
623
695
  }
624
696
  };
625
697
 
@@ -629,13 +701,19 @@ var Events = class {
629
701
  this.request = request;
630
702
  }
631
703
  async list(merchantId, params) {
632
- return this.request("POST", `/events/${merchantId}`, { body: params });
704
+ return this.request("POST", `/events/${encodeURIComponent(merchantId)}`, { body: params });
633
705
  }
634
706
  async listDeliveryAttempts(merchantId, eventId) {
635
- return this.request("GET", `/events/${merchantId}/${eventId}/attempts`);
707
+ return this.request(
708
+ "GET",
709
+ `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/attempts`
710
+ );
636
711
  }
637
712
  async retryDelivery(merchantId, eventId) {
638
- return this.request("POST", `/events/${merchantId}/${eventId}/retry`);
713
+ return this.request(
714
+ "POST",
715
+ `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/retry`
716
+ );
639
717
  }
640
718
  // --- Profile-scoped listing (Task 4.12) ---
641
719
  /** List events (profile-scoped). `POST /events/profile/list` */
@@ -680,7 +758,7 @@ var PlatformFees = class {
680
758
  * @returns The fee schedule.
681
759
  */
682
760
  async retrieve(feeId) {
683
- return this.request("GET", `/admin/fees/${feeId}`);
761
+ return this.request("GET", `/admin/fees/${encodeURIComponent(feeId)}`);
684
762
  }
685
763
  /**
686
764
  * Update a fee schedule (admin only).
@@ -690,7 +768,7 @@ var PlatformFees = class {
690
768
  * @returns The updated fee schedule.
691
769
  */
692
770
  async update(feeId, params) {
693
- return this.request("PUT", `/admin/fees/${feeId}`, { body: params });
771
+ return this.request("PUT", `/admin/fees/${encodeURIComponent(feeId)}`, { body: params });
694
772
  }
695
773
  /**
696
774
  * Delete a fee schedule (admin only).
@@ -699,7 +777,7 @@ var PlatformFees = class {
699
777
  * @returns The deleted fee schedule.
700
778
  */
701
779
  async delete(feeId) {
702
- return this.request("DELETE", `/admin/fees/${feeId}`);
780
+ return this.request("DELETE", `/admin/fees/${encodeURIComponent(feeId)}`);
703
781
  }
704
782
  };
705
783
  var MerchantFees = class {
@@ -738,7 +816,7 @@ var MerchantFees = class {
738
816
  * @returns The updated fee schedule.
739
817
  */
740
818
  async update(feeId, params) {
741
- return this.request("PUT", `/merchant_fees/${feeId}`, { body: params });
819
+ return this.request("PUT", `/merchant_fees/${encodeURIComponent(feeId)}`, { body: params });
742
820
  }
743
821
  /**
744
822
  * Delete a merchant-scoped fee schedule.
@@ -747,7 +825,7 @@ var MerchantFees = class {
747
825
  * @returns The deleted fee schedule.
748
826
  */
749
827
  async delete(feeId) {
750
- return this.request("DELETE", `/merchant_fees/${feeId}`);
828
+ return this.request("DELETE", `/merchant_fees/${encodeURIComponent(feeId)}`);
751
829
  }
752
830
  };
753
831
  var Fees = class {
@@ -788,7 +866,7 @@ var Mandates = class {
788
866
  * @returns The mandate.
789
867
  */
790
868
  async retrieve(mandateId) {
791
- return this.request("GET", `/mandates/${mandateId}`);
869
+ return this.request("GET", `/mandates/${encodeURIComponent(mandateId)}`);
792
870
  }
793
871
  /**
794
872
  * Revoke an active mandate, preventing future charges.
@@ -797,7 +875,7 @@ var Mandates = class {
797
875
  * @returns Revocation confirmation.
798
876
  */
799
877
  async revoke(mandateId) {
800
- return this.request("POST", `/mandates/revoke/${mandateId}`);
878
+ return this.request("POST", `/mandates/revoke/${encodeURIComponent(mandateId)}`);
801
879
  }
802
880
  /**
803
881
  * List mandates, optionally filtered by customer or status.
@@ -821,13 +899,13 @@ var MerchantAccounts = class {
821
899
  return this.request("POST", "/accounts", { body: params });
822
900
  }
823
901
  async retrieve(accountId) {
824
- return this.request("GET", `/accounts/${accountId}`);
902
+ return this.request("GET", `/accounts/${encodeURIComponent(accountId)}`);
825
903
  }
826
904
  async update(accountId, params) {
827
- return this.request("POST", `/accounts/${accountId}`, { body: params });
905
+ return this.request("POST", `/accounts/${encodeURIComponent(accountId)}`, { body: params });
828
906
  }
829
907
  async delete(accountId) {
830
- return this.request("DELETE", `/accounts/${accountId}`);
908
+ return this.request("DELETE", `/accounts/${encodeURIComponent(accountId)}`);
831
909
  }
832
910
  // --- Advanced operations (Task 4.9) ---
833
911
  /** List all merchant accounts. `GET /accounts/list` */
@@ -836,15 +914,15 @@ var MerchantAccounts = class {
836
914
  }
837
915
  /** Toggle key-value store for a merchant. `POST /accounts/{accountId}/kv` */
838
916
  async toggleKv(accountId) {
839
- return this.request("POST", `/accounts/${accountId}/kv`);
917
+ return this.request("POST", `/accounts/${encodeURIComponent(accountId)}/kv`);
840
918
  }
841
919
  /** Get KV status for a merchant. `GET /accounts/{accountId}/kv` */
842
920
  async getKvStatus(accountId) {
843
- return this.request("GET", `/accounts/${accountId}/kv`);
921
+ return this.request("GET", `/accounts/${encodeURIComponent(accountId)}/kv`);
844
922
  }
845
- /** Transfer keys between merchants. `POST /accounts/transfer_keys` */
923
+ /** Transfer keys between merchants. `POST /accounts/transfer` */
846
924
  async transferKeys(params) {
847
- return this.request("POST", "/accounts/transfer_keys", { body: params });
925
+ return this.request("POST", "/accounts/transfer", { body: params });
848
926
  }
849
927
  };
850
928
 
@@ -860,7 +938,7 @@ var PaymentLinks = class {
860
938
  * @returns The payment link details.
861
939
  */
862
940
  async retrieve(linkId) {
863
- return this.request("GET", `/payment_link/${linkId}`);
941
+ return this.request("GET", `/payment_link/${encodeURIComponent(linkId)}`);
864
942
  }
865
943
  /**
866
944
  * List payment links, optionally filtered by status or date range.
@@ -873,11 +951,17 @@ var PaymentLinks = class {
873
951
  }
874
952
  /** Initiate (render) a payment link page. `GET /payment_link/{merchantId}/{paymentId}` */
875
953
  async initiate(merchantId, paymentId) {
876
- return this.request("GET", `/payment_link/${merchantId}/${paymentId}`);
954
+ return this.request(
955
+ "GET",
956
+ `/payment_link/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`
957
+ );
877
958
  }
878
959
  /** Get payment link status. `GET /payment_linkstatus/{merchantId}/{paymentId}` */
879
960
  async status(merchantId, paymentId) {
880
- return this.request("GET", `/payment_linkstatus/${merchantId}/${paymentId}`);
961
+ return this.request(
962
+ "GET",
963
+ `/payment_linkstatus/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`
964
+ );
881
965
  }
882
966
  };
883
967
 
@@ -911,7 +995,7 @@ var PaymentMethods = class {
911
995
  * @returns The payment method.
912
996
  */
913
997
  async retrieve(methodId) {
914
- return this.request("GET", `/payment_methods/${methodId}`);
998
+ return this.request("GET", `/payment_methods/${encodeURIComponent(methodId)}`);
915
999
  }
916
1000
  /**
917
1001
  * Update an existing payment method (e.g. update card expiry).
@@ -921,7 +1005,9 @@ var PaymentMethods = class {
921
1005
  * @returns The updated payment method.
922
1006
  */
923
1007
  async update(methodId, params) {
924
- return this.request("POST", `/payment_methods/${methodId}/update`, { body: params });
1008
+ return this.request("POST", `/payment_methods/${encodeURIComponent(methodId)}/update`, {
1009
+ body: params
1010
+ });
925
1011
  }
926
1012
  /**
927
1013
  * Delete a saved payment method.
@@ -930,7 +1016,7 @@ var PaymentMethods = class {
930
1016
  * @returns Deletion confirmation.
931
1017
  */
932
1018
  async delete(methodId) {
933
- return this.request("DELETE", `/payment_methods/${methodId}`);
1019
+ return this.request("DELETE", `/payment_methods/${encodeURIComponent(methodId)}`);
934
1020
  }
935
1021
  /**
936
1022
  * List payment methods using a client secret.
@@ -944,18 +1030,25 @@ var PaymentMethods = class {
944
1030
  });
945
1031
  }
946
1032
  /**
947
- * List all saved payment methods for a customer.
1033
+ * List all saved payment methods for a customer, optionally filtered.
948
1034
  *
949
1035
  * @param customerId - The customer ID.
1036
+ * @param params - Optional filters: `client_secret`, `accepted_countries`, `accepted_currencies`,
1037
+ * `amount`, `recurring_enabled`, `installment_payment_enabled`, `limit`, `card_networks`.
950
1038
  * @returns Customer's saved payment methods.
951
1039
  *
952
1040
  * @example
953
1041
  * ```typescript
954
- * const { customer_payment_methods } = await delopay.paymentMethods.listForCustomer('cus_123');
1042
+ * const { customer_payment_methods } = await delopay.paymentMethods.listForCustomer(
1043
+ * 'cus_123',
1044
+ * { accepted_currencies: ['EUR'], amount: 5000 },
1045
+ * );
955
1046
  * ```
956
1047
  */
957
- async listForCustomer(customerId) {
958
- return this.request("GET", `/customers/${customerId}/payment_methods`);
1048
+ async listForCustomer(customerId, params) {
1049
+ return this.request("GET", `/customers/${encodeURIComponent(customerId)}/payment_methods`, {
1050
+ query: params
1051
+ });
959
1052
  }
960
1053
  /**
961
1054
  * Set a payment method as the default for a customer.
@@ -965,7 +1058,10 @@ var PaymentMethods = class {
965
1058
  * @returns The updated payment method.
966
1059
  */
967
1060
  async setDefault(customerId, methodId) {
968
- return this.request("POST", `/customers/${customerId}/payment_methods/${methodId}/default`);
1061
+ return this.request(
1062
+ "POST",
1063
+ `/customers/${encodeURIComponent(customerId)}/payment_methods/${encodeURIComponent(methodId)}/default`
1064
+ );
969
1065
  }
970
1066
  // --- Advanced operations (Task 3.3) ---
971
1067
  /** Migrate a payment method. `POST /payment_methods/migrate` */
@@ -998,7 +1094,9 @@ var PaymentMethods = class {
998
1094
  }
999
1095
  /** Save a payment method. `POST /payment_methods/{methodId}/save` */
1000
1096
  async save(methodId, params) {
1001
- return this.request("POST", `/payment_methods/${methodId}/save`, { body: params });
1097
+ return this.request("POST", `/payment_methods/${encodeURIComponent(methodId)}/save`, {
1098
+ body: params
1099
+ });
1002
1100
  }
1003
1101
  /** Create payment method auth link token. `POST /payment_methods/auth/link` */
1004
1102
  async createAuthLink(params) {
@@ -1010,7 +1108,9 @@ var PaymentMethods = class {
1010
1108
  }
1011
1109
  /** Tokenize card using existing PM. `POST /payment_methods/{methodId}/tokenize-card` */
1012
1110
  async tokenizeCardForMethod(methodId, params) {
1013
- return this.request("POST", `/payment_methods/${methodId}/tokenize-card`, { body: params });
1111
+ return this.request("POST", `/payment_methods/${encodeURIComponent(methodId)}/tokenize-card`, {
1112
+ body: params
1113
+ });
1014
1114
  }
1015
1115
  };
1016
1116
 
@@ -1049,7 +1149,7 @@ var Payments = class {
1049
1149
  * ```
1050
1150
  */
1051
1151
  async retrieve(paymentId) {
1052
- return this.request("GET", `/payments/${paymentId}`);
1152
+ return this.request("GET", `/payments/${encodeURIComponent(paymentId)}`);
1053
1153
  }
1054
1154
  /**
1055
1155
  * Update an existing payment intent before it is confirmed.
@@ -1059,7 +1159,7 @@ var Payments = class {
1059
1159
  * @returns The updated payment intent.
1060
1160
  */
1061
1161
  async update(paymentId, params) {
1062
- return this.request("POST", `/payments/${paymentId}`, { body: params });
1162
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}`, { body: params });
1063
1163
  }
1064
1164
  /**
1065
1165
  * Confirm a payment intent, triggering authorisation with the selected gateway.
@@ -1069,7 +1169,9 @@ var Payments = class {
1069
1169
  * @returns The updated payment intent.
1070
1170
  */
1071
1171
  async confirm(paymentId, params) {
1072
- return this.request("POST", `/payments/${paymentId}/confirm`, { body: params });
1172
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/confirm`, {
1173
+ body: params
1174
+ });
1073
1175
  }
1074
1176
  /**
1075
1177
  * Capture a previously authorised payment.
@@ -1079,7 +1181,9 @@ var Payments = class {
1079
1181
  * @returns The updated payment intent.
1080
1182
  */
1081
1183
  async capture(paymentId, params) {
1082
- return this.request("POST", `/payments/${paymentId}/capture`, { body: params });
1184
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/capture`, {
1185
+ body: params
1186
+ });
1083
1187
  }
1084
1188
  /**
1085
1189
  * Cancel a payment intent that has not yet been captured.
@@ -1089,7 +1193,9 @@ var Payments = class {
1089
1193
  * @returns The updated payment intent.
1090
1194
  */
1091
1195
  async cancel(paymentId, params) {
1092
- return this.request("POST", `/payments/${paymentId}/cancel`, { body: params });
1196
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/cancel`, {
1197
+ body: params
1198
+ });
1093
1199
  }
1094
1200
  /**
1095
1201
  * List payment intents, optionally filtered by customer or date range.
@@ -1118,33 +1224,47 @@ var Payments = class {
1118
1224
  }
1119
1225
  /** Cancel after partial capture. `POST /payments/{paymentId}/cancel_post_capture` */
1120
1226
  async cancelPostCapture(paymentId, params) {
1121
- return this.request("POST", `/payments/${paymentId}/cancel_post_capture`, { body: params });
1227
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/cancel_post_capture`, {
1228
+ body: params
1229
+ });
1122
1230
  }
1123
1231
  /** Incrementally authorize more funds. `POST /payments/{paymentId}/incremental_authorization` */
1124
1232
  async incrementalAuthorization(paymentId, params) {
1125
- return this.request("POST", `/payments/${paymentId}/incremental_authorization`, {
1126
- body: params
1127
- });
1233
+ return this.request(
1234
+ "POST",
1235
+ `/payments/${encodeURIComponent(paymentId)}/incremental_authorization`,
1236
+ {
1237
+ body: params
1238
+ }
1239
+ );
1128
1240
  }
1129
1241
  /** Extend authorization window. `POST /payments/{paymentId}/extend_authorization` */
1130
1242
  async extendAuthorization(paymentId, params) {
1131
- return this.request("POST", `/payments/${paymentId}/extend_authorization`, { body: params });
1243
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/extend_authorization`, {
1244
+ body: params
1245
+ });
1132
1246
  }
1133
1247
  /** Complete authorization. `POST /payments/{paymentId}/complete_authorize` */
1134
1248
  async completeAuthorize(paymentId, params) {
1135
- return this.request("POST", `/payments/${paymentId}/complete_authorize`, { body: params });
1249
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/complete_authorize`, {
1250
+ body: params
1251
+ });
1136
1252
  }
1137
1253
  /** Dynamic tax calculation. `POST /payments/{paymentId}/calculate_tax` */
1138
1254
  async calculateTax(paymentId, params) {
1139
- return this.request("POST", `/payments/${paymentId}/calculate_tax`, { body: params });
1255
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/calculate_tax`, {
1256
+ body: params
1257
+ });
1140
1258
  }
1141
1259
  /** Update payment metadata. `POST /payments/{paymentId}/update_metadata` */
1142
1260
  async updateMetadata(paymentId, params) {
1143
- return this.request("POST", `/payments/${paymentId}/update_metadata`, { body: params });
1261
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/update_metadata`, {
1262
+ body: params
1263
+ });
1144
1264
  }
1145
1265
  /** Retrieve extended card info. `GET /payments/{paymentId}/extended_card_info` */
1146
1266
  async extendedCardInfo(paymentId) {
1147
- return this.request("GET", `/payments/${paymentId}/extended_card_info`);
1267
+ return this.request("GET", `/payments/${encodeURIComponent(paymentId)}/extended_card_info`);
1148
1268
  }
1149
1269
  // --- OLAP extensions (Task 4.2) ---
1150
1270
  /** List payments (profile-scoped). `GET /payments/profile/list` */
@@ -1181,19 +1301,27 @@ var Payments = class {
1181
1301
  }
1182
1302
  /** Manually update payment status. `PUT /payments/{paymentId}/manual-update` */
1183
1303
  async manualUpdate(paymentId, params) {
1184
- return this.request("PUT", `/payments/${paymentId}/manual-update`, { body: params });
1304
+ return this.request("PUT", `/payments/${encodeURIComponent(paymentId)}/manual-update`, {
1305
+ body: params
1306
+ });
1185
1307
  }
1186
1308
  /** Approve a payment waiting for review. `POST /payments/{paymentId}/approve` */
1187
1309
  async approve(paymentId, params) {
1188
- return this.request("POST", `/payments/${paymentId}/approve`, { body: params });
1310
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/approve`, {
1311
+ body: params
1312
+ });
1189
1313
  }
1190
1314
  /** Reject a payment waiting for review. `POST /payments/{paymentId}/reject` */
1191
1315
  async reject(paymentId, params) {
1192
- return this.request("POST", `/payments/${paymentId}/reject`, { body: params });
1316
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/reject`, {
1317
+ body: params
1318
+ });
1193
1319
  }
1194
1320
  /** Initiate external 3DS authentication. `POST /payments/{paymentId}/3ds/authentication` */
1195
1321
  async threeDsAuthentication(paymentId, params) {
1196
- return this.request("POST", `/payments/${paymentId}/3ds/authentication`, { body: params });
1322
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/3ds/authentication`, {
1323
+ body: params
1324
+ });
1197
1325
  }
1198
1326
  };
1199
1327
 
@@ -1227,7 +1355,7 @@ var Payouts = class {
1227
1355
  * @returns The payout.
1228
1356
  */
1229
1357
  async retrieve(payoutId) {
1230
- return this.request("GET", `/payouts/${payoutId}`);
1358
+ return this.request("GET", `/payouts/${encodeURIComponent(payoutId)}`);
1231
1359
  }
1232
1360
  /**
1233
1361
  * Update a payout before it is confirmed.
@@ -1237,7 +1365,7 @@ var Payouts = class {
1237
1365
  * @returns The updated payout.
1238
1366
  */
1239
1367
  async update(payoutId, params) {
1240
- return this.request("PUT", `/payouts/${payoutId}`, { body: params });
1368
+ return this.request("PUT", `/payouts/${encodeURIComponent(payoutId)}`, { body: params });
1241
1369
  }
1242
1370
  /**
1243
1371
  * Confirm a payout, triggering the actual transfer.
@@ -1247,7 +1375,9 @@ var Payouts = class {
1247
1375
  * @returns The updated payout.
1248
1376
  */
1249
1377
  async confirm(payoutId, params) {
1250
- return this.request("POST", `/payouts/${payoutId}/confirm`, { body: params });
1378
+ return this.request("POST", `/payouts/${encodeURIComponent(payoutId)}/confirm`, {
1379
+ body: params
1380
+ });
1251
1381
  }
1252
1382
  /**
1253
1383
  * Cancel a payout before it is fulfilled.
@@ -1256,7 +1386,7 @@ var Payouts = class {
1256
1386
  * @returns The cancelled payout.
1257
1387
  */
1258
1388
  async cancel(payoutId) {
1259
- return this.request("POST", `/payouts/${payoutId}/cancel`);
1389
+ return this.request("POST", `/payouts/${encodeURIComponent(payoutId)}/cancel`);
1260
1390
  }
1261
1391
  /**
1262
1392
  * Mark a payout as fulfilled (manual confirmation of successful transfer).
@@ -1265,7 +1395,7 @@ var Payouts = class {
1265
1395
  * @returns The fulfilled payout.
1266
1396
  */
1267
1397
  async fulfill(payoutId) {
1268
- return this.request("POST", `/payouts/${payoutId}/fulfill`);
1398
+ return this.request("POST", `/payouts/${encodeURIComponent(payoutId)}/fulfill`);
1269
1399
  }
1270
1400
  /**
1271
1401
  * List payouts, optionally filtered by status or date range.
@@ -1307,7 +1437,9 @@ var Payouts = class {
1307
1437
  }
1308
1438
  /** Manually update payout status. `PUT /payouts/{payoutId}/manual-update` */
1309
1439
  async manualUpdate(payoutId, params) {
1310
- return this.request("PUT", `/payouts/${payoutId}/manual-update`, { body: params });
1440
+ return this.request("PUT", `/payouts/${encodeURIComponent(payoutId)}/manual-update`, {
1441
+ body: params
1442
+ });
1311
1443
  }
1312
1444
  };
1313
1445
 
@@ -1317,7 +1449,7 @@ var Poll = class {
1317
1449
  this.request = request;
1318
1450
  }
1319
1451
  async getStatus(pollId) {
1320
- return this.request("GET", `/poll/status/${pollId}`);
1452
+ return this.request("GET", `/poll/status/${encodeURIComponent(pollId)}`);
1321
1453
  }
1322
1454
  };
1323
1455
 
@@ -1330,9 +1462,13 @@ var ProfileAcquirers = class {
1330
1462
  return this.request("POST", "/profile_acquirer", { body: params });
1331
1463
  }
1332
1464
  async update(profileId, profileAcquirerId, params) {
1333
- return this.request("POST", `/profile_acquirer/${profileId}/${profileAcquirerId}`, {
1334
- body: params
1335
- });
1465
+ return this.request(
1466
+ "POST",
1467
+ `/profile_acquirer/${encodeURIComponent(profileId)}/${encodeURIComponent(profileAcquirerId)}`,
1468
+ {
1469
+ body: params
1470
+ }
1471
+ );
1336
1472
  }
1337
1473
  };
1338
1474
 
@@ -1342,35 +1478,47 @@ var Profiles = class {
1342
1478
  this.request = request;
1343
1479
  }
1344
1480
  async create(accountId, params) {
1345
- return this.request("POST", `/account/${accountId}/business_profile`, { body: params });
1481
+ return this.request("POST", `/account/${encodeURIComponent(accountId)}/business_profile`, {
1482
+ body: params
1483
+ });
1346
1484
  }
1347
1485
  async retrieve(accountId, profileId) {
1348
- return this.request("GET", `/account/${accountId}/business_profile/${profileId}`);
1486
+ return this.request(
1487
+ "GET",
1488
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}`
1489
+ );
1349
1490
  }
1350
1491
  async list(accountId) {
1351
- return this.request("GET", `/account/${accountId}/business_profile`);
1492
+ return this.request("GET", `/account/${encodeURIComponent(accountId)}/business_profile`);
1352
1493
  }
1353
1494
  async update(accountId, profileId, params) {
1354
- return this.request("POST", `/account/${accountId}/business_profile/${profileId}`, {
1355
- body: params
1356
- });
1495
+ return this.request(
1496
+ "POST",
1497
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}`,
1498
+ {
1499
+ body: params
1500
+ }
1501
+ );
1357
1502
  }
1358
1503
  async delete(accountId, profileId) {
1359
- return this.request("DELETE", `/account/${accountId}/business_profile/${profileId}`);
1504
+ return this.request(
1505
+ "DELETE",
1506
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}`
1507
+ );
1360
1508
  }
1361
1509
  // --- Advanced operations (Task 4.8) ---
1362
1510
  /** Toggle extended card info for a profile. `POST /account/{accountId}/business_profile/{profileId}/toggle_extended_card_info` */
1363
1511
  async toggleExtendedCardInfo(accountId, profileId) {
1364
1512
  return this.request(
1365
1513
  "POST",
1366
- `/account/${accountId}/business_profile/${profileId}/toggle_extended_card_info`
1514
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}/toggle_extended_card_info`
1367
1515
  );
1368
1516
  }
1369
1517
  /** Toggle connector agnostic MIT. `POST /account/{accountId}/business_profile/{profileId}/toggle_connector_agnostic_mit` */
1370
1518
  async toggleConnectorAgnosticMit(accountId, profileId) {
1371
1519
  return this.request(
1372
1520
  "POST",
1373
- `/account/${accountId}/business_profile/${profileId}/toggle_connector_agnostic_mit`
1521
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}/toggle_connector_agnostic_mit`
1374
1522
  );
1375
1523
  }
1376
1524
  };
@@ -1405,7 +1553,7 @@ var Projects = class {
1405
1553
  * @returns The project.
1406
1554
  */
1407
1555
  async retrieve(projectId) {
1408
- return this.request("GET", `/projects/${projectId}`);
1556
+ return this.request("GET", `/projects/${encodeURIComponent(projectId)}`);
1409
1557
  }
1410
1558
  /**
1411
1559
  * Update a project's details.
@@ -1415,7 +1563,7 @@ var Projects = class {
1415
1563
  * @returns The updated project.
1416
1564
  */
1417
1565
  async update(projectId, params) {
1418
- return this.request("PUT", `/projects/${projectId}`, { body: params });
1566
+ return this.request("PUT", `/projects/${encodeURIComponent(projectId)}`, { body: params });
1419
1567
  }
1420
1568
  /**
1421
1569
  * Delete a project.
@@ -1424,7 +1572,7 @@ var Projects = class {
1424
1572
  * @returns The deleted project object.
1425
1573
  */
1426
1574
  async delete(projectId) {
1427
- return this.request("DELETE", `/projects/${projectId}`);
1575
+ return this.request("DELETE", `/projects/${encodeURIComponent(projectId)}`);
1428
1576
  }
1429
1577
  /**
1430
1578
  * List all projects for a merchant.
@@ -1495,7 +1643,7 @@ var Refunds = class {
1495
1643
  * ```
1496
1644
  */
1497
1645
  async retrieve(refundId) {
1498
- return this.request("GET", `/refunds/${refundId}`);
1646
+ return this.request("GET", `/refunds/${encodeURIComponent(refundId)}`);
1499
1647
  }
1500
1648
  /**
1501
1649
  * Update the reason or metadata on an existing refund.
@@ -1505,7 +1653,7 @@ var Refunds = class {
1505
1653
  * @returns The updated refund.
1506
1654
  */
1507
1655
  async update(refundId, params) {
1508
- return this.request("POST", `/refunds/${refundId}`, { body: params });
1656
+ return this.request("POST", `/refunds/${encodeURIComponent(refundId)}`, { body: params });
1509
1657
  }
1510
1658
  /**
1511
1659
  * List refunds, optionally filtered by payment, status, or date range.
@@ -1539,7 +1687,9 @@ var Refunds = class {
1539
1687
  }
1540
1688
  /** Manually update refund status. `PUT /refunds/{refundId}/manual-update` */
1541
1689
  async manualUpdate(refundId, params) {
1542
- return this.request("PUT", `/refunds/${refundId}/manual-update`, { body: params });
1690
+ return this.request("PUT", `/refunds/${encodeURIComponent(refundId)}/manual-update`, {
1691
+ body: params
1692
+ });
1543
1693
  }
1544
1694
  };
1545
1695
 
@@ -1552,7 +1702,7 @@ var Relay = class {
1552
1702
  return this.request("POST", "/relay", { body: params });
1553
1703
  }
1554
1704
  async retrieve(relayId) {
1555
- return this.request("GET", `/relay/${relayId}`);
1705
+ return this.request("GET", `/relay/${encodeURIComponent(relayId)}`);
1556
1706
  }
1557
1707
  };
1558
1708
 
@@ -1586,7 +1736,7 @@ var Routing = class {
1586
1736
  * @returns The routing configuration.
1587
1737
  */
1588
1738
  async retrieve(algorithmId) {
1589
- return this.request("GET", `/routing/${algorithmId}`);
1739
+ return this.request("GET", `/routing/${encodeURIComponent(algorithmId)}`);
1590
1740
  }
1591
1741
  /**
1592
1742
  * Activate a routing algorithm, making it the active routing strategy for the shop.
@@ -1595,7 +1745,7 @@ var Routing = class {
1595
1745
  * @returns The activated routing configuration.
1596
1746
  */
1597
1747
  async activate(algorithmId) {
1598
- return this.request("POST", `/routing/${algorithmId}/activate`);
1748
+ return this.request("POST", `/routing/${encodeURIComponent(algorithmId)}/activate`);
1599
1749
  }
1600
1750
  /**
1601
1751
  * Deactivate the currently active routing algorithm (falls back to default routing).
@@ -1628,7 +1778,9 @@ var Routing = class {
1628
1778
  }
1629
1779
  /** Update default config for a profile. `POST /routing/default/profile/{profileId}` */
1630
1780
  async updateDefaultProfile(profileId, params) {
1631
- return this.request("POST", `/routing/default/profile/${profileId}`, { body: params });
1781
+ return this.request("POST", `/routing/default/profile/${encodeURIComponent(profileId)}`, {
1782
+ body: params
1783
+ });
1632
1784
  }
1633
1785
  /** List routing configs for profile. `GET /routing/list/profile` */
1634
1786
  async listForProfile() {
@@ -1695,7 +1847,11 @@ var ShopGateways = class {
1695
1847
  * @returns The created gateway connection.
1696
1848
  */
1697
1849
  async connect(merchantId, shopId, params) {
1698
- return this.request("POST", `/shops/${merchantId}/${shopId}/gateways`, { body: params });
1850
+ return this.request(
1851
+ "POST",
1852
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`,
1853
+ { body: params }
1854
+ );
1699
1855
  }
1700
1856
  /**
1701
1857
  * List all gateway connections for a shop.
@@ -1705,7 +1861,10 @@ var ShopGateways = class {
1705
1861
  * @returns Array of gateway connections.
1706
1862
  */
1707
1863
  async list(merchantId, shopId) {
1708
- return this.request("GET", `/shops/${merchantId}/${shopId}/gateways`);
1864
+ return this.request(
1865
+ "GET",
1866
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`
1867
+ );
1709
1868
  }
1710
1869
  /**
1711
1870
  * Disconnect a gateway from a shop.
@@ -1716,7 +1875,10 @@ var ShopGateways = class {
1716
1875
  * @returns The removed gateway connection.
1717
1876
  */
1718
1877
  async disconnect(merchantId, shopId, gatewayId) {
1719
- return this.request("DELETE", `/shops/${merchantId}/${shopId}/gateways/${gatewayId}`);
1878
+ return this.request(
1879
+ "DELETE",
1880
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways/${encodeURIComponent(gatewayId)}`
1881
+ );
1720
1882
  }
1721
1883
  };
1722
1884
  var Shops = class {
@@ -1737,7 +1899,7 @@ var Shops = class {
1737
1899
  * ```
1738
1900
  */
1739
1901
  async create(merchantId, params) {
1740
- return this.request("POST", `/shops/${merchantId}`, { body: params });
1902
+ return this.request("POST", `/shops/${encodeURIComponent(merchantId)}`, { body: params });
1741
1903
  }
1742
1904
  /**
1743
1905
  * Retrieve a shop by its ID.
@@ -1747,7 +1909,10 @@ var Shops = class {
1747
1909
  * @returns The shop.
1748
1910
  */
1749
1911
  async retrieve(merchantId, shopId) {
1750
- return this.request("GET", `/shops/${merchantId}/${shopId}`);
1912
+ return this.request(
1913
+ "GET",
1914
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`
1915
+ );
1751
1916
  }
1752
1917
  /**
1753
1918
  * Update a shop's configuration.
@@ -1758,7 +1923,11 @@ var Shops = class {
1758
1923
  * @returns The updated shop.
1759
1924
  */
1760
1925
  async update(merchantId, shopId, params) {
1761
- return this.request("PUT", `/shops/${merchantId}/${shopId}`, { body: params });
1926
+ return this.request(
1927
+ "PUT",
1928
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,
1929
+ { body: params }
1930
+ );
1762
1931
  }
1763
1932
  /**
1764
1933
  * Delete a shop.
@@ -1768,7 +1937,10 @@ var Shops = class {
1768
1937
  * @returns The deleted shop object.
1769
1938
  */
1770
1939
  async delete(merchantId, shopId) {
1771
- return this.request("DELETE", `/shops/${merchantId}/${shopId}`);
1940
+ return this.request(
1941
+ "DELETE",
1942
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`
1943
+ );
1772
1944
  }
1773
1945
  /**
1774
1946
  * List all shops under a merchant account.
@@ -1777,7 +1949,7 @@ var Shops = class {
1777
1949
  * @returns Array of shops.
1778
1950
  */
1779
1951
  async list(merchantId) {
1780
- return this.request("GET", `/shops/${merchantId}`);
1952
+ return this.request("GET", `/shops/${encodeURIComponent(merchantId)}`);
1781
1953
  }
1782
1954
  };
1783
1955
 
@@ -2035,11 +2207,11 @@ var Users = class {
2035
2207
  }
2036
2208
  /** Get role by ID. `GET /user/role/{roleId}` */
2037
2209
  async getRoleById(roleId) {
2038
- return this.request("GET", `/user/role/${roleId}`);
2210
+ return this.request("GET", `/user/role/${encodeURIComponent(roleId)}`);
2039
2211
  }
2040
2212
  /** Update role by ID. `PUT /user/role/{roleId}` */
2041
2213
  async updateRole(roleId, params) {
2042
- return this.request("PUT", `/user/role/${roleId}`, { body: params });
2214
+ return this.request("PUT", `/user/role/${encodeURIComponent(roleId)}`, { body: params });
2043
2215
  }
2044
2216
  };
2045
2217
 
@@ -2049,7 +2221,9 @@ var Verification = class {
2049
2221
  this.request = request;
2050
2222
  }
2051
2223
  async registerApplePayDomains(merchantId, params) {
2052
- return this.request("POST", `/verify/apple_pay/${merchantId}`, { body: params });
2224
+ return this.request("POST", `/verify/apple_pay/${encodeURIComponent(merchantId)}`, {
2225
+ body: params
2226
+ });
2053
2227
  }
2054
2228
  async getApplePayVerifiedDomains(params) {
2055
2229
  return this.request("GET", "/verify/applepay_verified_domains", {
@@ -2059,10 +2233,23 @@ var Verification = class {
2059
2233
  };
2060
2234
 
2061
2235
  // src/resources/webhooks.ts
2236
+ function hexToBytes(hex) {
2237
+ if (hex.length === 0 || hex.length % 2 !== 0) return null;
2238
+ const bytes = new Uint8Array(hex.length / 2);
2239
+ for (let i = 0; i < hex.length; i += 2) {
2240
+ const byte = Number.parseInt(hex.slice(i, i + 2), 16);
2241
+ if (Number.isNaN(byte)) return null;
2242
+ bytes[i / 2] = byte;
2243
+ }
2244
+ return bytes;
2245
+ }
2062
2246
  var Webhooks = {
2063
2247
  /**
2064
2248
  * Verify the signature of an incoming Delopay webhook and return the parsed event.
2065
2249
  *
2250
+ * Uses the Web Crypto API (`globalThis.crypto.subtle`), so it runs unchanged in
2251
+ * Node 18+, modern browsers, Deno, Bun, and edge runtimes (Cloudflare Workers, Vercel Edge).
2252
+ *
2066
2253
  * This method is available as a static property on the `Delopay` class
2067
2254
  * (`Delopay.webhooks.verify`) and does not require a client instance.
2068
2255
  *
@@ -2070,14 +2257,14 @@ var Webhooks = {
2070
2257
  * @param signatureHeader - The value of the `delopay-signature` HTTP header.
2071
2258
  * @param secret - Your webhook signing secret from the Delopay dashboard.
2072
2259
  * @param options - Optional verification settings (replay tolerance).
2073
- * @returns The parsed webhook event.
2260
+ * @returns Promise that resolves to the parsed webhook event.
2074
2261
  * @throws {Error} When the signature is invalid, the timestamp is missing, or the event is too old.
2075
2262
  *
2076
2263
  * @example
2077
2264
  * ```typescript
2078
2265
  * // Express example
2079
- * app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
2080
- * const event = Delopay.webhooks.verify(
2266
+ * app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
2267
+ * const event = await Delopay.webhooks.verify(
2081
2268
  * req.body.toString(),
2082
2269
  * req.headers['delopay-signature'] as string,
2083
2270
  * process.env.DELOPAY_WEBHOOK_SECRET!,
@@ -2087,7 +2274,7 @@ var Webhooks = {
2087
2274
  * });
2088
2275
  * ```
2089
2276
  */
2090
- verify(rawBody, signatureHeader, secret, options) {
2277
+ async verify(rawBody, signatureHeader, secret, options) {
2091
2278
  const tolerance = options?.tolerance ?? 300;
2092
2279
  const parts = signatureHeader.split(",");
2093
2280
  const timestampPart = parts.find((p) => p.startsWith("t="));
@@ -2095,19 +2282,29 @@ var Webhooks = {
2095
2282
  if (!timestampPart || !signaturePart) {
2096
2283
  throw new Error("Invalid webhook signature format");
2097
2284
  }
2098
- const timestamp = parseInt(timestampPart.slice(2), 10);
2285
+ const timestamp = Number.parseInt(timestampPart.slice(2), 10);
2099
2286
  if (!Number.isFinite(timestamp)) {
2100
2287
  throw new Error("Invalid webhook timestamp");
2101
2288
  }
2102
- const signature = signaturePart.slice(3);
2103
- const crypto = __require("crypto");
2104
- const signedPayload = `${timestamp}.${rawBody}`;
2105
- const expected = crypto.createHmac("sha256", secret).update(signedPayload).digest("hex");
2106
- const sigBuf = Buffer.from(signature);
2107
- const expBuf = Buffer.from(expected);
2108
- const lengthsMatch = sigBuf.length === expBuf.length;
2109
- const paddedSig = lengthsMatch ? sigBuf : Buffer.alloc(expBuf.length, 0);
2110
- const signaturesMatch = lengthsMatch && crypto.timingSafeEqual(paddedSig, expBuf);
2289
+ const signatureHex = signaturePart.slice(3);
2290
+ const signatureBytes = hexToBytes(signatureHex);
2291
+ const subtle = globalThis.crypto?.subtle;
2292
+ if (!subtle) {
2293
+ throw new Error(
2294
+ "Web Crypto unavailable: Delopay.webhooks.verify requires globalThis.crypto.subtle (Node 18+, modern browsers, Workers, Deno)"
2295
+ );
2296
+ }
2297
+ const encoder = new TextEncoder();
2298
+ const asBufferSource = (bytes) => bytes;
2299
+ const key = await subtle.importKey(
2300
+ "raw",
2301
+ asBufferSource(encoder.encode(secret)),
2302
+ { name: "HMAC", hash: "SHA-256" },
2303
+ false,
2304
+ ["verify"]
2305
+ );
2306
+ const signedPayload = asBufferSource(encoder.encode(`${timestamp}.${rawBody}`));
2307
+ const signaturesMatch = signatureBytes !== null && await subtle.verify("HMAC", key, asBufferSource(signatureBytes), signedPayload);
2111
2308
  if (!signaturesMatch) {
2112
2309
  throw new Error("Invalid webhook signature");
2113
2310
  }
@@ -2128,22 +2325,30 @@ var AnalyticsDomain = class {
2128
2325
  /** Get metrics. `POST /analytics/v1/metrics/{domain}` */
2129
2326
  async metrics(params, scope) {
2130
2327
  const prefix = scope ? `/analytics/v1/${scope}` : "/analytics/v1";
2131
- return this.request("POST", `${prefix}/metrics/${this.domain}`, { body: params });
2328
+ return this.request("POST", `${prefix}/metrics/${encodeURIComponent(this.domain)}`, {
2329
+ body: [params]
2330
+ });
2132
2331
  }
2133
2332
  /** Get filters. `POST /analytics/v1/filters/{domain}` */
2134
2333
  async filters(params, scope) {
2135
2334
  const prefix = scope ? `/analytics/v1/${scope}` : "/analytics/v1";
2136
- return this.request("POST", `${prefix}/filters/${this.domain}`, { body: params });
2335
+ return this.request("POST", `${prefix}/filters/${encodeURIComponent(this.domain)}`, {
2336
+ body: params
2337
+ });
2137
2338
  }
2138
2339
  /** Generate report. `POST /analytics/v1/report/{domain}` */
2139
2340
  async report(params, scope) {
2140
2341
  const prefix = scope ? `/analytics/v1/${scope}` : "/analytics/v1";
2141
- return this.request("POST", `${prefix}/report/${this.domain}`, { body: params });
2342
+ return this.request("POST", `${prefix}/report/${encodeURIComponent(this.domain)}`, {
2343
+ body: params
2344
+ });
2142
2345
  }
2143
2346
  /** Sankey chart data. `POST /analytics/v1/metrics/{domain}/sankey` */
2144
2347
  async sankey(params, scope) {
2145
2348
  const prefix = scope ? `/analytics/v1/${scope}` : "/analytics/v1";
2146
- return this.request("POST", `${prefix}/metrics/${this.domain}/sankey`, { body: params });
2349
+ return this.request("POST", `${prefix}/metrics/${encodeURIComponent(this.domain)}/sankey`, {
2350
+ body: params
2351
+ });
2147
2352
  }
2148
2353
  };
2149
2354
  var Analytics = class {
@@ -2164,11 +2369,13 @@ var Analytics = class {
2164
2369
  }
2165
2370
  /** Domain-specific search. `POST /analytics/v1/search/{domain}` */
2166
2371
  async searchDomain(domain, params) {
2167
- return this.request("POST", `/analytics/v1/search/${domain}`, { body: params });
2372
+ return this.request("POST", `/analytics/v1/search/${encodeURIComponent(domain)}`, {
2373
+ body: params
2374
+ });
2168
2375
  }
2169
2376
  /** Get analytics info. `GET /analytics/v1/{domain}/info` */
2170
2377
  async getInfo(domain) {
2171
- return this.request("GET", `/analytics/v1/${domain}/info`);
2378
+ return this.request("GET", `/analytics/v1/${encodeURIComponent(domain)}/info`);
2172
2379
  }
2173
2380
  /** Get API event logs. `GET /analytics/v1/api_event_logs` */
2174
2381
  async apiEventLogs(params) {
@@ -2214,7 +2421,7 @@ var Cache = class {
2214
2421
  }
2215
2422
  /** Invalidate a cache entry by key. `POST /cache/invalidate/{key}` */
2216
2423
  async invalidate(key) {
2217
- return this.request("POST", `/cache/invalidate/${key}`);
2424
+ return this.request("POST", `/cache/invalidate/${encodeURIComponent(key)}`);
2218
2425
  }
2219
2426
  };
2220
2427
 
@@ -2233,7 +2440,7 @@ var Cards = class {
2233
2440
  }
2234
2441
  /** Retrieve card info by BIN. `GET /cards/{bin}` */
2235
2442
  async retrieve(bin) {
2236
- return this.request("GET", `/cards/${bin}`);
2443
+ return this.request("GET", `/cards/${encodeURIComponent(bin)}`);
2237
2444
  }
2238
2445
  };
2239
2446
 
@@ -2248,15 +2455,15 @@ var Configs = class {
2248
2455
  }
2249
2456
  /** Retrieve a config by key. `GET /configs/{key}` */
2250
2457
  async retrieve(key) {
2251
- return this.request("GET", `/configs/${key}`);
2458
+ return this.request("GET", `/configs/${encodeURIComponent(key)}`);
2252
2459
  }
2253
2460
  /** Update a config. `PUT /configs/{key}` */
2254
2461
  async update(key, params) {
2255
- return this.request("PUT", `/configs/${key}`, { body: params });
2462
+ return this.request("PUT", `/configs/${encodeURIComponent(key)}`, { body: params });
2256
2463
  }
2257
2464
  /** Delete a config. `DELETE /configs/{key}` */
2258
2465
  async delete(key) {
2259
- return this.request("DELETE", `/configs/${key}`);
2466
+ return this.request("DELETE", `/configs/${encodeURIComponent(key)}`);
2260
2467
  }
2261
2468
  };
2262
2469
 
@@ -2293,11 +2500,11 @@ var Files = class {
2293
2500
  }
2294
2501
  /** Retrieve/download a file. `GET /files/{fileId}` */
2295
2502
  async retrieve(fileId) {
2296
- return this.request("GET", `/files/${fileId}`);
2503
+ return this.request("GET", `/files/${encodeURIComponent(fileId)}`);
2297
2504
  }
2298
2505
  /** Delete a file. `DELETE /files/{fileId}` */
2299
2506
  async delete(fileId) {
2300
- return this.request("DELETE", `/files/${fileId}`);
2507
+ return this.request("DELETE", `/files/${encodeURIComponent(fileId)}`);
2301
2508
  }
2302
2509
  };
2303
2510
 
@@ -2327,15 +2534,15 @@ var Regions = class {
2327
2534
  }
2328
2535
  /** Retrieve a region by ID. `GET /regions/{regionId}` */
2329
2536
  async retrieve(regionId) {
2330
- return this.request("GET", `/regions/${regionId}`);
2537
+ return this.request("GET", `/regions/${encodeURIComponent(regionId)}`);
2331
2538
  }
2332
2539
  /** Update a region. `PUT /regions/{regionId}` */
2333
2540
  async update(regionId, params) {
2334
- return this.request("PUT", `/regions/${regionId}`, { body: params });
2541
+ return this.request("PUT", `/regions/${encodeURIComponent(regionId)}`, { body: params });
2335
2542
  }
2336
2543
  /** Delete a region. `DELETE /regions/{regionId}` */
2337
2544
  async delete(regionId) {
2338
- return this.request("DELETE", `/regions/${regionId}`);
2545
+ return this.request("DELETE", `/regions/${encodeURIComponent(regionId)}`);
2339
2546
  }
2340
2547
  /** List all regions. `GET /regions/list` */
2341
2548
  async list() {
@@ -2358,17 +2565,19 @@ var Subscriptions = class {
2358
2565
  }
2359
2566
  /** Retrieve a subscription by ID. `GET /subscriptions/{subscriptionId}` */
2360
2567
  async retrieve(subscriptionId) {
2361
- return this.request("GET", `/subscriptions/${subscriptionId}`);
2568
+ return this.request("GET", `/subscriptions/${encodeURIComponent(subscriptionId)}`);
2362
2569
  }
2363
2570
  /** Confirm a subscription. `POST /subscriptions/{subscriptionId}/confirm` */
2364
2571
  async confirm(subscriptionId, params) {
2365
- return this.request("POST", `/subscriptions/${subscriptionId}/confirm`, {
2572
+ return this.request("POST", `/subscriptions/${encodeURIComponent(subscriptionId)}/confirm`, {
2366
2573
  body: params
2367
2574
  });
2368
2575
  }
2369
2576
  /** Update a subscription. `PUT /subscriptions/{subscriptionId}/update` */
2370
2577
  async update(subscriptionId, params) {
2371
- return this.request("PUT", `/subscriptions/${subscriptionId}/update`, { body: params });
2578
+ return this.request("PUT", `/subscriptions/${encodeURIComponent(subscriptionId)}/update`, {
2579
+ body: params
2580
+ });
2372
2581
  }
2373
2582
  /** List subscriptions. `GET /subscriptions/list` */
2374
2583
  async list(params) {
@@ -2386,21 +2595,95 @@ var Subscriptions = class {
2386
2595
  }
2387
2596
  /** Pause a subscription. `POST /subscriptions/{subscriptionId}/pause` */
2388
2597
  async pause(subscriptionId) {
2389
- return this.request("POST", `/subscriptions/${subscriptionId}/pause`);
2598
+ return this.request("POST", `/subscriptions/${encodeURIComponent(subscriptionId)}/pause`);
2390
2599
  }
2391
2600
  /** Resume a subscription. `POST /subscriptions/{subscriptionId}/resume` */
2392
2601
  async resume(subscriptionId) {
2393
- return this.request("POST", `/subscriptions/${subscriptionId}/resume`);
2602
+ return this.request("POST", `/subscriptions/${encodeURIComponent(subscriptionId)}/resume`);
2394
2603
  }
2395
2604
  /** Cancel a subscription. `POST /subscriptions/{subscriptionId}/cancel` */
2396
2605
  async cancel(subscriptionId) {
2397
- return this.request("POST", `/subscriptions/${subscriptionId}/cancel`);
2606
+ return this.request("POST", `/subscriptions/${encodeURIComponent(subscriptionId)}/cancel`);
2398
2607
  }
2399
2608
  };
2400
2609
 
2401
2610
  // src/client.ts
2402
2611
  var PRODUCTION_URL = "https://api.delopay.net";
2403
2612
  var SANDBOX_URL = "https://sandbox.delopay.net";
2613
+ var MAX_RAW_BODY_BYTES = 2048;
2614
+ var MAX_RETRY_AFTER_MS = 3e4;
2615
+ function parseRetryAfter(header) {
2616
+ if (!header) return null;
2617
+ const trimmed = header.trim();
2618
+ const seconds = Number(trimmed);
2619
+ if (Number.isFinite(seconds) && seconds >= 0) {
2620
+ return Math.min(seconds * 1e3, MAX_RETRY_AFTER_MS);
2621
+ }
2622
+ const date = Date.parse(trimmed);
2623
+ if (Number.isFinite(date)) {
2624
+ const delta = date - Date.now();
2625
+ return delta > 0 ? Math.min(delta, MAX_RETRY_AFTER_MS) : 0;
2626
+ }
2627
+ return null;
2628
+ }
2629
+ function truncateRawBody(raw) {
2630
+ if (!raw) return void 0;
2631
+ return raw.length > MAX_RAW_BODY_BYTES ? raw.slice(0, MAX_RAW_BODY_BYTES) + "\u2026" : raw;
2632
+ }
2633
+ function findIdempotencyKey(headers) {
2634
+ for (const [k, v] of Object.entries(headers)) {
2635
+ if (k.toLowerCase() === "idempotency-key") return v;
2636
+ }
2637
+ return void 0;
2638
+ }
2639
+ function noop() {
2640
+ }
2641
+ function combineSignals(signals) {
2642
+ const controller = new AbortController();
2643
+ const listeners = [];
2644
+ const dispose = () => {
2645
+ for (const { signal, handler } of listeners) {
2646
+ signal.removeEventListener("abort", handler);
2647
+ }
2648
+ listeners.length = 0;
2649
+ };
2650
+ for (const signal of signals) {
2651
+ if (signal.aborted) {
2652
+ controller.abort(signal.reason);
2653
+ dispose();
2654
+ return { signal: controller.signal, dispose: noop };
2655
+ }
2656
+ const handler = () => {
2657
+ controller.abort(signal.reason);
2658
+ dispose();
2659
+ };
2660
+ signal.addEventListener("abort", handler, { once: true });
2661
+ listeners.push({ signal, handler });
2662
+ }
2663
+ return { signal: controller.signal, dispose };
2664
+ }
2665
+ var SENSITIVE_QUERY_KEYS = /* @__PURE__ */ new Set([
2666
+ "client_secret",
2667
+ "ephemeral_key",
2668
+ "api_key",
2669
+ "publishable_key"
2670
+ ]);
2671
+ function redactUrlForLogging(url) {
2672
+ const qIdx = url.indexOf("?");
2673
+ if (qIdx === -1) return url;
2674
+ const base = url.slice(0, qIdx);
2675
+ const query = url.slice(qIdx + 1);
2676
+ const parts = query.split("&").map((pair) => {
2677
+ const eqIdx = pair.indexOf("=");
2678
+ if (eqIdx === -1) return pair;
2679
+ const key = pair.slice(0, eqIdx);
2680
+ if (SENSITIVE_QUERY_KEYS.has(decodeURIComponent(key).toLowerCase())) {
2681
+ return `${key}=REDACTED`;
2682
+ }
2683
+ return pair;
2684
+ });
2685
+ return `${base}?${parts.join("&")}`;
2686
+ }
2404
2687
  var Delopay = class {
2405
2688
  /**
2406
2689
  * Create a new Delopay client.
@@ -2414,6 +2697,7 @@ var Delopay = class {
2414
2697
  this.timeout = options?.timeout ?? 3e4;
2415
2698
  this.maxRetries = options?.maxRetries ?? 2;
2416
2699
  this.debug = options?.debug ?? false;
2700
+ if (options?.logger !== void 0) this.logger = options.logger;
2417
2701
  if (options?.baseUrl !== void 0) {
2418
2702
  this.baseUrl = options.baseUrl;
2419
2703
  } else if (options?.sandbox) {
@@ -2499,7 +2783,12 @@ var Delopay = class {
2499
2783
  if (options?.query) {
2500
2784
  const params = new URLSearchParams();
2501
2785
  for (const [key, value] of Object.entries(options.query)) {
2502
- if (value !== void 0) {
2786
+ if (value === void 0 || value === null) continue;
2787
+ if (Array.isArray(value)) {
2788
+ for (const v of value) {
2789
+ if (v !== void 0 && v !== null) params.append(key, String(v));
2790
+ }
2791
+ } else {
2503
2792
  params.set(key, String(value));
2504
2793
  }
2505
2794
  }
@@ -2515,46 +2804,94 @@ var Delopay = class {
2515
2804
  if (options?.body) {
2516
2805
  headers["Content-Type"] = "application/json";
2517
2806
  }
2518
- const isRetryable = method === "GET" || method === "DELETE" || "Idempotency-Key" in headers;
2807
+ const idempotencyKey = findIdempotencyKey(headers)?.trim();
2808
+ const isRetryable = method === "GET" || method === "DELETE" || idempotencyKey !== void 0 && idempotencyKey !== "";
2809
+ const serializedBody = options?.body ? JSON.stringify(options.body) : void 0;
2810
+ const callerSignal = options?.signal;
2811
+ if (callerSignal?.aborted) {
2812
+ throw new DelopayError("Request aborted", {
2813
+ status: 0,
2814
+ code: "ABORTED",
2815
+ type: "abort_error"
2816
+ });
2817
+ }
2818
+ const timeoutMs = options?.timeout ?? this.timeout;
2519
2819
  let lastError;
2820
+ let retryAfterOverrideMs = null;
2821
+ const safeUrl = () => redactUrlForLogging(url);
2822
+ const emit = (event, data) => {
2823
+ if (!this.debug) return;
2824
+ if (this.logger) {
2825
+ this.logger(event, data);
2826
+ return;
2827
+ }
2828
+ if (event === "request")
2829
+ console.log(`[delopay] ${data.method} ${data.url}`);
2830
+ else if (event === "response")
2831
+ console.log(
2832
+ `[delopay] ${data.status} ${data.method} ${data.path}`
2833
+ );
2834
+ else
2835
+ console.log(
2836
+ `[delopay] retry ${data.attempt}/${data.maxRetries} ${data.method} ${data.path}`
2837
+ );
2838
+ };
2520
2839
  for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
2521
2840
  if (attempt > 0) {
2522
- const delay = Math.min(500 * 2 ** (attempt - 1), 5e3);
2841
+ const base = Math.min(500 * 2 ** (attempt - 1), 5e3);
2842
+ const jittered = Math.random() * base;
2843
+ const delay = Math.max(retryAfterOverrideMs ?? 0, jittered);
2844
+ retryAfterOverrideMs = null;
2523
2845
  await new Promise((resolve) => setTimeout(resolve, delay));
2524
- if (this.debug) {
2525
- console.log(`[delopay] retry ${attempt}/${this.maxRetries} ${method} ${path}`);
2526
- }
2846
+ emit("retry", { attempt, maxRetries: this.maxRetries, method, path });
2527
2847
  }
2528
- const controller = new AbortController();
2529
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
2848
+ const timeoutCtrl = new AbortController();
2849
+ const timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);
2850
+ const combined = combineSignals(
2851
+ callerSignal ? [timeoutCtrl.signal, callerSignal] : [timeoutCtrl.signal]
2852
+ );
2530
2853
  try {
2531
- if (this.debug) {
2532
- console.log(`[delopay] ${method} ${url}`);
2533
- }
2854
+ emit("request", { method, url: safeUrl(), path });
2534
2855
  const response = await fetch(url, {
2535
2856
  method,
2536
2857
  headers,
2537
- body: options?.body ? JSON.stringify(options.body) : void 0,
2538
- signal: controller.signal
2858
+ body: serializedBody,
2859
+ signal: combined.signal
2539
2860
  });
2540
- if (this.debug) {
2541
- console.log(`[delopay] ${response.status} ${method} ${path}`);
2542
- }
2861
+ const requestId = response.headers?.get("x-request-id") ?? response.headers?.get("x-trace-id") ?? void 0;
2862
+ emit("response", { status: response.status, method, path, requestId });
2543
2863
  if (!response.ok) {
2544
- const body = await response.json().catch(() => ({}));
2545
- const err = body.error ?? body;
2864
+ const rawBody = await response.text().catch(() => "");
2865
+ let parsed = {};
2866
+ if (rawBody) {
2867
+ try {
2868
+ parsed = JSON.parse(rawBody);
2869
+ } catch {
2870
+ }
2871
+ }
2872
+ const err = parsed.error ?? parsed;
2546
2873
  const message = err.message ?? `Request failed with status ${response.status}`;
2547
2874
  const code = err.code ?? "";
2548
2875
  const type = err.error_type ?? err.type ?? "";
2876
+ const truncatedRaw = truncateRawBody(rawBody);
2549
2877
  if (response.status === 401) {
2550
- throw new DelopayAuthenticationError(message);
2878
+ throw new DelopayAuthenticationError(message, {
2879
+ requestId,
2880
+ rawBody: truncatedRaw
2881
+ });
2551
2882
  }
2552
2883
  const error = new DelopayError(message, {
2553
2884
  status: response.status,
2554
2885
  code,
2555
- type
2886
+ type,
2887
+ requestId,
2888
+ rawBody: truncatedRaw
2556
2889
  });
2557
- if (response.status >= 500 && isRetryable && attempt < this.maxRetries) {
2890
+ const isTransientStatus = response.status >= 500 || response.status === 429;
2891
+ if (isTransientStatus && isRetryable && attempt < this.maxRetries) {
2892
+ if (response.status === 429) {
2893
+ retryAfterOverrideMs = parseRetryAfter(response.headers?.get("retry-after") ?? null);
2894
+ }
2558
2895
  lastError = error;
2559
2896
  continue;
2560
2897
  }
@@ -2566,7 +2903,14 @@ var Delopay = class {
2566
2903
  if (err instanceof DelopayError || err instanceof DelopayAuthenticationError) {
2567
2904
  throw err;
2568
2905
  }
2569
- if (err instanceof DOMException && err.name === "AbortError") {
2906
+ if (err instanceof Error && err.name === "AbortError") {
2907
+ if (callerSignal?.aborted) {
2908
+ throw new DelopayError("Request aborted", {
2909
+ status: 0,
2910
+ code: "ABORTED",
2911
+ type: "abort_error"
2912
+ });
2913
+ }
2570
2914
  lastError = new DelopayError("Request timed out", {
2571
2915
  status: 0,
2572
2916
  code: "TIMEOUT",
@@ -2587,6 +2931,7 @@ var Delopay = class {
2587
2931
  throw err;
2588
2932
  } finally {
2589
2933
  clearTimeout(timeoutId);
2934
+ combined.dispose();
2590
2935
  }
2591
2936
  }
2592
2937
  throw lastError;