@delopay/sdk 0.1.7 → 0.3.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
  }
@@ -38,16 +39,27 @@ var Admin = class {
38
39
  async createTenant(params) {
39
40
  return this.request("POST", "/admin/tenant_signup", { body: params });
40
41
  }
41
- // --- Advanced operations (Task 4.10) ---
42
- /** Set signup settings. `POST /admin/signup_settings` */
42
+ /**
43
+ * Create a new merchant admin user and merchant account atomically.
44
+ *
45
+ * This is the correct endpoint for bootstrapping the first admin user in a
46
+ * fresh deployment — `internal_signup`/`tenant_signup` both require
47
+ * pre-existing merchant records that don't exist on a clean database.
48
+ *
49
+ * `POST /admin/signup_with_merchant_id`
50
+ */
51
+ async signupWithMerchantId(params) {
52
+ return this.request("POST", "/admin/signup_with_merchant_id", { body: params });
53
+ }
54
+ /** Toggle public signup on/off. `POST /admin/settings/signup` */
43
55
  async setSignupSettings(params) {
44
- return this.request("POST", "/admin/signup_settings", { body: params });
56
+ return this.request("POST", "/admin/settings/signup", { body: params });
45
57
  }
46
- /** Get signup settings. `GET /admin/signup_settings` */
58
+ /** Read current public-signup status. `GET /admin/settings/signup` */
47
59
  async getSignupSettings() {
48
- return this.request("GET", "/admin/signup_settings");
60
+ return this.request("GET", "/admin/settings/signup");
49
61
  }
50
- /** Onboard a merchant. `POST /admin/onboard_merchant` */
62
+ /** Full merchant bootstrap — user + merchant + project + profile + keys. `POST /admin/onboard_merchant` */
51
63
  async onboardMerchant(params) {
52
64
  return this.request("POST", "/admin/onboard_merchant", { body: params });
53
65
  }
@@ -64,7 +76,7 @@ var AdminPortal = class {
64
76
  });
65
77
  }
66
78
  async getCustomer(customerId) {
67
- return this.request("GET", `/admin-portal/customers/${customerId}`);
79
+ return this.request("GET", `/admin-portal/customers/${encodeURIComponent(customerId)}`);
68
80
  }
69
81
  async listTransactions(params) {
70
82
  return this.request("GET", "/admin-portal/transactions", {
@@ -104,7 +116,7 @@ var ApiKeys = class {
104
116
  * ```
105
117
  */
106
118
  async create(merchantId, params) {
107
- return this.request("POST", `/api_keys/${merchantId}`, { body: params });
119
+ return this.request("POST", `/api_keys/${encodeURIComponent(merchantId)}`, { body: params });
108
120
  }
109
121
  /**
110
122
  * Retrieve metadata about an API key (does not return the plaintext secret).
@@ -114,7 +126,10 @@ var ApiKeys = class {
114
126
  * @returns The API key metadata.
115
127
  */
116
128
  async retrieve(merchantId, keyId) {
117
- return this.request("GET", `/api_keys/${merchantId}/${keyId}`);
129
+ return this.request(
130
+ "GET",
131
+ `/api_keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`
132
+ );
118
133
  }
119
134
  /**
120
135
  * Update an API key's name or expiry.
@@ -125,7 +140,11 @@ var ApiKeys = class {
125
140
  * @returns The updated API key metadata.
126
141
  */
127
142
  async update(merchantId, keyId, params) {
128
- return this.request("POST", `/api_keys/${merchantId}/${keyId}`, { body: params });
143
+ return this.request(
144
+ "POST",
145
+ `/api_keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,
146
+ { body: params }
147
+ );
129
148
  }
130
149
  /**
131
150
  * Revoke an API key, immediately invalidating it.
@@ -135,7 +154,10 @@ var ApiKeys = class {
135
154
  * @returns Revocation confirmation.
136
155
  */
137
156
  async revoke(merchantId, keyId) {
138
- return this.request("DELETE", `/api_keys/${merchantId}/${keyId}`);
157
+ return this.request(
158
+ "DELETE",
159
+ `/api_keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`
160
+ );
139
161
  }
140
162
  /**
141
163
  * List all API keys for a merchant.
@@ -144,7 +166,7 @@ var ApiKeys = class {
144
166
  * @returns Array of API key metadata objects.
145
167
  */
146
168
  async list(merchantId) {
147
- return this.request("GET", `/api_keys/${merchantId}/list`);
169
+ return this.request("GET", `/api_keys/${encodeURIComponent(merchantId)}/list`);
148
170
  }
149
171
  };
150
172
 
@@ -159,7 +181,7 @@ var AuditLogs = class {
159
181
  });
160
182
  }
161
183
  async retrieve(logId) {
162
- return this.request("GET", `/admin-portal/audit/${logId}`);
184
+ return this.request("GET", `/admin-portal/audit/${encodeURIComponent(logId)}`);
163
185
  }
164
186
  };
165
187
 
@@ -172,27 +194,39 @@ var Authentication = class {
172
194
  return this.request("POST", "/authentication", { body: params });
173
195
  }
174
196
  async checkEligibility(authId) {
175
- return this.request("POST", `/authentication/${authId}/eligibility`);
197
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/eligibility`);
176
198
  }
177
199
  async authenticate(authId, params) {
178
- return this.request("POST", `/authentication/${authId}/authenticate`, { body: params });
200
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/authenticate`, {
201
+ body: params
202
+ });
179
203
  }
180
204
  async sync(authId, params) {
181
- return this.request("POST", `/authentication/${authId}/sync`, { body: params });
205
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/sync`, {
206
+ body: params
207
+ });
182
208
  }
183
209
  /** Redirect after authentication. `POST /authentication/{authId}/redirect` */
184
210
  async redirect(authId, params) {
185
- return this.request("POST", `/authentication/${authId}/redirect`, { body: params });
211
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/redirect`, {
212
+ body: params
213
+ });
186
214
  }
187
215
  /** Enable authn methods token. `POST /authentication/{authId}/enabled_authn_methods_token` */
188
216
  async enabledAuthnMethodsToken(authId, params) {
189
- return this.request("POST", `/authentication/${authId}/enabled_authn_methods_token`, {
190
- body: params
191
- });
217
+ return this.request(
218
+ "POST",
219
+ `/authentication/${encodeURIComponent(authId)}/enabled_authn_methods_token`,
220
+ {
221
+ body: params
222
+ }
223
+ );
192
224
  }
193
225
  /** Submit eligibility check. `POST /authentication/{authId}/eligibility-check` */
194
226
  async eligibilityCheck(authId, params) {
195
- return this.request("POST", `/authentication/${authId}/eligibility-check`, { body: params });
227
+ return this.request("POST", `/authentication/${encodeURIComponent(authId)}/eligibility-check`, {
228
+ body: params
229
+ });
196
230
  }
197
231
  };
198
232
 
@@ -209,7 +243,11 @@ var BillingAllocations = class {
209
243
  * @returns The allocation transfer result.
210
244
  */
211
245
  async transferIn(merchantId, params) {
212
- return this.request("POST", `/billing/${merchantId}/allocations/transfer-in`, { body: params });
246
+ return this.request(
247
+ "POST",
248
+ `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-in`,
249
+ { body: params }
250
+ );
213
251
  }
214
252
  /**
215
253
  * Transfer funds from a shop's allocation back to the host merchant treasury.
@@ -219,9 +257,13 @@ var BillingAllocations = class {
219
257
  * @returns The allocation transfer result.
220
258
  */
221
259
  async transferOut(merchantId, params) {
222
- return this.request("POST", `/billing/${merchantId}/allocations/transfer-out`, {
223
- body: params
224
- });
260
+ return this.request(
261
+ "POST",
262
+ `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-out`,
263
+ {
264
+ body: params
265
+ }
266
+ );
225
267
  }
226
268
  /**
227
269
  * List all shop balance allocations for a merchant.
@@ -230,7 +272,7 @@ var BillingAllocations = class {
230
272
  * @returns List of shop allocations.
231
273
  */
232
274
  async list(merchantId) {
233
- return this.request("GET", `/billing/${merchantId}/allocations`);
275
+ return this.request("GET", `/billing/${encodeURIComponent(merchantId)}/allocations`);
234
276
  }
235
277
  /**
236
278
  * Get the balance allocation for a specific shop.
@@ -240,7 +282,10 @@ var BillingAllocations = class {
240
282
  * @returns The shop's balance allocation.
241
283
  */
242
284
  async get(merchantId, profileId) {
243
- return this.request("GET", `/billing/${merchantId}/allocations/${profileId}`);
285
+ return this.request(
286
+ "GET",
287
+ `/billing/${encodeURIComponent(merchantId)}/allocations/${encodeURIComponent(profileId)}`
288
+ );
244
289
  }
245
290
  };
246
291
  var Billing = class {
@@ -261,7 +306,7 @@ var Billing = class {
261
306
  * ```
262
307
  */
263
308
  async getProfile(merchantId) {
264
- return this.request("GET", `/billing/${merchantId}`);
309
+ return this.request("GET", `/billing/${encodeURIComponent(merchantId)}`);
265
310
  }
266
311
  /**
267
312
  * Start a Stripe SetupIntent flow to collect a payment card for auto-recharge.
@@ -271,7 +316,9 @@ var Billing = class {
271
316
  * @returns The Stripe client secret needed to render the card element.
272
317
  */
273
318
  async setup(merchantId, params) {
274
- return this.request("POST", `/billing/${merchantId}/setup`, { body: params });
319
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/setup`, {
320
+ body: params
321
+ });
275
322
  }
276
323
  /**
277
324
  * Confirm card setup after the Stripe SetupIntent completes on the frontend.
@@ -281,7 +328,9 @@ var Billing = class {
281
328
  * @returns The updated billing profile.
282
329
  */
