@garuhq/node 3.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 +83 -14
- package/README.md +29 -22
- package/dist/index.cjs +55 -28
- package/dist/index.d.cts +69 -14
- package/dist/index.d.ts +69 -14
- package/dist/index.js +55 -28
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,72 @@
|
|
|
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
|
+
|
|
24
|
+
## [4.0.0] — 2026-08-22
|
|
25
|
+
|
|
26
|
+
**Breaking:** `scheduledCharges` now targets the versioned public API
|
|
27
|
+
`/api/v1/scheduled-charges`. `id` was already a stable, non-enumerable
|
|
28
|
+
string (`sch_...`) — no identifier change — but the list envelope shape
|
|
29
|
+
changed. If you use `garu.scheduledCharges.*`, read the migration below.
|
|
30
|
+
|
|
31
|
+
### Breaking
|
|
32
|
+
|
|
33
|
+
- **`scheduledCharges` moved to `/api/v1/scheduled-charges`.**
|
|
34
|
+
- **`scheduledCharges.list()` and `.listAttempts()` now return
|
|
35
|
+
`{ data, count, totalCount, totalPages }`** (was `{ data, meta }`).
|
|
36
|
+
- No method signatures changed — every method already took/returned the
|
|
37
|
+
same shapes, since `id` was never a numeric internal id here.
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- `ScheduledChargeRecord` now explicitly types `recurrence`,
|
|
42
|
+
`cancelAtPeriodEnd`, `trialEndsAt`, and `subscriptionId` (previously only
|
|
43
|
+
reachable via the type's index signature, untyped).
|
|
44
|
+
- Test coverage for `cancelRecurrence`, `setCancelAtPeriodEnd`,
|
|
45
|
+
`changePaymentMethod`, `clearPaymentMethod`, and `listAttempts` — none of
|
|
46
|
+
these five methods had a single test before this release.
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- `ScheduledChargeLinkedTransaction.value`'s docstring claimed centavos;
|
|
51
|
+
`/api/v1/charges`' own mapper treats the same `transaction.value` column
|
|
52
|
+
as decimal reais with no conversion. Corrected to match reality — this is
|
|
53
|
+
a documentation fix, not a behavior or wire-format change.
|
|
54
|
+
- `scheduledCharges.create()`'s docstring claimed the SDK's
|
|
55
|
+
`X-Idempotency-Key` prevents duplicate creates on retry. The gateway does
|
|
56
|
+
not deduplicate `/scheduled-charges` creates against it (same pre-existing
|
|
57
|
+
gap as `webhookEvents.resend()` had). Corrected the docstring; the header
|
|
58
|
+
is still sent (harmless) in case the gateway adds this later.
|
|
59
|
+
|
|
60
|
+
### Migration
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// before (≤ 3.x)
|
|
64
|
+
const { data, meta } = await garu.scheduledCharges.list({ status: 'overdue' });
|
|
65
|
+
meta.total; // number
|
|
66
|
+
|
|
67
|
+
// after (4.0.0)
|
|
68
|
+
const { data, totalCount } = await garu.scheduledCharges.list({ status: 'overdue' });
|
|
69
|
+
totalCount; // number
|
|
70
|
+
```
|
|
71
|
+
|
|
6
72
|
## [3.0.0] — 2026-08-22
|
|
7
73
|
|
|
8
74
|
**Breaking:** `webhookEvents` now targets the versioned public API
|
|
@@ -34,16 +100,16 @@ read the migration below.
|
|
|
34
100
|
// before (0.x – 2.x)
|
|
35
101
|
const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
|
|
36
102
|
const event = failed.data[0];
|
|
37
|
-
event.id;
|
|
103
|
+
event.id; // number
|
|
38
104
|
const clone = await garu.webhookEvents.resend(event.id);
|
|
39
|
-
clone.manualResendOf === event.id;
|
|
105
|
+
clone.manualResendOf === event.id; // true
|
|
40
106
|
|
|
41
107
|
// after (3.0.0)
|
|
42
108
|
const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
|
|
43
109
|
const event = failed.data[0];
|
|
44
|
-
event.uuid;
|
|
110
|
+
event.uuid; // string
|
|
45
111
|
const clone = await garu.webhookEvents.resend(event.uuid);
|
|
46
|
-
clone.manualResendOf === event.uuid;
|
|
112
|
+
clone.manualResendOf === event.uuid; // true
|
|
47
113
|
```
|
|
48
114
|
|
|
49
115
|
## [2.0.0] — 2026-08-22
|
|
@@ -78,14 +144,14 @@ keyed on `uuid`. If you use `garu.customers.*`, read the migration below.
|
|
|
78
144
|
```ts
|
|
79
145
|
// before (1.x)
|
|
80
146
|
const c = await garu.customers.create({ name, email, document, phone, personType });
|
|
81
|
-
c.id;
|
|
147
|
+
c.id; // number
|
|
82
148
|
const one = await garu.customers.get(c.id);
|
|
83
149
|
await garu.customers.update(c.id, { name: 'Maria Santos' });
|
|
84
150
|
await garu.customers.delete(c.id);
|
|
85
151
|
|
|
86
152
|
// after (2.0.0)
|
|
87
153
|
const c = await garu.customers.create({ name, email, document, phone, personType });
|
|
88
|
-
c.uuid;
|
|
154
|
+
c.uuid; // string
|
|
89
155
|
const one = await garu.customers.get(c.uuid);
|
|
90
156
|
await garu.customers.update(c.uuid, { name: 'Maria Santos' });
|
|
91
157
|
const { removed } = await garu.customers.delete(c.uuid);
|
|
@@ -93,7 +159,6 @@ const { removed } = await garu.customers.delete(c.uuid);
|
|
|
93
159
|
|
|
94
160
|
## [1.1.0] — 2026-08-15
|
|
95
161
|
|
|
96
|
-
|
|
97
162
|
### Added
|
|
98
163
|
|
|
99
164
|
- **`garu.installmentPlans` — boleto parcelado (carnê).** One product sold as N
|
|
@@ -170,22 +235,26 @@ webhook-events) changed.
|
|
|
170
235
|
```ts
|
|
171
236
|
// before (0.16.x)
|
|
172
237
|
const c = await garu.charges.create({
|
|
173
|
-
productId,
|
|
238
|
+
productId,
|
|
239
|
+
paymentMethod: 'credit_card',
|
|
240
|
+
customer,
|
|
174
241
|
cardInfo: { cardNumber: '4111…', cvv, expirationDate, holderName, installments: 2 }
|
|
175
242
|
});
|
|
176
|
-
c.id;
|
|
177
|
-
c.paymentMethodId;
|
|
243
|
+
c.id; // number
|
|
244
|
+
c.paymentMethodId; // 'creditcard'
|
|
178
245
|
const one = await garu.charges.get(c.id);
|
|
179
246
|
await garu.charges.refund(c.id, { amount: 1000 }); // "R$10,00" (bug: reais)
|
|
180
247
|
|
|
181
248
|
// after (1.0.0)
|
|
182
249
|
const c = await garu.charges.create({
|
|
183
|
-
productId,
|
|
250
|
+
productId,
|
|
251
|
+
paymentMethod: 'creditCard',
|
|
252
|
+
customer,
|
|
184
253
|
card: { number: '4111…', cvv, expirationDate, holderName, installments: 2 }
|
|
185
254
|
});
|
|
186
|
-
c.uuid;
|
|
187
|
-
c.paymentMethod;
|
|
188
|
-
c.chargedTotal;
|
|
255
|
+
c.uuid; // string
|
|
256
|
+
c.paymentMethod; // 'creditCard'
|
|
257
|
+
c.chargedTotal; // what was actually charged
|
|
189
258
|
const one = await garu.charges.retrieve(c.uuid);
|
|
190
259
|
await garu.charges.refund(c.uuid, { amount: 10.0 }); // R$10,00
|
|
191
260
|
```
|
package/README.md
CHANGED
|
@@ -147,10 +147,13 @@ await garu.charges.refund('6f1c9b2e-…', { amount: 10.0 }); // partial refund (
|
|
|
147
147
|
## Customers
|
|
148
148
|
|
|
149
149
|
Backed by `/api/v1/customers`, keyed on `uuid` — there is no numeric id in
|
|
150
|
-
this shape. `installmentPlans.create`
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
this shape. `installmentPlans.create` still links customers by the internal
|
|
151
|
+
numeric id (unmigrated resource); fetch that id from the dashboard or the
|
|
152
|
+
internal `/api/customers` endpoint until it moves to `/api/v1` too.
|
|
153
|
+
`scheduledCharges.create` also takes the internal numeric `customerId` —
|
|
154
|
+
customers and scheduled charges are on separate `/api/v1` resources, and
|
|
155
|
+
neither exposes a cross-reference between a customer's `uuid` and their
|
|
156
|
+
numeric id yet.
|
|
154
157
|
|
|
155
158
|
| Method | Description |
|
|
156
159
|
| --------------------------------------- | ----------------------------------------------- |
|
|
@@ -206,20 +209,25 @@ await garu.products.portalConfig.patch('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
|
206
209
|
|
|
207
210
|
Bill an existing customer on a future date — one-time or recurring with card tokenization. The Garu drives email reminders, dunning, retries, and the lifecycle state machine.
|
|
208
211
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
|
215
|
-
|
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `
|
|
212
|
+
Backed by `/api/v1/scheduled-charges`. Unlike products/customers/webhook-events,
|
|
213
|
+
`id` here was already a stable, non-enumerable string (`sch_...`) before this
|
|
214
|
+
move — there is no separate uuid and no id change, only the path and the list
|
|
215
|
+
envelope (`totalCount`/`totalPages`, not `meta.total`/`meta.totalPages`).
|
|
216
|
+
|
|
217
|
+
| Method | Description |
|
|
218
|
+
| --------------------------------------- | ------------------------------------------------------------------------- |
|
|
219
|
+
| `create(params)` | Create one-time or recurring schedule. |
|
|
220
|
+
| `list(params?)` | Paginated list with status / type / dueFrom / dueTo / customerId filters. |
|
|
221
|
+
| `get(id)` | Detail bundle: charge + event timeline + linked transactions. |
|
|
222
|
+
| `chargeNow(id)` | Force-bill the current cycle now instead of waiting for the due date. |
|
|
223
|
+
| `markPaid(id, params)` | Mark cycle paid (off-Garu reconciliation). |
|
|
224
|
+
| `postpone(id, params)` | Move the next cycle's due date forward. |
|
|
225
|
+
| `pause(id, params?)` / `resume(id)` | Suspend / re-enable a series. |
|
|
226
|
+
| `cancelRecurrence(id, params?)` | Hard-stop future cycles (recurring only). |
|
|
227
|
+
| `setCancelAtPeriodEnd(id, { enabled })` | Stripe-style soft-cancel; reversible. |
|
|
228
|
+
| `changePaymentMethod(id, params)` | Swap the saved card. |
|
|
229
|
+
| `clearPaymentMethod(id)` | Remove the saved card; future cycles email-with-link. |
|
|
230
|
+
| `listAttempts(id, params?)` | Per-attempt billing log — every silent-charge / retry / mark-paid. |
|
|
223
231
|
|
|
224
232
|
```ts
|
|
225
233
|
// Recurring with 7-day trial. `maxRecoveryDays` caps how long past the due
|
|
@@ -240,11 +248,10 @@ const series = await garu.scheduledCharges.create({
|
|
|
240
248
|
// Idempotent: a cycle already dispatched today reports `already_sent`.
|
|
241
249
|
const result = await garu.scheduledCharges.chargeNow(series.id);
|
|
242
250
|
if (result.outcome === 'failed') {
|
|
243
|
-
|
|
244
|
-
console.error(`${result.message} (${result.reason})`);
|
|
251
|
+
result.reason; // e.g. 'card_expired' or a gateway decline code
|
|
245
252
|
}
|
|
246
253
|
|
|
247
|
-
// Audit why cycle 3 failed
|
|
254
|
+
// Audit why cycle 3 failed
|
|
248
255
|
const { data } = await garu.scheduledCharges.listAttempts(series.id, {
|
|
249
256
|
cycleNumber: 3
|
|
250
257
|
});
|
|
@@ -308,7 +315,7 @@ const series = await garu.scheduledCharges.create({
|
|
|
308
315
|
});
|
|
309
316
|
```
|
|
310
317
|
|
|
311
|
-
Cancel and the rest of the lifecycle use the **same methods** as card-backed series — `cancelRecurrence(id)`, `
|
|
318
|
+
Cancel and the rest of the lifecycle use the **same methods** as card-backed series — `cancelRecurrence(id)`, `setCancelAtPeriodEnd(id, { enabled })`, `pause(id)` / `resume(id)`. The customer can also revoke the authorization directly in their bank app; Garu surfaces that as a `subscription.cancelled` event.
|
|
312
319
|
|
|
313
320
|
### 3. Handle the webhooks
|
|
314
321
|
|
package/dist/index.cjs
CHANGED
|
@@ -217,7 +217,7 @@ var Charges = class {
|
|
|
217
217
|
* phone: '11987654321'
|
|
218
218
|
* }
|
|
219
219
|
* });
|
|
220
|
-
*
|
|
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
|
-
*
|
|
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, {
|
|
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
|
|
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
|
|
668
|
+
body,
|
|
669
|
+
headers: { "X-Idempotency-Key": idempotencyKey },
|
|
642
670
|
signal
|
|
643
671
|
}).then((r) => r)
|
|
644
672
|
);
|
|
@@ -942,9 +970,10 @@ var ScheduledCharges = class {
|
|
|
942
970
|
}
|
|
943
971
|
http;
|
|
944
972
|
/**
|
|
945
|
-
* Create a new scheduled charge.
|
|
946
|
-
*
|
|
947
|
-
*
|
|
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.
|
|
948
977
|
*
|
|
949
978
|
* @example
|
|
950
979
|
* const charge = await garu.scheduledCharges.create({
|
|
@@ -974,7 +1003,7 @@ var ScheduledCharges = class {
|
|
|
974
1003
|
const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
|
|
975
1004
|
const { idempotencyKey: _omit, ...body } = params;
|
|
976
1005
|
return this.http.call(
|
|
977
|
-
(signal) => this.http.client.POST("/api/scheduled-charges", {
|
|
1006
|
+
(signal) => this.http.client.POST("/api/v1/scheduled-charges", {
|
|
978
1007
|
body,
|
|
979
1008
|
headers: { "X-Idempotency-Key": idempotencyKey },
|
|
980
1009
|
signal
|
|
@@ -1009,7 +1038,7 @@ var ScheduledCharges = class {
|
|
|
1009
1038
|
for (const s of statuses) qs.append("status", s);
|
|
1010
1039
|
}
|
|
1011
1040
|
const query = qs.toString();
|
|
1012
|
-
const url = `/api/scheduled-charges${query ? `?${query}` : ""}`;
|
|
1041
|
+
const url = `/api/v1/scheduled-charges${query ? `?${query}` : ""}`;
|
|
1013
1042
|
return this.http.call(
|
|
1014
1043
|
(signal) => this.http.client.GET(url, { signal }).then(
|
|
1015
1044
|
(r) => r
|
|
@@ -1026,7 +1055,7 @@ var ScheduledCharges = class {
|
|
|
1026
1055
|
*/
|
|
1027
1056
|
async get(id) {
|
|
1028
1057
|
return this.http.call(
|
|
1029
|
-
(signal) => this.http.client.GET(`/api/scheduled-charges/${encodeURIComponent(id)}`, {
|
|
1058
|
+
(signal) => this.http.client.GET(`/api/v1/scheduled-charges/${encodeURIComponent(id)}`, {
|
|
1030
1059
|
signal
|
|
1031
1060
|
}).then((r) => r)
|
|
1032
1061
|
);
|
|
@@ -1045,7 +1074,7 @@ var ScheduledCharges = class {
|
|
|
1045
1074
|
async postpone(id, params) {
|
|
1046
1075
|
return this.http.call(
|
|
1047
1076
|
(signal) => this.http.client.POST(
|
|
1048
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/postpone`,
|
|
1077
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/postpone`,
|
|
1049
1078
|
{
|
|
1050
1079
|
body: params,
|
|
1051
1080
|
signal
|
|
@@ -1064,7 +1093,7 @@ var ScheduledCharges = class {
|
|
|
1064
1093
|
async pause(id, params = {}) {
|
|
1065
1094
|
return this.http.call(
|
|
1066
1095
|
(signal) => this.http.client.POST(
|
|
1067
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/pause`,
|
|
1096
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/pause`,
|
|
1068
1097
|
{
|
|
1069
1098
|
body: params,
|
|
1070
1099
|
signal
|
|
@@ -1081,7 +1110,7 @@ var ScheduledCharges = class {
|
|
|
1081
1110
|
async resume(id) {
|
|
1082
1111
|
return this.http.call(
|
|
1083
1112
|
(signal) => this.http.client.POST(
|
|
1084
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/resume`,
|
|
1113
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/resume`,
|
|
1085
1114
|
{
|
|
1086
1115
|
body: {},
|
|
1087
1116
|
signal
|
|
@@ -1115,7 +1144,7 @@ var ScheduledCharges = class {
|
|
|
1115
1144
|
async markPaid(id, params) {
|
|
1116
1145
|
return this.http.call(
|
|
1117
1146
|
(signal) => this.http.client.POST(
|
|
1118
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/mark-paid`,
|
|
1147
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/mark-paid`,
|
|
1119
1148
|
{
|
|
1120
1149
|
body: params,
|
|
1121
1150
|
signal
|
|
@@ -1137,24 +1166,22 @@ var ScheduledCharges = class {
|
|
|
1137
1166
|
* const result = await garu.scheduledCharges.chargeNow('sch_abc123');
|
|
1138
1167
|
* switch (result.outcome) {
|
|
1139
1168
|
* case 'dispatched':
|
|
1140
|
-
*
|
|
1169
|
+
* result.cycleNumber; // billed this cycle
|
|
1141
1170
|
* break;
|
|
1142
1171
|
* case 'already_sent':
|
|
1143
|
-
*
|
|
1144
|
-
* break;
|
|
1172
|
+
* break; // nothing to do
|
|
1145
1173
|
* case 'failed':
|
|
1146
|
-
*
|
|
1147
|
-
* console.error(`Falha na cobrança: ${result.reason}. ${result.message}`);
|
|
1174
|
+
* result.reason; // e.g. 'card_expired' or a gateway decline code
|
|
1148
1175
|
* break;
|
|
1149
1176
|
* case 'not_sent':
|
|
1150
|
-
*
|
|
1177
|
+
* result.reason;
|
|
1151
1178
|
* break;
|
|
1152
1179
|
* }
|
|
1153
1180
|
*/
|
|
1154
1181
|
async chargeNow(id) {
|
|
1155
1182
|
return this.http.call(
|
|
1156
1183
|
(signal) => this.http.client.POST(
|
|
1157
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/charge-now`,
|
|
1184
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/charge-now`,
|
|
1158
1185
|
{
|
|
1159
1186
|
body: {},
|
|
1160
1187
|
signal
|
|
@@ -1176,7 +1203,7 @@ var ScheduledCharges = class {
|
|
|
1176
1203
|
async cancelRecurrence(id, params = {}) {
|
|
1177
1204
|
return this.http.call(
|
|
1178
1205
|
(signal) => this.http.client.POST(
|
|
1179
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/cancel-recurrence`,
|
|
1206
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/cancel-recurrence`,
|
|
1180
1207
|
{
|
|
1181
1208
|
body: params,
|
|
1182
1209
|
signal
|
|
@@ -1196,7 +1223,7 @@ var ScheduledCharges = class {
|
|
|
1196
1223
|
async setCancelAtPeriodEnd(id, params) {
|
|
1197
1224
|
return this.http.call(
|
|
1198
1225
|
(signal) => this.http.client.POST(
|
|
1199
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/cancel-at-period-end`,
|
|
1226
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/cancel-at-period-end`,
|
|
1200
1227
|
{
|
|
1201
1228
|
body: params,
|
|
1202
1229
|
signal
|
|
@@ -1215,7 +1242,7 @@ var ScheduledCharges = class {
|
|
|
1215
1242
|
async changePaymentMethod(id, params) {
|
|
1216
1243
|
return this.http.call(
|
|
1217
1244
|
(signal) => this.http.client.POST(
|
|
1218
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
1245
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
1219
1246
|
{
|
|
1220
1247
|
body: params,
|
|
1221
1248
|
signal
|
|
@@ -1234,7 +1261,7 @@ var ScheduledCharges = class {
|
|
|
1234
1261
|
async clearPaymentMethod(id) {
|
|
1235
1262
|
return this.http.call(
|
|
1236
1263
|
(signal) => this.http.client.DELETE(
|
|
1237
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
1264
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
1238
1265
|
{
|
|
1239
1266
|
body: {},
|
|
1240
1267
|
signal
|
|
@@ -1261,7 +1288,7 @@ var ScheduledCharges = class {
|
|
|
1261
1288
|
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
1262
1289
|
if (params.cycleNumber !== void 0) qs.set("cycleNumber", String(params.cycleNumber));
|
|
1263
1290
|
const query = qs.toString();
|
|
1264
|
-
const url = `/api/scheduled-charges/${encodeURIComponent(id)}/attempts${query ? `?${query}` : ""}`;
|
|
1291
|
+
const url = `/api/v1/scheduled-charges/${encodeURIComponent(id)}/attempts${query ? `?${query}` : ""}`;
|
|
1265
1292
|
return this.http.call(
|
|
1266
1293
|
(signal) => this.http.client.GET(url, { signal }).then(
|
|
1267
1294
|
(r) => r
|
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;
|
|
@@ -390,7 +404,13 @@ interface ScheduledChargeRecord {
|
|
|
390
404
|
/** YYYY-MM-DD in São Paulo time. */
|
|
391
405
|
dueDate: string;
|
|
392
406
|
methods: ScheduledPaymentMethod[];
|
|
407
|
+
recurrence: RecurrenceConfig | null;
|
|
393
408
|
status: ScheduledChargeStatus;
|
|
409
|
+
subscriptionId: number | null;
|
|
410
|
+
/** ISO-8601. Set only when the series was created with `trialDays`. */
|
|
411
|
+
trialEndsAt: string | null;
|
|
412
|
+
/** Recurring only. Toggle with `setCancelAtPeriodEnd`. */
|
|
413
|
+
cancelAtPeriodEnd: boolean;
|
|
394
414
|
externalReference: string | null;
|
|
395
415
|
/**
|
|
396
416
|
* Max days past `dueDate` the daily recovery sweep will still auto-bill a
|
|
@@ -425,7 +445,7 @@ interface ScheduledChargeEvent {
|
|
|
425
445
|
}
|
|
426
446
|
interface ScheduledChargeLinkedTransaction {
|
|
427
447
|
id: number;
|
|
428
|
-
/**
|
|
448
|
+
/** Decimal BRL (e.g. `297.50`), never centavos. */
|
|
429
449
|
value: number;
|
|
430
450
|
paymentMethod: string;
|
|
431
451
|
status: string;
|
|
@@ -438,7 +458,14 @@ interface ScheduledChargeDetail {
|
|
|
438
458
|
events: ScheduledChargeEvent[];
|
|
439
459
|
transactions: ScheduledChargeLinkedTransaction[];
|
|
440
460
|
}
|
|
441
|
-
|
|
461
|
+
interface ScheduledChargeList {
|
|
462
|
+
data: ScheduledChargeRecord[];
|
|
463
|
+
/** Items on this page. */
|
|
464
|
+
count: number;
|
|
465
|
+
/** Total matches across all pages. */
|
|
466
|
+
totalCount: number;
|
|
467
|
+
totalPages: number;
|
|
468
|
+
}
|
|
442
469
|
/** Source of a billing attempt — see SPEC §3.1. */
|
|
443
470
|
type ScheduledChargeAttemptSource = 'cycle1_interactive' | 'silent_charge' | 'card_retry' | 'manual_mark_paid' | 'fallback_pix';
|
|
444
471
|
type ScheduledChargeAttemptStatus = 'pending' | 'succeeded' | 'declined' | 'canceled' | 'errored';
|
|
@@ -460,7 +487,14 @@ interface ScheduledChargeAttempt {
|
|
|
460
487
|
gatewayChargeId: number | null;
|
|
461
488
|
transactionId: number | null;
|
|
462
489
|
}
|
|
463
|
-
|
|
490
|
+
interface ScheduledChargeAttemptList {
|
|
491
|
+
data: ScheduledChargeAttempt[];
|
|
492
|
+
/** Items on this page. */
|
|
493
|
+
count: number;
|
|
494
|
+
/** Total matches across all pages. */
|
|
495
|
+
totalCount: number;
|
|
496
|
+
totalPages: number;
|
|
497
|
+
}
|
|
464
498
|
interface ListScheduledChargeAttemptsParams {
|
|
465
499
|
page?: number;
|
|
466
500
|
limit?: number;
|
|
@@ -1031,6 +1065,13 @@ interface RequestPlanRefundParams {
|
|
|
1031
1065
|
/** Defaults to everything the carnê has collected. */
|
|
1032
1066
|
amount?: number;
|
|
1033
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;
|
|
1034
1075
|
}
|
|
1035
1076
|
interface ListRefundRequestsParams {
|
|
1036
1077
|
page?: number;
|
|
@@ -1075,7 +1116,7 @@ declare class Charges {
|
|
|
1075
1116
|
* phone: '11987654321'
|
|
1076
1117
|
* }
|
|
1077
1118
|
* });
|
|
1078
|
-
*
|
|
1119
|
+
* // charge.uuid, charge.pix?.code
|
|
1079
1120
|
*
|
|
1080
1121
|
* @example
|
|
1081
1122
|
* // Credit card, 2 installments. Server-to-server only (PCI scope).
|
|
@@ -1107,7 +1148,7 @@ declare class Charges {
|
|
|
1107
1148
|
*
|
|
1108
1149
|
* @example
|
|
1109
1150
|
* const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
|
|
1110
|
-
*
|
|
1151
|
+
* // data.length of totalCount paid charges
|
|
1111
1152
|
*/
|
|
1112
1153
|
list(params?: ListChargesParams): Promise<ChargeList>;
|
|
1113
1154
|
/**
|
|
@@ -1117,6 +1158,12 @@ declare class Charges {
|
|
|
1117
1158
|
* charge in `refund_pending`, reaching `refunded` only once the transfer
|
|
1118
1159
|
* settles.
|
|
1119
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
|
+
*
|
|
1120
1167
|
* @example
|
|
1121
1168
|
* await garu.charges.refund('6f1c9b2e-...'); // full
|
|
1122
1169
|
* await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
|
|
@@ -1263,6 +1310,11 @@ declare class InstallmentPlans {
|
|
|
1263
1310
|
* team. Transfer the money to the buyer yourself, then close it with
|
|
1264
1311
|
* `garu.refundRequests.confirm`.
|
|
1265
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
|
+
*
|
|
1266
1318
|
* @example
|
|
1267
1319
|
* const request = await garu.installmentPlans.requestRefund(uuid, {
|
|
1268
1320
|
* reason: 'Produto não entregue'
|
|
@@ -1352,6 +1404,10 @@ declare class Customers {
|
|
|
1352
1404
|
/**
|
|
1353
1405
|
* Register a customer for the current seller.
|
|
1354
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
|
+
*
|
|
1355
1411
|
* @example
|
|
1356
1412
|
* const customer = await garu.customers.create({
|
|
1357
1413
|
* name: 'Maria Silva',
|
|
@@ -1573,9 +1629,10 @@ declare class ScheduledCharges {
|
|
|
1573
1629
|
private readonly http;
|
|
1574
1630
|
constructor(http: HttpClient);
|
|
1575
1631
|
/**
|
|
1576
|
-
* Create a new scheduled charge.
|
|
1577
|
-
*
|
|
1578
|
-
*
|
|
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.
|
|
1579
1636
|
*
|
|
1580
1637
|
* @example
|
|
1581
1638
|
* const charge = await garu.scheduledCharges.create({
|
|
@@ -1692,17 +1749,15 @@ declare class ScheduledCharges {
|
|
|
1692
1749
|
* const result = await garu.scheduledCharges.chargeNow('sch_abc123');
|
|
1693
1750
|
* switch (result.outcome) {
|
|
1694
1751
|
* case 'dispatched':
|
|
1695
|
-
*
|
|
1752
|
+
* result.cycleNumber; // billed this cycle
|
|
1696
1753
|
* break;
|
|
1697
1754
|
* case 'already_sent':
|
|
1698
|
-
*
|
|
1699
|
-
* break;
|
|
1755
|
+
* break; // nothing to do
|
|
1700
1756
|
* case 'failed':
|
|
1701
|
-
*
|
|
1702
|
-
* console.error(`Falha na cobrança: ${result.reason}. ${result.message}`);
|
|
1757
|
+
* result.reason; // e.g. 'card_expired' or a gateway decline code
|
|
1703
1758
|
* break;
|
|
1704
1759
|
* case 'not_sent':
|
|
1705
|
-
*
|
|
1760
|
+
* result.reason;
|
|
1706
1761
|
* break;
|
|
1707
1762
|
* }
|
|
1708
1763
|
*/
|
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;
|
|
@@ -390,7 +404,13 @@ interface ScheduledChargeRecord {
|
|
|
390
404
|
/** YYYY-MM-DD in São Paulo time. */
|
|
391
405
|
dueDate: string;
|
|
392
406
|
methods: ScheduledPaymentMethod[];
|
|
407
|
+
recurrence: RecurrenceConfig | null;
|
|
393
408
|
status: ScheduledChargeStatus;
|
|
409
|
+
subscriptionId: number | null;
|
|
410
|
+
/** ISO-8601. Set only when the series was created with `trialDays`. */
|
|
411
|
+
trialEndsAt: string | null;
|
|
412
|
+
/** Recurring only. Toggle with `setCancelAtPeriodEnd`. */
|
|
413
|
+
cancelAtPeriodEnd: boolean;
|
|
394
414
|
externalReference: string | null;
|
|
395
415
|
/**
|
|
396
416
|
* Max days past `dueDate` the daily recovery sweep will still auto-bill a
|
|
@@ -425,7 +445,7 @@ interface ScheduledChargeEvent {
|
|
|
425
445
|
}
|
|
426
446
|
interface ScheduledChargeLinkedTransaction {
|
|
427
447
|
id: number;
|
|
428
|
-
/**
|
|
448
|
+
/** Decimal BRL (e.g. `297.50`), never centavos. */
|
|
429
449
|
value: number;
|
|
430
450
|
paymentMethod: string;
|
|
431
451
|
status: string;
|
|
@@ -438,7 +458,14 @@ interface ScheduledChargeDetail {
|
|
|
438
458
|
events: ScheduledChargeEvent[];
|
|
439
459
|
transactions: ScheduledChargeLinkedTransaction[];
|
|
440
460
|
}
|
|
441
|
-
|
|
461
|
+
interface ScheduledChargeList {
|
|
462
|
+
data: ScheduledChargeRecord[];
|
|
463
|
+
/** Items on this page. */
|
|
464
|
+
count: number;
|
|
465
|
+
/** Total matches across all pages. */
|
|
466
|
+
totalCount: number;
|
|
467
|
+
totalPages: number;
|
|
468
|
+
}
|
|
442
469
|
/** Source of a billing attempt — see SPEC §3.1. */
|
|
443
470
|
type ScheduledChargeAttemptSource = 'cycle1_interactive' | 'silent_charge' | 'card_retry' | 'manual_mark_paid' | 'fallback_pix';
|
|
444
471
|
type ScheduledChargeAttemptStatus = 'pending' | 'succeeded' | 'declined' | 'canceled' | 'errored';
|
|
@@ -460,7 +487,14 @@ interface ScheduledChargeAttempt {
|
|
|
460
487
|
gatewayChargeId: number | null;
|
|
461
488
|
transactionId: number | null;
|
|
462
489
|
}
|
|
463
|
-
|
|
490
|
+
interface ScheduledChargeAttemptList {
|
|
491
|
+
data: ScheduledChargeAttempt[];
|
|
492
|
+
/** Items on this page. */
|
|
493
|
+
count: number;
|
|
494
|
+
/** Total matches across all pages. */
|
|
495
|
+
totalCount: number;
|
|
496
|
+
totalPages: number;
|
|
497
|
+
}
|
|
464
498
|
interface ListScheduledChargeAttemptsParams {
|
|
465
499
|
page?: number;
|
|
466
500
|
limit?: number;
|
|
@@ -1031,6 +1065,13 @@ interface RequestPlanRefundParams {
|
|
|
1031
1065
|
/** Defaults to everything the carnê has collected. */
|
|
1032
1066
|
amount?: number;
|
|
1033
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;
|
|
1034
1075
|
}
|
|
1035
1076
|
interface ListRefundRequestsParams {
|
|
1036
1077
|
page?: number;
|
|
@@ -1075,7 +1116,7 @@ declare class Charges {
|
|
|
1075
1116
|
* phone: '11987654321'
|
|
1076
1117
|
* }
|
|
1077
1118
|
* });
|
|
1078
|
-
*
|
|
1119
|
+
* // charge.uuid, charge.pix?.code
|
|
1079
1120
|
*
|
|
1080
1121
|
* @example
|
|
1081
1122
|
* // Credit card, 2 installments. Server-to-server only (PCI scope).
|
|
@@ -1107,7 +1148,7 @@ declare class Charges {
|
|
|
1107
1148
|
*
|
|
1108
1149
|
* @example
|
|
1109
1150
|
* const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
|
|
1110
|
-
*
|
|
1151
|
+
* // data.length of totalCount paid charges
|
|
1111
1152
|
*/
|
|
1112
1153
|
list(params?: ListChargesParams): Promise<ChargeList>;
|
|
1113
1154
|
/**
|
|
@@ -1117,6 +1158,12 @@ declare class Charges {
|
|
|
1117
1158
|
* charge in `refund_pending`, reaching `refunded` only once the transfer
|
|
1118
1159
|
* settles.
|
|
1119
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
|
+
*
|
|
1120
1167
|
* @example
|
|
1121
1168
|
* await garu.charges.refund('6f1c9b2e-...'); // full
|
|
1122
1169
|
* await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
|
|
@@ -1263,6 +1310,11 @@ declare class InstallmentPlans {
|
|
|
1263
1310
|
* team. Transfer the money to the buyer yourself, then close it with
|
|
1264
1311
|
* `garu.refundRequests.confirm`.
|
|
1265
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
|
+
*
|
|
1266
1318
|
* @example
|
|
1267
1319
|
* const request = await garu.installmentPlans.requestRefund(uuid, {
|
|
1268
1320
|
* reason: 'Produto não entregue'
|
|
@@ -1352,6 +1404,10 @@ declare class Customers {
|
|
|
1352
1404
|
/**
|
|
1353
1405
|
* Register a customer for the current seller.
|
|
1354
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
|
+
*
|
|
1355
1411
|
* @example
|
|
1356
1412
|
* const customer = await garu.customers.create({
|
|
1357
1413
|
* name: 'Maria Silva',
|
|
@@ -1573,9 +1629,10 @@ declare class ScheduledCharges {
|
|
|
1573
1629
|
private readonly http;
|
|
1574
1630
|
constructor(http: HttpClient);
|
|
1575
1631
|
/**
|
|
1576
|
-
* Create a new scheduled charge.
|
|
1577
|
-
*
|
|
1578
|
-
*
|
|
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.
|
|
1579
1636
|
*
|
|
1580
1637
|
* @example
|
|
1581
1638
|
* const charge = await garu.scheduledCharges.create({
|
|
@@ -1692,17 +1749,15 @@ declare class ScheduledCharges {
|
|
|
1692
1749
|
* const result = await garu.scheduledCharges.chargeNow('sch_abc123');
|
|
1693
1750
|
* switch (result.outcome) {
|
|
1694
1751
|
* case 'dispatched':
|
|
1695
|
-
*
|
|
1752
|
+
* result.cycleNumber; // billed this cycle
|
|
1696
1753
|
* break;
|
|
1697
1754
|
* case 'already_sent':
|
|
1698
|
-
*
|
|
1699
|
-
* break;
|
|
1755
|
+
* break; // nothing to do
|
|
1700
1756
|
* case 'failed':
|
|
1701
|
-
*
|
|
1702
|
-
* console.error(`Falha na cobrança: ${result.reason}. ${result.message}`);
|
|
1757
|
+
* result.reason; // e.g. 'card_expired' or a gateway decline code
|
|
1703
1758
|
* break;
|
|
1704
1759
|
* case 'not_sent':
|
|
1705
|
-
*
|
|
1760
|
+
* result.reason;
|
|
1706
1761
|
* break;
|
|
1707
1762
|
* }
|
|
1708
1763
|
*/
|
package/dist/index.js
CHANGED
|
@@ -211,7 +211,7 @@ var Charges = class {
|
|
|
211
211
|
* phone: '11987654321'
|
|
212
212
|
* }
|
|
213
213
|
* });
|
|
214
|
-
*
|
|
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
|
-
*
|
|
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, {
|
|
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
|
|
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
|
|
662
|
+
body,
|
|
663
|
+
headers: { "X-Idempotency-Key": idempotencyKey },
|
|
636
664
|
signal
|
|
637
665
|
}).then((r) => r)
|
|
638
666
|
);
|
|
@@ -936,9 +964,10 @@ var ScheduledCharges = class {
|
|
|
936
964
|
}
|
|
937
965
|
http;
|
|
938
966
|
/**
|
|
939
|
-
* Create a new scheduled charge.
|
|
940
|
-
*
|
|
941
|
-
*
|
|
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.
|
|
942
971
|
*
|
|
943
972
|
* @example
|
|
944
973
|
* const charge = await garu.scheduledCharges.create({
|
|
@@ -968,7 +997,7 @@ var ScheduledCharges = class {
|
|
|
968
997
|
const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
|
|
969
998
|
const { idempotencyKey: _omit, ...body } = params;
|
|
970
999
|
return this.http.call(
|
|
971
|
-
(signal) => this.http.client.POST("/api/scheduled-charges", {
|
|
1000
|
+
(signal) => this.http.client.POST("/api/v1/scheduled-charges", {
|
|
972
1001
|
body,
|
|
973
1002
|
headers: { "X-Idempotency-Key": idempotencyKey },
|
|
974
1003
|
signal
|
|
@@ -1003,7 +1032,7 @@ var ScheduledCharges = class {
|
|
|
1003
1032
|
for (const s of statuses) qs.append("status", s);
|
|
1004
1033
|
}
|
|
1005
1034
|
const query = qs.toString();
|
|
1006
|
-
const url = `/api/scheduled-charges${query ? `?${query}` : ""}`;
|
|
1035
|
+
const url = `/api/v1/scheduled-charges${query ? `?${query}` : ""}`;
|
|
1007
1036
|
return this.http.call(
|
|
1008
1037
|
(signal) => this.http.client.GET(url, { signal }).then(
|
|
1009
1038
|
(r) => r
|
|
@@ -1020,7 +1049,7 @@ var ScheduledCharges = class {
|
|
|
1020
1049
|
*/
|
|
1021
1050
|
async get(id) {
|
|
1022
1051
|
return this.http.call(
|
|
1023
|
-
(signal) => this.http.client.GET(`/api/scheduled-charges/${encodeURIComponent(id)}`, {
|
|
1052
|
+
(signal) => this.http.client.GET(`/api/v1/scheduled-charges/${encodeURIComponent(id)}`, {
|
|
1024
1053
|
signal
|
|
1025
1054
|
}).then((r) => r)
|
|
1026
1055
|
);
|
|
@@ -1039,7 +1068,7 @@ var ScheduledCharges = class {
|
|
|
1039
1068
|
async postpone(id, params) {
|
|
1040
1069
|
return this.http.call(
|
|
1041
1070
|
(signal) => this.http.client.POST(
|
|
1042
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/postpone`,
|
|
1071
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/postpone`,
|
|
1043
1072
|
{
|
|
1044
1073
|
body: params,
|
|
1045
1074
|
signal
|
|
@@ -1058,7 +1087,7 @@ var ScheduledCharges = class {
|
|
|
1058
1087
|
async pause(id, params = {}) {
|
|
1059
1088
|
return this.http.call(
|
|
1060
1089
|
(signal) => this.http.client.POST(
|
|
1061
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/pause`,
|
|
1090
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/pause`,
|
|
1062
1091
|
{
|
|
1063
1092
|
body: params,
|
|
1064
1093
|
signal
|
|
@@ -1075,7 +1104,7 @@ var ScheduledCharges = class {
|
|
|
1075
1104
|
async resume(id) {
|
|
1076
1105
|
return this.http.call(
|
|
1077
1106
|
(signal) => this.http.client.POST(
|
|
1078
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/resume`,
|
|
1107
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/resume`,
|
|
1079
1108
|
{
|
|
1080
1109
|
body: {},
|
|
1081
1110
|
signal
|
|
@@ -1109,7 +1138,7 @@ var ScheduledCharges = class {
|
|
|
1109
1138
|
async markPaid(id, params) {
|
|
1110
1139
|
return this.http.call(
|
|
1111
1140
|
(signal) => this.http.client.POST(
|
|
1112
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/mark-paid`,
|
|
1141
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/mark-paid`,
|
|
1113
1142
|
{
|
|
1114
1143
|
body: params,
|
|
1115
1144
|
signal
|
|
@@ -1131,24 +1160,22 @@ var ScheduledCharges = class {
|
|
|
1131
1160
|
* const result = await garu.scheduledCharges.chargeNow('sch_abc123');
|
|
1132
1161
|
* switch (result.outcome) {
|
|
1133
1162
|
* case 'dispatched':
|
|
1134
|
-
*
|
|
1163
|
+
* result.cycleNumber; // billed this cycle
|
|
1135
1164
|
* break;
|
|
1136
1165
|
* case 'already_sent':
|
|
1137
|
-
*
|
|
1138
|
-
* break;
|
|
1166
|
+
* break; // nothing to do
|
|
1139
1167
|
* case 'failed':
|
|
1140
|
-
*
|
|
1141
|
-
* console.error(`Falha na cobrança: ${result.reason}. ${result.message}`);
|
|
1168
|
+
* result.reason; // e.g. 'card_expired' or a gateway decline code
|
|
1142
1169
|
* break;
|
|
1143
1170
|
* case 'not_sent':
|
|
1144
|
-
*
|
|
1171
|
+
* result.reason;
|
|
1145
1172
|
* break;
|
|
1146
1173
|
* }
|
|
1147
1174
|
*/
|
|
1148
1175
|
async chargeNow(id) {
|
|
1149
1176
|
return this.http.call(
|
|
1150
1177
|
(signal) => this.http.client.POST(
|
|
1151
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/charge-now`,
|
|
1178
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/charge-now`,
|
|
1152
1179
|
{
|
|
1153
1180
|
body: {},
|
|
1154
1181
|
signal
|
|
@@ -1170,7 +1197,7 @@ var ScheduledCharges = class {
|
|
|
1170
1197
|
async cancelRecurrence(id, params = {}) {
|
|
1171
1198
|
return this.http.call(
|
|
1172
1199
|
(signal) => this.http.client.POST(
|
|
1173
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/cancel-recurrence`,
|
|
1200
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/cancel-recurrence`,
|
|
1174
1201
|
{
|
|
1175
1202
|
body: params,
|
|
1176
1203
|
signal
|
|
@@ -1190,7 +1217,7 @@ var ScheduledCharges = class {
|
|
|
1190
1217
|
async setCancelAtPeriodEnd(id, params) {
|
|
1191
1218
|
return this.http.call(
|
|
1192
1219
|
(signal) => this.http.client.POST(
|
|
1193
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/cancel-at-period-end`,
|
|
1220
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/cancel-at-period-end`,
|
|
1194
1221
|
{
|
|
1195
1222
|
body: params,
|
|
1196
1223
|
signal
|
|
@@ -1209,7 +1236,7 @@ var ScheduledCharges = class {
|
|
|
1209
1236
|
async changePaymentMethod(id, params) {
|
|
1210
1237
|
return this.http.call(
|
|
1211
1238
|
(signal) => this.http.client.POST(
|
|
1212
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
1239
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
1213
1240
|
{
|
|
1214
1241
|
body: params,
|
|
1215
1242
|
signal
|
|
@@ -1228,7 +1255,7 @@ var ScheduledCharges = class {
|
|
|
1228
1255
|
async clearPaymentMethod(id) {
|
|
1229
1256
|
return this.http.call(
|
|
1230
1257
|
(signal) => this.http.client.DELETE(
|
|
1231
|
-
`/api/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
1258
|
+
`/api/v1/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
1232
1259
|
{
|
|
1233
1260
|
body: {},
|
|
1234
1261
|
signal
|
|
@@ -1255,7 +1282,7 @@ var ScheduledCharges = class {
|
|
|
1255
1282
|
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
1256
1283
|
if (params.cycleNumber !== void 0) qs.set("cycleNumber", String(params.cycleNumber));
|
|
1257
1284
|
const query = qs.toString();
|
|
1258
|
-
const url = `/api/scheduled-charges/${encodeURIComponent(id)}/attempts${query ? `?${query}` : ""}`;
|
|
1285
|
+
const url = `/api/v1/scheduled-charges/${encodeURIComponent(id)}/attempts${query ? `?${query}` : ""}`;
|
|
1259
1286
|
return this.http.call(
|
|
1260
1287
|
(signal) => this.http.client.GET(url, { signal }).then(
|
|
1261
1288
|
(r) => r
|