@garuhq/node 0.12.1 → 0.14.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 +57 -1
- package/README.md +150 -62
- package/dist/index.cjs +113 -36
- package/dist/index.d.cts +108 -6
- package/dist/index.d.ts +108 -6
- package/dist/index.js +113 -36
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,62 @@
|
|
|
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
|
+
## [0.14.0] — 2026-05-31
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **Pix Automático support** — Brazil's BACEN auto-debit recurring Pix, where
|
|
11
|
+
the customer authorizes once via a consent QR/link in their bank app and
|
|
12
|
+
cycles 2+ debit silently. All changes are additive; existing
|
|
13
|
+
Card / Pix / Boleto callers are unaffected.
|
|
14
|
+
- `'pix_automatic'` added to the `ScheduledPaymentMethod` union, so
|
|
15
|
+
`scheduledCharges.create({ methods: ['pix_automatic'], ... })` is now
|
|
16
|
+
typed. Recurring-only and requires `productId` (whose product must have
|
|
17
|
+
Pix Automático enabled).
|
|
18
|
+
- `Product.pixAutomatic: boolean` — when `true`, the public subscription
|
|
19
|
+
checkout exposes Pix Automático. Enabled by default; sellers can disable
|
|
20
|
+
it per product.
|
|
21
|
+
- `'pix_automatic'` added to the `ScheduledChargeAttempt.paymentMethod`
|
|
22
|
+
union and to `WirePaymentMethodId`, so transactions/charges read back
|
|
23
|
+
from Pix Automático cycles type-check.
|
|
24
|
+
- README: new **Pix Automático** section — what it is, when to use it, how to
|
|
25
|
+
enable it on a product, creating a `pix_automatic` scheduled charge, and
|
|
26
|
+
branching webhook handlers on `paymentMethod === 'pix_automatic'`.
|
|
27
|
+
|
|
28
|
+
### Notes
|
|
29
|
+
|
|
30
|
+
- No new webhook event names: Pix Automático fires the same
|
|
31
|
+
`subscription.*` / `transaction.*` events as card recurrence. Branch on the
|
|
32
|
+
payload's `paymentMethod` field. Refused debits are **not** retried at the
|
|
33
|
+
network level — Garu fires `subscription.payment_failed` and moves the
|
|
34
|
+
series to `past_due`.
|
|
35
|
+
|
|
36
|
+
## [0.13.0] — 2026-05-25
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- `scheduledCharges.chargeNow(id)` — `POST /api/scheduled-charges/{id}/charge-now`.
|
|
41
|
+
Force-bills the current cycle right now instead of waiting for its due
|
|
42
|
+
date, running the same dispatch the daily billing cron would (customer
|
|
43
|
+
email/notification + outbound webhook + timeline event). Allowed only
|
|
44
|
+
from a billable status (`scheduled` / `due_today`); a recurring series
|
|
45
|
+
must have an open cycle. **Idempotent** — a cycle whose d-day was
|
|
46
|
+
already dispatched reports `already_sent` and does not re-charge.
|
|
47
|
+
Returns `{ outcome, cycleNumber, reason?, message }`:
|
|
48
|
+
- `outcome` is `'dispatched' | 'already_sent' | 'not_sent' | 'failed'`.
|
|
49
|
+
- `reason` (on `not_sent` / `failed`) is one of the documented literals
|
|
50
|
+
(`no_email`, `lock_lost`, `no_saved_payment_method`, `card_expired`,
|
|
51
|
+
`payment_method_missing`, `customer_missing`) or a raw gateway decline
|
|
52
|
+
code.
|
|
53
|
+
- `message` is a ready-to-show pt-BR string.
|
|
54
|
+
- `ChargeNowOutcome`, `ChargeNowReason`, and `ChargeNowResult` types
|
|
55
|
+
exported from the package root.
|
|
56
|
+
- `maxRecoveryDays?: number` (integer 1–365) on
|
|
57
|
+
`CreateScheduledChargeParams` — caps how many days past `dueDate` the
|
|
58
|
+
daily recovery sweep will still auto-bill a missed charge. Omit for the
|
|
59
|
+
system default (14). Also surfaced on the scheduled charge object as
|
|
60
|
+
`ScheduledChargeRecord.maxRecoveryDays: number | null`.
|
|
61
|
+
|
|
6
62
|
## [0.12.1] — 2026-05-19
|
|
7
63
|
|
|
8
64
|
### Fixed
|
|
@@ -30,7 +86,7 @@ All notable changes to `@garuhq/node` are documented in this file. Format:
|
|
|
30
86
|
|
|
31
87
|
- `webhookEvents.resend(id)` — `POST /api/webhook-events/{id}/resend`,
|
|
32
88
|
the audit-trail-preserving counterpart to `retry()`. The backend
|
|
33
|
-
inserts a
|
|
89
|
+
inserts a _clone_ event (new numeric id) that points back at the
|
|
34
90
|
source via `manualResendOf`, then dispatches that clone. The
|
|
35
91
|
original row is untouched, so the historical record of the prior
|
|
36
92
|
failure (status, response status/body, attempts) survives. Works on
|
package/README.md
CHANGED
|
@@ -54,8 +54,8 @@ const charge = await garu.charges.create({
|
|
|
54
54
|
name: 'Maria Silva',
|
|
55
55
|
email: 'maria@exemplo.com.br',
|
|
56
56
|
document: '12345678909', // CPF, digits only
|
|
57
|
-
phone: '11987654321'
|
|
58
|
-
}
|
|
57
|
+
phone: '11987654321'
|
|
58
|
+
}
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
console.log(charge.id, charge.status);
|
|
@@ -78,7 +78,7 @@ const garu = new Garu({ apiKey: process.env.GARU_API_KEY });
|
|
|
78
78
|
const garu = new Garu({
|
|
79
79
|
apiKey: process.env.GARU_API_KEY,
|
|
80
80
|
timeoutMs: 30_000, // default
|
|
81
|
-
maxRetries: 2
|
|
81
|
+
maxRetries: 2 // default (3 total attempts)
|
|
82
82
|
});
|
|
83
83
|
```
|
|
84
84
|
|
|
@@ -101,8 +101,8 @@ const charge = await garu.charges.create({
|
|
|
101
101
|
name: 'Maria Silva',
|
|
102
102
|
email: 'maria@exemplo.com.br',
|
|
103
103
|
document: '12345678909',
|
|
104
|
-
phone: '11987654321'
|
|
105
|
-
}
|
|
104
|
+
phone: '11987654321'
|
|
105
|
+
}
|
|
106
106
|
});
|
|
107
107
|
```
|
|
108
108
|
|
|
@@ -117,14 +117,14 @@ const charge = await garu.charges.create({
|
|
|
117
117
|
holderName: 'MARIA SILVA',
|
|
118
118
|
expirationMonth: '12',
|
|
119
119
|
expirationYear: '2028',
|
|
120
|
-
cvv: '123'
|
|
120
|
+
cvv: '123'
|
|
121
121
|
},
|
|
122
122
|
customer: {
|
|
123
123
|
name: 'Maria Silva',
|
|
124
124
|
email: 'maria@exemplo.com.br',
|
|
125
125
|
document: '12345678909',
|
|
126
|
-
phone: '11987654321'
|
|
127
|
-
}
|
|
126
|
+
phone: '11987654321'
|
|
127
|
+
}
|
|
128
128
|
});
|
|
129
129
|
```
|
|
130
130
|
|
|
@@ -145,13 +145,13 @@ await garu.charges.refund(4472, { amount: 1000 }); // partial refund (R$10.00)
|
|
|
145
145
|
|
|
146
146
|
## Customers
|
|
147
147
|
|
|
148
|
-
| Method
|
|
149
|
-
|
|
|
150
|
-
| `create(params)`
|
|
151
|
-
| `list(params?)`
|
|
152
|
-
| `get(id)`
|
|
153
|
-
| `update(id, params)`
|
|
154
|
-
| `delete(id)`
|
|
148
|
+
| Method | Description |
|
|
149
|
+
| -------------------- | ------------------------------------------ |
|
|
150
|
+
| `create(params)` | Create a new customer. |
|
|
151
|
+
| `list(params?)` | List customers with pagination and search. |
|
|
152
|
+
| `get(id)` | Fetch a single customer by ID. |
|
|
153
|
+
| `update(id, params)` | Update a customer's profile. |
|
|
154
|
+
| `delete(id)` | Delete a customer. |
|
|
155
155
|
|
|
156
156
|
```ts
|
|
157
157
|
const customer = await garu.customers.create({
|
|
@@ -159,7 +159,7 @@ const customer = await garu.customers.create({
|
|
|
159
159
|
email: 'maria@exemplo.com.br',
|
|
160
160
|
document: '12345678909',
|
|
161
161
|
phone: '11987654321',
|
|
162
|
-
personType: 'fisica'
|
|
162
|
+
personType: 'fisica'
|
|
163
163
|
});
|
|
164
164
|
|
|
165
165
|
const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
|
|
@@ -171,26 +171,26 @@ Discover products and customize the per-product portal experience (B2B2C).
|
|
|
171
171
|
|
|
172
172
|
`portalConfig.*` methods accept `productId` as either the product UUID (preferred — same identifier returned by `list()` and webhook payloads) or the legacy numeric id (Garu v0.10.0+).
|
|
173
173
|
|
|
174
|
-
| Method
|
|
175
|
-
|
|
|
176
|
-
| `list(params?)`
|
|
177
|
-
| `get(uuid)`
|
|
178
|
-
| `portalConfig.get(productId)`
|
|
179
|
-
| `portalConfig.set(productId, p)`
|
|
180
|
-
| `portalConfig.patch(productId, p)`
|
|
181
|
-
| `portalConfig.clear(productId)`
|
|
174
|
+
| Method | Description |
|
|
175
|
+
| ---------------------------------- | --------------------------------------------------------------- |
|
|
176
|
+
| `list(params?)` | Paginated list of products for the seller. |
|
|
177
|
+
| `get(uuid)` | Fetch a single product by UUID — same id used by charges. |
|
|
178
|
+
| `portalConfig.get(productId)` | Read per-product portal customization. Returns `null` if unset. |
|
|
179
|
+
| `portalConfig.set(productId, p)` | Upsert with merge — only fields present are written. |
|
|
180
|
+
| `portalConfig.patch(productId, p)` | Same merge semantics as `set` — alias for HTTP-PATCH callers. |
|
|
181
|
+
| `portalConfig.clear(productId)` | Remove the customization; product falls back to seller config. |
|
|
182
182
|
|
|
183
183
|
```ts
|
|
184
184
|
// SaaS de coaching: per-coach branding under one Seller account
|
|
185
185
|
await garu.products.portalConfig.set('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
186
186
|
businessName: 'Coach Maria — Corrida & Trilha',
|
|
187
187
|
primaryColor: '#257264',
|
|
188
|
-
logoUrl: 'https://cdn.exemplo.com/coaches/maria.png'
|
|
188
|
+
logoUrl: 'https://cdn.exemplo.com/coaches/maria.png'
|
|
189
189
|
});
|
|
190
190
|
|
|
191
191
|
// Pass `null` on a field to inherit from the seller-level config
|
|
192
192
|
await garu.products.portalConfig.patch('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
193
|
-
primaryColor: null
|
|
193
|
+
primaryColor: null
|
|
194
194
|
});
|
|
195
195
|
```
|
|
196
196
|
|
|
@@ -198,22 +198,24 @@ await garu.products.portalConfig.patch('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
|
198
198
|
|
|
199
199
|
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.
|
|
200
200
|
|
|
201
|
-
| Method
|
|
202
|
-
|
|
|
203
|
-
| `create(params)`
|
|
204
|
-
| `list(params?)`
|
|
205
|
-
| `get(id)`
|
|
206
|
-
| `
|
|
207
|
-
| `
|
|
208
|
-
| `
|
|
209
|
-
| `
|
|
210
|
-
| `
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
213
|
-
| `
|
|
201
|
+
| Method | Description |
|
|
202
|
+
| ------------------------------------ | --------------------------------------------------------------------------- |
|
|
203
|
+
| `create(params)` | Create one-time or recurring schedule. Auto-attaches `X-Idempotency-Key`. |
|
|
204
|
+
| `list(params?)` | Paginated list with status / type / dueFrom / dueTo / customerId filters. |
|
|
205
|
+
| `get(id)` | Detail bundle: charge + event timeline + linked transactions. |
|
|
206
|
+
| `chargeNow(id)` | Force-bill the current cycle now instead of waiting for the due date. |
|
|
207
|
+
| `markPaid(id, params)` | Mark cycle paid (off-Garu reconciliation). |
|
|
208
|
+
| `postpone(id, params)` | Move the next cycle's due date forward. |
|
|
209
|
+
| `pause(id, params?)` / `resume(id)` | Suspend / re-enable a series. |
|
|
210
|
+
| `cancelRecurrence(id, params?)` | Hard-stop future cycles (recurring only). |
|
|
211
|
+
| `cancelAtPeriodEnd(id, { enabled })` | Stripe-style soft-cancel; reversible. |
|
|
212
|
+
| `changePaymentMethod(id, params)` | Swap the saved card. |
|
|
213
|
+
| `clearPaymentMethod(id)` | Remove the saved card; future cycles email-with-link. |
|
|
214
|
+
| `listAttempts(id, params?)` | Per-attempt billing log — every silent-charge / retry / mark-paid (v0.8.2). |
|
|
214
215
|
|
|
215
216
|
```ts
|
|
216
|
-
// Recurring with 7-day trial
|
|
217
|
+
// Recurring with 7-day trial. `maxRecoveryDays` caps how long past the due
|
|
218
|
+
// date the daily recovery sweep keeps auto-billing a missed charge (default 14).
|
|
217
219
|
const series = await garu.scheduledCharges.create({
|
|
218
220
|
customerId: 42,
|
|
219
221
|
productId: 17,
|
|
@@ -223,11 +225,20 @@ const series = await garu.scheduledCharges.create({
|
|
|
223
225
|
methods: ['card', 'pix'],
|
|
224
226
|
recurrence: { interval: 'monthly' },
|
|
225
227
|
trialDays: 7,
|
|
228
|
+
maxRecoveryDays: 30
|
|
226
229
|
});
|
|
227
230
|
|
|
231
|
+
// Force-bill the current cycle now instead of waiting for the due date.
|
|
232
|
+
// Idempotent: a cycle already dispatched today reports `already_sent`.
|
|
233
|
+
const result = await garu.scheduledCharges.chargeNow(series.id);
|
|
234
|
+
if (result.outcome === 'failed') {
|
|
235
|
+
// result.reason is e.g. 'card_expired' or a gateway decline code
|
|
236
|
+
console.error(`${result.message} (${result.reason})`);
|
|
237
|
+
}
|
|
238
|
+
|
|
228
239
|
// Audit why cycle 3 failed (v0.8.2)
|
|
229
240
|
const { data } = await garu.scheduledCharges.listAttempts(series.id, {
|
|
230
|
-
cycleNumber: 3
|
|
241
|
+
cycleNumber: 3
|
|
231
242
|
});
|
|
232
243
|
const declines = data.filter((a) => a.status === 'declined');
|
|
233
244
|
// → each declines[i].failureCode is one of GaruFailureCode (insufficient_funds,
|
|
@@ -253,6 +264,83 @@ function shouldAskForNewCard(code: GaruFailureCode): boolean {
|
|
|
253
264
|
|
|
254
265
|
Full table at [docs.garu.com.br/api-reference/webhooks/codigos-de-falha](https://docs.garu.com.br/api-reference/webhooks/codigos-de-falha).
|
|
255
266
|
|
|
267
|
+
## Pix Automático
|
|
268
|
+
|
|
269
|
+
Pix Automático is Brazil's BACEN auto-debit recurring Pix. The customer authorizes **once** — they open their bank app, find the "Pix Automático" / "Recorrência Pix" section, and approve a consent QR/link. Every cycle from the second onward debits silently, with no further customer action.
|
|
270
|
+
|
|
271
|
+
**When to use it:** recurring billing where you want bank-level auto-debit instead of a saved card — subscriptions, mensalidades, memberships. Use card recurrence when you need installments or international cards; use Pix Automático for low-friction domestic recurring Pix.
|
|
272
|
+
|
|
273
|
+
It rides the **same SDK surface** as card-backed recurrence — no new methods, no new webhook events. The only differences are the `pix_automatic` method literal and a per-product enable flag.
|
|
274
|
+
|
|
275
|
+
### 1. Enable it on a product
|
|
276
|
+
|
|
277
|
+
Pix Automático only shows up on a product's checkout when the product has it enabled (`Product.pixAutomatic`). This is a property of the product (managed in the dashboard / product API); the SDK surfaces it as a boolean:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
const product = await garu.products.get('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
281
|
+
if (!product.pixAutomatic) {
|
|
282
|
+
// Pix Automático is off for this product — enable it before scheduling a
|
|
283
|
+
// `pix_automatic` charge, or the create call will 400.
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### 2. Create a Pix Automático scheduled charge
|
|
288
|
+
|
|
289
|
+
`pix_automatic` is **recurring-only** and **requires `productId`** (the product must have `pixAutomatic` enabled). The charge starts in a waiting state until the customer approves the consent; cycles 2+ then debit silently.
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
const series = await garu.scheduledCharges.create({
|
|
293
|
+
customerId: 42,
|
|
294
|
+
productId: 17,
|
|
295
|
+
amount: 49.9,
|
|
296
|
+
type: 'recurring',
|
|
297
|
+
dueDate: '2026-06-15',
|
|
298
|
+
methods: ['pix_automatic'],
|
|
299
|
+
recurrence: { interval: 'monthly' }
|
|
300
|
+
});
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Cancel and the rest of the lifecycle use the **same methods** as card-backed series — `cancelRecurrence(id)`, `cancelAtPeriodEnd(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.
|
|
304
|
+
|
|
305
|
+
### 3. Handle the webhooks
|
|
306
|
+
|
|
307
|
+
Pix Automático fires the **same events** as card recurrence — there are no Pix-Automático-specific event names. Branch on the payload's `paymentMethod` field (`'pix_automatic'`) when you need method-specific handling:
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
app.post('/webhooks/garu', express.raw({ type: 'application/json' }), (req, res) => {
|
|
311
|
+
const { event } = Garu.webhooks.verify({
|
|
312
|
+
payload: req.body,
|
|
313
|
+
signature: req.header('x-garu-signature') ?? '',
|
|
314
|
+
secret: process.env.GARU_WEBHOOK_SECRET!
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// `event` is the verified payload. It carries the Garu `eventType` and a
|
|
318
|
+
// `paymentMethod` field; branch on `paymentMethod` to special-case Pix
|
|
319
|
+
// Automático. (Field paths follow your webhook payload reference.)
|
|
320
|
+
const { eventType, paymentMethod } = event as {
|
|
321
|
+
eventType?: string;
|
|
322
|
+
paymentMethod?: string;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
if (paymentMethod === 'pix_automatic') {
|
|
326
|
+
switch (eventType) {
|
|
327
|
+
case 'transaction.payment.succeeded':
|
|
328
|
+
// a Pix Automático cycle debited
|
|
329
|
+
break;
|
|
330
|
+
case 'subscription.payment_failed':
|
|
331
|
+
// Pix Automático does NOT retry a refused debit at the network level —
|
|
332
|
+
// Garu flips the series to `past_due` and the usual dunning applies.
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
res.sendStatus(200);
|
|
338
|
+
});
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
> [!NOTE]
|
|
342
|
+
> Failure model: Pix Automático does not retry a refused debit at the payment-network level. On a refused cycle Garu fires `subscription.payment_failed` and moves the series to `past_due`; your existing dunning handles recovery.
|
|
343
|
+
|
|
256
344
|
## Meta
|
|
257
345
|
|
|
258
346
|
Discover available payment methods and webhook events. No authentication required.
|
|
@@ -277,7 +365,7 @@ app.post('/webhooks/garu', express.raw({ type: 'application/json' }), (req, res)
|
|
|
277
365
|
const { event } = Garu.webhooks.verify({
|
|
278
366
|
payload: req.body, // raw Buffer — do NOT re-serialize parsed JSON
|
|
279
367
|
signature: req.header('x-garu-signature') ?? '',
|
|
280
|
-
secret: process.env.GARU_WEBHOOK_SECRET
|
|
368
|
+
secret: process.env.GARU_WEBHOOK_SECRET!
|
|
281
369
|
});
|
|
282
370
|
|
|
283
371
|
console.log('Received', event);
|
|
@@ -294,7 +382,7 @@ app.post('/webhooks/garu', express.raw({ type: 'application/json' }), (req, res)
|
|
|
294
382
|
|
|
295
383
|
## Webhook events
|
|
296
384
|
|
|
297
|
-
The seller-facing delivery log for outbound webhooks. Use it to audit deliveries, surface failures, and replay events when a customer's endpoint missed one. Webhook endpoint
|
|
385
|
+
The seller-facing delivery log for outbound webhooks. Use it to audit deliveries, surface failures, and replay events when a customer's endpoint missed one. Webhook endpoint _configuration_ (URL, subscribed events, secret) is still dashboard-only — this resource only covers the event log + manual retries.
|
|
298
386
|
|
|
299
387
|
```ts
|
|
300
388
|
// Surface anything that didn't make it through
|
|
@@ -306,7 +394,7 @@ console.log(event.responseStatus, event.responseBody);
|
|
|
306
394
|
|
|
307
395
|
// Audit-trail-preserving replay (recommended)
|
|
308
396
|
const clone = await garu.webhookEvents.resend(42);
|
|
309
|
-
clone.id !== event.id;
|
|
397
|
+
clone.id !== event.id; // true — fresh row with its own id
|
|
310
398
|
clone.manualResendOf === event.id; // true — points back at the source
|
|
311
399
|
```
|
|
312
400
|
|
|
@@ -317,12 +405,12 @@ Outbound deliveries of a resent event carry `Idempotency-Key: resend_<originalId
|
|
|
317
405
|
> [!NOTE]
|
|
318
406
|
> The SDK auto-attaches `X-Idempotency-Key` (UUIDv4) on `resend()` so transient transport retries can't create duplicate clones. Pass `{ idempotencyKey }` to dedupe across your own retry layer.
|
|
319
407
|
|
|
320
|
-
| Method
|
|
321
|
-
|
|
|
322
|
-
| `list(params?)`
|
|
323
|
-
| `get(id)`
|
|
324
|
-
| `resend(id, params?)`
|
|
325
|
-
| `retry(id)`
|
|
408
|
+
| Method | Purpose |
|
|
409
|
+
| --------------------- | --------------------------------------------------------------------------------- |
|
|
410
|
+
| `list(params?)` | Paginated event log. Filter by `status`, `eventType`, `endpointId`. Newest first. |
|
|
411
|
+
| `get(id)` | One event — full payload, endpoint snapshot, most recent response. |
|
|
412
|
+
| `resend(id, params?)` | Clone-on-resend. Returns the new event; original is untouched. **Preferred.** |
|
|
413
|
+
| `retry(id)` | Legacy in-place reset (mutates the original row). Soft-deprecated. |
|
|
326
414
|
|
|
327
415
|
## Error handling
|
|
328
416
|
|
|
@@ -333,7 +421,7 @@ import {
|
|
|
333
421
|
GaruAPIError,
|
|
334
422
|
GaruNotFoundError,
|
|
335
423
|
GaruRateLimitError,
|
|
336
|
-
GaruValidationError
|
|
424
|
+
GaruValidationError
|
|
337
425
|
} from '@garuhq/node';
|
|
338
426
|
|
|
339
427
|
try {
|
|
@@ -354,16 +442,16 @@ try {
|
|
|
354
442
|
}
|
|
355
443
|
```
|
|
356
444
|
|
|
357
|
-
| Error class
|
|
358
|
-
|
|
|
359
|
-
| `GaruAuthenticationError`
|
|
360
|
-
| `GaruPermissionError`
|
|
361
|
-
| `GaruNotFoundError`
|
|
362
|
-
| `GaruValidationError`
|
|
363
|
-
| `GaruRateLimitError`
|
|
364
|
-
| `GaruServerError`
|
|
365
|
-
| `GaruConnectionError`
|
|
366
|
-
| `GaruSignatureVerificationError`
|
|
445
|
+
| Error class | HTTP status |
|
|
446
|
+
| -------------------------------- | ---------------- |
|
|
447
|
+
| `GaruAuthenticationError` | `401` |
|
|
448
|
+
| `GaruPermissionError` | `403` |
|
|
449
|
+
| `GaruNotFoundError` | `404` |
|
|
450
|
+
| `GaruValidationError` | `400` / `422` |
|
|
451
|
+
| `GaruRateLimitError` | `429` |
|
|
452
|
+
| `GaruServerError` | `5xx` |
|
|
453
|
+
| `GaruConnectionError` | Network failure |
|
|
454
|
+
| `GaruSignatureVerificationError` | Webhook mismatch |
|
|
367
455
|
|
|
368
456
|
## Retries
|
|
369
457
|
|
|
@@ -381,7 +469,7 @@ import type {
|
|
|
381
469
|
Customer,
|
|
382
470
|
CardInfo,
|
|
383
471
|
PaymentMethod,
|
|
384
|
-
MetaResponse
|
|
472
|
+
MetaResponse
|
|
385
473
|
} from '@garuhq/node';
|
|
386
474
|
```
|
|
387
475
|
|
package/dist/index.cjs
CHANGED
|
@@ -596,6 +596,20 @@ var ScheduledCharges = class {
|
|
|
596
596
|
* methods: ['pix', 'boleto'],
|
|
597
597
|
* description: 'Mensalidade Junho'
|
|
598
598
|
* });
|
|
599
|
+
*
|
|
600
|
+
* @example
|
|
601
|
+
* // Pix Automático (BACEN auto-debit). Requires `type: 'recurring'` and a
|
|
602
|
+
* // `productId` whose product has Pix Automático enabled. The customer
|
|
603
|
+
* // authorizes once via their bank app; cycles 2+ debit silently.
|
|
604
|
+
* const series = await garu.scheduledCharges.create({
|
|
605
|
+
* customerId: 42,
|
|
606
|
+
* productId: 17,
|
|
607
|
+
* amount: 49.9,
|
|
608
|
+
* type: 'recurring',
|
|
609
|
+
* dueDate: '2026-06-15',
|
|
610
|
+
* methods: ['pix_automatic'],
|
|
611
|
+
* recurrence: { interval: 'monthly' }
|
|
612
|
+
* });
|
|
599
613
|
*/
|
|
600
614
|
async create(params) {
|
|
601
615
|
const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
|
|
@@ -653,9 +667,9 @@ var ScheduledCharges = class {
|
|
|
653
667
|
*/
|
|
654
668
|
async get(id) {
|
|
655
669
|
return this.http.call(
|
|
656
|
-
(signal) => this.http.client.GET(`/api/scheduled-charges/${id}`, {
|
|
657
|
-
|
|
658
|
-
)
|
|
670
|
+
(signal) => this.http.client.GET(`/api/scheduled-charges/${encodeURIComponent(id)}`, {
|
|
671
|
+
signal
|
|
672
|
+
}).then((r) => r)
|
|
659
673
|
);
|
|
660
674
|
}
|
|
661
675
|
/**
|
|
@@ -671,10 +685,13 @@ var ScheduledCharges = class {
|
|
|
671
685
|
*/
|
|
672
686
|
async postpone(id, params) {
|
|
673
687
|
return this.http.call(
|
|
674
|
-
(signal) => this.http.client.POST(
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
688
|
+
(signal) => this.http.client.POST(
|
|
689
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/postpone`,
|
|
690
|
+
{
|
|
691
|
+
body: params,
|
|
692
|
+
signal
|
|
693
|
+
}
|
|
694
|
+
).then((r) => r)
|
|
678
695
|
);
|
|
679
696
|
}
|
|
680
697
|
/**
|
|
@@ -687,10 +704,13 @@ var ScheduledCharges = class {
|
|
|
687
704
|
*/
|
|
688
705
|
async pause(id, params = {}) {
|
|
689
706
|
return this.http.call(
|
|
690
|
-
(signal) => this.http.client.POST(
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
707
|
+
(signal) => this.http.client.POST(
|
|
708
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/pause`,
|
|
709
|
+
{
|
|
710
|
+
body: params,
|
|
711
|
+
signal
|
|
712
|
+
}
|
|
713
|
+
).then((r) => r)
|
|
694
714
|
);
|
|
695
715
|
}
|
|
696
716
|
/**
|
|
@@ -701,10 +721,13 @@ var ScheduledCharges = class {
|
|
|
701
721
|
*/
|
|
702
722
|
async resume(id) {
|
|
703
723
|
return this.http.call(
|
|
704
|
-
(signal) => this.http.client.POST(
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
724
|
+
(signal) => this.http.client.POST(
|
|
725
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/resume`,
|
|
726
|
+
{
|
|
727
|
+
body: {},
|
|
728
|
+
signal
|
|
729
|
+
}
|
|
730
|
+
).then((r) => r)
|
|
708
731
|
);
|
|
709
732
|
}
|
|
710
733
|
/**
|
|
@@ -732,10 +755,52 @@ var ScheduledCharges = class {
|
|
|
732
755
|
*/
|
|
733
756
|
async markPaid(id, params) {
|
|
734
757
|
return this.http.call(
|
|
735
|
-
(signal) => this.http.client.POST(
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
758
|
+
(signal) => this.http.client.POST(
|
|
759
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/mark-paid`,
|
|
760
|
+
{
|
|
761
|
+
body: params,
|
|
762
|
+
signal
|
|
763
|
+
}
|
|
764
|
+
).then((r) => r)
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Force-bill the current cycle right now instead of waiting for its due
|
|
769
|
+
* date. Runs the same dispatch the daily billing cron would (customer
|
|
770
|
+
* email/notification + outbound webhook + timeline event). Allowed only
|
|
771
|
+
* from a billable status (`scheduled` / `due_today`); a recurring series
|
|
772
|
+
* must have an open cycle (else the backend returns 400).
|
|
773
|
+
*
|
|
774
|
+
* Idempotent: if this cycle's d-day was already dispatched it reports
|
|
775
|
+
* `already_sent` and does not re-charge. Inspect `outcome` to branch.
|
|
776
|
+
*
|
|
777
|
+
* @example
|
|
778
|
+
* const result = await garu.scheduledCharges.chargeNow('sch_abc123');
|
|
779
|
+
* switch (result.outcome) {
|
|
780
|
+
* case 'dispatched':
|
|
781
|
+
* console.log(`Cobrança enviada (ciclo ${result.cycleNumber}).`);
|
|
782
|
+
* break;
|
|
783
|
+
* case 'already_sent':
|
|
784
|
+
* console.log('Já havia sido enviada — nada a fazer.');
|
|
785
|
+
* break;
|
|
786
|
+
* case 'failed':
|
|
787
|
+
* // result.reason is e.g. 'card_expired' or a gateway decline code
|
|
788
|
+
* console.error(`Falha na cobrança: ${result.reason}. ${result.message}`);
|
|
789
|
+
* break;
|
|
790
|
+
* case 'not_sent':
|
|
791
|
+
* console.warn(`Não enviada (${result.reason}): ${result.message}`);
|
|
792
|
+
* break;
|
|
793
|
+
* }
|
|
794
|
+
*/
|
|
795
|
+
async chargeNow(id) {
|
|
796
|
+
return this.http.call(
|
|
797
|
+
(signal) => this.http.client.POST(
|
|
798
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/charge-now`,
|
|
799
|
+
{
|
|
800
|
+
body: {},
|
|
801
|
+
signal
|
|
802
|
+
}
|
|
803
|
+
).then((r) => r)
|
|
739
804
|
);
|
|
740
805
|
}
|
|
741
806
|
/**
|
|
@@ -751,10 +816,13 @@ var ScheduledCharges = class {
|
|
|
751
816
|
*/
|
|
752
817
|
async cancelRecurrence(id, params = {}) {
|
|
753
818
|
return this.http.call(
|
|
754
|
-
(signal) => this.http.client.POST(
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
819
|
+
(signal) => this.http.client.POST(
|
|
820
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/cancel-recurrence`,
|
|
821
|
+
{
|
|
822
|
+
body: params,
|
|
823
|
+
signal
|
|
824
|
+
}
|
|
825
|
+
).then((r) => r)
|
|
758
826
|
);
|
|
759
827
|
}
|
|
760
828
|
/**
|
|
@@ -768,10 +836,13 @@ var ScheduledCharges = class {
|
|
|
768
836
|
*/
|
|
769
837
|
async setCancelAtPeriodEnd(id, params) {
|
|
770
838
|
return this.http.call(
|
|
771
|
-
(signal) => this.http.client.POST(
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
839
|
+
(signal) => this.http.client.POST(
|
|
840
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/cancel-at-period-end`,
|
|
841
|
+
{
|
|
842
|
+
body: params,
|
|
843
|
+
signal
|
|
844
|
+
}
|
|
845
|
+
).then((r) => r)
|
|
775
846
|
);
|
|
776
847
|
}
|
|
777
848
|
/**
|
|
@@ -784,10 +855,13 @@ var ScheduledCharges = class {
|
|
|
784
855
|
*/
|
|
785
856
|
async changePaymentMethod(id, params) {
|
|
786
857
|
return this.http.call(
|
|
787
|
-
(signal) => this.http.client.POST(
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
858
|
+
(signal) => this.http.client.POST(
|
|
859
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
860
|
+
{
|
|
861
|
+
body: params,
|
|
862
|
+
signal
|
|
863
|
+
}
|
|
864
|
+
).then((r) => r)
|
|
791
865
|
);
|
|
792
866
|
}
|
|
793
867
|
/**
|
|
@@ -800,10 +874,13 @@ var ScheduledCharges = class {
|
|
|
800
874
|
*/
|
|
801
875
|
async clearPaymentMethod(id) {
|
|
802
876
|
return this.http.call(
|
|
803
|
-
(signal) => this.http.client.DELETE(
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
877
|
+
(signal) => this.http.client.DELETE(
|
|
878
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
879
|
+
{
|
|
880
|
+
body: {},
|
|
881
|
+
signal
|
|
882
|
+
}
|
|
883
|
+
).then((r) => r)
|
|
807
884
|
);
|
|
808
885
|
}
|
|
809
886
|
/**
|
|
@@ -825,7 +902,7 @@ var ScheduledCharges = class {
|
|
|
825
902
|
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
826
903
|
if (params.cycleNumber !== void 0) qs.set("cycleNumber", String(params.cycleNumber));
|
|
827
904
|
const query = qs.toString();
|
|
828
|
-
const url = `/api/scheduled-charges/${id}/attempts${query ? `?${query}` : ""}`;
|
|
905
|
+
const url = `/api/scheduled-charges/${encodeURIComponent(id)}/attempts${query ? `?${query}` : ""}`;
|
|
829
906
|
return this.http.call(
|
|
830
907
|
(signal) => this.http.client.GET(url, { signal }).then(
|
|
831
908
|
(r) => r
|
package/dist/index.d.cts
CHANGED
|
@@ -99,8 +99,13 @@ declare class HttpClient {
|
|
|
99
99
|
*/
|
|
100
100
|
|
|
101
101
|
type PaymentMethod = 'pix' | 'credit_card' | 'boleto';
|
|
102
|
-
/**
|
|
103
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Payment-method identifier as it appears on the wire. `pix_automatic`
|
|
104
|
+
* (Pix Automático auto-debit) surfaces here on transactions/charges read
|
|
105
|
+
* back from Pix Automático recurring cycles. It is never produced by
|
|
106
|
+
* `toWirePaymentMethod`, since one-off charges can't use it.
|
|
107
|
+
*/
|
|
108
|
+
type WirePaymentMethodId = 'pix' | 'creditcard' | 'boleto' | 'pix_automatic';
|
|
104
109
|
type ChargeStatus = 'pending' | 'authorized' | 'paid' | 'failed' | 'refunded' | 'cancelled' | 'expired';
|
|
105
110
|
interface Customer {
|
|
106
111
|
/** Full legal name. 3–255 chars. */
|
|
@@ -277,7 +282,16 @@ interface ListCustomersParams {
|
|
|
277
282
|
}
|
|
278
283
|
type ScheduledChargeStatus = 'scheduled' | 'due_today' | 'overdue' | 'paid' | 'paused' | 'canceled' | 'trial' | 'pending_tokenization' | 'recurrence_canceled';
|
|
279
284
|
type ScheduledChargeType = 'one_time' | 'recurring';
|
|
280
|
-
|
|
285
|
+
/**
|
|
286
|
+
* Payment method for a scheduled charge.
|
|
287
|
+
*
|
|
288
|
+
* `pix_automatic` is Pix Automático — Brazil's BACEN auto-debit recurring
|
|
289
|
+
* Pix. The customer authorizes **once** via a consent link/QR in their bank
|
|
290
|
+
* app; every cycle from the second onward debits silently with no further
|
|
291
|
+
* action. It is only valid when `type='recurring'` **and** `productId` is
|
|
292
|
+
* set; the product must also have Pix Automático enabled (`pixAutomatic`).
|
|
293
|
+
*/
|
|
294
|
+
type ScheduledPaymentMethod = 'pix' | 'boleto' | 'card' | 'pix_automatic';
|
|
281
295
|
type RecurrenceInterval = 'weekly' | 'biweekly' | 'monthly' | 'bimonthly' | 'quarterly' | 'biannual' | 'yearly';
|
|
282
296
|
interface RecurrenceConfig {
|
|
283
297
|
interval: RecurrenceInterval;
|
|
@@ -312,6 +326,11 @@ interface ScheduledChargeRecord {
|
|
|
312
326
|
methods: ScheduledPaymentMethod[];
|
|
313
327
|
status: ScheduledChargeStatus;
|
|
314
328
|
externalReference: string | null;
|
|
329
|
+
/**
|
|
330
|
+
* Max days past `dueDate` the daily recovery sweep will still auto-bill a
|
|
331
|
+
* missed charge. `null` means the system default (14) applies.
|
|
332
|
+
*/
|
|
333
|
+
maxRecoveryDays: number | null;
|
|
315
334
|
metadata: Record<string, unknown> | null;
|
|
316
335
|
createdAt: string;
|
|
317
336
|
updatedAt: string;
|
|
@@ -364,7 +383,7 @@ interface ScheduledChargeAttempt {
|
|
|
364
383
|
attemptNumber: number;
|
|
365
384
|
attemptedAt: string;
|
|
366
385
|
source: ScheduledChargeAttemptSource;
|
|
367
|
-
paymentMethod: 'card' | 'pix' | 'boleto' | 'manual';
|
|
386
|
+
paymentMethod: 'card' | 'pix' | 'boleto' | 'pix_automatic' | 'manual';
|
|
368
387
|
paymentMethodId: number | null;
|
|
369
388
|
cardLast4: string | null;
|
|
370
389
|
cardBrand: string | null;
|
|
@@ -395,7 +414,11 @@ interface CreateScheduledChargeParams {
|
|
|
395
414
|
type: ScheduledChargeType;
|
|
396
415
|
/** YYYY-MM-DD in São Paulo time. Must be today or future. */
|
|
397
416
|
dueDate: string;
|
|
398
|
-
/**
|
|
417
|
+
/**
|
|
418
|
+
* `card` is recurring-only and requires `productId`. `pix_automatic`
|
|
419
|
+
* (Pix Automático auto-debit) likewise requires `type='recurring'` **and**
|
|
420
|
+
* `productId`, and the product must have Pix Automático enabled.
|
|
421
|
+
*/
|
|
399
422
|
methods: ScheduledPaymentMethod[];
|
|
400
423
|
/** Cadence for `type='recurring'`. Must be omitted when `type='one_time'`. */
|
|
401
424
|
recurrence?: RecurrenceConfig;
|
|
@@ -407,6 +430,11 @@ interface CreateScheduledChargeParams {
|
|
|
407
430
|
trialDays?: number;
|
|
408
431
|
externalReference?: string;
|
|
409
432
|
metadata?: Record<string, unknown>;
|
|
433
|
+
/**
|
|
434
|
+
* Max days past `dueDate` the daily recovery sweep will still auto-bill a
|
|
435
|
+
* missed charge (integer 1..365). Omit for the system default (14).
|
|
436
|
+
*/
|
|
437
|
+
maxRecoveryDays?: number;
|
|
410
438
|
/**
|
|
411
439
|
* Optional idempotency key for safe retries. The SDK auto-generates a
|
|
412
440
|
* UUIDv4 when omitted and forwards it as `X-Idempotency-Key`.
|
|
@@ -456,6 +484,30 @@ interface ChangePaymentMethodScheduledChargeParams {
|
|
|
456
484
|
/** PaymentMethod id to bind. Must belong to the same customerId. */
|
|
457
485
|
paymentMethodId: number;
|
|
458
486
|
}
|
|
487
|
+
/**
|
|
488
|
+
* Result of `scheduledCharges.chargeNow(id)` — what the immediate dispatch did:
|
|
489
|
+
*
|
|
490
|
+
* - `dispatched` — sent now (customer email/notification + outbound webhook + timeline event).
|
|
491
|
+
* - `already_sent` — this cycle's d-day was already dispatched; no-op (the action is idempotent).
|
|
492
|
+
* - `not_sent` — couldn't send; see `reason` (e.g. `no_email`, `lock_lost`, `no_saved_payment_method`).
|
|
493
|
+
* - `failed` — card charge failed; see `reason` (e.g. `card_expired`, or a gateway decline code).
|
|
494
|
+
*/
|
|
495
|
+
type ChargeNowOutcome = 'dispatched' | 'already_sent' | 'not_sent' | 'failed';
|
|
496
|
+
/**
|
|
497
|
+
* Why a `not_sent` / `failed` charge-now didn't go through. The documented
|
|
498
|
+
* literals are stable; `failed` may also surface a raw gateway decline code,
|
|
499
|
+
* so the type stays open (`string & {}`) without losing autocomplete.
|
|
500
|
+
*/
|
|
501
|
+
type ChargeNowReason = 'no_email' | 'lock_lost' | 'no_saved_payment_method' | 'card_expired' | 'payment_method_missing' | 'customer_missing' | (string & {});
|
|
502
|
+
interface ChargeNowResult {
|
|
503
|
+
outcome: ChargeNowOutcome;
|
|
504
|
+
/** Cycle that was dispatched/attempted, or `null` for one-time charges. */
|
|
505
|
+
cycleNumber: number | null;
|
|
506
|
+
/** Present on `not_sent` / `failed`. See {@link ChargeNowReason}. */
|
|
507
|
+
reason?: ChargeNowReason;
|
|
508
|
+
/** Ready-to-show pt-BR message describing the outcome. */
|
|
509
|
+
message: string;
|
|
510
|
+
}
|
|
459
511
|
interface Product {
|
|
460
512
|
id: number;
|
|
461
513
|
uuid: string;
|
|
@@ -469,6 +521,13 @@ interface Product {
|
|
|
469
521
|
pix: boolean;
|
|
470
522
|
boleto: boolean;
|
|
471
523
|
creditCard: boolean;
|
|
524
|
+
/**
|
|
525
|
+
* When `true`, the public subscription checkout exposes Pix Automático
|
|
526
|
+
* (BACEN auto-debit recurring Pix) as a payment option. Enabled by
|
|
527
|
+
* default; sellers can disable it per product. Only the subscription
|
|
528
|
+
* checkout mode reads this flag. See {@link ScheduledPaymentMethod}.
|
|
529
|
+
*/
|
|
530
|
+
pixAutomatic: boolean;
|
|
472
531
|
installments: number[];
|
|
473
532
|
tags?: string[];
|
|
474
533
|
isSubscription?: boolean;
|
|
@@ -957,6 +1016,20 @@ declare class ScheduledCharges {
|
|
|
957
1016
|
* methods: ['pix', 'boleto'],
|
|
958
1017
|
* description: 'Mensalidade Junho'
|
|
959
1018
|
* });
|
|
1019
|
+
*
|
|
1020
|
+
* @example
|
|
1021
|
+
* // Pix Automático (BACEN auto-debit). Requires `type: 'recurring'` and a
|
|
1022
|
+
* // `productId` whose product has Pix Automático enabled. The customer
|
|
1023
|
+
* // authorizes once via their bank app; cycles 2+ debit silently.
|
|
1024
|
+
* const series = await garu.scheduledCharges.create({
|
|
1025
|
+
* customerId: 42,
|
|
1026
|
+
* productId: 17,
|
|
1027
|
+
* amount: 49.9,
|
|
1028
|
+
* type: 'recurring',
|
|
1029
|
+
* dueDate: '2026-06-15',
|
|
1030
|
+
* methods: ['pix_automatic'],
|
|
1031
|
+
* recurrence: { interval: 'monthly' }
|
|
1032
|
+
* });
|
|
960
1033
|
*/
|
|
961
1034
|
create(params: CreateScheduledChargeParams): Promise<ScheduledChargeRecord>;
|
|
962
1035
|
/**
|
|
@@ -1035,6 +1108,35 @@ declare class ScheduledCharges {
|
|
|
1035
1108
|
* });
|
|
1036
1109
|
*/
|
|
1037
1110
|
markPaid(id: string, params: MarkPaidScheduledChargeParams): Promise<ScheduledChargeRecord>;
|
|
1111
|
+
/**
|
|
1112
|
+
* Force-bill the current cycle right now instead of waiting for its due
|
|
1113
|
+
* date. Runs the same dispatch the daily billing cron would (customer
|
|
1114
|
+
* email/notification + outbound webhook + timeline event). Allowed only
|
|
1115
|
+
* from a billable status (`scheduled` / `due_today`); a recurring series
|
|
1116
|
+
* must have an open cycle (else the backend returns 400).
|
|
1117
|
+
*
|
|
1118
|
+
* Idempotent: if this cycle's d-day was already dispatched it reports
|
|
1119
|
+
* `already_sent` and does not re-charge. Inspect `outcome` to branch.
|
|
1120
|
+
*
|
|
1121
|
+
* @example
|
|
1122
|
+
* const result = await garu.scheduledCharges.chargeNow('sch_abc123');
|
|
1123
|
+
* switch (result.outcome) {
|
|
1124
|
+
* case 'dispatched':
|
|
1125
|
+
* console.log(`Cobrança enviada (ciclo ${result.cycleNumber}).`);
|
|
1126
|
+
* break;
|
|
1127
|
+
* case 'already_sent':
|
|
1128
|
+
* console.log('Já havia sido enviada — nada a fazer.');
|
|
1129
|
+
* break;
|
|
1130
|
+
* case 'failed':
|
|
1131
|
+
* // result.reason is e.g. 'card_expired' or a gateway decline code
|
|
1132
|
+
* console.error(`Falha na cobrança: ${result.reason}. ${result.message}`);
|
|
1133
|
+
* break;
|
|
1134
|
+
* case 'not_sent':
|
|
1135
|
+
* console.warn(`Não enviada (${result.reason}): ${result.message}`);
|
|
1136
|
+
* break;
|
|
1137
|
+
* }
|
|
1138
|
+
*/
|
|
1139
|
+
chargeNow(id: string): Promise<ChargeNowResult>;
|
|
1038
1140
|
/**
|
|
1039
1141
|
* Stop future cycles for a recurring series. The currently in-flight
|
|
1040
1142
|
* cycle (if any) remains active until paid, postponed, or marked-paid;
|
|
@@ -1289,4 +1391,4 @@ declare class GaruServerError extends GaruAPIError {
|
|
|
1289
1391
|
constructor(message: string, status: number, requestId: string | null, body: unknown);
|
|
1290
1392
|
}
|
|
1291
1393
|
|
|
1292
|
-
export { type CancelAtPeriodEndScheduledChargeParams, type CancelRecurrenceScheduledChargeParams, type CardInfo, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type ListChargesParams, type ListCustomersParams, type ListProductsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethod, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type ResendWebhookEventParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, type WirePaymentMethodId, webhooks };
|
|
1394
|
+
export { type CancelAtPeriodEndScheduledChargeParams, type CancelRecurrenceScheduledChargeParams, type CardInfo, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeNowOutcome, type ChargeNowReason, type ChargeNowResult, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type ListChargesParams, type ListCustomersParams, type ListProductsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethod, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type ResendWebhookEventParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, type WirePaymentMethodId, webhooks };
|
package/dist/index.d.ts
CHANGED
|
@@ -99,8 +99,13 @@ declare class HttpClient {
|
|
|
99
99
|
*/
|
|
100
100
|
|
|
101
101
|
type PaymentMethod = 'pix' | 'credit_card' | 'boleto';
|
|
102
|
-
/**
|
|
103
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Payment-method identifier as it appears on the wire. `pix_automatic`
|
|
104
|
+
* (Pix Automático auto-debit) surfaces here on transactions/charges read
|
|
105
|
+
* back from Pix Automático recurring cycles. It is never produced by
|
|
106
|
+
* `toWirePaymentMethod`, since one-off charges can't use it.
|
|
107
|
+
*/
|
|
108
|
+
type WirePaymentMethodId = 'pix' | 'creditcard' | 'boleto' | 'pix_automatic';
|
|
104
109
|
type ChargeStatus = 'pending' | 'authorized' | 'paid' | 'failed' | 'refunded' | 'cancelled' | 'expired';
|
|
105
110
|
interface Customer {
|
|
106
111
|
/** Full legal name. 3–255 chars. */
|
|
@@ -277,7 +282,16 @@ interface ListCustomersParams {
|
|
|
277
282
|
}
|
|
278
283
|
type ScheduledChargeStatus = 'scheduled' | 'due_today' | 'overdue' | 'paid' | 'paused' | 'canceled' | 'trial' | 'pending_tokenization' | 'recurrence_canceled';
|
|
279
284
|
type ScheduledChargeType = 'one_time' | 'recurring';
|
|
280
|
-
|
|
285
|
+
/**
|
|
286
|
+
* Payment method for a scheduled charge.
|
|
287
|
+
*
|
|
288
|
+
* `pix_automatic` is Pix Automático — Brazil's BACEN auto-debit recurring
|
|
289
|
+
* Pix. The customer authorizes **once** via a consent link/QR in their bank
|
|
290
|
+
* app; every cycle from the second onward debits silently with no further
|
|
291
|
+
* action. It is only valid when `type='recurring'` **and** `productId` is
|
|
292
|
+
* set; the product must also have Pix Automático enabled (`pixAutomatic`).
|
|
293
|
+
*/
|
|
294
|
+
type ScheduledPaymentMethod = 'pix' | 'boleto' | 'card' | 'pix_automatic';
|
|
281
295
|
type RecurrenceInterval = 'weekly' | 'biweekly' | 'monthly' | 'bimonthly' | 'quarterly' | 'biannual' | 'yearly';
|
|
282
296
|
interface RecurrenceConfig {
|
|
283
297
|
interval: RecurrenceInterval;
|
|
@@ -312,6 +326,11 @@ interface ScheduledChargeRecord {
|
|
|
312
326
|
methods: ScheduledPaymentMethod[];
|
|
313
327
|
status: ScheduledChargeStatus;
|
|
314
328
|
externalReference: string | null;
|
|
329
|
+
/**
|
|
330
|
+
* Max days past `dueDate` the daily recovery sweep will still auto-bill a
|
|
331
|
+
* missed charge. `null` means the system default (14) applies.
|
|
332
|
+
*/
|
|
333
|
+
maxRecoveryDays: number | null;
|
|
315
334
|
metadata: Record<string, unknown> | null;
|
|
316
335
|
createdAt: string;
|
|
317
336
|
updatedAt: string;
|
|
@@ -364,7 +383,7 @@ interface ScheduledChargeAttempt {
|
|
|
364
383
|
attemptNumber: number;
|
|
365
384
|
attemptedAt: string;
|
|
366
385
|
source: ScheduledChargeAttemptSource;
|
|
367
|
-
paymentMethod: 'card' | 'pix' | 'boleto' | 'manual';
|
|
386
|
+
paymentMethod: 'card' | 'pix' | 'boleto' | 'pix_automatic' | 'manual';
|
|
368
387
|
paymentMethodId: number | null;
|
|
369
388
|
cardLast4: string | null;
|
|
370
389
|
cardBrand: string | null;
|
|
@@ -395,7 +414,11 @@ interface CreateScheduledChargeParams {
|
|
|
395
414
|
type: ScheduledChargeType;
|
|
396
415
|
/** YYYY-MM-DD in São Paulo time. Must be today or future. */
|
|
397
416
|
dueDate: string;
|
|
398
|
-
/**
|
|
417
|
+
/**
|
|
418
|
+
* `card` is recurring-only and requires `productId`. `pix_automatic`
|
|
419
|
+
* (Pix Automático auto-debit) likewise requires `type='recurring'` **and**
|
|
420
|
+
* `productId`, and the product must have Pix Automático enabled.
|
|
421
|
+
*/
|
|
399
422
|
methods: ScheduledPaymentMethod[];
|
|
400
423
|
/** Cadence for `type='recurring'`. Must be omitted when `type='one_time'`. */
|
|
401
424
|
recurrence?: RecurrenceConfig;
|
|
@@ -407,6 +430,11 @@ interface CreateScheduledChargeParams {
|
|
|
407
430
|
trialDays?: number;
|
|
408
431
|
externalReference?: string;
|
|
409
432
|
metadata?: Record<string, unknown>;
|
|
433
|
+
/**
|
|
434
|
+
* Max days past `dueDate` the daily recovery sweep will still auto-bill a
|
|
435
|
+
* missed charge (integer 1..365). Omit for the system default (14).
|
|
436
|
+
*/
|
|
437
|
+
maxRecoveryDays?: number;
|
|
410
438
|
/**
|
|
411
439
|
* Optional idempotency key for safe retries. The SDK auto-generates a
|
|
412
440
|
* UUIDv4 when omitted and forwards it as `X-Idempotency-Key`.
|
|
@@ -456,6 +484,30 @@ interface ChangePaymentMethodScheduledChargeParams {
|
|
|
456
484
|
/** PaymentMethod id to bind. Must belong to the same customerId. */
|
|
457
485
|
paymentMethodId: number;
|
|
458
486
|
}
|
|
487
|
+
/**
|
|
488
|
+
* Result of `scheduledCharges.chargeNow(id)` — what the immediate dispatch did:
|
|
489
|
+
*
|
|
490
|
+
* - `dispatched` — sent now (customer email/notification + outbound webhook + timeline event).
|
|
491
|
+
* - `already_sent` — this cycle's d-day was already dispatched; no-op (the action is idempotent).
|
|
492
|
+
* - `not_sent` — couldn't send; see `reason` (e.g. `no_email`, `lock_lost`, `no_saved_payment_method`).
|
|
493
|
+
* - `failed` — card charge failed; see `reason` (e.g. `card_expired`, or a gateway decline code).
|
|
494
|
+
*/
|
|
495
|
+
type ChargeNowOutcome = 'dispatched' | 'already_sent' | 'not_sent' | 'failed';
|
|
496
|
+
/**
|
|
497
|
+
* Why a `not_sent` / `failed` charge-now didn't go through. The documented
|
|
498
|
+
* literals are stable; `failed` may also surface a raw gateway decline code,
|
|
499
|
+
* so the type stays open (`string & {}`) without losing autocomplete.
|
|
500
|
+
*/
|
|
501
|
+
type ChargeNowReason = 'no_email' | 'lock_lost' | 'no_saved_payment_method' | 'card_expired' | 'payment_method_missing' | 'customer_missing' | (string & {});
|
|
502
|
+
interface ChargeNowResult {
|
|
503
|
+
outcome: ChargeNowOutcome;
|
|
504
|
+
/** Cycle that was dispatched/attempted, or `null` for one-time charges. */
|
|
505
|
+
cycleNumber: number | null;
|
|
506
|
+
/** Present on `not_sent` / `failed`. See {@link ChargeNowReason}. */
|
|
507
|
+
reason?: ChargeNowReason;
|
|
508
|
+
/** Ready-to-show pt-BR message describing the outcome. */
|
|
509
|
+
message: string;
|
|
510
|
+
}
|
|
459
511
|
interface Product {
|
|
460
512
|
id: number;
|
|
461
513
|
uuid: string;
|
|
@@ -469,6 +521,13 @@ interface Product {
|
|
|
469
521
|
pix: boolean;
|
|
470
522
|
boleto: boolean;
|
|
471
523
|
creditCard: boolean;
|
|
524
|
+
/**
|
|
525
|
+
* When `true`, the public subscription checkout exposes Pix Automático
|
|
526
|
+
* (BACEN auto-debit recurring Pix) as a payment option. Enabled by
|
|
527
|
+
* default; sellers can disable it per product. Only the subscription
|
|
528
|
+
* checkout mode reads this flag. See {@link ScheduledPaymentMethod}.
|
|
529
|
+
*/
|
|
530
|
+
pixAutomatic: boolean;
|
|
472
531
|
installments: number[];
|
|
473
532
|
tags?: string[];
|
|
474
533
|
isSubscription?: boolean;
|
|
@@ -957,6 +1016,20 @@ declare class ScheduledCharges {
|
|
|
957
1016
|
* methods: ['pix', 'boleto'],
|
|
958
1017
|
* description: 'Mensalidade Junho'
|
|
959
1018
|
* });
|
|
1019
|
+
*
|
|
1020
|
+
* @example
|
|
1021
|
+
* // Pix Automático (BACEN auto-debit). Requires `type: 'recurring'` and a
|
|
1022
|
+
* // `productId` whose product has Pix Automático enabled. The customer
|
|
1023
|
+
* // authorizes once via their bank app; cycles 2+ debit silently.
|
|
1024
|
+
* const series = await garu.scheduledCharges.create({
|
|
1025
|
+
* customerId: 42,
|
|
1026
|
+
* productId: 17,
|
|
1027
|
+
* amount: 49.9,
|
|
1028
|
+
* type: 'recurring',
|
|
1029
|
+
* dueDate: '2026-06-15',
|
|
1030
|
+
* methods: ['pix_automatic'],
|
|
1031
|
+
* recurrence: { interval: 'monthly' }
|
|
1032
|
+
* });
|
|
960
1033
|
*/
|
|
961
1034
|
create(params: CreateScheduledChargeParams): Promise<ScheduledChargeRecord>;
|
|
962
1035
|
/**
|
|
@@ -1035,6 +1108,35 @@ declare class ScheduledCharges {
|
|
|
1035
1108
|
* });
|
|
1036
1109
|
*/
|
|
1037
1110
|
markPaid(id: string, params: MarkPaidScheduledChargeParams): Promise<ScheduledChargeRecord>;
|
|
1111
|
+
/**
|
|
1112
|
+
* Force-bill the current cycle right now instead of waiting for its due
|
|
1113
|
+
* date. Runs the same dispatch the daily billing cron would (customer
|
|
1114
|
+
* email/notification + outbound webhook + timeline event). Allowed only
|
|
1115
|
+
* from a billable status (`scheduled` / `due_today`); a recurring series
|
|
1116
|
+
* must have an open cycle (else the backend returns 400).
|
|
1117
|
+
*
|
|
1118
|
+
* Idempotent: if this cycle's d-day was already dispatched it reports
|
|
1119
|
+
* `already_sent` and does not re-charge. Inspect `outcome` to branch.
|
|
1120
|
+
*
|
|
1121
|
+
* @example
|
|
1122
|
+
* const result = await garu.scheduledCharges.chargeNow('sch_abc123');
|
|
1123
|
+
* switch (result.outcome) {
|
|
1124
|
+
* case 'dispatched':
|
|
1125
|
+
* console.log(`Cobrança enviada (ciclo ${result.cycleNumber}).`);
|
|
1126
|
+
* break;
|
|
1127
|
+
* case 'already_sent':
|
|
1128
|
+
* console.log('Já havia sido enviada — nada a fazer.');
|
|
1129
|
+
* break;
|
|
1130
|
+
* case 'failed':
|
|
1131
|
+
* // result.reason is e.g. 'card_expired' or a gateway decline code
|
|
1132
|
+
* console.error(`Falha na cobrança: ${result.reason}. ${result.message}`);
|
|
1133
|
+
* break;
|
|
1134
|
+
* case 'not_sent':
|
|
1135
|
+
* console.warn(`Não enviada (${result.reason}): ${result.message}`);
|
|
1136
|
+
* break;
|
|
1137
|
+
* }
|
|
1138
|
+
*/
|
|
1139
|
+
chargeNow(id: string): Promise<ChargeNowResult>;
|
|
1038
1140
|
/**
|
|
1039
1141
|
* Stop future cycles for a recurring series. The currently in-flight
|
|
1040
1142
|
* cycle (if any) remains active until paid, postponed, or marked-paid;
|
|
@@ -1289,4 +1391,4 @@ declare class GaruServerError extends GaruAPIError {
|
|
|
1289
1391
|
constructor(message: string, status: number, requestId: string | null, body: unknown);
|
|
1290
1392
|
}
|
|
1291
1393
|
|
|
1292
|
-
export { type CancelAtPeriodEndScheduledChargeParams, type CancelRecurrenceScheduledChargeParams, type CardInfo, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type ListChargesParams, type ListCustomersParams, type ListProductsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethod, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type ResendWebhookEventParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, type WirePaymentMethodId, webhooks };
|
|
1394
|
+
export { type CancelAtPeriodEndScheduledChargeParams, type CancelRecurrenceScheduledChargeParams, type CardInfo, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeNowOutcome, type ChargeNowReason, type ChargeNowResult, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type ListChargesParams, type ListCustomersParams, type ListProductsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethod, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type ResendWebhookEventParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, type WirePaymentMethodId, webhooks };
|
package/dist/index.js
CHANGED
|
@@ -590,6 +590,20 @@ var ScheduledCharges = class {
|
|
|
590
590
|
* methods: ['pix', 'boleto'],
|
|
591
591
|
* description: 'Mensalidade Junho'
|
|
592
592
|
* });
|
|
593
|
+
*
|
|
594
|
+
* @example
|
|
595
|
+
* // Pix Automático (BACEN auto-debit). Requires `type: 'recurring'` and a
|
|
596
|
+
* // `productId` whose product has Pix Automático enabled. The customer
|
|
597
|
+
* // authorizes once via their bank app; cycles 2+ debit silently.
|
|
598
|
+
* const series = await garu.scheduledCharges.create({
|
|
599
|
+
* customerId: 42,
|
|
600
|
+
* productId: 17,
|
|
601
|
+
* amount: 49.9,
|
|
602
|
+
* type: 'recurring',
|
|
603
|
+
* dueDate: '2026-06-15',
|
|
604
|
+
* methods: ['pix_automatic'],
|
|
605
|
+
* recurrence: { interval: 'monthly' }
|
|
606
|
+
* });
|
|
593
607
|
*/
|
|
594
608
|
async create(params) {
|
|
595
609
|
const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
|
|
@@ -647,9 +661,9 @@ var ScheduledCharges = class {
|
|
|
647
661
|
*/
|
|
648
662
|
async get(id) {
|
|
649
663
|
return this.http.call(
|
|
650
|
-
(signal) => this.http.client.GET(`/api/scheduled-charges/${id}`, {
|
|
651
|
-
|
|
652
|
-
)
|
|
664
|
+
(signal) => this.http.client.GET(`/api/scheduled-charges/${encodeURIComponent(id)}`, {
|
|
665
|
+
signal
|
|
666
|
+
}).then((r) => r)
|
|
653
667
|
);
|
|
654
668
|
}
|
|
655
669
|
/**
|
|
@@ -665,10 +679,13 @@ var ScheduledCharges = class {
|
|
|
665
679
|
*/
|
|
666
680
|
async postpone(id, params) {
|
|
667
681
|
return this.http.call(
|
|
668
|
-
(signal) => this.http.client.POST(
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
682
|
+
(signal) => this.http.client.POST(
|
|
683
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/postpone`,
|
|
684
|
+
{
|
|
685
|
+
body: params,
|
|
686
|
+
signal
|
|
687
|
+
}
|
|
688
|
+
).then((r) => r)
|
|
672
689
|
);
|
|
673
690
|
}
|
|
674
691
|
/**
|
|
@@ -681,10 +698,13 @@ var ScheduledCharges = class {
|
|
|
681
698
|
*/
|
|
682
699
|
async pause(id, params = {}) {
|
|
683
700
|
return this.http.call(
|
|
684
|
-
(signal) => this.http.client.POST(
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
701
|
+
(signal) => this.http.client.POST(
|
|
702
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/pause`,
|
|
703
|
+
{
|
|
704
|
+
body: params,
|
|
705
|
+
signal
|
|
706
|
+
}
|
|
707
|
+
).then((r) => r)
|
|
688
708
|
);
|
|
689
709
|
}
|
|
690
710
|
/**
|
|
@@ -695,10 +715,13 @@ var ScheduledCharges = class {
|
|
|
695
715
|
*/
|
|
696
716
|
async resume(id) {
|
|
697
717
|
return this.http.call(
|
|
698
|
-
(signal) => this.http.client.POST(
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
718
|
+
(signal) => this.http.client.POST(
|
|
719
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/resume`,
|
|
720
|
+
{
|
|
721
|
+
body: {},
|
|
722
|
+
signal
|
|
723
|
+
}
|
|
724
|
+
).then((r) => r)
|
|
702
725
|
);
|
|
703
726
|
}
|
|
704
727
|
/**
|
|
@@ -726,10 +749,52 @@ var ScheduledCharges = class {
|
|
|
726
749
|
*/
|
|
727
750
|
async markPaid(id, params) {
|
|
728
751
|
return this.http.call(
|
|
729
|
-
(signal) => this.http.client.POST(
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
752
|
+
(signal) => this.http.client.POST(
|
|
753
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/mark-paid`,
|
|
754
|
+
{
|
|
755
|
+
body: params,
|
|
756
|
+
signal
|
|
757
|
+
}
|
|
758
|
+
).then((r) => r)
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Force-bill the current cycle right now instead of waiting for its due
|
|
763
|
+
* date. Runs the same dispatch the daily billing cron would (customer
|
|
764
|
+
* email/notification + outbound webhook + timeline event). Allowed only
|
|
765
|
+
* from a billable status (`scheduled` / `due_today`); a recurring series
|
|
766
|
+
* must have an open cycle (else the backend returns 400).
|
|
767
|
+
*
|
|
768
|
+
* Idempotent: if this cycle's d-day was already dispatched it reports
|
|
769
|
+
* `already_sent` and does not re-charge. Inspect `outcome` to branch.
|
|
770
|
+
*
|
|
771
|
+
* @example
|
|
772
|
+
* const result = await garu.scheduledCharges.chargeNow('sch_abc123');
|
|
773
|
+
* switch (result.outcome) {
|
|
774
|
+
* case 'dispatched':
|
|
775
|
+
* console.log(`Cobrança enviada (ciclo ${result.cycleNumber}).`);
|
|
776
|
+
* break;
|
|
777
|
+
* case 'already_sent':
|
|
778
|
+
* console.log('Já havia sido enviada — nada a fazer.');
|
|
779
|
+
* break;
|
|
780
|
+
* case 'failed':
|
|
781
|
+
* // result.reason is e.g. 'card_expired' or a gateway decline code
|
|
782
|
+
* console.error(`Falha na cobrança: ${result.reason}. ${result.message}`);
|
|
783
|
+
* break;
|
|
784
|
+
* case 'not_sent':
|
|
785
|
+
* console.warn(`Não enviada (${result.reason}): ${result.message}`);
|
|
786
|
+
* break;
|
|
787
|
+
* }
|
|
788
|
+
*/
|
|
789
|
+
async chargeNow(id) {
|
|
790
|
+
return this.http.call(
|
|
791
|
+
(signal) => this.http.client.POST(
|
|
792
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/charge-now`,
|
|
793
|
+
{
|
|
794
|
+
body: {},
|
|
795
|
+
signal
|
|
796
|
+
}
|
|
797
|
+
).then((r) => r)
|
|
733
798
|
);
|
|
734
799
|
}
|
|
735
800
|
/**
|
|
@@ -745,10 +810,13 @@ var ScheduledCharges = class {
|
|
|
745
810
|
*/
|
|
746
811
|
async cancelRecurrence(id, params = {}) {
|
|
747
812
|
return this.http.call(
|
|
748
|
-
(signal) => this.http.client.POST(
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
813
|
+
(signal) => this.http.client.POST(
|
|
814
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/cancel-recurrence`,
|
|
815
|
+
{
|
|
816
|
+
body: params,
|
|
817
|
+
signal
|
|
818
|
+
}
|
|
819
|
+
).then((r) => r)
|
|
752
820
|
);
|
|
753
821
|
}
|
|
754
822
|
/**
|
|
@@ -762,10 +830,13 @@ var ScheduledCharges = class {
|
|
|
762
830
|
*/
|
|
763
831
|
async setCancelAtPeriodEnd(id, params) {
|
|
764
832
|
return this.http.call(
|
|
765
|
-
(signal) => this.http.client.POST(
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
833
|
+
(signal) => this.http.client.POST(
|
|
834
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/cancel-at-period-end`,
|
|
835
|
+
{
|
|
836
|
+
body: params,
|
|
837
|
+
signal
|
|
838
|
+
}
|
|
839
|
+
).then((r) => r)
|
|
769
840
|
);
|
|
770
841
|
}
|
|
771
842
|
/**
|
|
@@ -778,10 +849,13 @@ var ScheduledCharges = class {
|
|
|
778
849
|
*/
|
|
779
850
|
async changePaymentMethod(id, params) {
|
|
780
851
|
return this.http.call(
|
|
781
|
-
(signal) => this.http.client.POST(
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
852
|
+
(signal) => this.http.client.POST(
|
|
853
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
854
|
+
{
|
|
855
|
+
body: params,
|
|
856
|
+
signal
|
|
857
|
+
}
|
|
858
|
+
).then((r) => r)
|
|
785
859
|
);
|
|
786
860
|
}
|
|
787
861
|
/**
|
|
@@ -794,10 +868,13 @@ var ScheduledCharges = class {
|
|
|
794
868
|
*/
|
|
795
869
|
async clearPaymentMethod(id) {
|
|
796
870
|
return this.http.call(
|
|
797
|
-
(signal) => this.http.client.DELETE(
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
871
|
+
(signal) => this.http.client.DELETE(
|
|
872
|
+
`/api/scheduled-charges/${encodeURIComponent(id)}/payment-method`,
|
|
873
|
+
{
|
|
874
|
+
body: {},
|
|
875
|
+
signal
|
|
876
|
+
}
|
|
877
|
+
).then((r) => r)
|
|
801
878
|
);
|
|
802
879
|
}
|
|
803
880
|
/**
|
|
@@ -819,7 +896,7 @@ var ScheduledCharges = class {
|
|
|
819
896
|
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
820
897
|
if (params.cycleNumber !== void 0) qs.set("cycleNumber", String(params.cycleNumber));
|
|
821
898
|
const query = qs.toString();
|
|
822
|
-
const url = `/api/scheduled-charges/${id}/attempts${query ? `?${query}` : ""}`;
|
|
899
|
+
const url = `/api/scheduled-charges/${encodeURIComponent(id)}/attempts${query ? `?${query}` : ""}`;
|
|
823
900
|
return this.http.call(
|
|
824
901
|
(signal) => this.http.client.GET(url, { signal }).then(
|
|
825
902
|
(r) => r
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@garuhq/node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.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",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"typecheck": "tsc --noEmit",
|
|
47
47
|
"test": "vitest run",
|
|
48
48
|
"test:watch": "vitest",
|
|
49
|
-
"generate:fetch": "curl -sf ${GARU_SPEC_URL:-https://garu.com.br/api/
|
|
49
|
+
"generate:fetch": "curl -sf ${GARU_SPEC_URL:-https://garu.com.br/api/openapi.json} -o src/generated/openapi.json",
|
|
50
50
|
"generate:filter": "node scripts/filter-spec.mjs",
|
|
51
51
|
"generate": "npm run generate:fetch && npm run generate:filter && openapi-typescript src/generated/openapi-sdk.json -o src/generated/schema.d.ts",
|
|
52
52
|
"prepublishOnly": "npm run typecheck && npm test && npm run build"
|