283
330
  async completeSetup(merchantId, params) {
284
- return this.request("POST", `/billing/${merchantId}/setup/complete`, { body: params });
331
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/setup/complete`, {
332
+ body: params
333
+ });
285
334
  }
286
335
  /**
287
336
  * Manually top up a merchant's prepaid balance by charging their saved card.
@@ -291,7 +340,9 @@ var Billing = class {
291
340
  * @returns The top-up result.
292
341
  */
293
342
  async topup(merchantId, params) {
294
- return this.request("POST", `/billing/${merchantId}/topup`, { body: params });
343
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/topup`, {
344
+ body: params
345
+ });
295
346
  }
296
347
  /**
297
348
  * List the balance ledger (credits and debits) for a merchant.
@@ -301,7 +352,7 @@ var Billing = class {
301
352
  * @returns The ledger entries.
302
353
  */
303
354
  async listLedger(merchantId, params) {
304
- return this.request("GET", `/billing/${merchantId}/ledger`, {
355
+ return this.request("GET", `/billing/${encodeURIComponent(merchantId)}/ledger`, {
305
356
  query: params
306
357
  });
307
358
  }
@@ -313,7 +364,9 @@ var Billing = class {
313
364
  * @returns The updated billing profile.
314
365
  */
315
366
  async updateAutoRecharge(merchantId, params) {
316
- return this.request("PATCH", `/billing/${merchantId}/auto-recharge`, { body: params });
367
+ return this.request("PATCH", `/billing/${encodeURIComponent(merchantId)}/auto-recharge`, {
368
+ body: params
369
+ });
317
370
  }
318
371
  /**
319
372
  * Admin: manually credit a merchant's balance (e.g. promotional credit).
@@ -323,7 +376,9 @@ var Billing = class {
323
376
  * @returns The adjustment result.
324
377
  */
325
378
  async adminCredit(merchantId, params) {
326
- return this.request("POST", `/billing/${merchantId}/admin/credit`, { body: params });
379
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/admin/credit`, {
380
+ body: params
381
+ });
327
382
  }
328
383
  /**
329
384
  * Admin: manually debit a merchant's balance.
@@ -333,7 +388,9 @@ var Billing = class {
333
388
  * @returns The adjustment result.
334
389
  */
335
390
  async adminDebit(merchantId, params) {
336
- return this.request("POST", `/billing/${merchantId}/admin/debit`, { body: params });
391
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/admin/debit`, {
392
+ body: params
393
+ });
337
394
  }
338
395
  };
339
396
 
@@ -367,7 +424,7 @@ var CardIssuers = class {
367
424
  return this.request("POST", "/card_issuers", { body: params });
368
425
  }
369
426
  async update(issuerId, params) {
370
- return this.request("PUT", `/card_issuers/${issuerId}`, { body: params });
427
+ return this.request("PUT", `/card_issuers/${encodeURIComponent(issuerId)}`, { body: params });
371
428
  }
372
429
  async list() {
373
430
  return this.request("GET", "/card_issuers");
@@ -380,21 +437,33 @@ var Connectors = class {
380
437
  this.request = request;
381
438
  }
382
439
  async create(accountId, params) {
383
- return this.request("POST", `/account/${accountId}/connectors`, { body: params });
440
+ return this.request("POST", `/account/${encodeURIComponent(accountId)}/connectors`, {
441
+ body: params
442
+ });
384
443
  }
385
444
  async retrieve(accountId, connectorId) {
386
- return this.request("GET", `/account/${accountId}/connectors/${connectorId}`);
445
+ return this.request(
446
+ "GET",
447
+ `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`
448
+ );
387
449
  }
388
450
  async list(accountId) {
389
- return this.request("GET", `/account/${accountId}/connectors`);
451
+ return this.request("GET", `/account/${encodeURIComponent(accountId)}/connectors`);
390
452
  }
391
453
  async update(accountId, connectorId, params) {
392
- return this.request("POST", `/account/${accountId}/connectors/${connectorId}`, {
393
- body: params
394
- });
454
+ return this.request(
455
+ "POST",
456
+ `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,
457
+ {
458
+ body: params
459
+ }
460
+ );
395
461
  }
396
462
  async delete(accountId, connectorId) {
397
- return this.request("DELETE", `/account/${accountId}/connectors/${connectorId}`);
463
+ return this.request(
464
+ "DELETE",
465
+ `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`
466
+ );
398
467
  }
399
468
  // --- Advanced operations (Task 4.8) ---
400
469
  /** Verify connector credentials. `POST /account/connectors/verify` */
@@ -403,11 +472,17 @@ var Connectors = class {
403
472
  }
404
473
  /** Register a webhook for a connector. `POST /account/{merchantId}/connectors/webhooks/{connectorId}` */
405
474
  async registerWebhook(merchantId, connectorId) {
406
- return this.request("POST", `/account/${merchantId}/connectors/webhooks/${connectorId}`);
475
+ return this.request(
476
+ "POST",
477
+ `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`
478
+ );
407
479
  }
408
480
  /** Get a webhook for a connector. `GET /account/{merchantId}/connectors/webhooks/{connectorId}` */
409
481
  async getWebhook(merchantId, connectorId) {
410
- return this.request("GET", `/account/${merchantId}/connectors/webhooks/${connectorId}`);
482
+ return this.request(
483
+ "GET",
484
+ `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`
485
+ );
411
486
  }
412
487
  /** List available payment methods. `GET /account/payment_methods` */
413
488
  async listPaymentMethods() {
@@ -449,7 +524,7 @@ var Customers = class {
449
524
  * ```
450
525
  */
451
526
  async retrieve(customerId) {
452
- return this.request("GET", `/customers/${customerId}`);
527
+ return this.request("GET", `/customers/${encodeURIComponent(customerId)}`);
453
528
  }
454
529
  /**
455
530
  * Update an existing customer's details.
@@ -459,7 +534,7 @@ var Customers = class {
459
534
  * @returns The updated customer.
460
535
  */
461
536
  async update(customerId, params) {
462
- return this.request("POST", `/customers/${customerId}`, { body: params });
537
+ return this.request("POST", `/customers/${encodeURIComponent(customerId)}`, { body: params });
463
538
  }
464
539
  /**
465
540
  * Delete a customer and all their saved payment methods.
@@ -468,7 +543,7 @@ var Customers = class {
468
543
  * @returns The deleted customer object.
469
544
  */
470
545
  async delete(customerId) {
471
- return this.request("DELETE", `/customers/${customerId}`);
546
+ return this.request("DELETE", `/customers/${encodeURIComponent(customerId)}`);
472
547
  }
473
548
  /**
474
549
  * List customers, optionally filtered by email.
@@ -490,7 +565,7 @@ var Customers = class {
490
565
  }
491
566
  /** List mandates for a customer. `GET /customers/{customerId}/mandates` */
492
567
  async listMandates(customerId) {
493
- return this.request("GET", `/customers/${customerId}/mandates`);
568
+ return this.request("GET", `/customers/${encodeURIComponent(customerId)}/mandates`);
494
569
  }
495
570
  };
496
571
 
@@ -506,7 +581,7 @@ var Disputes = class {
506
581
  * @returns The dispute.
507
582
  */
508
583
  async retrieve(disputeId) {
509
- return this.request("GET", `/disputes/${disputeId}`);
584
+ return this.request("GET", `/disputes/${encodeURIComponent(disputeId)}`);
510
585
  }
511
586
  /**
512
587
  * List disputes, optionally filtered by status, stage, or date range.
@@ -526,7 +601,7 @@ var Disputes = class {
526
601
  * @returns The updated dispute.
527
602
  */
528
603
  async accept(disputeId) {
529
- return this.request("POST", `/disputes/accept/${disputeId}`);
604
+ return this.request("POST", `/disputes/accept/${encodeURIComponent(disputeId)}`);
530
605
  }
531
606
  /**
532
607
  * Submit evidence to challenge a dispute.
@@ -552,7 +627,7 @@ var Disputes = class {
552
627
  * @returns The submitted evidence.
553
628
  */
554
629
  async retrieveEvidence(disputeId) {
555
- return this.request("GET", `/disputes/evidence/${disputeId}`);
630
+ return this.request("GET", `/disputes/evidence/${encodeURIComponent(disputeId)}`);
556
631
  }
557
632
  /**
558
633
  * Delete submitted evidence for a dispute.
@@ -586,9 +661,17 @@ var Disputes = class {
586
661
  async aggregateByProfile(params) {
587
662
  return this.request("GET", "/disputes/profile/aggregate", { query: params });
588
663
  }
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`);
664
+ /**
665
+ * Fetch the latest dispute state from the connector (gateway).
666
+ * `GET /disputes/{connectorId}/fetch`
667
+ *
668
+ * Note: the path parameter is the **connector dispute id** on the gateway, not the
669
+ * Delopay dispute id. Method is GET (not POST) and this method signature was
670
+ * previously wrong — callers depending on the old `POST /disputes/{id}/fetch_from_connector`
671
+ * path were silently hitting 404s.
672
+ */
673
+ async fetchFromConnector(connectorId) {
674
+ return this.request("GET", `/disputes/${encodeURIComponent(connectorId)}/fetch`);
592
675
  }
593
676
  };
594
677
 
@@ -619,7 +702,7 @@ var EphemeralKeys = class {
619
702
  * @returns The deleted key object.
620
703
  */
621
704
  async delete(keyId) {
622
- return this.request("DELETE", `/ephemeral_keys/${keyId}`);
705
+ return this.request("DELETE", `/ephemeral_keys/${encodeURIComponent(keyId)}`);
623
706
  }
624
707
  };
625
708
 
@@ -629,13 +712,19 @@ var Events = class {
629
712
  this.request = request;
630
713
  }
631
714
  async list(merchantId, params) {
632
- return this.request("POST", `/events/${merchantId}`, { body: params });
715
+ return this.request("POST", `/events/${encodeURIComponent(merchantId)}`, { body: params });
633
716
  }
634
717
  async listDeliveryAttempts(merchantId, eventId) {
635
- return this.request("GET", `/events/${merchantId}/${eventId}/attempts`);
718
+ return this.request(
719
+ "GET",
720
+ `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/attempts`
721
+ );
636
722
  }
637
723
  async retryDelivery(merchantId, eventId) {
638
- return this.request("POST", `/events/${merchantId}/${eventId}/retry`);
724
+ return this.request(
725
+ "POST",
726
+ `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/retry`
727
+ );
639
728
  }
640
729
  // --- Profile-scoped listing (Task 4.12) ---
641
730
  /** List events (profile-scoped). `POST /events/profile/list` */
@@ -680,7 +769,7 @@ var PlatformFees = class {
680
769
  * @returns The fee schedule.
681
770
  */
682
771
  async retrieve(feeId) {
683
- return this.request("GET", `/admin/fees/${feeId}`);
772
+ return this.request("GET", `/admin/fees/${encodeURIComponent(feeId)}`);
684
773
  }
685
774
  /**
686
775
  * Update a fee schedule (admin only).
@@ -690,7 +779,7 @@ var PlatformFees = class {
690
779
  * @returns The updated fee schedule.
691
780
  */
692
781
  async update(feeId, params) {
693
- return this.request("PUT", `/admin/fees/${feeId}`, { body: params });
782
+ return this.request("PUT", `/admin/fees/${encodeURIComponent(feeId)}`, { body: params });
694
783
  }
695
784
  /**
696
785
  * Delete a fee schedule (admin only).
@@ -699,7 +788,7 @@ var PlatformFees = class {
699
788
  * @returns The deleted fee schedule.
700
789
  */
701
790
  async delete(feeId) {
702
- return this.request("DELETE", `/admin/fees/${feeId}`);
791
+ return this.request("DELETE", `/admin/fees/${encodeURIComponent(feeId)}`);
703
792
  }
704
793
  };
705
794
  var MerchantFees = class {
@@ -738,7 +827,7 @@ var MerchantFees = class {
738
827
  * @returns The updated fee schedule.
739
828
  */
740
829
  async update(feeId, params) {
741
- return this.request("PUT", `/merchant_fees/${feeId}`, { body: params });
830
+ return this.request("PUT", `/merchant_fees/${encodeURIComponent(feeId)}`, { body: params });
742
831
  }
743
832
  /**
744
833
  * Delete a merchant-scoped fee schedule.
@@ -747,7 +836,7 @@ var MerchantFees = class {
747
836
  * @returns The deleted fee schedule.
748
837
  */
749
838
  async delete(feeId) {
750
- return this.request("DELETE", `/merchant_fees/${feeId}`);
839
+ return this.request("DELETE", `/merchant_fees/${encodeURIComponent(feeId)}`);
751
840
  }
752
841
  };
753
842
  var Fees = class {
@@ -788,7 +877,7 @@ var Mandates = class {
788
877
  * @returns The mandate.
789
878
  */
790
879
  async retrieve(mandateId) {
791
- return this.request("GET", `/mandates/${mandateId}`);
880
+ return this.request("GET", `/mandates/${encodeURIComponent(mandateId)}`);
792
881
  }
793
882
  /**
794
883
  * Revoke an active mandate, preventing future charges.
@@ -797,7 +886,7 @@ var Mandates = class {
797
886
  * @returns Revocation confirmation.
798
887
  */
799
888
  async revoke(mandateId) {
800
- return this.request("POST", `/mandates/revoke/${mandateId}`);
889
+ return this.request("POST", `/mandates/revoke/${encodeURIComponent(mandateId)}`);
801
890
  }
802
891
  /**
803
892
  * List mandates, optionally filtered by customer or status.
@@ -821,13 +910,13 @@ var MerchantAccounts = class {
821
910
  return this.request("POST", "/accounts", { body: params });
822
911
  }
823
912
  async retrieve(accountId) {
824
- return this.request("GET", `/accounts/${accountId}`);
913
+ return this.request("GET", `/accounts/${encodeURIComponent(accountId)}`);
825
914
  }
826
915
  async update(accountId, params) {
827
- return this.request("POST", `/accounts/${accountId}`, { body: params });
916
+ return this.request("POST", `/accounts/${encodeURIComponent(accountId)}`, { body: params });
828
917
  }
829
918
  async delete(accountId) {
830
- return this.request("DELETE", `/accounts/${accountId}`);
919
+ return this.request("DELETE", `/accounts/${encodeURIComponent(accountId)}`);
831
920
  }
832
921
  // --- Advanced operations (Task 4.9) ---
833
922
  /** List all merchant accounts. `GET /accounts/list` */
@@ -836,15 +925,15 @@ var MerchantAccounts = class {
836
925
  }
837
926
  /** Toggle key-value store for a merchant. `POST /accounts/{accountId}/kv` */
838
927
  async toggleKv(accountId) {
839
- return this.request("POST", `/accounts/${accountId}/kv`);
928
+ return this.request("POST", `/accounts/${encodeURIComponent(accountId)}/kv`);
840
929
  }
841
930
  /** Get KV status for a merchant. `GET /accounts/{accountId}/kv` */
842
931
  async getKvStatus(accountId) {
843
- return this.request("GET", `/accounts/${accountId}/kv`);
932
+ return this.request("GET", `/accounts/${encodeURIComponent(accountId)}/kv`);
844
933
  }
845
- /** Transfer keys between merchants. `POST /accounts/transfer_keys` */
934
+ /** Transfer keys between merchants. `POST /accounts/transfer` */
846
935
  async transferKeys(params) {
847
- return this.request("POST", "/accounts/transfer_keys", { body: params });
936
+ return this.request("POST", "/accounts/transfer", { body: params });
848
937
  }
849
938
  };
850
939
 
@@ -860,7 +949,7 @@ var PaymentLinks = class {
860
949
  * @returns The payment link details.
861
950
  */
862
951
  async retrieve(linkId) {
863
- return this.request("GET", `/payment_link/${linkId}`);
952
+ return this.request("GET", `/payment_link/${encodeURIComponent(linkId)}`);
864
953
  }
865
954
  /**
866
955
  * List payment links, optionally filtered by status or date range.
@@ -873,11 +962,17 @@ var PaymentLinks = class {
873
962
  }
874
963
  /** Initiate (render) a payment link page. `GET /payment_link/{merchantId}/{paymentId}` */
875
964
  async initiate(merchantId, paymentId) {
876
- return this.request("GET", `/payment_link/${merchantId}/${paymentId}`);
965
+ return this.request(
966
+ "GET",
967
+ `/payment_link/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`
968
+ );
877
969
  }
878
970
  /** Get payment link status. `GET /payment_linkstatus/{merchantId}/{paymentId}` */
879
971
  async status(merchantId, paymentId) {
880
- return this.request("GET", `/payment_linkstatus/${merchantId}/${paymentId}`);
972
+ return this.request(
973
+ "GET",
974
+ `/payment_linkstatus/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`
975
+ );
881
976
  }
882
977
  };
883
978
 
@@ -911,7 +1006,7 @@ var PaymentMethods = class {
911
1006
  * @returns The payment method.
912
1007
  */
913
1008
  async retrieve(methodId) {
914
- return this.request("GET", `/payment_methods/${methodId}`);
1009
+ return this.request("GET", `/payment_methods/${encodeURIComponent(methodId)}`);
915
1010
  }
916
1011
  /**
917
1012
  * Update an existing payment method (e.g. update card expiry).
@@ -921,7 +1016,9 @@ var PaymentMethods = class {
921
1016
  * @returns The updated payment method.
922
1017
  */
923
1018
  async update(methodId, params) {
924
- return this.request("POST", `/payment_methods/${methodId}/update`, { body: params });
1019
+ return this.request("POST", `/payment_methods/${encodeURIComponent(methodId)}/update`, {
1020
+ body: params
1021
+ });
925
1022
  }
926
1023
  /**
927
1024
  * Delete a saved payment method.
@@ -930,7 +1027,7 @@ var PaymentMethods = class {
930
1027
  * @returns Deletion confirmation.
931
1028
  */
932
1029
  async delete(methodId) {
933
- return this.request("DELETE", `/payment_methods/${methodId}`);
1030
+ return this.request("DELETE", `/payment_methods/${encodeURIComponent(methodId)}`);
934
1031
  }
935
1032
  /**
936
1033
  * List payment methods using a client secret.
@@ -944,18 +1041,25 @@ var PaymentMethods = class {
944
1041
  });
945
1042
  }
946
1043
  /**
947
- * List all saved payment methods for a customer.
1044
+ * List all saved payment methods for a customer, optionally filtered.
948
1045
  *
949
1046
  * @param customerId - The customer ID.
1047
+ * @param params - Optional filters: `client_secret`, `accepted_countries`, `accepted_currencies`,
1048
+ * `amount`, `recurring_enabled`, `installment_payment_enabled`, `limit`, `card_networks`.
950
1049
  * @returns Customer's saved payment methods.
951
1050
  *
952
1051
  * @example
953
1052
  * ```typescript
954
- * const { customer_payment_methods } = await delopay.paymentMethods.listForCustomer('cus_123');
1053
+ * const { customer_payment_methods } = await delopay.paymentMethods.listForCustomer(
1054
+ * 'cus_123',
1055
+ * { accepted_currencies: ['EUR'], amount: 5000 },
1056
+ * );
955
1057
  * ```
956
1058
  */
957
- async listForCustomer(customerId) {
958
- return this.request("GET", `/customers/${customerId}/payment_methods`);
1059
+ async listForCustomer(customerId, params) {
1060
+ return this.request("GET", `/customers/${encodeURIComponent(customerId)}/payment_methods`, {
1061
+ query: params
1062
+ });
959
1063
  }
960
1064
  /**
961
1065
  * Set a payment method as the default for a customer.
@@ -965,7 +1069,10 @@ var PaymentMethods = class {
965
1069
  * @returns The updated payment method.
966
1070
  */
967
1071
  async setDefault(customerId, methodId) {
968
- return this.request("POST", `/customers/${customerId}/payment_methods/${methodId}/default`);
1072
+ return this.request(
1073
+ "POST",
1074
+ `/customers/${encodeURIComponent(customerId)}/payment_methods/${encodeURIComponent(methodId)}/default`
1075
+ );
969
1076
  }
970
1077
  // --- Advanced operations (Task 3.3) ---
971
1078
  /** Migrate a payment method. `POST /payment_methods/migrate` */
@@ -998,7 +1105,9 @@ var PaymentMethods = class {
998
1105
  }
999
1106
  /** Save a payment method. `POST /payment_methods/{methodId}/save` */
1000
1107
  async save(methodId, params) {
1001
- return this.request("POST", `/payment_methods/${methodId}/save`, { body: params });
1108
+ return this.request("POST", `/payment_methods/${encodeURIComponent(methodId)}/save`, {
1109
+ body: params
1110
+ });
1002
1111
  }
1003
1112
  /** Create payment method auth link token. `POST /payment_methods/auth/link` */
1004
1113
  async createAuthLink(params) {
@@ -1010,7 +1119,9 @@ var PaymentMethods = class {
1010
1119
  }
1011
1120
  /** Tokenize card using existing PM. `POST /payment_methods/{methodId}/tokenize-card` */
1012
1121
  async tokenizeCardForMethod(methodId, params) {
1013
- return this.request("POST", `/payment_methods/${methodId}/tokenize-card`, { body: params });
1122
+ return this.request("POST", `/payment_methods/${encodeURIComponent(methodId)}/tokenize-card`, {
1123
+ body: params
1124
+ });
1014
1125
  }
1015
1126
  };
1016
1127
 
@@ -1049,7 +1160,7 @@ var Payments = class {
1049
1160
  * ```
1050
1161
  */
1051
1162
  async retrieve(paymentId) {
1052
- return this.request("GET", `/payments/${paymentId}`);
1163
+ return this.request("GET", `/payments/${encodeURIComponent(paymentId)}`);
1053
1164
  }
1054
1165
  /**
1055
1166
  * Update an existing payment intent before it is confirmed.
@@ -1059,7 +1170,7 @@ var Payments = class {
1059
1170
  * @returns The updated payment intent.
1060
1171
  */
1061
1172
  async update(paymentId, params) {
1062
- return this.request("POST", `/payments/${paymentId}`, { body: params });
1173
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}`, { body: params });
1063
1174
  }
1064
1175
  /**
1065
1176
  * Confirm a payment intent, triggering authorisation with the selected gateway.
@@ -1069,7 +1180,9 @@ var Payments = class {
1069
1180
  * @returns The updated payment intent.
1070
1181
  */
1071
1182
  async confirm(paymentId, params) {
1072
- return this.request("POST", `/payments/${paymentId}/confirm`, { body: params });
1183
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/confirm`, {
1184
+ body: params
1185
+ });
1073
1186
  }
1074
1187
  /**
1075
1188
  * Capture a previously authorised payment.
@@ -1079,7 +1192,9 @@ var Payments = class {
1079
1192
  * @returns The updated payment intent.
1080
1193
  */
1081
1194
  async capture(paymentId, params) {
1082
- return this.request("POST", `/payments/${paymentId}/capture`, { body: params });
1195
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/capture`, {
1196
+ body: params
1197
+ });
1083
1198
  }
1084
1199
  /**
1085
1200
  * Cancel a payment intent that has not yet been captured.
@@ -1089,7 +1204,9 @@ var Payments = class {
1089
1204
  * @returns The updated payment intent.
1090
1205
  */
1091
1206
  async cancel(paymentId, params) {
1092
- return this.request("POST", `/payments/${paymentId}/cancel`, { body: params });
1207
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/cancel`, {
1208
+ body: params
1209
+ });
1093
1210
  }
1094
1211
  /**
1095
1212
  * List payment intents, optionally filtered by customer or date range.
@@ -1118,33 +1235,47 @@ var Payments = class {
1118
1235
  }
1119
1236
  /** Cancel after partial capture. `POST /payments/{paymentId}/cancel_post_capture` */
1120
1237
  async cancelPostCapture(paymentId, params) {
1121
- return this.request("POST", `/payments/${paymentId}/cancel_post_capture`, { body: params });
1238
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/cancel_post_capture`, {
1239
+ body: params
1240
+ });
1122
1241
  }
1123
1242
  /** Incrementally authorize more funds. `POST /payments/{paymentId}/incremental_authorization` */
1124
1243
  async incrementalAuthorization(paymentId, params) {
1125
- return this.request("POST", `/payments/${paymentId}/incremental_authorization`, {
1126
- body: params
1127
- });
1244
+ return this.request(
1245
+ "POST",
1246
+ `/payments/${encodeURIComponent(paymentId)}/incremental_authorization`,
1247
+ {
1248
+ body: params
1249
+ }
1250
+ );
1128
1251
  }
1129
1252
  /** Extend authorization window. `POST /payments/{paymentId}/extend_authorization` */
1130
1253
  async extendAuthorization(paymentId, params) {
1131
- return this.request("POST", `/payments/${paymentId}/extend_authorization`, { body: params });
1254
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/extend_authorization`, {
1255
+ body: params
1256
+ });
1132
1257
  }
1133
1258
  /** Complete authorization. `POST /payments/{paymentId}/complete_authorize` */
1134
1259
  async completeAuthorize(paymentId, params) {
1135
- return this.request("POST", `/payments/${paymentId}/complete_authorize`, { body: params });
1260
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/complete_authorize`, {
1261
+ body: params
1262
+ });
1136
1263
  }
1137
1264
  /** Dynamic tax calculation. `POST /payments/{paymentId}/calculate_tax` */
1138
1265
  async calculateTax(paymentId, params) {
1139
- return this.request("POST", `/payments/${paymentId}/calculate_tax`, { body: params });
1266
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/calculate_tax`, {
1267
+ body: params
1268
+ });
1140
1269
  }
1141
1270
  /** Update payment metadata. `POST /payments/{paymentId}/update_metadata` */
1142
1271
  async updateMetadata(paymentId, params) {
1143
- return this.request("POST", `/payments/${paymentId}/update_metadata`, { body: params });
1272
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/update_metadata`, {
1273
+ body: params
1274
+ });
1144
1275
  }
1145
1276
  /** Retrieve extended card info. `GET /payments/{paymentId}/extended_card_info` */
1146
1277
  async extendedCardInfo(paymentId) {
1147
- return this.request("GET", `/payments/${paymentId}/extended_card_info`);
1278
+ return this.request("GET", `/payments/${encodeURIComponent(paymentId)}/extended_card_info`);
1148
1279
  }
1149
1280
  // --- OLAP extensions (Task 4.2) ---
1150
1281
  /** List payments (profile-scoped). `GET /payments/profile/list` */
@@ -1181,19 +1312,27 @@ var Payments = class {
1181
1312
  }
1182
1313
  /** Manually update payment status. `PUT /payments/{paymentId}/manual-update` */
1183
1314
  async manualUpdate(paymentId, params) {
1184
- return this.request("PUT", `/payments/${paymentId}/manual-update`, { body: params });
1315
+ return this.request("PUT", `/payments/${encodeURIComponent(paymentId)}/manual-update`, {
1316
+ body: params
1317
+ });
1185
1318
  }
1186
1319
  /** Approve a payment waiting for review. `POST /payments/{paymentId}/approve` */
1187
1320
  async approve(paymentId, params) {
1188
- return this.request("POST", `/payments/${paymentId}/approve`, { body: params });
1321
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/approve`, {
1322
+ body: params
1323
+ });
1189
1324
  }
1190
1325
  /** Reject a payment waiting for review. `POST /payments/{paymentId}/reject` */
1191
1326
  async reject(paymentId, params) {
1192
- return this.request("POST", `/payments/${paymentId}/reject`, { body: params });
1327
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/reject`, {
1328
+ body: params
1329
+ });
1193
1330
  }
1194
1331
  /** Initiate external 3DS authentication. `POST /payments/{paymentId}/3ds/authentication` */
1195
1332
  async threeDsAuthentication(paymentId, params) {
1196
- return this.request("POST", `/payments/${paymentId}/3ds/authentication`, { body: params });
1333
+ return this.request("POST", `/payments/${encodeURIComponent(paymentId)}/3ds/authentication`, {
1334
+ body: params
1335
+ });
1197
1336
  }
1198
1337
  };
