@garuhq/node 4.0.0 → 4.1.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/CHANGELOG.md CHANGED
@@ -3,6 +3,24 @@
3
3
  All notable changes to `@garuhq/node` are documented in this file. Format:
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning: [SemVer](https://semver.org/).
5
5
 
6
+ ## [4.1.0] — 2026-08-22
7
+
8
+ ### Added
9
+
10
+ - `customers.create()`, `charges.refund()`, and
11
+ `installmentPlans.requestRefund()` now attach an `X-Idempotency-Key`
12
+ header automatically (UUIDv4 unless you pass `idempotencyKey`). The
13
+ gateway now caches and replays the first response for 24h, so a network
14
+ retry can no longer register a duplicate customer, open a second refund
15
+ request, or (via `scheduledCharges.create()` — see Fixed below)
16
+ double-book recurring billing.
17
+
18
+ ### Fixed
19
+
20
+ - `scheduledCharges.create()`'s docstring dropped the "the gateway does not
21
+ currently deduplicate" caveat — the backend now enforces it, so a retried
22
+ create is safe by default.
23
+
6
24
  ## [4.0.0] — 2026-08-22
7
25
 
8
26
  **Breaking:** `scheduledCharges` now targets the versioned public API
package/dist/index.cjs CHANGED
@@ -217,7 +217,7 @@ var Charges = class {
217
217
  * phone: '11987654321'
218
218
  * }
219
219
  * });
220
- * console.log(charge.uuid, charge.pix?.code);
220
+ * // charge.uuid, charge.pix?.code
221
221
  *
222
222
  * @example
223
223
  * // Credit card, 2 installments. Server-to-server only (PCI scope).
