@garuhq/node 0.13.0 → 0.15.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 +53 -1
- package/README.md +140 -63
- package/dist/index.cjs +96 -15
- package/dist/index.d.cts +134 -6
- package/dist/index.d.ts +134 -6
- package/dist/index.js +96 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,58 @@
|
|
|
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.15.0] — 2026-05-31
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **Product writes** — the `Products` resource now wraps the create and update
|
|
11
|
+
endpoints, not just reads:
|
|
12
|
+
- `products.create(params)` — `POST /api/products`, returns the created
|
|
13
|
+
`Product`. Only `name` is required; all other fields fall back to
|
|
14
|
+
seller/server defaults. Auto-attaches an `X-Idempotency-Key` (override
|
|
15
|
+
via `params.idempotencyKey`), so the built-in retry can't create a
|
|
16
|
+
duplicate product.
|
|
17
|
+
- `products.update(id, params)` — `PATCH /api/products/{id}`, partial update
|
|
18
|
+
returning the updated `Product`. `id` accepts the numeric id or the
|
|
19
|
+
product UUID, matching the `/api/products/:id` portal-config methods.
|
|
20
|
+
- New exported param types `CreateProductParams` and `UpdateProductParams`,
|
|
21
|
+
covering `name`, `value` (centavos), `description`, `image`, `tags`,
|
|
22
|
+
`pix`, `boleto`, `creditCard`, `pixAutomatic`, `installments`,
|
|
23
|
+
`isSubscription`, `subscriptionType`, `unitLabel`, `returnUrl`,
|
|
24
|
+
`returnUrlButtonText`, and `statementDescriptor`.
|
|
25
|
+
- Both param types include `pixAutomatic` so you can toggle Pix Automático
|
|
26
|
+
on the subscription checkout at create/update time.
|
|
27
|
+
|
|
28
|
+
## [0.14.0] — 2026-05-31
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- **Pix Automático support** — Brazil's BACEN auto-debit recurring Pix, where
|
|
33
|
+
the customer authorizes once via a consent QR/link in their bank app and
|
|
34
|
+
cycles 2+ debit silently. All changes are additive; existing
|
|
35
|
+
Card / Pix / Boleto callers are unaffected.
|
|
36
|
+
- `'pix_automatic'` added to the `ScheduledPaymentMethod` union, so
|
|
37
|
+
`scheduledCharges.create({ methods: ['pix_automatic'], ... })` is now
|
|
38
|
+
typed. Recurring-only and requires `productId` (whose product must have
|
|
39
|
+
Pix Automático enabled).
|
|
40
|
+
- `Product.pixAutomatic: boolean` — when `true`, the public subscription
|
|
41
|
+
checkout exposes Pix Automático. Enabled by default; sellers can disable
|
|
42
|
+
it per product.
|
|
43
|
+
- `'pix_automatic'` added to the `ScheduledChargeAttempt.paymentMethod`
|
|
44
|
+
union and to `WirePaymentMethodId`, so transactions/charges read back
|
|
45
|
+
from Pix Automático cycles type-check.
|
|
46
|
+
- README: new **Pix Automático** section — what it is, when to use it, how to
|
|
47
|
+
enable it on a product, creating a `pix_automatic` scheduled charge, and
|
|
48
|
+
branching webhook handlers on `paymentMethod === 'pix_automatic'`.
|
|
49
|
+
|
|
50
|
+
### Notes
|
|
51
|
+
|
|
52
|
+
- No new webhook event names: Pix Automático fires the same
|
|
53
|
+
`subscription.*` / `transaction.*` events as card recurrence. Branch on the
|
|
54
|
+
payload's `paymentMethod` field. Refused debits are **not** retried at the
|
|
55
|
+
network level — Garu fires `subscription.payment_failed` and moves the
|
|
56
|
+
series to `past_due`.
|
|
57
|
+
|
|
6
58
|
## [0.13.0] — 2026-05-25
|
|
7
59
|
|
|
8
60
|
### Added
|
|
@@ -56,7 +108,7 @@ All notable changes to `@garuhq/node` are documented in this file. Format:
|
|
|
56
108
|
|
|
57
109
|
- `webhookEvents.resend(id)` — `POST /api/webhook-events/{id}/resend`,
|
|
58
110
|
the audit-trail-preserving counterpart to `retry()`. The backend
|
|
59
|
-
inserts a
|
|
111
|
+
inserts a _clone_ event (new numeric id) that points back at the
|
|
60
112
|
source via `manualResendOf`, then dispatches that clone. The
|
|
61
113
|
original row is untouched, so the historical record of the prior
|
|
62
114
|
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,20 +198,20 @@ 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
|
-
| `chargeNow(id)`
|
|
207
|
-
| `markPaid(id, params)`
|
|
208
|
-
| `postpone(id, params)`
|
|
209
|
-
| `pause(id, params?)` / `resume(id)`
|
|
210
|
-
| `cancelRecurrence(id, params?)`
|
|
211
|
-
| `cancelAtPeriodEnd(id, { enabled })`
|
|
212
|
-
| `changePaymentMethod(id, params)`
|
|
213
|
-
| `clearPaymentMethod(id)`
|
|
214
|
-
| `listAttempts(id, params?)`
|
|
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). |
|
|
215
215
|
|
|
216
216
|
```ts
|
|
217
217
|
// Recurring with 7-day trial. `maxRecoveryDays` caps how long past the due
|
|
@@ -225,7 +225,7 @@ const series = await garu.scheduledCharges.create({
|
|
|
225
225
|
methods: ['card', 'pix'],
|
|
226
226
|
recurrence: { interval: 'monthly' },
|
|
227
227
|
trialDays: 7,
|
|
228
|
-
maxRecoveryDays: 30
|
|
228
|
+
maxRecoveryDays: 30
|
|
229
229
|
});
|
|
230
230
|
|
|
231
231
|
// Force-bill the current cycle now instead of waiting for the due date.
|
|
@@ -238,7 +238,7 @@ if (result.outcome === 'failed') {
|
|
|
238
238
|
|
|
239
239
|
// Audit why cycle 3 failed (v0.8.2)
|
|
240
240
|
const { data } = await garu.scheduledCharges.listAttempts(series.id, {
|
|
241
|
-
cycleNumber: 3
|
|
241
|
+
cycleNumber: 3
|
|
242
242
|
});
|
|
243
243
|
const declines = data.filter((a) => a.status === 'declined');
|
|
244
244
|
// → each declines[i].failureCode is one of GaruFailureCode (insufficient_funds,
|
|
@@ -264,6 +264,83 @@ function shouldAskForNewCard(code: GaruFailureCode): boolean {
|
|
|
264
264
|
|
|
265
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).
|
|
266
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
|
+
|
|
267
344
|
## Meta
|
|
268
345
|
|
|
269
346
|
Discover available payment methods and webhook events. No authentication required.
|
|
@@ -288,7 +365,7 @@ app.post('/webhooks/garu', express.raw({ type: 'application/json' }), (req, res)
|
|
|
288
365
|
const { event } = Garu.webhooks.verify({
|
|
289
366
|
payload: req.body, // raw Buffer — do NOT re-serialize parsed JSON
|
|
290
367
|
signature: req.header('x-garu-signature') ?? '',
|
|
291
|
-
secret: process.env.GARU_WEBHOOK_SECRET
|
|
368
|
+
secret: process.env.GARU_WEBHOOK_SECRET!
|
|
292
369
|
});
|
|
293
370
|
|
|
294
371
|
console.log('Received', event);
|
|
@@ -305,7 +382,7 @@ app.post('/webhooks/garu', express.raw({ type: 'application/json' }), (req, res)
|
|
|
305
382
|
|
|
306
383
|
## Webhook events
|
|
307
384
|
|
|
308
|
-
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.
|
|
309
386
|
|
|
310
387
|
```ts
|
|
311
388
|
// Surface anything that didn't make it through
|
|
@@ -317,7 +394,7 @@ console.log(event.responseStatus, event.responseBody);
|
|
|
317
394
|
|
|
318
395
|
// Audit-trail-preserving replay (recommended)
|
|
319
396
|
const clone = await garu.webhookEvents.resend(42);
|
|
320
|
-
clone.id !== event.id;
|
|
397
|
+
clone.id !== event.id; // true — fresh row with its own id
|
|
321
398
|
clone.manualResendOf === event.id; // true — points back at the source
|
|
322
399
|
```
|
|
323
400
|
|
|
@@ -328,12 +405,12 @@ Outbound deliveries of a resent event carry `Idempotency-Key: resend_<originalId
|
|
|
328
405
|
> [!NOTE]
|
|
329
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.
|
|
330
407
|
|
|
331
|
-
| Method
|
|
332
|
-
|
|
|
333
|
-
| `list(params?)`
|
|
334
|
-
| `get(id)`
|
|
335
|
-
| `resend(id, params?)`
|
|
336
|
-
| `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. |
|
|
337
414
|
|
|
338
415
|
## Error handling
|
|
339
416
|
|
|
@@ -344,7 +421,7 @@ import {
|
|
|
344
421
|
GaruAPIError,
|
|
345
422
|
GaruNotFoundError,
|
|
346
423
|
GaruRateLimitError,
|
|
347
|
-
GaruValidationError
|
|
424
|
+
GaruValidationError
|
|
348
425
|
} from '@garuhq/node';
|
|
349
426
|
|
|
350
427
|
try {
|
|
@@ -365,16 +442,16 @@ try {
|
|
|
365
442
|
}
|
|
366
443
|
```
|
|
367
444
|
|
|
368
|
-
| Error class
|
|
369
|
-
|
|
|
370
|
-
| `GaruAuthenticationError`
|
|
371
|
-
| `GaruPermissionError`
|
|
372
|
-
| `GaruNotFoundError`
|
|
373
|
-
| `GaruValidationError`
|
|
374
|
-
| `GaruRateLimitError`
|
|
375
|
-
| `GaruServerError`
|
|
376
|
-
| `GaruConnectionError`
|
|
377
|
-
| `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 |
|
|
378
455
|
|
|
379
456
|
## Retries
|
|
380
457
|
|
|
@@ -392,7 +469,7 @@ import type {
|
|
|
392
469
|
Customer,
|
|
393
470
|
CardInfo,
|
|
394
471
|
PaymentMethod,
|
|
395
|
-
MetaResponse
|
|
472
|
+
MetaResponse
|
|
396
473
|
} from '@garuhq/node';
|
|
397
474
|
```
|
|
398
475
|
|
package/dist/index.cjs
CHANGED
|
@@ -480,9 +480,12 @@ var ProductPortalConfigResource = class {
|
|
|
480
480
|
*/
|
|
481
481
|
async get(productId) {
|
|
482
482
|
return this.http.call(
|
|
483
|
-
(signal) => this.http.client.GET(
|
|
484
|
-
|
|
485
|
-
|
|
483
|
+
(signal) => this.http.client.GET(
|
|
484
|
+
`/api/products/${encodeURIComponent(String(productId))}/portal-config`,
|
|
485
|
+
{
|
|
486
|
+
signal
|
|
487
|
+
}
|
|
488
|
+
).then((r) => r)
|
|
486
489
|
);
|
|
487
490
|
}
|
|
488
491
|
/**
|
|
@@ -500,19 +503,25 @@ var ProductPortalConfigResource = class {
|
|
|
500
503
|
*/
|
|
501
504
|
async set(productId, params) {
|
|
502
505
|
return this.http.call(
|
|
503
|
-
(signal) => this.http.client.POST(
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
506
|
+
(signal) => this.http.client.POST(
|
|
507
|
+
`/api/products/${encodeURIComponent(String(productId))}/portal-config`,
|
|
508
|
+
{
|
|
509
|
+
body: params,
|
|
510
|
+
signal
|
|
511
|
+
}
|
|
512
|
+
).then((r) => r)
|
|
507
513
|
);
|
|
508
514
|
}
|
|
509
515
|
/** Same merge semantics as `set` — alias for HTTP-PATCH-prefering callers. */
|
|
510
516
|
async patch(productId, params) {
|
|
511
517
|
return this.http.call(
|
|
512
|
-
(signal) => this.http.client.PATCH(
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
518
|
+
(signal) => this.http.client.PATCH(
|
|
519
|
+
`/api/products/${encodeURIComponent(String(productId))}/portal-config`,
|
|
520
|
+
{
|
|
521
|
+
body: params,
|
|
522
|
+
signal
|
|
523
|
+
}
|
|
524
|
+
).then((r) => r)
|
|
516
525
|
);
|
|
517
526
|
}
|
|
518
527
|
/**
|
|
@@ -525,10 +534,13 @@ var ProductPortalConfigResource = class {
|
|
|
525
534
|
*/
|
|
526
535
|
async clear(productId) {
|
|
527
536
|
return this.http.call(
|
|
528
|
-
(signal) => this.http.client.DELETE(
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
537
|
+
(signal) => this.http.client.DELETE(
|
|
538
|
+
`/api/products/${encodeURIComponent(String(productId))}/portal-config`,
|
|
539
|
+
{
|
|
540
|
+
body: {},
|
|
541
|
+
signal
|
|
542
|
+
}
|
|
543
|
+
).then((r) => r)
|
|
532
544
|
);
|
|
533
545
|
}
|
|
534
546
|
};
|
|
@@ -574,6 +586,61 @@ var Products = class {
|
|
|
574
586
|
)
|
|
575
587
|
);
|
|
576
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* Create a product for the authenticated seller. Returns the created
|
|
591
|
+
* product (HTTP 201). Only `name` is required; everything else falls back
|
|
592
|
+
* to seller/server defaults.
|
|
593
|
+
*
|
|
594
|
+
* Automatically attaches an `X-Idempotency-Key` header — if you don't pass
|
|
595
|
+
* `idempotencyKey`, the SDK generates a UUIDv4. This makes the built-in
|
|
596
|
+
* retry on transient failures safe: a retried POST returns the original
|
|
597
|
+
* product instead of creating a duplicate.
|
|
598
|
+
*
|
|
599
|
+
* @example
|
|
600
|
+
* const product = await garu.products.create({
|
|
601
|
+
* name: 'Plano Mensal',
|
|
602
|
+
* value: 4990, // R$ 49,90 in centavos
|
|
603
|
+
* description: 'Acesso completo à plataforma',
|
|
604
|
+
* pix: true,
|
|
605
|
+
* creditCard: true,
|
|
606
|
+
* isSubscription: true,
|
|
607
|
+
* subscriptionType: 'monthly',
|
|
608
|
+
* pixAutomatic: true // expose Pix Automático on the subscription checkout
|
|
609
|
+
* });
|
|
610
|
+
*/
|
|
611
|
+
async create(params) {
|
|
612
|
+
const { idempotencyKey, ...body } = params;
|
|
613
|
+
const key = idempotencyKey ?? generateIdempotencyKey();
|
|
614
|
+
return this.http.call(
|
|
615
|
+
(signal) => this.http.client.POST("/api/products", {
|
|
616
|
+
body,
|
|
617
|
+
headers: { "X-Idempotency-Key": key },
|
|
618
|
+
signal
|
|
619
|
+
}).then((r) => r)
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Update a product (partial PATCH — only the fields you pass are changed).
|
|
624
|
+
* Returns the updated product.
|
|
625
|
+
*
|
|
626
|
+
* `id` accepts the numeric id or the product UUID — the same identifiers
|
|
627
|
+
* accepted elsewhere on the `/api/products/:id` path (see
|
|
628
|
+
* {@link ProductPortalConfigResource}).
|
|
629
|
+
*
|
|
630
|
+
* @example
|
|
631
|
+
* const updated = await garu.products.update('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
632
|
+
* value: 5990,
|
|
633
|
+
* pixAutomatic: true // turn on Pix Automático for this product
|
|
634
|
+
* });
|
|
635
|
+
*/
|
|
636
|
+
async update(id, params) {
|
|
637
|
+
return this.http.call(
|
|
638
|
+
(signal) => this.http.client.PATCH(`/api/products/${encodeURIComponent(String(id))}`, {
|
|
639
|
+
body: params,
|
|
640
|
+
signal
|
|
641
|
+
}).then((r) => r)
|
|
642
|
+
);
|
|
643
|
+
}
|
|
577
644
|
};
|
|
578
645
|
|
|
579
646
|
// src/resources/scheduled-charges.ts
|
|
@@ -596,6 +663,20 @@ var ScheduledCharges = class {
|
|
|
596
663
|
* methods: ['pix', 'boleto'],
|
|
597
664
|
* description: 'Mensalidade Junho'
|
|
598
665
|
* });
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* // Pix Automático (BACEN auto-debit). Requires `type: 'recurring'` and a
|
|
669
|
+
* // `productId` whose product has Pix Automático enabled. The customer
|
|
670
|
+
* // authorizes once via their bank app; cycles 2+ debit silently.
|
|
671
|
+
* const series = await garu.scheduledCharges.create({
|
|
672
|
+
* customerId: 42,
|
|
673
|
+
* productId: 17,
|
|
674
|
+
* amount: 49.9,
|
|
675
|
+
* type: 'recurring',
|
|
676
|
+
* dueDate: '2026-06-15',
|
|
677
|
+
* methods: ['pix_automatic'],
|
|
678
|
+
* recurrence: { interval: 'monthly' }
|
|
679
|
+
* });
|
|
599
680
|
*/
|
|
600
681
|
async create(params) {
|
|
601
682
|
const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
|
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;
|
|
@@ -369,7 +383,7 @@ interface ScheduledChargeAttempt {
|
|
|
369
383
|
attemptNumber: number;
|
|
370
384
|
attemptedAt: string;
|
|
371
385
|
source: ScheduledChargeAttemptSource;
|
|
372
|
-
paymentMethod: 'card' | 'pix' | 'boleto' | 'manual';
|
|
386
|
+
paymentMethod: 'card' | 'pix' | 'boleto' | 'pix_automatic' | 'manual';
|
|
373
387
|
paymentMethodId: number | null;
|
|
374
388
|
cardLast4: string | null;
|
|
375
389
|
cardBrand: string | null;
|
|
@@ -400,7 +414,11 @@ interface CreateScheduledChargeParams {
|
|
|
400
414
|
type: ScheduledChargeType;
|
|
401
415
|
/** YYYY-MM-DD in São Paulo time. Must be today or future. */
|
|
402
416
|
dueDate: string;
|
|
403
|
-
/**
|
|
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
|
+
*/
|
|
404
422
|
methods: ScheduledPaymentMethod[];
|
|
405
423
|
/** Cadence for `type='recurring'`. Must be omitted when `type='one_time'`. */
|
|
406
424
|
recurrence?: RecurrenceConfig;
|
|
@@ -503,6 +521,13 @@ interface Product {
|
|
|
503
521
|
pix: boolean;
|
|
504
522
|
boleto: boolean;
|
|
505
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;
|
|
506
531
|
installments: number[];
|
|
507
532
|
tags?: string[];
|
|
508
533
|
isSubscription?: boolean;
|
|
@@ -525,6 +550,57 @@ interface ListProductsParams {
|
|
|
525
550
|
/** Backend tab filter (e.g. `active`, `archived`). Backend default is used when omitted. */
|
|
526
551
|
tab?: string;
|
|
527
552
|
}
|
|
553
|
+
interface CreateProductParams {
|
|
554
|
+
name: string;
|
|
555
|
+
/** Price in centavos (BRL × 100). */
|
|
556
|
+
value?: number;
|
|
557
|
+
description?: string;
|
|
558
|
+
/** HTTPS URL of the product cover image. */
|
|
559
|
+
image?: string;
|
|
560
|
+
tags?: string[];
|
|
561
|
+
pix?: boolean;
|
|
562
|
+
boleto?: boolean;
|
|
563
|
+
creditCard?: boolean;
|
|
564
|
+
/**
|
|
565
|
+
* Enable Pix Automático (BACEN auto-debit recurring Pix) on the
|
|
566
|
+
* subscription checkout. Defaults to enabled server-side. Only the
|
|
567
|
+
* subscription checkout mode reads this flag. See {@link Product.pixAutomatic}.
|
|
568
|
+
*/
|
|
569
|
+
pixAutomatic?: boolean;
|
|
570
|
+
/** Max number of installments offered on credit card. */
|
|
571
|
+
installments?: number;
|
|
572
|
+
isSubscription?: boolean;
|
|
573
|
+
subscriptionType?: string;
|
|
574
|
+
unitLabel?: string;
|
|
575
|
+
returnUrl?: string;
|
|
576
|
+
returnUrlButtonText?: string;
|
|
577
|
+
/** Text shown on the buyer's card/bank statement. */
|
|
578
|
+
statementDescriptor?: string;
|
|
579
|
+
/**
|
|
580
|
+
* Idempotency key for the create request. Defaults to a generated UUIDv4.
|
|
581
|
+
* Pass your own to make a retry across process restarts safe — the backend
|
|
582
|
+
* returns the original product instead of creating a duplicate.
|
|
583
|
+
*/
|
|
584
|
+
idempotencyKey?: string;
|
|
585
|
+
}
|
|
586
|
+
interface UpdateProductParams {
|
|
587
|
+
name?: string;
|
|
588
|
+
value?: number;
|
|
589
|
+
description?: string;
|
|
590
|
+
image?: string;
|
|
591
|
+
tags?: string[];
|
|
592
|
+
pix?: boolean;
|
|
593
|
+
boleto?: boolean;
|
|
594
|
+
creditCard?: boolean;
|
|
595
|
+
pixAutomatic?: boolean;
|
|
596
|
+
installments?: number;
|
|
597
|
+
isSubscription?: boolean;
|
|
598
|
+
subscriptionType?: string;
|
|
599
|
+
unitLabel?: string;
|
|
600
|
+
returnUrl?: string;
|
|
601
|
+
returnUrlButtonText?: string;
|
|
602
|
+
statementDescriptor?: string;
|
|
603
|
+
}
|
|
528
604
|
interface MetaFeatures {
|
|
529
605
|
subscriptions: boolean;
|
|
530
606
|
checkout_sessions: boolean;
|
|
@@ -958,6 +1034,44 @@ declare class Products {
|
|
|
958
1034
|
* const product = await garu.products.get('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
959
1035
|
*/
|
|
960
1036
|
get(uuid: string): Promise<Product>;
|
|
1037
|
+
/**
|
|
1038
|
+
* Create a product for the authenticated seller. Returns the created
|
|
1039
|
+
* product (HTTP 201). Only `name` is required; everything else falls back
|
|
1040
|
+
* to seller/server defaults.
|
|
1041
|
+
*
|
|
1042
|
+
* Automatically attaches an `X-Idempotency-Key` header — if you don't pass
|
|
1043
|
+
* `idempotencyKey`, the SDK generates a UUIDv4. This makes the built-in
|
|
1044
|
+
* retry on transient failures safe: a retried POST returns the original
|
|
1045
|
+
* product instead of creating a duplicate.
|
|
1046
|
+
*
|
|
1047
|
+
* @example
|
|
1048
|
+
* const product = await garu.products.create({
|
|
1049
|
+
* name: 'Plano Mensal',
|
|
1050
|
+
* value: 4990, // R$ 49,90 in centavos
|
|
1051
|
+
* description: 'Acesso completo à plataforma',
|
|
1052
|
+
* pix: true,
|
|
1053
|
+
* creditCard: true,
|
|
1054
|
+
* isSubscription: true,
|
|
1055
|
+
* subscriptionType: 'monthly',
|
|
1056
|
+
* pixAutomatic: true // expose Pix Automático on the subscription checkout
|
|
1057
|
+
* });
|
|
1058
|
+
*/
|
|
1059
|
+
create(params: CreateProductParams): Promise<Product>;
|
|
1060
|
+
/**
|
|
1061
|
+
* Update a product (partial PATCH — only the fields you pass are changed).
|
|
1062
|
+
* Returns the updated product.
|
|
1063
|
+
*
|
|
1064
|
+
* `id` accepts the numeric id or the product UUID — the same identifiers
|
|
1065
|
+
* accepted elsewhere on the `/api/products/:id` path (see
|
|
1066
|
+
* {@link ProductPortalConfigResource}).
|
|
1067
|
+
*
|
|
1068
|
+
* @example
|
|
1069
|
+
* const updated = await garu.products.update('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
1070
|
+
* value: 5990,
|
|
1071
|
+
* pixAutomatic: true // turn on Pix Automático for this product
|
|
1072
|
+
* });
|
|
1073
|
+
*/
|
|
1074
|
+
update(id: string | number, params: UpdateProductParams): Promise<Product>;
|
|
961
1075
|
}
|
|
962
1076
|
|
|
963
1077
|
/**
|
|
@@ -991,6 +1105,20 @@ declare class ScheduledCharges {
|
|
|
991
1105
|
* methods: ['pix', 'boleto'],
|
|
992
1106
|
* description: 'Mensalidade Junho'
|
|
993
1107
|
* });
|
|
1108
|
+
*
|
|
1109
|
+
* @example
|
|
1110
|
+
* // Pix Automático (BACEN auto-debit). Requires `type: 'recurring'` and a
|
|
1111
|
+
* // `productId` whose product has Pix Automático enabled. The customer
|
|
1112
|
+
* // authorizes once via their bank app; cycles 2+ debit silently.
|
|
1113
|
+
* const series = await garu.scheduledCharges.create({
|
|
1114
|
+
* customerId: 42,
|
|
1115
|
+
* productId: 17,
|
|
1116
|
+
* amount: 49.9,
|
|
1117
|
+
* type: 'recurring',
|
|
1118
|
+
* dueDate: '2026-06-15',
|
|
1119
|
+
* methods: ['pix_automatic'],
|
|
1120
|
+
* recurrence: { interval: 'monthly' }
|
|
1121
|
+
* });
|
|
994
1122
|
*/
|
|
995
1123
|
create(params: CreateScheduledChargeParams): Promise<ScheduledChargeRecord>;
|
|
996
1124
|
/**
|
|
@@ -1352,4 +1480,4 @@ declare class GaruServerError extends GaruAPIError {
|
|
|
1352
1480
|
constructor(message: string, status: number, requestId: string | null, body: unknown);
|
|
1353
1481
|
}
|
|
1354
1482
|
|
|
1355
|
-
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 };
|
|
1483
|
+
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 CreateProductParams, 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 UpdateProductParams, 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;
|
|
@@ -369,7 +383,7 @@ interface ScheduledChargeAttempt {
|
|
|
369
383
|
attemptNumber: number;
|
|
370
384
|
attemptedAt: string;
|
|
371
385
|
source: ScheduledChargeAttemptSource;
|
|
372
|
-
paymentMethod: 'card' | 'pix' | 'boleto' | 'manual';
|
|
386
|
+
paymentMethod: 'card' | 'pix' | 'boleto' | 'pix_automatic' | 'manual';
|
|
373
387
|
paymentMethodId: number | null;
|
|
374
388
|
cardLast4: string | null;
|
|
375
389
|
cardBrand: string | null;
|
|
@@ -400,7 +414,11 @@ interface CreateScheduledChargeParams {
|
|
|
400
414
|
type: ScheduledChargeType;
|
|
401
415
|
/** YYYY-MM-DD in São Paulo time. Must be today or future. */
|
|
402
416
|
dueDate: string;
|
|
403
|
-
/**
|
|
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
|
+
*/
|
|
404
422
|
methods: ScheduledPaymentMethod[];
|
|
405
423
|
/** Cadence for `type='recurring'`. Must be omitted when `type='one_time'`. */
|
|
406
424
|
recurrence?: RecurrenceConfig;
|
|
@@ -503,6 +521,13 @@ interface Product {
|
|
|
503
521
|
pix: boolean;
|
|
504
522
|
boleto: boolean;
|
|
505
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;
|
|
506
531
|
installments: number[];
|
|
507
532
|
tags?: string[];
|
|
508
533
|
isSubscription?: boolean;
|
|
@@ -525,6 +550,57 @@ interface ListProductsParams {
|
|
|
525
550
|
/** Backend tab filter (e.g. `active`, `archived`). Backend default is used when omitted. */
|
|
526
551
|
tab?: string;
|
|
527
552
|
}
|
|
553
|
+
interface CreateProductParams {
|
|
554
|
+
name: string;
|
|
555
|
+
/** Price in centavos (BRL × 100). */
|
|
556
|
+
value?: number;
|
|
557
|
+
description?: string;
|
|
558
|
+
/** HTTPS URL of the product cover image. */
|
|
559
|
+
image?: string;
|
|
560
|
+
tags?: string[];
|
|
561
|
+
pix?: boolean;
|
|
562
|
+
boleto?: boolean;
|
|
563
|
+
creditCard?: boolean;
|
|
564
|
+
/**
|
|
565
|
+
* Enable Pix Automático (BACEN auto-debit recurring Pix) on the
|
|
566
|
+
* subscription checkout. Defaults to enabled server-side. Only the
|
|
567
|
+
* subscription checkout mode reads this flag. See {@link Product.pixAutomatic}.
|
|
568
|
+
*/
|
|
569
|
+
pixAutomatic?: boolean;
|
|
570
|
+
/** Max number of installments offered on credit card. */
|
|
571
|
+
installments?: number;
|
|
572
|
+
isSubscription?: boolean;
|
|
573
|
+
subscriptionType?: string;
|
|
574
|
+
unitLabel?: string;
|
|
575
|
+
returnUrl?: string;
|
|
576
|
+
returnUrlButtonText?: string;
|
|
577
|
+
/** Text shown on the buyer's card/bank statement. */
|
|
578
|
+
statementDescriptor?: string;
|
|
579
|
+
/**
|
|
580
|
+
* Idempotency key for the create request. Defaults to a generated UUIDv4.
|
|
581
|
+
* Pass your own to make a retry across process restarts safe — the backend
|
|
582
|
+
* returns the original product instead of creating a duplicate.
|
|
583
|
+
*/
|
|
584
|
+
idempotencyKey?: string;
|
|
585
|
+
}
|
|
586
|
+
interface UpdateProductParams {
|
|
587
|
+
name?: string;
|
|
588
|
+
value?: number;
|
|
589
|
+
description?: string;
|
|
590
|
+
image?: string;
|
|
591
|
+
tags?: string[];
|
|
592
|
+
pix?: boolean;
|
|
593
|
+
boleto?: boolean;
|
|
594
|
+
creditCard?: boolean;
|
|
595
|
+
pixAutomatic?: boolean;
|
|
596
|
+
installments?: number;
|
|
597
|
+
isSubscription?: boolean;
|
|
598
|
+
subscriptionType?: string;
|
|
599
|
+
unitLabel?: string;
|
|
600
|
+
returnUrl?: string;
|
|
601
|
+
returnUrlButtonText?: string;
|
|
602
|
+
statementDescriptor?: string;
|
|
603
|
+
}
|
|
528
604
|
interface MetaFeatures {
|
|
529
605
|
subscriptions: boolean;
|
|
530
606
|
checkout_sessions: boolean;
|
|
@@ -958,6 +1034,44 @@ declare class Products {
|
|
|
958
1034
|
* const product = await garu.products.get('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
959
1035
|
*/
|
|
960
1036
|
get(uuid: string): Promise<Product>;
|
|
1037
|
+
/**
|
|
1038
|
+
* Create a product for the authenticated seller. Returns the created
|
|
1039
|
+
* product (HTTP 201). Only `name` is required; everything else falls back
|
|
1040
|
+
* to seller/server defaults.
|
|
1041
|
+
*
|
|
1042
|
+
* Automatically attaches an `X-Idempotency-Key` header — if you don't pass
|
|
1043
|
+
* `idempotencyKey`, the SDK generates a UUIDv4. This makes the built-in
|
|
1044
|
+
* retry on transient failures safe: a retried POST returns the original
|
|
1045
|
+
* product instead of creating a duplicate.
|
|
1046
|
+
*
|
|
1047
|
+
* @example
|
|
1048
|
+
* const product = await garu.products.create({
|
|
1049
|
+
* name: 'Plano Mensal',
|
|
1050
|
+
* value: 4990, // R$ 49,90 in centavos
|
|
1051
|
+
* description: 'Acesso completo à plataforma',
|
|
1052
|
+
* pix: true,
|
|
1053
|
+
* creditCard: true,
|
|
1054
|
+
* isSubscription: true,
|
|
1055
|
+
* subscriptionType: 'monthly',
|
|
1056
|
+
* pixAutomatic: true // expose Pix Automático on the subscription checkout
|
|
1057
|
+
* });
|
|
1058
|
+
*/
|
|
1059
|
+
create(params: CreateProductParams): Promise<Product>;
|
|
1060
|
+
/**
|
|
1061
|
+
* Update a product (partial PATCH — only the fields you pass are changed).
|
|
1062
|
+
* Returns the updated product.
|
|
1063
|
+
*
|
|
1064
|
+
* `id` accepts the numeric id or the product UUID — the same identifiers
|
|
1065
|
+
* accepted elsewhere on the `/api/products/:id` path (see
|
|
1066
|
+
* {@link ProductPortalConfigResource}).
|
|
1067
|
+
*
|
|
1068
|
+
* @example
|
|
1069
|
+
* const updated = await garu.products.update('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
1070
|
+
* value: 5990,
|
|
1071
|
+
* pixAutomatic: true // turn on Pix Automático for this product
|
|
1072
|
+
* });
|
|
1073
|
+
*/
|
|
1074
|
+
update(id: string | number, params: UpdateProductParams): Promise<Product>;
|
|
961
1075
|
}
|
|
962
1076
|
|
|
963
1077
|
/**
|
|
@@ -991,6 +1105,20 @@ declare class ScheduledCharges {
|
|
|
991
1105
|
* methods: ['pix', 'boleto'],
|
|
992
1106
|
* description: 'Mensalidade Junho'
|
|
993
1107
|
* });
|
|
1108
|
+
*
|
|
1109
|
+
* @example
|
|
1110
|
+
* // Pix Automático (BACEN auto-debit). Requires `type: 'recurring'` and a
|
|
1111
|
+
* // `productId` whose product has Pix Automático enabled. The customer
|
|
1112
|
+
* // authorizes once via their bank app; cycles 2+ debit silently.
|
|
1113
|
+
* const series = await garu.scheduledCharges.create({
|
|
1114
|
+
* customerId: 42,
|
|
1115
|
+
* productId: 17,
|
|
1116
|
+
* amount: 49.9,
|
|
1117
|
+
* type: 'recurring',
|
|
1118
|
+
* dueDate: '2026-06-15',
|
|
1119
|
+
* methods: ['pix_automatic'],
|
|
1120
|
+
* recurrence: { interval: 'monthly' }
|
|
1121
|
+
* });
|
|
994
1122
|
*/
|
|
995
1123
|
create(params: CreateScheduledChargeParams): Promise<ScheduledChargeRecord>;
|
|
996
1124
|
/**
|
|
@@ -1352,4 +1480,4 @@ declare class GaruServerError extends GaruAPIError {
|
|
|
1352
1480
|
constructor(message: string, status: number, requestId: string | null, body: unknown);
|
|
1353
1481
|
}
|
|
1354
1482
|
|
|
1355
|
-
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 };
|
|
1483
|
+
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 CreateProductParams, 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 UpdateProductParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, type WirePaymentMethodId, webhooks };
|
package/dist/index.js
CHANGED
|
@@ -474,9 +474,12 @@ var ProductPortalConfigResource = class {
|
|
|
474
474
|
*/
|
|
475
475
|
async get(productId) {
|
|
476
476
|
return this.http.call(
|
|
477
|
-
(signal) => this.http.client.GET(
|
|
478
|
-
|
|
479
|
-
|
|
477
|
+
(signal) => this.http.client.GET(
|
|
478
|
+
`/api/products/${encodeURIComponent(String(productId))}/portal-config`,
|
|
479
|
+
{
|
|
480
|
+
signal
|
|
481
|
+
}
|
|
482
|
+
).then((r) => r)
|
|
480
483
|
);
|
|
481
484
|
}
|
|
482
485
|
/**
|
|
@@ -494,19 +497,25 @@ var ProductPortalConfigResource = class {
|
|
|
494
497
|
*/
|
|
495
498
|
async set(productId, params) {
|
|
496
499
|
return this.http.call(
|
|
497
|
-
(signal) => this.http.client.POST(
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
500
|
+
(signal) => this.http.client.POST(
|
|
501
|
+
`/api/products/${encodeURIComponent(String(productId))}/portal-config`,
|
|
502
|
+
{
|
|
503
|
+
body: params,
|
|
504
|
+
signal
|
|
505
|
+
}
|
|
506
|
+
).then((r) => r)
|
|
501
507
|
);
|
|
502
508
|
}
|
|
503
509
|
/** Same merge semantics as `set` — alias for HTTP-PATCH-prefering callers. */
|
|
504
510
|
async patch(productId, params) {
|
|
505
511
|
return this.http.call(
|
|
506
|
-
(signal) => this.http.client.PATCH(
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
512
|
+
(signal) => this.http.client.PATCH(
|
|
513
|
+
`/api/products/${encodeURIComponent(String(productId))}/portal-config`,
|
|
514
|
+
{
|
|
515
|
+
body: params,
|
|
516
|
+
signal
|
|
517
|
+
}
|
|
518
|
+
).then((r) => r)
|
|
510
519
|
);
|
|
511
520
|
}
|
|
512
521
|
/**
|
|
@@ -519,10 +528,13 @@ var ProductPortalConfigResource = class {
|
|
|
519
528
|
*/
|
|
520
529
|
async clear(productId) {
|
|
521
530
|
return this.http.call(
|
|
522
|
-
(signal) => this.http.client.DELETE(
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
531
|
+
(signal) => this.http.client.DELETE(
|
|
532
|
+
`/api/products/${encodeURIComponent(String(productId))}/portal-config`,
|
|
533
|
+
{
|
|
534
|
+
body: {},
|
|
535
|
+
signal
|
|
536
|
+
}
|
|
537
|
+
).then((r) => r)
|
|
526
538
|
);
|
|
527
539
|
}
|
|
528
540
|
};
|
|
@@ -568,6 +580,61 @@ var Products = class {
|
|
|
568
580
|
)
|
|
569
581
|
);
|
|
570
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* Create a product for the authenticated seller. Returns the created
|
|
585
|
+
* product (HTTP 201). Only `name` is required; everything else falls back
|
|
586
|
+
* to seller/server defaults.
|
|
587
|
+
*
|
|
588
|
+
* Automatically attaches an `X-Idempotency-Key` header — if you don't pass
|
|
589
|
+
* `idempotencyKey`, the SDK generates a UUIDv4. This makes the built-in
|
|
590
|
+
* retry on transient failures safe: a retried POST returns the original
|
|
591
|
+
* product instead of creating a duplicate.
|
|
592
|
+
*
|
|
593
|
+
* @example
|
|
594
|
+
* const product = await garu.products.create({
|
|
595
|
+
* name: 'Plano Mensal',
|
|
596
|
+
* value: 4990, // R$ 49,90 in centavos
|
|
597
|
+
* description: 'Acesso completo à plataforma',
|
|
598
|
+
* pix: true,
|
|
599
|
+
* creditCard: true,
|
|
600
|
+
* isSubscription: true,
|
|
601
|
+
* subscriptionType: 'monthly',
|
|
602
|
+
* pixAutomatic: true // expose Pix Automático on the subscription checkout
|
|
603
|
+
* });
|
|
604
|
+
*/
|
|
605
|
+
async create(params) {
|
|
606
|
+
const { idempotencyKey, ...body } = params;
|
|
607
|
+
const key = idempotencyKey ?? generateIdempotencyKey();
|
|
608
|
+
return this.http.call(
|
|
609
|
+
(signal) => this.http.client.POST("/api/products", {
|
|
610
|
+
body,
|
|
611
|
+
headers: { "X-Idempotency-Key": key },
|
|
612
|
+
signal
|
|
613
|
+
}).then((r) => r)
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Update a product (partial PATCH — only the fields you pass are changed).
|
|
618
|
+
* Returns the updated product.
|
|
619
|
+
*
|
|
620
|
+
* `id` accepts the numeric id or the product UUID — the same identifiers
|
|
621
|
+
* accepted elsewhere on the `/api/products/:id` path (see
|
|
622
|
+
* {@link ProductPortalConfigResource}).
|
|
623
|
+
*
|
|
624
|
+
* @example
|
|
625
|
+
* const updated = await garu.products.update('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
626
|
+
* value: 5990,
|
|
627
|
+
* pixAutomatic: true // turn on Pix Automático for this product
|
|
628
|
+
* });
|
|
629
|
+
*/
|
|
630
|
+
async update(id, params) {
|
|
631
|
+
return this.http.call(
|
|
632
|
+
(signal) => this.http.client.PATCH(`/api/products/${encodeURIComponent(String(id))}`, {
|
|
633
|
+
body: params,
|
|
634
|
+
signal
|
|
635
|
+
}).then((r) => r)
|
|
636
|
+
);
|
|
637
|
+
}
|
|
571
638
|
};
|
|
572
639
|
|
|
573
640
|
// src/resources/scheduled-charges.ts
|
|
@@ -590,6 +657,20 @@ var ScheduledCharges = class {
|
|
|
590
657
|
* methods: ['pix', 'boleto'],
|
|
591
658
|
* description: 'Mensalidade Junho'
|
|
592
659
|
* });
|
|
660
|
+
*
|
|
661
|
+
* @example
|
|
662
|
+
* // Pix Automático (BACEN auto-debit). Requires `type: 'recurring'` and a
|
|
663
|
+
* // `productId` whose product has Pix Automático enabled. The customer
|
|
664
|
+
* // authorizes once via their bank app; cycles 2+ debit silently.
|
|
665
|
+
* const series = await garu.scheduledCharges.create({
|
|
666
|
+
* customerId: 42,
|
|
667
|
+
* productId: 17,
|
|
668
|
+
* amount: 49.9,
|
|
669
|
+
* type: 'recurring',
|
|
670
|
+
* dueDate: '2026-06-15',
|
|
671
|
+
* methods: ['pix_automatic'],
|
|
672
|
+
* recurrence: { interval: 'monthly' }
|
|
673
|
+
* });
|
|
593
674
|
*/
|
|
594
675
|
async create(params) {
|
|
595
676
|
const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
|