1199
1338
 
@@ -1227,7 +1366,7 @@ var Payouts = class {
1227
1366
  * @returns The payout.
1228
1367
  */
1229
1368
  async retrieve(payoutId) {
1230
- return this.request("GET", `/payouts/${payoutId}`);
1369
+ return this.request("GET", `/payouts/${encodeURIComponent(payoutId)}`);
1231
1370
  }
1232
1371
  /**
1233
1372
  * Update a payout before it is confirmed.
@@ -1237,7 +1376,7 @@ var Payouts = class {
1237
1376
  * @returns The updated payout.
1238
1377
  */
1239
1378
  async update(payoutId, params) {
1240
- return this.request("PUT", `/payouts/${payoutId}`, { body: params });
1379
+ return this.request("PUT", `/payouts/${encodeURIComponent(payoutId)}`, { body: params });
1241
1380
  }
1242
1381
  /**
1243
1382
  * Confirm a payout, triggering the actual transfer.
@@ -1247,7 +1386,9 @@ var Payouts = class {
1247
1386
  * @returns The updated payout.
1248
1387
  */
1249
1388
  async confirm(payoutId, params) {
1250
- return this.request("POST", `/payouts/${payoutId}/confirm`, { body: params });
1389
+ return this.request("POST", `/payouts/${encodeURIComponent(payoutId)}/confirm`, {
1390
+ body: params
1391
+ });
1251
1392
  }
1252
1393
  /**
1253
1394
  * Cancel a payout before it is fulfilled.
@@ -1256,7 +1397,7 @@ var Payouts = class {
1256
1397
  * @returns The cancelled payout.
1257
1398
  */
1258
1399
  async cancel(payoutId) {
1259
- return this.request("POST", `/payouts/${payoutId}/cancel`);
1400
+ return this.request("POST", `/payouts/${encodeURIComponent(payoutId)}/cancel`);
1260
1401
  }
1261
1402
  /**
1262
1403
  * Mark a payout as fulfilled (manual confirmation of successful transfer).
@@ -1265,7 +1406,7 @@ var Payouts = class {
1265
1406
  * @returns The fulfilled payout.
1266
1407
  */
1267
1408
  async fulfill(payoutId) {
1268
- return this.request("POST", `/payouts/${payoutId}/fulfill`);
1409
+ return this.request("POST", `/payouts/${encodeURIComponent(payoutId)}/fulfill`);
1269
1410
  }
1270
1411
  /**
1271
1412
  * List payouts, optionally filtered by status or date range.
@@ -1307,7 +1448,9 @@ var Payouts = class {
1307
1448
  }
1308
1449
  /** Manually update payout status. `PUT /payouts/{payoutId}/manual-update` */
1309
1450
  async manualUpdate(payoutId, params) {
1310
- return this.request("PUT", `/payouts/${payoutId}/manual-update`, { body: params });
1451
+ return this.request("PUT", `/payouts/${encodeURIComponent(payoutId)}/manual-update`, {
1452
+ body: params
1453
+ });
1311
1454
  }
1312
1455
  };