@@ -262,7 +262,7 @@ var Charges = class {
262
262
  *
263
263
  * @example
264
264
  * const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
265
- * console.log(`${data.length} of ${totalCount} paid charges`);
265
+ * // data.length of totalCount paid charges
266
266
  */
267
267
  async list(params = {}) {
268
268
  const query = {};
@@ -285,15 +285,24 @@ var Charges = class {
285
285
  * charge in `refund_pending`, reaching `refunded` only once the transfer
286
286
  * settles.
287
287
  *
288
+ * For Pix/boleto (which open a refund request instead of an automated
289
+ * reversal), attaches an `X-Idempotency-Key` header automatically — if you
290
+ * don't pass `idempotencyKey`, the SDK generates a UUIDv4. Ignored for
291
+ * card, which reverses automatically and has no manual request to
292
+ * duplicate.
293
+ *
288
294
  * @example
289
295
  * await garu.charges.refund('6f1c9b2e-...'); // full
290
296
  * await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
291
297
  */
292
298
  async refund(uuid, params = {}) {
299
+ const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
293
300
  const body = {};
294
301
  if (params.amount !== void 0) body.amount = params.amount;
295
302
  if (params.reason !== void 0) body.reason = params.reason;
296
- return this.post(`/api/v1/charges/${encodeURIComponent(uuid)}/refund`, body);
303
+ return this.post(`/api/v1/charges/${encodeURIComponent(uuid)}/refund`, body, {
304
+ "X-Idempotency-Key": idempotencyKey
305
+ });
297
306
  }
298
307
  /**
299
308
  * Cancel an unpaid charge.
@@ -318,7 +327,11 @@ var Charges = class {
318
327
  }
319
328
  post(url, body, headers) {
320
329
  return this.http.call(
321
- (signal) => this.http.client.POST(url, { body, headers, signal })
330
+ (signal) => this.http.client.POST(url, {
331
+ body,
332
+ headers,
333
+ signal
334
+ })
322
335
  );
323
336
  }
324
337
  };
@@ -507,6 +520,11 @@ var InstallmentPlans = class {
507
520
  * team. Transfer the money to the buyer yourself, then close it with
508
521
  * `garu.refundRequests.confirm`.
509
522
  *
523
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
524
+ * `idempotencyKey`, the SDK generates a UUIDv4. The backend already dedupes
525
+ * a second pending request for the same carnê, so this is mainly
526
+ * defense-in-depth for the request-in-flight window.
527
+ *
510
528
  * @example
511
529
  * const request = await garu.installmentPlans.requestRefund(uuid, {
512
530
  * reason: 'Produto não entregue'
@@ -515,9 +533,12 @@ var InstallmentPlans = class {
515
533
  * request.amount; // defaults to everything the carnê collected
516
534
  */
517
535
  async requestRefund(uuid, params = {}) {
536
+ const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
537
+ const { idempotencyKey: _omit, ...body } = params;
518
538
  return this.http.call(
519
539
  (signal) => this.http.client.POST(`/api/v1/installment-plans/${uuid}/refund-requests`, {
520
- body: params,
540
+ body,
541
+ headers: { "X-Idempotency-Key": idempotencyKey },
521
542
  signal
522
543
  }).then((r) => r)
523
544
  );
@@ -625,6 +646,10 @@ var Customers = class {
625
646
  /**
626
647
  * Register a customer for the current seller.
627
648
  *
649
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
650
+ * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the same key
651
+ * returns the originally-created/matched customer for 24h.
652
+ *
628
653
  * @example
629
654
  * const customer = await garu.customers.create({
630
655
  * name: 'Maria Silva',
@@ -636,9 +661,12 @@ var Customers = class {
636
661
  * customer.uuid;
637
662
  */
638
663
  async create(params) {
664
+ const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
665
+ const { idempotencyKey: _omit, ...body } = params;
639
666
  return this.http.call(
640
667
  (signal) => this.http.client.POST("/api/v1/customers", {
641
- body: params,
668
+ body,
669
+ headers: { "X-Idempotency-Key": idempotencyKey },
642
670
  signal
643
671
  }).then((r) => r)
644
672
  );
@@ -942,13 +970,10 @@ var ScheduledCharges = class {
942
970
  }
943
971
  http;
944
972
  /**
945
- * Create a new scheduled charge. The SDK attaches an `X-Idempotency-Key`
946
- * header (UUIDv4 unless you pass `idempotencyKey`), but the gateway does
947
- * not currently deduplicate `/scheduled-charges` creates against it a
948
- * retry after a network failure can create more than one series. Pair
949
- * this with your own retry-suppression (e.g. check `list` for an existing
950
- * series with the same `externalReference`) if that matters for your
951
- * integration.
973
+ * Create a new scheduled charge. Attaches an `X-Idempotency-Key` header
974
+ * automatically if you don't pass `idempotencyKey`, the SDK generates a
975
+ * UUIDv4. Safe to retry: the same key returns the originally-created
976
+ * series for 24h instead of double-booking recurring billing.
952
977
  *
953
978
  * @example
954
979
  * const charge = await garu.scheduledCharges.create({
package/dist/index.d.cts CHANGED
@@ -219,6 +219,13 @@ interface RefundChargeParams {
219
219
  amount?: number;
220
220
  /** Free-form reason stored on the refund. */
221
221
  reason?: string;
222
+ /**
223
+ * Optional idempotency key for safe retries. The SDK auto-generates a
224
+ * UUIDv4 when omitted and forwards it as `X-Idempotency-Key`. Only used
225
+ * for Pix/boleto, which open a refund request instead of an automated
226
+ * reversal — ignored for card, which has no manual request to duplicate.
227
+ */
228
+ idempotencyKey?: string;
222
229
  }
223
230
  interface ListChargesParams {
224
231
  /** Page number (1-based). Default: 1. */
@@ -324,6 +331,13 @@ interface CreateCustomerParams {
324
331
  city?: string;
325
332
  /** 2-letter uppercase state code, e.g. `SP`. */
326
333
  state?: string;
334
+ /**
335
+ * Optional idempotency key for safe retries. The SDK auto-generates a
336
+ * UUIDv4 when omitted and forwards it as `X-Idempotency-Key`. Document
337
+ * uniqueness already merges a retried create into the same customer, so
338
+ * this mainly protects registrations with no document set.
339
+ */
340
+ idempotencyKey?: string;
327
341
  }
328
342
  interface UpdateCustomerParams {
329
343
  name?: string;
@@ -1051,6 +1065,13 @@ interface RequestPlanRefundParams {
1051
1065
  /** Defaults to everything the carnê has collected. */
1052
1066
  amount?: number;
1053
1067
  reason?: string;
1068
+ /**
1069
+ * Optional idempotency key for safe retries. The SDK auto-generates a
1070
+ * UUIDv4 when omitted and forwards it as `X-Idempotency-Key`. The backend
1071
+ * already dedupes a second pending request for the same carnê, so this is
1072
+ * mainly defense-in-depth for the request-in-flight window.
1073
+ */
1074
+ idempotencyKey?: string;
1054
1075
  }
1055
1076
  interface ListRefundRequestsParams {
1056
1077
  page?: number;
@@ -1095,7 +1116,7 @@ declare class Charges {
1095
1116
  * phone: '11987654321'
1096
1117
  * }
1097
1118
  * });
1098
- * console.log(charge.uuid, charge.pix?.code);
1119
+ * // charge.uuid, charge.pix?.code
1099
1120
  *
1100
1121
  * @example
1101
1122
  * // Credit card, 2 installments. Server-to-server only (PCI scope).
@@ -1127,7 +1148,7 @@ declare class Charges {
1127
1148
  *
1128
1149
  * @example
1129
1150
  * const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
1130
- * console.log(`${data.length} of ${totalCount} paid charges`);
1151
+ * // data.length of totalCount paid charges
1131
1152
  */
1132
1153
  list(params?: ListChargesParams): Promise<ChargeList>;
1133
1154
  /**
@@ -1137,6 +1158,12 @@ declare class Charges {
1137
1158
  * charge in `refund_pending`, reaching `refunded` only once the transfer
1138
1159
  * settles.
1139
1160
  *
1161
+ * For Pix/boleto (which open a refund request instead of an automated
1162
+ * reversal), attaches an `X-Idempotency-Key` header automatically — if you
1163
+ * don't pass `idempotencyKey`, the SDK generates a UUIDv4. Ignored for
1164
+ * card, which reverses automatically and has no manual request to
1165
+ * duplicate.
1166
+ *
1140
1167
  * @example
1141
1168
  * await garu.charges.refund('6f1c9b2e-...'); // full
1142
1169
  * await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
@@ -1283,6 +1310,11 @@ declare class InstallmentPlans {
1283
1310
  * team. Transfer the money to the buyer yourself, then close it with
1284
1311
  * `garu.refundRequests.confirm`.
1285
1312
  *
1313
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
1314
+ * `idempotencyKey`, the SDK generates a UUIDv4. The backend already dedupes
1315
+ * a second pending request for the same carnê, so this is mainly
1316
+ * defense-in-depth for the request-in-flight window.
1317
+ *
1286
1318
  * @example
1287
1319
  * const request = await garu.installmentPlans.requestRefund(uuid, {
1288
1320
  * reason: 'Produto não entregue'
@@ -1372,6 +1404,10 @@ declare class Customers {
1372
1404
  /**
1373
1405
  * Register a customer for the current seller.
1374
1406
  *
1407
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
1408
+ * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the same key
1409
+ * returns the originally-created/matched customer for 24h.
1410
+ *
1375
1411
  * @example
1376
1412
  * const customer = await garu.customers.create({
1377
1413
  * name: 'Maria Silva',
@@ -1593,13 +1629,10 @@ declare class ScheduledCharges {
1593
1629
  private readonly http;
1594
1630
  constructor(http: HttpClient);
1595
1631
  /**
1596
- * Create a new scheduled charge. The SDK attaches an `X-Idempotency-Key`
1597
- * header (UUIDv4 unless you pass `idempotencyKey`), but the gateway does
1598
- * not currently deduplicate `/scheduled-charges` creates against it a
1599
- * retry after a network failure can create more than one series. Pair
1600
- * this with your own retry-suppression (e.g. check `list` for an existing
1601
- * series with the same `externalReference`) if that matters for your
1602
- * integration.
1632
+ * Create a new scheduled charge. Attaches an `X-Idempotency-Key` header
1633
+ * automatically if you don't pass `idempotencyKey`, the SDK generates a
1634
+ * UUIDv4. Safe to retry: the same key returns the originally-created
1635
+ * series for 24h instead of double-booking recurring billing.
1603
1636
  *
1604
1637
  * @example
1605
1638
  * const charge = await garu.scheduledCharges.create({
package/dist/index.d.ts CHANGED
@@ -219,6 +219,13 @@ interface RefundChargeParams {
219
219
  amount?: number;
220
220
  /** Free-form reason stored on the refund. */
221
221
  reason?: string;
222
+ /**
223
+ * Optional idempotency key for safe retries. The SDK auto-generates a
224
+ * UUIDv4 when omitted and forwards it as `X-Idempotency-Key`. Only used
225
+ * for Pix/boleto, which open a refund request instead of an automated
226
+ * reversal — ignored for card, which has no manual request to duplicate.
227
+ */
228
+ idempotencyKey?: string;
222
229
  }
223
230
  interface ListChargesParams {
224
231
  /** Page number (1-based). Default: 1. */
@@ -324,6 +331,13 @@ interface CreateCustomerParams {
324
331
  city?: string;
325
332
  /** 2-letter uppercase state code, e.g. `SP`. */
326
333
  state?: string;
334
+ /**
335
+ * Optional idempotency key for safe retries. The SDK auto-generates a
336
+ * UUIDv4 when omitted and forwards it as `X-Idempotency-Key`. Document
337
+ * uniqueness already merges a retried create into the same customer, so
338
+ * this mainly protects registrations with no document set.
339
+ */
340
+ idempotencyKey?: string;
327
341
  }
328
342
  interface UpdateCustomerParams {
329
343
  name?: string;
@@ -1051,6 +1065,13 @@ interface RequestPlanRefundParams {
1051
1065
  /** Defaults to everything the carnê has collected. */
1052
1066
  amount?: number;
1053
1067
  reason?: string;
1068
+ /**
1069
+ * Optional idempotency key for safe retries. The SDK auto-generates a
1070
+ * UUIDv4 when omitted and forwards it as `X-Idempotency-Key`. The backend
1071
+ * already dedupes a second pending request for the same carnê, so this is
1072
+ * mainly defense-in-depth for the request-in-flight window.
1073
+ */
1074
+ idempotencyKey?: string;
1054
1075
  }
1055
1076
  interface ListRefundRequestsParams {
1056
1077
  page?: number;
@@ -1095,7 +1116,7 @@ declare class Charges {
1095
1116
  * phone: '11987654321'
1096
1117
  * }
1097
1118
  * });
1098
- * console.log(charge.uuid, charge.pix?.code);
1119
+ * // charge.uuid, charge.pix?.code
1099
1120
  *
1100
1121
  * @example
1101
1122
  * // Credit card, 2 installments. Server-to-server only (PCI scope).
@@ -1127,7 +1148,7 @@ declare class Charges {
1127
1148
  *
1128
1149
  * @example
1129
1150
  * const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
1130
- * console.log(`${data.length} of ${totalCount} paid charges`);
1151
+ * // data.length of totalCount paid charges
1131
1152
  */
1132
1153
  list(params?: ListChargesParams): Promise<ChargeList>;
1133
1154
  /**
@@ -1137,6 +1158,12 @@ declare class Charges {
1137
1158
  * charge in `refund_pending`, reaching `refunded` only once the transfer
1138
1159
  * settles.
1139
1160
  *
1161
+ * For Pix/boleto (which open a refund request instead of an automated
1162
+ * reversal), attaches an `X-Idempotency-Key` header automatically — if you
1163
+ * don't pass `idempotencyKey`, the SDK generates a UUIDv4. Ignored for
1164
+ * card, which reverses automatically and has no manual request to
1165
+ * duplicate.
1166
+ *
1140
1167
  * @example
1141
1168
  * await garu.charges.refund('6f1c9b2e-...'); // full
1142
1169
  * await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
@@ -1283,6 +1310,11 @@ declare class InstallmentPlans {
1283
1310
  * team. Transfer the money to the buyer yourself, then close it with
1284
1311
  * `garu.refundRequests.confirm`.
1285
1312
  *
1313
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
1314
+ * `idempotencyKey`, the SDK generates a UUIDv4. The backend already dedupes
1315
+ * a second pending request for the same carnê, so this is mainly
1316
+ * defense-in-depth for the request-in-flight window.
1317
+ *
1286
1318
  * @example
1287
1319
  * const request = await garu.installmentPlans.requestRefund(uuid, {
1288
1320
  * reason: 'Produto não entregue'
@@ -1372,6 +1404,10 @@ declare class Customers {
1372
1404
  /**
1373
1405
  * Register a customer for the current seller.
1374
1406
  *
1407
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
1408
+ * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the same key
1409
+ * returns the originally-created/matched customer for 24h.
1410
+ *
1375
1411
  * @example
1376
1412
  * const customer = await garu.customers.create({
1377
1413
  * name: 'Maria Silva',
@@ -1593,13 +1629,10 @@ declare class ScheduledCharges {
1593
1629
  private readonly http;
1594
1630
  constructor(http: HttpClient);
1595
1631
  /**
1596
- * Create a new scheduled charge. The SDK attaches an `X-Idempotency-Key`
1597
- * header (UUIDv4 unless you pass `idempotencyKey`), but the gateway does
1598
- * not currently deduplicate `/scheduled-charges` creates against it a
1599
- * retry after a network failure can create more than one series. Pair
1600
- * this with your own retry-suppression (e.g. check `list` for an existing
1601
- * series with the same `externalReference`) if that matters for your
1602
- * integration.
1632
+ * Create a new scheduled charge. Attaches an `X-Idempotency-Key` header
1633
+ * automatically if you don't pass `idempotencyKey`, the SDK generates a
1634
+ * UUIDv4. Safe to retry: the same key returns the originally-created
1635
+ * series for 24h instead of double-booking recurring billing.
1603
1636
  *
1604
1637
  * @example
1605
1638
  * const charge = await garu.scheduledCharges.create({
package/dist/index.js CHANGED
@@ -211,7 +211,7 @@ var Charges = class {
211
211
  * phone: '11987654321'
212
212
  * }
213
213
  * });
214
- * console.log(charge.uuid, charge.pix?.code);
214
+ * // charge.uuid, charge.pix?.code
215
215
  *
216
216
  * @example
217
217
  * // Credit card, 2 installments. Server-to-server only (PCI scope).
@@ -256,7 +256,7 @@ var Charges = class {
256
256
  *
257
257
  * @example
258
258
  * const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
259
- * console.log(`${data.length} of ${totalCount} paid charges`);
259
+ * // data.length of totalCount paid charges
260
260
  */
261
261
  async list(params = {}) {
262
262
  const query = {};
@@ -279,15 +279,24 @@ var Charges = class {
279
279
  * charge in `refund_pending`, reaching `refunded` only once the transfer
280
280
  * settles.
281
281
  *
282
+ * For Pix/boleto (which open a refund request instead of an automated
283
+ * reversal), attaches an `X-Idempotency-Key` header automatically — if you
284
+ * don't pass `idempotencyKey`, the SDK generates a UUIDv4. Ignored for
285
+ * card, which reverses automatically and has no manual request to
286
+ * duplicate.
287
+ *
282
288
  * @example
283
289
  * await garu.charges.refund('6f1c9b2e-...'); // full
284
290
  * await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
285
291
  */
286
292
  async refund(uuid, params = {}) {
293
+ const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
287
294
  const body = {};
288
295
  if (params.amount !== void 0) body.amount = params.amount;
289
296
  if (params.reason !== void 0) body.reason = params.reason;
290
- return this.post(`/api/v1/charges/${encodeURIComponent(uuid)}/refund`, body);
297
+ return this.post(`/api/v1/charges/${encodeURIComponent(uuid)}/refund`, body, {
298
+ "X-Idempotency-Key": idempotencyKey
299
+ });
291
300
  }
292
301
  /**
293
302
  * Cancel an unpaid charge.
@@ -312,7 +321,11 @@ var Charges = class {
312
321
  }
313
322
  post(url, body, headers) {
314
323
  return this.http.call(
315
- (signal) => this.http.client.POST(url, { body, headers, signal })
324
+ (signal) => this.http.client.POST(url, {
325
+ body,
326
+ headers,
327
+ signal
328
+ })
316
329
  );
317
330
  }
318
331
  };
@@ -501,6 +514,11 @@ var InstallmentPlans = class {
501
514
  * team. Transfer the money to the buyer yourself, then close it with
502
515
  * `garu.refundRequests.confirm`.
503
516
  *
517
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
518
+ * `idempotencyKey`, the SDK generates a UUIDv4. The backend already dedupes
519
+ * a second pending request for the same carnê, so this is mainly
520
+ * defense-in-depth for the request-in-flight window.
521
+ *
504
522
  * @example
505
523
  * const request = await garu.installmentPlans.requestRefund(uuid, {
506
524
  * reason: 'Produto não entregue'
@@ -509,9 +527,12 @@ var InstallmentPlans = class {
509
527
  * request.amount; // defaults to everything the carnê collected
510
528
  */
511
529
  async requestRefund(uuid, params = {}) {
530
+ const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
531
+ const { idempotencyKey: _omit, ...body } = params;
512
532
  return this.http.call(
513
533
  (signal) => this.http.client.POST(`/api/v1/installment-plans/${uuid}/refund-requests`, {
514
- body: params,
534
+ body,
535
+ headers: { "X-Idempotency-Key": idempotencyKey },
515
536
  signal
516
537
  }).then((r) => r)
517
538
  );
@@ -619,6 +640,10 @@ var Customers = class {
619
640
  /**
620
641
  * Register a customer for the current seller.
621
642
  *
643
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
644
+ * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the same key
645
+ * returns the originally-created/matched customer for 24h.
646
+ *
622
647
  * @example
623
648
  * const customer = await garu.customers.create({
624
649
  * name: 'Maria Silva',
@@ -630,9 +655,12 @@ var Customers = class {
630
655
  * customer.uuid;
631
656
  */
632
657
  async create(params) {
658
+ const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
659
+ const { idempotencyKey: _omit, ...body } = params;
633
660
  return this.http.call(
634
661
  (signal) => this.http.client.POST("/api/v1/customers", {
635
- body: params,
662
+ body,
663
+ headers: { "X-Idempotency-Key": idempotencyKey },
636
664
  signal
637
665
  }).then((r) => r)
638
666
  );
@@ -936,13 +964,10 @@ var ScheduledCharges = class {
936
964
  }
937
965
  http;
938
966
  /**
939
- * Create a new scheduled charge. The SDK attaches an `X-Idempotency-Key`
940
- * header (UUIDv4 unless you pass `idempotencyKey`), but the gateway does
941
- * not currently deduplicate `/scheduled-charges` creates against it a
942
- * retry after a network failure can create more than one series. Pair
943
- * this with your own retry-suppression (e.g. check `list` for an existing
944
- * series with the same `externalReference`) if that matters for your
945
- * integration.
967
+ * Create a new scheduled charge. Attaches an `X-Idempotency-Key` header
968
+ * automatically if you don't pass `idempotencyKey`, the SDK generates a
969
+ * UUIDv4. Safe to retry: the same key returns the originally-created
970
+ * series for 24h instead of double-booking recurring billing.
946
971
  *
947
972
  * @example
948
973
  * const charge = await garu.scheduledCharges.create({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@garuhq/node",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "Official Node.js / TypeScript SDK for the Garu payment gateway.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://garu.com.br",