1313
1456
 
@@ -1317,7 +1460,7 @@ var Poll = class {
1317
1460
  this.request = request;
1318
1461
  }
1319
1462
  async getStatus(pollId) {
1320
- return this.request("GET", `/poll/status/${pollId}`);
1463
+ return this.request("GET", `/poll/status/${encodeURIComponent(pollId)}`);
1321
1464
  }
1322
1465
  };
1323
1466
 
@@ -1330,9 +1473,13 @@ var ProfileAcquirers = class {
1330
1473
  return this.request("POST", "/profile_acquirer", { body: params });
1331
1474
  }
1332
1475
  async update(profileId, profileAcquirerId, params) {
1333
- return this.request("POST", `/profile_acquirer/${profileId}/${profileAcquirerId}`, {
1334
- body: params
1335
- });
1476
+ return this.request(
1477
+ "POST",
1478
+ `/profile_acquirer/${encodeURIComponent(profileId)}/${encodeURIComponent(profileAcquirerId)}`,
1479
+ {
1480
+ body: params
1481
+ }
1482
+ );
1336
1483
  }
1337
1484
  };
1338
1485
 
@@ -1342,35 +1489,47 @@ var Profiles = class {
1342
1489
  this.request = request;
1343
1490
  }
1344
1491
  async create(accountId, params) {
1345
- return this.request("POST", `/account/${accountId}/business_profile`, { body: params });
1492
+ return this.request("POST", `/account/${encodeURIComponent(accountId)}/business_profile`, {
1493
+ body: params
1494
+ });
1346
1495
  }
1347
1496
  async retrieve(accountId, profileId) {
1348
- return this.request("GET", `/account/${accountId}/business_profile/${profileId}`);
1497
+ return this.request(
1498
+ "GET",
1499
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}`
1500
+ );
1349
1501
  }
1350
1502
  async list(accountId) {
1351
- return this.request("GET", `/account/${accountId}/business_profile`);
1503
+ return this.request("GET", `/account/${encodeURIComponent(accountId)}/business_profile`);
1352
1504
  }
1353
1505
  async update(accountId, profileId, params) {
1354
- return this.request("POST", `/account/${accountId}/business_profile/${profileId}`, {
1355
- body: params
1356
- });
1506
+ return this.request(
1507
+ "POST",
1508
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}`,
1509
+ {
1510
+ body: params
1511
+ }
1512
+ );
1357
1513
  }
1358
1514
  async delete(accountId, profileId) {
1359
- return this.request("DELETE", `/account/${accountId}/business_profile/${profileId}`);
1515
+ return this.request(
1516
+ "DELETE",
1517
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}`
1518
+ );
1360
1519
  }
1361
1520
  // --- Advanced operations (Task 4.8) ---
1362
1521
  /** Toggle extended card info for a profile. `POST /account/{accountId}/business_profile/{profileId}/toggle_extended_card_info` */
1363
1522
  async toggleExtendedCardInfo(accountId, profileId) {
1364
1523
  return this.request(
1365
1524
  "POST",
1366
- `/account/${accountId}/business_profile/${profileId}/toggle_extended_card_info`
1525
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}/toggle_extended_card_info`
1367
1526
  );
1368
1527
  }
1369
1528
  /** Toggle connector agnostic MIT. `POST /account/{accountId}/business_profile/{profileId}/toggle_connector_agnostic_mit` */
1370
1529
  async toggleConnectorAgnosticMit(accountId, profileId) {
1371
1530
  return this.request(
1372
1531
  "POST",
1373
- `/account/${accountId}/business_profile/${profileId}/toggle_connector_agnostic_mit`
1532
+ `/account/${encodeURIComponent(accountId)}/business_profile/${encodeURIComponent(profileId)}/toggle_connector_agnostic_mit`
1374
1533
  );
1375
1534
  }
1376
1535
  };
@@ -1405,7 +1564,7 @@ var Projects = class {
1405
1564
  * @returns The project.
1406
1565
  */
1407
1566
  async retrieve(projectId) {
1408
- return this.request("GET", `/projects/${projectId}`);
1567
+ return this.request("GET", `/projects/${encodeURIComponent(projectId)}`);
1409
1568
  }
1410
1569
  /**
1411
1570
  * Update a project's details.
@@ -1415,7 +1574,7 @@ var Projects = class {
1415
1574
  * @returns The updated project.
1416
1575
  */
1417
1576
  async update(projectId, params) {
1418
- return this.request("PUT", `/projects/${projectId}`, { body: params });
1577
+ return this.request("PUT", `/projects/${encodeURIComponent(projectId)}`, { body: params });
1419
1578
  }
1420
1579
  /**
1421
1580
  * Delete a project.
@@ -1424,7 +1583,7 @@ var Projects = class {
1424
1583
  * @returns The deleted project object.
1425
1584
  */
1426
1585
  async delete(projectId) {
1427
- return this.request("DELETE", `/projects/${projectId}`);
1586
+ return this.request("DELETE", `/projects/${encodeURIComponent(projectId)}`);
1428
1587
  }
1429
1588
  /**
1430
1589
  * List all projects for a merchant.
@@ -1495,7 +1654,7 @@ var Refunds = class {
1495
1654
  * ```
1496
1655
  */
1497
1656
  async retrieve(refundId) {
1498
- return this.request("GET", `/refunds/${refundId}`);
1657
+ return this.request("GET", `/refunds/${encodeURIComponent(refundId)}`);
1499
1658
  }
1500
1659
  /**
1501
1660
  * Update the reason or metadata on an existing refund.
@@ -1505,7 +1664,7 @@ var Refunds = class {
1505
1664
  * @returns The updated refund.
1506
1665
  */
1507
1666
  async update(refundId, params) {
1508
- return this.request("POST", `/refunds/${refundId}`, { body: params });
1667
+ return this.request("POST", `/refunds/${encodeURIComponent(refundId)}`, { body: params });
1509
1668
  }
1510
1669
  /**
1511
1670
  * List refunds, optionally filtered by payment, status, or date range.
@@ -1539,7 +1698,9 @@ var Refunds = class {
1539
1698
  }
1540
1699
  /** Manually update refund status. `PUT /refunds/{refundId}/manual-update` */
1541
1700
  async manualUpdate(refundId, params) {
1542
- return this.request("PUT", `/refunds/${refundId}/manual-update`, { body: params });
1701
+ return this.request("PUT", `/refunds/${encodeURIComponent(refundId)}/manual-update`, {
1702
+ body: params
1703
+ });
1543
1704
  }
1544
1705
  };
1545
1706
 
@@ -1552,7 +1713,7 @@ var Relay = class {
1552
1713
  return this.request("POST", "/relay", { body: params });
1553
1714
  }
1554
1715
  async retrieve(relayId) {
1555
- return this.request("GET", `/relay/${relayId}`);
1716
+ return this.request("GET", `/relay/${encodeURIComponent(relayId)}`);
1556
1717
  }
1557
1718
  };
1558
1719
 
@@ -1586,7 +1747,7 @@ var Routing = class {
1586
1747
  * @returns The routing configuration.
1587
1748
  */
1588
1749
  async retrieve(algorithmId) {
1589
- return this.request("GET", `/routing/${algorithmId}`);
1750
+ return this.request("GET", `/routing/${encodeURIComponent(algorithmId)}`);
1590
1751
  }
1591
1752
  /**
1592
1753
  * Activate a routing algorithm, making it the active routing strategy for the shop.
@@ -1595,7 +1756,7 @@ var Routing = class {
1595
1756
  * @returns The activated routing configuration.
1596
1757
  */
1597
1758
  async activate(algorithmId) {
1598
- return this.request("POST", `/routing/${algorithmId}/activate`);
1759
+ return this.request("POST", `/routing/${encodeURIComponent(algorithmId)}/activate`);
1599
1760
  }
1600
1761
  /**
1601
1762
  * Deactivate the currently active routing algorithm (falls back to default routing).
@@ -1628,7 +1789,9 @@ var Routing = class {
1628
1789
  }
1629
1790
  /** Update default config for a profile. `POST /routing/default/profile/{profileId}` */
1630
1791
  async updateDefaultProfile(profileId, params) {
1631
- return this.request("POST", `/routing/default/profile/${profileId}`, { body: params });
1792
+ return this.request("POST", `/routing/default/profile/${encodeURIComponent(profileId)}`, {
1793
+ body: params
1794
+ });
1632
1795
  }
1633
1796
  /** List routing configs for profile. `GET /routing/list/profile` */
1634
1797
  async listForProfile() {
@@ -1695,7 +1858,11 @@ var ShopGateways = class {
1695
1858
  * @returns The created gateway connection.
1696
1859
  */
1697
1860
  async connect(merchantId, shopId, params) {
1698
- return this.request("POST", `/shops/${merchantId}/${shopId}/gateways`, { body: params });
1861
+ return this.request(
1862
+ "POST",
1863
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`,
1864
+ { body: params }
1865
+ );
1699
1866
  }
1700
1867
  /**
1701
1868
  * List all gateway connections for a shop.
@@ -1705,7 +1872,10 @@ var ShopGateways = class {
1705
1872
  * @returns Array of gateway connections.
1706
1873
  */
1707
1874
  async list(merchantId, shopId) {
1708
- return this.request("GET", `/shops/${merchantId}/${shopId}/gateways`);
1875
+ return this.request(
1876
+ "GET",
1877
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`
1878
+ );
1709
1879
  }
1710
1880
  /**
1711
1881
  * Disconnect a gateway from a shop.
@@ -1716,7 +1886,10 @@ var ShopGateways = class {
1716
1886
  * @returns The removed gateway connection.
1717
1887
  */
1718
1888
  async disconnect(merchantId, shopId, gatewayId) {
1719
- return this.request("DELETE", `/shops/${merchantId}/${shopId}/gateways/${gatewayId}`);
1889
+ return this.request(
1890
+ "DELETE",
1891
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways/${encodeURIComponent(gatewayId)}`
1892
+ );
1720
1893
  }
1721
1894
  };
1722
1895
  var Shops = class {
@@ -1737,7 +1910,7 @@ var Shops = class {
1737
1910
  * ```
1738
1911
  */
1739
1912
  async create(merchantId, params) {
1740
- return this.request("POST", `/shops/${merchantId}`, { body: params });
1913
+ return this.request("POST", `/shops/${encodeURIComponent(merchantId)}`, { body: params });
1741
1914
  }
1742
1915
  /**
1743
1916
  * Retrieve a shop by its ID.
@@ -1747,7 +1920,10 @@ var Shops = class {
1747
1920
  * @returns The shop.
1748
1921
  */
1749
1922
  async retrieve(merchantId, shopId) {
1750
- return this.request("GET", `/shops/${merchantId}/${shopId}`);
1923
+ return this.request(
1924
+ "GET",
1925
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`
1926
+ );
1751
1927
  }
1752
1928
  /**
1753
1929
  * Update a shop's configuration.
@@ -1758,7 +1934,11 @@ var Shops = class {
1758
1934
  * @returns The updated shop.
1759
1935
  */
1760
1936
  async update(merchantId, shopId, params) {
1761
- return this.request("PUT", `/shops/${merchantId}/${shopId}`, { body: params });
1937
+ return this.request(
1938
+ "PUT",
1939
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,
1940
+ { body: params }
1941
+ );
1762
1942
  }
1763
1943
  /**
1764
1944
  * Delete a shop.
@@ -1768,7 +1948,10 @@ var Shops = class {
1768
1948
  * @returns The deleted shop object.
1769
1949
  */
1770
1950
  async delete(merchantId, shopId) {
1771
- return this.request("DELETE", `/shops/${merchantId}/${shopId}`);
1951
+ return this.request(
1952
+ "DELETE",
1953
+ `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`
1954
+ );
1772
1955
  }
1773
1956
  /**
1774
1957
  * List all shops under a merchant account.
@@ -1777,7 +1960,7 @@ var Shops = class {
1777
1960
  * @returns Array of shops.
1778
1961
  */
1779
1962
  async list(merchantId) {
1780
- return this.request("GET", `/shops/${merchantId}`);
1963
+ return this.request("GET", `/shops/${encodeURIComponent(merchantId)}`);
1781
1964
  }
1782
1965
  };
1783
1966
 
@@ -2035,11 +2218,11 @@ var Users = class {
2035
2218
  }
2036
2219
  /** Get role by ID. `GET /user/role/{roleId}` */
2037
2220
  async getRoleById(roleId) {
2038
- return this.request("GET", `/user/role/${roleId}`);
2221
+ return this.request("GET", `/user/role/${encodeURIComponent(roleId)}`);
2039
2222
  }
2040
2223
  /** Update role by ID. `PUT /user/role/{roleId}` */
2041
2224
  async updateRole(roleId, params) {
2042
- return this.request("PUT", `/user/role/${roleId}`, { body: params });
2225
+ return this.request("PUT", `/user/role/${encodeURIComponent(roleId)}`, { body: params });
2043
2226
  }
2044
2227
  };
2045
2228
 
@@ -2049,7 +2232,9 @@ var Verification = class {
2049
2232
  this.request = request;
2050
2233
  }
2051
2234
  async registerApplePayDomains(merchantId, params) {
2052
- return this.request("POST", `/verify/apple_pay/${merchantId}`, { body: params });
2235
+ return this.request("POST", `/verify/apple_pay/${encodeURIComponent(merchantId)}`, {
2236
+ body: params
2237
+ });
2053
2238
  }
2054
2239
  async getApplePayVerifiedDomains(params) {
2055
2240
  return this.request("GET", "/verify/applepay_verified_domains", {
@@ -2059,10 +2244,23 @@ var Verification = class {
2059
2244
  };
2060
2245
 
2061
2246
  // src/resources/webhooks.ts
2247
+ function hexToBytes(hex) {
2248
+ if (hex.length === 0 || hex.length % 2 !== 0) return null;
2249
+ const bytes = new Uint8Array(hex.length / 2);
2250
+ for (let i = 0; i < hex.length; i += 2) {
2251
+ const byte = Number.parseInt(hex.slice(i, i + 2), 16);
2252
+ if (Number.isNaN(byte)) return null;
2253
+ bytes[i / 2] = byte;
2254
+ }
2255
+ return bytes;
2256
+ }
2062
2257
  var Webhooks = {
2063
2258
  /**
2064
2259
  * Verify the signature of an incoming Delopay webhook and return the parsed event.
2065
2260
  *
2261
+ * Uses the Web Crypto API (`globalThis.crypto.subtle`), so it runs unchanged in
2262
+ * Node 18+, modern browsers, Deno, Bun, and edge runtimes (Cloudflare Workers, Vercel Edge).
2263
+ *
2066
2264
  * This method is available as a static property on the `Delopay` class
2067
2265
  * (`Delopay.webhooks.verify`) and does not require a client instance.
2068
2266
  *
@@ -2070,14 +2268,14 @@ var Webhooks = {
2070
2268
  * @param signatureHeader - The value of the `delopay-signature` HTTP header.
2071
2269
  * @param secret - Your webhook signing secret from the Delopay dashboard.
2072
2270
  * @param options - Optional verification settings (replay tolerance).
2073
- * @returns The parsed webhook event.
2271
+ * @returns Promise that resolves to the parsed webhook event.
2074
2272
  * @throws {Error} When the signature is invalid, the timestamp is missing, or the event is too old.
2075
2273
  *
2076
2274
  * @example
2077
2275
  * ```typescript
2078
2276
  * // Express example
2079
- * app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
2080
- * const event = Delopay.webhooks.verify(
2277
+ * app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
2278
+ * const event = await Delopay.webhooks.verify(
2081
2279
  * req.body.toString(),
2082
2280
  * req.headers['delopay-signature'] as string,
2083
2281
  * process.env.DELOPAY_WEBHOOK_SECRET!,
@@ -2087,7 +2285,7 @@ var Webhooks = {
2087
2285
  * });
2088
2286
  * ```
2089
2287
  */
2090
- verify(rawBody, signatureHeader, secret, options) {
2288
+ async verify(rawBody, signatureHeader, secret, options) {
2091
2289
  const tolerance = options?.tolerance ?? 300;
2092
2290
  const parts = signatureHeader.split(",");
2093
2291
  const timestampPart = parts.find((p) => p.startsWith("t="));
@@ -2095,19 +2293,29 @@ var Webhooks = {
2095
2293
  if (!timestampPart || !signaturePart) {
2096
2294
  throw new Error("Invalid webhook signature format");
2097
2295
  }
2098
- const timestamp = parseInt(timestampPart.slice(2), 10);
2296
+ const timestamp = Number.parseInt(timestampPart.slice(2), 10);
2099
2297
  if (!Number.isFinite(timestamp)) {
2100
2298
  throw new Error("Invalid webhook timestamp");
2101
2299
  }
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);
2300
+ const signatureHex = signaturePart.slice(3);
2301
+ const signatureBytes = hexToBytes(signatureHex);
2302
+ const subtle = globalThis.crypto?.subtle;
2303
+ if (!subtle) {
2304
+ throw new Error(
2305
+ "Web Crypto unavailable: Delopay.webhooks.verify requires globalThis.crypto.subtle (Node 18+, modern browsers, Workers, Deno)"
2306
+ );
2307
+ }
2308
+ const encoder = new TextEncoder();
2309
+ const asBufferSource = (bytes) => bytes;
2310
+ const key = await subtle.importKey(
2311
+ "raw",
2312
+ asBufferSource(encoder.encode(secret)),
2313
+ { name: "HMAC", hash: "SHA-256" },
2314
+ false,
2315
+ ["verify"]
2316
+ );
2317
+ const signedPayload = asBufferSource(encoder.encode(`${timestamp}.${rawBody}`));
2318
+ const signaturesMatch = signatureBytes !== null && await subtle.verify("HMAC", key, asBufferSource(signatureBytes), signedPayload);
2111
2319
  if (!signaturesMatch) {
2112
2320
  throw new Error("Invalid webhook signature");
2113
2321
  }
@@ -2128,22 +2336,30 @@ var AnalyticsDomain = class {
2128
2336
  /** Get metrics. `POST /analytics/v1/metrics/{domain}` */
2129
2337
  async metrics(params, scope) {
2130
2338
  const prefix = scope ? `/analytics/v1/${scope}` : "/analytics/v1";
2131
- return this.request("POST", `${prefix}/metrics/${this.domain}`, { body: [params] });
2339
+ return this.request("POST", `${prefix}/metrics/${encodeURIComponent(this.domain)}`, {
2340
+ body: [params]
2341
+ });
2132
2342
  }
2133
2343
  /** Get filters. `POST /analytics/v1/filters/{domain}` */
2134
2344
  async filters(params, scope) {
2135
2345
  const prefix = scope ? `/analytics/v1/${scope}` : "/analytics/v1";
2136
- return this.request("POST", `${prefix}/filters/${this.domain}`, { body: params });
2346
+ return this.request("POST", `${prefix}/filters/${encodeURIComponent(this.domain)}`, {
2347
+ body: params
2348
+ });
2137
2349
  }
2138
2350
  /** Generate report. `POST /analytics/v1/report/{domain}` */
2139
2351
  async report(params, scope) {
2140
2352
  const prefix = scope ? `/analytics/v1/${scope}` : "/analytics/v1";
2141
- return this.request("POST", `${prefix}/report/${this.domain}`, { body: params });
2353
+ return this.request("POST", `${prefix}/report/${encodeURIComponent(this.domain)}`, {
2354
+ body: params
2355
+ });
2142
2356
  }
2143
2357
  /** Sankey chart data. `POST /analytics/v1/metrics/{domain}/sankey` */
2144
2358
  async sankey(params, scope) {
2145
2359
  const prefix = scope ? `/analytics/v1/${scope}` : "/analytics/v1";
2146
- return this.request("POST", `${prefix}/metrics/${this.domain}/sankey`, { body: params });
2360
+ return this.request("POST", `${prefix}/metrics/${encodeURIComponent(this.domain)}/sankey`, {
2361
+ body: params
2362
+ });
2147
2363
  }
2148
2364
  };
2149
2365
  var Analytics = class {
@@ -2164,11 +2380,13 @@ var Analytics = class {
2164
2380
  }
2165
2381
  /** Domain-specific search. `POST /analytics/v1/search/{domain}` */
2166
2382
  async searchDomain(domain, params) {
2167
- return this.request("POST", `/analytics/v1/search/${domain}`, { body: params });
2383
+ return this.request("POST", `/analytics/v1/search/${encodeURIComponent(domain)}`, {
2384
+ body: params
2385
+ });
2168
2386
  }
2169
2387
  /** Get analytics info. `GET /analytics/v1/{domain}/info` */
2170
2388
  async getInfo(domain) {
2171
- return this.request("GET", `/analytics/v1/${domain}/info`);
2389
+ return this.request("GET", `/analytics/v1/${encodeURIComponent(domain)}/info`);
2172
2390
  }
2173
2391
  /** Get API event logs. `GET /analytics/v1/api_event_logs` */
2174
2392
  async apiEventLogs(params) {
@@ -2214,7 +2432,7 @@ var Cache = class {
2214
2432
  }
2215
2433
  /** Invalidate a cache entry by key. `POST /cache/invalidate/{key}` */
2216
2434
  async invalidate(key) {
2217
- return this.request("POST", `/cache/invalidate/${key}`);
2435
+ return this.request("POST", `/cache/invalidate/${encodeURIComponent(key)}`);
2218
2436
  }
2219
2437
  };
2220
2438
 
@@ -2233,7 +2451,7 @@ var Cards = class {
2233
2451
  }
2234
2452
  /** Retrieve card info by BIN. `GET /cards/{bin}` */
2235
2453
  async retrieve(bin) {
2236
- return this.request("GET", `/cards/${bin}`);
2454
+ return this.request("GET", `/cards/${encodeURIComponent(bin)}`);
2237
2455
  }
2238
2456
  };
2239
2457
 
@@ -2248,15 +2466,15 @@ var Configs = class {
2248
2466
  }
2249
2467
  /** Retrieve a config by key. `GET /configs/{key}` */
2250
2468
  async retrieve(key) {
2251
- return this.request("GET", `/configs/${key}`);
2469
+ return this.request("GET", `/configs/${encodeURIComponent(key)}`);
2252
2470
  }
2253
2471
  /** Update a config. `PUT /configs/{key}` */
2254
2472
  async update(key, params) {
2255
- return this.request("PUT", `/configs/${key}`, { body: params });
2473
+ return this.request("PUT", `/configs/${encodeURIComponent(key)}`, { body: params });
2256
2474
  }
2257
2475
  /** Delete a config. `DELETE /configs/{key}` */
2258
2476
  async delete(key) {
2259
- return this.request("DELETE", `/configs/${key}`);
2477
+ return this.request("DELETE", `/configs/${encodeURIComponent(key)}`);
2260
2478
  }
2261
2479
  };
2262
2480
 
@@ -2293,11 +2511,11 @@ var Files = class {
2293
2511
  }
2294
2512
  /** Retrieve/download a file. `GET /files/{fileId}` */
2295
2513
  async retrieve(fileId) {
2296
- return this.request("GET", `/files/${fileId}`);
2514
+ return this.request("GET", `/files/${encodeURIComponent(fileId)}`);
2297
2515
  }
2298
2516
  /** Delete a file. `DELETE /files/{fileId}` */
2299
2517
  async delete(fileId) {
2300
- return this.request("DELETE", `/files/${fileId}`);
2518
+ return this.request("DELETE", `/files/${encodeURIComponent(fileId)}`);
2301
2519
  }
2302
2520
  };
2303
2521
 
@@ -2327,15 +2545,15 @@ var Regions = class {
2327
2545
  }
2328
2546
  /** Retrieve a region by ID. `GET /regions/{regionId}` */
2329
2547
  async retrieve(regionId) {
2330
- return this.request("GET", `/regions/${regionId}`);
2548
+ return this.request("GET", `/regions/${encodeURIComponent(regionId)}`);
2331
2549
  }
2332
2550
  /** Update a region. `PUT /regions/{regionId}` */
2333
2551
  async update(regionId, params) {
2334
- return this.request("PUT", `/regions/${regionId}`, { body: params });
2552
+ return this.request("PUT", `/regions/${encodeURIComponent(regionId)}`, { body: params });
2335
2553
  }
2336
2554
  /** Delete a region. `DELETE /regions/{regionId}` */
2337
2555
  async delete(regionId) {
2338
- return this.request("DELETE", `/regions/${regionId}`);
2556
+ return this.request("DELETE", `/regions/${encodeURIComponent(regionId)}`);
2339
2557
  }
2340
2558
  /** List all regions. `GET /regions/list` */
2341
2559
  async list() {
@@ -2358,17 +2576,19 @@ var Subscriptions = class {
2358
2576
  }
2359
2577
  /** Retrieve a subscription by ID. `GET /subscriptions/{subscriptionId}` */
2360
2578
  async retrieve(subscriptionId) {
2361
- return this.request("GET", `/subscriptions/${subscriptionId}`);
2579
+ return this.request("GET", `/subscriptions/${encodeURIComponent(subscriptionId)}`);
2362
2580
  }
2363
2581
  /** Confirm a subscription. `POST /subscriptions/{subscriptionId}/confirm` */
2364
2582
  async confirm(subscriptionId, params) {
2365
- return this.request("POST", `/subscriptions/${subscriptionId}/confirm`, {
2583
+ return this.request("POST", `/subscriptions/${encodeURIComponent(subscriptionId)}/confirm`, {
2366
2584
  body: params
2367
2585
  });
2368
2586
  }
2369
2587
  /** Update a subscription. `PUT /subscriptions/{subscriptionId}/update` */
2370
2588
  async update(subscriptionId, params) {
2371
- return this.request("PUT", `/subscriptions/${subscriptionId}/update`, { body: params });
2589
+ return this.request("PUT", `/subscriptions/${encodeURIComponent(subscriptionId)}/update`, {
2590
+ body: params
2591
+ });
2372
2592
  }
2373
2593
  /** List subscriptions. `GET /subscriptions/list` */
2374
2594
  async list(params) {
@@ -2386,21 +2606,95 @@ var Subscriptions = class {
2386
2606
  }
2387
2607
  /** Pause a subscription. `POST /subscriptions/{subscriptionId}/pause` */
2388
2608
  async pause(subscriptionId) {
2389
- return this.request("POST", `/subscriptions/${subscriptionId}/pause`);
2609
+ return this.request("POST", `/subscriptions/${encodeURIComponent(subscriptionId)}/pause`);
2390
2610
  }
2391
2611
  /** Resume a subscription. `POST /subscriptions/{subscriptionId}/resume` */
2392
2612
  async resume(subscriptionId) {
2393
- return this.request("POST", `/subscriptions/${subscriptionId}/resume`);
2613
+ return this.request("POST", `/subscriptions/${encodeURIComponent(subscriptionId)}/resume`);
2394
2614
  }
2395
2615
  /** Cancel a subscription. `POST /subscriptions/{subscriptionId}/cancel` */
2396
2616
  async cancel(subscriptionId) {
2397
- return this.request("POST", `/subscriptions/${subscriptionId}/cancel`);
2617
+ return this.request("POST", `/subscriptions/${encodeURIComponent(subscriptionId)}/cancel`);
2398
2618
  }
2399
2619
  };
2400
2620
 
2401
2621
  // src/client.ts
2402
2622
  var PRODUCTION_URL = "https://api.delopay.net";
2403
2623
  var SANDBOX_URL = "https://sandbox.delopay.net";
2624
+ var MAX_RAW_BODY_BYTES = 2048;
2625
+ var MAX_RETRY_AFTER_MS = 3e4;
2626
+ function parseRetryAfter(header) {
2627
+ if (!header) return null;
2628
+ const trimmed = header.trim();
2629
+ const seconds = Number(trimmed);
2630
+ if (Number.isFinite(seconds) && seconds >= 0) {
2631
+ return Math.min(seconds * 1e3, MAX_RETRY_AFTER_MS);
2632
+ }
2633
+ const date = Date.parse(trimmed);
2634
+ if (Number.isFinite(date)) {
2635
+ const delta = date - Date.now();
2636
+ return delta > 0 ? Math.min(delta, MAX_RETRY_AFTER_MS) : 0;
2637
+ }
2638
+ return null;
2639
+ }
2640
+ function truncateRawBody(raw) {
2641
+ if (!raw) return void 0;
2642
+ return raw.length > MAX_RAW_BODY_BYTES ? raw.slice(0, MAX_RAW_BODY_BYTES) + "\u2026" : raw;
2643
+ }
2644
+ function findIdempotencyKey(headers) {
2645
+ for (const [k, v] of Object.entries(headers)) {
2646
+ if (k.toLowerCase() === "idempotency-key") return v;
2647
+ }
2648
+ return void 0;
2649
+ }
2650
+ function noop() {
2651
+ }
2652
+ function combineSignals(signals) {
2653
+ const controller = new AbortController();
2654
+ const listeners = [];
2655
+ const dispose = () => {
2656
+ for (const { signal, handler } of listeners) {
2657
+ signal.removeEventListener("abort", handler);
2658
+ }
2659
+ listeners.length = 0;
2660
+ };
2661
+ for (const signal of signals) {
2662
+ if (signal.aborted) {
2663
+ controller.abort(signal.reason);
2664
+ dispose();
2665
+ return { signal: controller.signal, dispose: noop };
2666
+ }
2667
+ const handler = () => {
2668
+ controller.abort(signal.reason);
2669
+ dispose();
2670
+ };
2671
+ signal.addEventListener("abort", handler, { once: true });
2672
+ listeners.push({ signal, handler });
2673
+ }
2674
+ return { signal: controller.signal, dispose };
2675
+ }
2676
+ var SENSITIVE_QUERY_KEYS = /* @__PURE__ */ new Set([
2677
+ "client_secret",
2678
+ "ephemeral_key",
2679
+ "api_key",
2680
+ "publishable_key"
2681
+ ]);
2682
+ function redactUrlForLogging(url) {
2683
+ const qIdx = url.indexOf("?");
2684
+ if (qIdx === -1) return url;
2685
+ const base = url.slice(0, qIdx);
2686
+ const query = url.slice(qIdx + 1);
2687
+ const parts = query.split("&").map((pair) => {
2688
+ const eqIdx = pair.indexOf("=");
2689
+ if (eqIdx === -1) return pair;
2690
+ const key = pair.slice(0, eqIdx);
2691
+ if (SENSITIVE_QUERY_KEYS.has(decodeURIComponent(key).toLowerCase())) {
2692
+ return `${key}=REDACTED`;
2693
+ }
2694
+ return pair;
2695
+ });
2696
+ return `${base}?${parts.join("&")}`;
2697
+ }
2404
2698
  var Delopay = class {
2405
2699
  /**
2406
2700
  * Create a new Delopay client.
@@ -2414,6 +2708,7 @@ var Delopay = class {
2414
2708
  this.timeout = options?.timeout ?? 3e4;
2415
2709
  this.maxRetries = options?.maxRetries ?? 2;
2416
2710
  this.debug = options?.debug ?? false;
2711
+ if (options?.logger !== void 0) this.logger = options.logger;
2417
2712
  if (options?.baseUrl !== void 0) {
2418
2713
  this.baseUrl = options.baseUrl;
2419
2714
  } else if (options?.sandbox) {
@@ -2499,7 +2794,12 @@ var Delopay = class {
2499
2794
  if (options?.query) {
2500
2795
  const params = new URLSearchParams();
2501
2796
  for (const [key, value] of Object.entries(options.query)) {
2502
- if (value !== void 0) {
2797
+ if (value === void 0 || value === null) continue;
2798
+ if (Array.isArray(value)) {
2799
+ for (const v of value) {
2800
+ if (v !== void 0 && v !== null) params.append(key, String(v));
2801
+ }
2802
+ } else {
2503
2803
  params.set(key, String(value));
2504
2804
  }
2505
2805
  }
@@ -2515,46 +2815,94 @@ var Delopay = class {
2515
2815
  if (options?.body) {
2516
2816
  headers["Content-Type"] = "application/json";
2517
2817
  }
2518
- const isRetryable = method === "GET" || method === "DELETE" || "Idempotency-Key" in headers;
2818
+ const idempotencyKey = findIdempotencyKey(headers)?.trim();
2819
+ const isRetryable = method === "GET" || method === "DELETE" || idempotencyKey !== void 0 && idempotencyKey !== "";
2820
+ const serializedBody = options?.body ? JSON.stringify(options.body) : void 0;
2821
+ const callerSignal = options?.signal;
2822
+ if (callerSignal?.aborted) {
2823
+ throw new DelopayError("Request aborted", {
2824
+ status: 0,
2825
+ code: "ABORTED",
2826
+ type: "abort_error"
2827
+ });
2828
+ }
2829
+ const timeoutMs = options?.timeout ?? this.timeout;
2519
2830
  let lastError;
2831
+ let retryAfterOverrideMs = null;
2832
+ const safeUrl = () => redactUrlForLogging(url);
2833
+ const emit = (event, data) => {
2834
+ if (!this.debug) return;
2835
+ if (this.logger) {
2836
+ this.logger(event, data);
2837
+ return;
2838
+ }
2839
+ if (event === "request")
2840
+ console.log(`[delopay] ${data.method} ${data.url}`);
2841
+ else if (event === "response")
2842
+ console.log(
2843
+ `[delopay] ${data.status} ${data.method} ${data.path}`
2844
+ );
2845
+ else
2846
+ console.log(
2847
+ `[delopay] retry ${data.attempt}/${data.maxRetries} ${data.method} ${data.path}`
2848
+ );
2849
+ };
2520
2850
  for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
2521
2851
  if (attempt > 0) {
2522
- const delay = Math.min(500 * 2 ** (attempt - 1), 5e3);
2852
+ const base = Math.min(500 * 2 ** (attempt - 1), 5e3);
2853
+ const jittered = Math.random() * base;
2854
+ const delay = Math.max(retryAfterOverrideMs ?? 0, jittered);
2855
+ retryAfterOverrideMs = null;
2523
2856
  await new Promise((resolve) => setTimeout(resolve, delay));
2524
- if (this.debug) {
2525
- console.log(`[delopay] retry ${attempt}/${this.maxRetries} ${method} ${path}`);
2526
- }
2857
+ emit("retry", { attempt, maxRetries: this.maxRetries, method, path });
2527
2858
  }
2528
- const controller = new AbortController();
2529
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
2859
+ const timeoutCtrl = new AbortController();
2860
+ const timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);
2861
+ const combined = combineSignals(
2862
+ callerSignal ? [timeoutCtrl.signal, callerSignal] : [timeoutCtrl.signal]
2863
+ );
2530
2864
  try {
2531
- if (this.debug) {
2532
- console.log(`[delopay] ${method} ${url}`);
2533
- }
2865
+ emit("request", { method, url: safeUrl(), path });
2534
2866
  const response = await fetch(url, {
2535
2867
  method,
2536
2868
  headers,
2537
- body: options?.body ? JSON.stringify(options.body) : void 0,
2538
- signal: controller.signal
2869
+ body: serializedBody,
2870
+ signal: combined.signal
2539
2871
  });
2540
- if (this.debug) {
2541
- console.log(`[delopay] ${response.status} ${method} ${path}`);
2542
- }
2872
+ const requestId = response.headers?.get("x-request-id") ?? response.headers?.get("x-trace-id") ?? void 0;
2873
+ emit("response", { status: response.status, method, path, requestId });
2543
2874
  if (!response.ok) {
2544
- const body = await response.json().catch(() => ({}));
2545
- const err = body.error ?? body;
2875
+ const rawBody = await response.text().catch(() => "");
2876
+ let parsed = {};
2877
+ if (rawBody) {
2878
+ try {
2879
+ parsed = JSON.parse(rawBody);
2880
+ } catch {
2881
+ }
2882
+ }
2883
+ const err = parsed.error ?? parsed;
2546
2884
  const message = err.message ?? `Request failed with status ${response.status}`;
2547
2885
  const code = err.code ?? "";
2548
2886
  const type = err.error_type ?? err.type ?? "";
2887
+ const truncatedRaw = truncateRawBody(rawBody);
2549
2888
  if (response.status === 401) {
2550
- throw new DelopayAuthenticationError(message);
2889
+ throw new DelopayAuthenticationError(message, {
2890
+ requestId,
2891
+ rawBody: truncatedRaw
2892
+ });
2551
2893
  }
2552
2894
  const error = new DelopayError(message, {
2553
2895
  status: response.status,
2554
2896
  code,
2555
- type
2897
+ type,
2898
+ requestId,
2899
+ rawBody: truncatedRaw
2556
2900
  });
2557
- if (response.status >= 500 && isRetryable && attempt < this.maxRetries) {
2901
+ const isTransientStatus = response.status >= 500 || response.status === 429;
2902
+ if (isTransientStatus && isRetryable && attempt < this.maxRetries) {
2903
+ if (response.status === 429) {
2904
+ retryAfterOverrideMs = parseRetryAfter(response.headers?.get("retry-after") ?? null);
2905
+ }
2558
2906
  lastError = error;
2559
2907
  continue;
2560
2908
  }
@@ -2566,7 +2914,14 @@ var Delopay = class {
2566
2914
  if (err instanceof DelopayError || err instanceof DelopayAuthenticationError) {
2567
2915
  throw err;
2568
2916
  }
2569
- if (err instanceof DOMException && err.name === "AbortError") {
2917
+ if (err instanceof Error && err.name === "AbortError") {
2918
+ if (callerSignal?.aborted) {
2919
+ throw new DelopayError("Request aborted", {
2920
+ status: 0,
2921
+ code: "ABORTED",
2922
+ type: "abort_error"
2923
+ });
2924
+ }
2570
2925
  lastError = new DelopayError("Request timed out", {
2571
2926
  status: 0,
2572
2927
  code: "TIMEOUT",
@@ -2587,6 +2942,7 @@ var Delopay = class {
2587
2942
  throw err;
2588
2943
  } finally {
2589
2944
  clearTimeout(timeoutId);
2945
+ combined.dispose();
2590
2946
  }
2591
2947
  }
2592
2948
  throw lastError;