@garuhq/node 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,80 @@
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
+ ## [2.0.0] — 2026-08-22
7
+
8
+ **Breaking:** `customers` now targets the versioned public API `/api/v1/customers`,
9
+ keyed on `uuid`. If you use `garu.customers.*`, read the migration below.
10
+
11
+ ### Breaking
12
+
13
+ - **`customers` moved to `/api/v1/customers`** and a customer is keyed by
14
+ **`uuid`**, not a numeric `id`.
15
+ - `customers.get(id: number)` → **`customers.get(uuid: string)`** (name
16
+ unchanged, param type changed).
17
+ - `customers.update(id, params)` — same signature shape, but the id
18
+ argument is now the `uuid`, and the request now goes out as `PATCH`
19
+ (was `PUT`).
20
+ - `customers.setBillingEmailOverride(id, params)` / `customers.delete(id)`
21
+ — same, `id` → `uuid`.
22
+ - `CustomerRecord.id` is **removed**; there is no numeric id in the public
23
+ shape. Use `CustomerRecord.uuid` everywhere.
24
+ - **`customers.delete()` now resolves `{ removed: boolean }`** (was `void`).
25
+ - **`customers.list()` returns `{ data, count, totalCount, totalPages }`**
26
+ (was `{ data, meta }`).
27
+ - `installmentPlans.create` and `scheduledCharges.create` are **not**
28
+ migrated yet — they still take a numeric `customerId`. Fetch that id from
29
+ the dashboard or the internal `/api/customers` endpoint until those two
30
+ resources move to `/api/v1` too (tracked in `SPEC-public-api-v1.md` §9
31
+ Phase 4 on the `gateway` repo).
32
+
33
+ ### Migration
34
+
35
+ ```ts
36
+ // before (1.x)
37
+ const c = await garu.customers.create({ name, email, document, phone, personType });
38
+ c.id; // number
39
+ const one = await garu.customers.get(c.id);
40
+ await garu.customers.update(c.id, { name: 'Maria Santos' });
41
+ await garu.customers.delete(c.id);
42
+
43
+ // after (2.0.0)
44
+ const c = await garu.customers.create({ name, email, document, phone, personType });
45
+ c.uuid; // string
46
+ const one = await garu.customers.get(c.uuid);
47
+ await garu.customers.update(c.uuid, { name: 'Maria Santos' });
48
+ const { removed } = await garu.customers.delete(c.uuid);
49
+ ```
50
+
51
+ ## [1.1.0] — 2026-08-15
52
+
53
+
54
+ ### Added
55
+
56
+ - **`garu.installmentPlans` — boleto parcelado (carnê).** One product sold as N
57
+ monthly bank slips. This is seller-financed consumer credit, not a card
58
+ instalment: nobody guarantees a boleto, so a buyer who stops at parcela 4
59
+ leaves the seller with four parcelas and no recourse through Garu. Only the
60
+ first slip is registered at creation; the rest are emitted month by month and
61
+ the sale activates when parcela 1 compensates.
62
+ - `create` (auto-attaches `X-Idempotency-Key`, which matters more here than
63
+ anywhere else in the API — the call registers a real boleto, so a blind
64
+ retry hands one buyer two payable barcodes), `list`, `get`,
65
+ `reissueInstallment`, `postponeInstallment`, `markInstallmentPaid`,
66
+ `cancel`, `requestRefund`.
67
+ - `create` takes an optional `affiliateId`. It is fixed at sale time and every
68
+ later parcela inherits it, so omitting it pays that affiliate nothing for
69
+ the whole carnê.
70
+ - Read `totalCollected` against `totalScheduled`: they differ once a bank adds
71
+ multa or mora, and `totalCollected` can legitimately exceed what was billed.
72
+
73
+ - **`garu.refundRequests` — refunds Garu cannot make for you.** A boleto cannot
74
+ be reversed and Celcoin exposes no Pix devolução, so the funds already settled
75
+ to you and the return is a bank transfer only you can make. `list`, `get`,
76
+ `confirm`, `reject`. Confirming records that you _assert_ the money went back;
77
+ Garu never observes the transfer. Card and Woovi Pix are unaffected and keep
78
+ their real automated reversals via `garu.charges.refund`.
79
+
6
80
  ## [1.0.0] — 2026-07-23
7
81
 
8
82
  First stable release. **Breaking:** `charges` now targets the versioned public
package/README.md CHANGED
@@ -84,13 +84,13 @@ const garu = new Garu({
84
84
 
85
85
  ## Charges
86
86
 
87
- | Method | Description |
88
- | ----------------------- | --------------------------------------------- |
89
- | `create(params)` | Create a PIX, credit-card, or boleto charge. |
90
- | `retrieve(uuid)` | Fetch a single charge by uuid. |
91
- | `list(params?)` | List charges with pagination and filters. |
92
- | `refund(uuid, params?)` | Refund a charge fully or partially (reais). |
93
- | `cancel(uuid)` | Cancel an unpaid charge. |
87
+ | Method | Description |
88
+ | ----------------------- | -------------------------------------------- |
89
+ | `create(params)` | Create a PIX, credit-card, or boleto charge. |
90
+ | `retrieve(uuid)` | Fetch a single charge by uuid. |
91
+ | `list(params?)` | List charges with pagination and filters. |
92
+ | `refund(uuid, params?)` | Refund a charge fully or partially (reais). |
93
+ | `cancel(uuid)` | Cancel an unpaid charge. |
94
94
 
95
95
  ### Create a PIX charge
96
96
 
@@ -146,13 +146,20 @@ await garu.charges.refund('6f1c9b2e-…', { amount: 10.0 }); // partial refund (
146
146
 
147
147
  ## Customers
148
148
 
149
- | Method | Description |
150
- | -------------------- | ------------------------------------------ |
151
- | `create(params)` | Create a new customer. |
152
- | `list(params?)` | List customers with pagination and search. |
153
- | `get(id)` | Fetch a single customer by ID. |
154
- | `update(id, params)` | Update a customer's profile. |
155
- | `delete(id)` | Delete a customer. |
149
+ Backed by `/api/v1/customers`, keyed on `uuid` — there is no numeric id in
150
+ this shape. `installmentPlans.create` and `scheduledCharges.create` still
151
+ link customers by the internal numeric id (unmigrated resources); fetch that
152
+ id from the dashboard or the internal `/api/customers` endpoint until they
153
+ move to `/api/v1` too.
154
+
155
+ | Method | Description |
156
+ | --------------------------------------- | ----------------------------------------------- |
157
+ | `create(params)` | Register a customer for the current seller. |
158
+ | `list(params?)` | List customers with pagination and search. |
159
+ | `get(uuid)` | Fetch a single customer by uuid. |
160
+ | `update(uuid, params)` | Partially update a customer's profile. |
161
+ | `setBillingEmailOverride(uuid, params)` | Set or clear the sticky billing-email override. |
162
+ | `delete(uuid)` | Remove a customer from the current seller. |
156
163
 
157
164
  ```ts
158
165
  const customer = await garu.customers.create({
@@ -163,7 +170,7 @@ const customer = await garu.customers.create({
163
170
  personType: 'fisica'
164
171
  });
165
172
 
166
- const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
173
+ const { data, totalCount } = await garu.customers.list({ search: 'maria', limit: 10 });
167
174
  ```
168
175
 
169
176
  ## Products
package/dist/index.cjs CHANGED
@@ -323,6 +323,299 @@ var Charges = class {
323
323
  }
324
324
  };
325
325
 
326
+ // src/resources/installment-plans.ts
327
+ var InstallmentPlans = class {
328
+ constructor(http) {
329
+ this.http = http;
330
+ }
331
+ http;
332
+ /**
333
+ * Sell a product as a carnê. Auto-attaches `X-Idempotency-Key` (UUIDv4 if
334
+ * you don't pass `idempotencyKey`), which matters more here than anywhere
335
+ * else in the API: this call registers a REAL boleto at the bank, so a
336
+ * blind retry can put two payable barcodes in one buyer's hands.
337
+ *
338
+ * @example
339
+ * const carne = await garu.installmentPlans.create({
340
+ * productId: '40381e8e-6ee7-4b8e-9393-766a6e2109d2',
341
+ * customerId: 4821,
342
+ * installments: 12
343
+ * });
344
+ * // A R$1.200 product at fator 1,30 bills R$130,00 a month:
345
+ * carne.totalScheduled; // 1560
346
+ * carne.installmentAmount; // 130
347
+ * carne.installmentsDetail?.[0]; // parcela 1, with its barcode
348
+ *
349
+ * @example
350
+ * // Attribute the sale to an affiliate. Fixed at sale time: every later
351
+ * // parcela inherits it, so omitting it pays them nothing for the whole
352
+ * // carnê. The affiliate must already be active on this product.
353
+ * await garu.installmentPlans.create({
354
+ * productId: '40381e8e-6ee7-4b8e-9393-766a6e2109d2',
355
+ * customerId: 4821,
356
+ * installments: 6,
357
+ * firstDueDate: '2026-10-05',
358
+ * affiliateId: 5
359
+ * });
360
+ */
361
+ async create(params) {
362
+ const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
363
+ const { idempotencyKey: _omit, ...body } = params;
364
+ return this.http.call(
365
+ (signal) => this.http.client.POST("/api/v1/installment-plans", {
366
+ body,
367
+ headers: { "X-Idempotency-Key": idempotencyKey },
368
+ signal
369
+ }).then((r) => r)
370
+ );
371
+ }
372
+ /**
373
+ * List carnês, newest first. `dueFrom`/`dueTo` filter on the FIRST
374
+ * parcela's due date, which is what identifies the plan; filtering on every
375
+ * parcela would return one carnê twelve times.
376
+ *
377
+ * @example
378
+ * const atRisk = await garu.installmentPlans.list({ status: 'defaulted' });
379
+ *
380
+ * @example
381
+ * const live = await garu.installmentPlans.list({
382
+ * status: ['active', 'pending_activation'],
383
+ * customerId: 4821,
384
+ * limit: 50
385
+ * });
386
+ */
387
+ async list(params = {}) {
388
+ const qs = new URLSearchParams();
389
+ if (params.page !== void 0) qs.set("page", String(params.page));
390
+ if (params.limit !== void 0) qs.set("limit", String(params.limit));
391
+ if (params.customerId !== void 0) qs.set("customerId", String(params.customerId));
392
+ if (params.productId) qs.set("productId", params.productId);
393
+ if (params.dueFrom) qs.set("dueFrom", params.dueFrom);
394
+ if (params.dueTo) qs.set("dueTo", params.dueTo);
395
+ if (params.status) {
396
+ const statuses = Array.isArray(params.status) ? params.status : [params.status];
397
+ for (const s of statuses) qs.append("status", s);
398
+ }
399
+ const query = qs.toString();
400
+ const url = `/api/v1/installment-plans${query ? `?${query}` : ""}`;
401
+ return this.http.call(
402
+ (signal) => this.http.client.GET(url, { signal }).then(
403
+ (r) => r
404
+ )
405
+ );
406
+ }
407
+ /**
408
+ * Retrieve one carnê with every parcela: due date, status, barcode line and
409
+ * boleto PDF.
410
+ *
411
+ * @example
412
+ * const carne = await garu.installmentPlans.get(uuid);
413
+ * const unpaid = carne.installmentsDetail?.filter((i) => i.status !== 'paid');
414
+ * carne.totalCollected; // what has actually cleared, not what was billed
415
+ */
416
+ async get(uuid) {
417
+ return this.http.call(
418
+ (signal) => this.http.client.GET(`/api/v1/installment-plans/${uuid}`, { signal }).then(
419
+ (r) => r
420
+ )
421
+ );
422
+ }
423
+ /**
424
+ * Issue a segunda via for one parcela, once the current slip has expired.
425
+ *
426
+ * A boleto stays payable at any bank until its due date plus five days, so
427
+ * Garu refuses while the old barcode is still live — two live barcodes for
428
+ * one parcela is how a buyer pays it twice. Once per parcela per day.
429
+ *
430
+ * @example
431
+ * const result = await garu.installmentPlans.reissueInstallment(uuid, 4);
432
+ * if (result.status === 'emitted') {
433
+ * send(result.installment!.boleto!.barcodeLine);
434
+ * }
435
+ */
436
+ async reissueInstallment(uuid, number) {
437
+ return this.http.call(
438
+ (signal) => this.http.client.POST(
439
+ `/api/v1/installment-plans/${uuid}/installments/${number}/reissue`,
440
+ { signal }
441
+ ).then((r) => r)
442
+ );
443
+ }
444
+ /**
445
+ * Move one parcela to a later date. Its siblings keep theirs — this
446
+ * postpones a payment, it does not restructure the carnê. A slip already
447
+ * emitted stays payable on its original date until it expires.
448
+ *
449
+ * @example
450
+ * await garu.installmentPlans.postponeInstallment(uuid, 4, {
451
+ * newDueDate: '2026-12-20'
452
+ * });
453
+ */
454
+ async postponeInstallment(uuid, number, params) {
455
+ return this.http.call(
456
+ (signal) => this.http.client.POST(
457
+ `/api/v1/installment-plans/${uuid}/installments/${number}/postpone`,
458
+ { body: params, signal }
459
+ ).then((r) => r)
460
+ );
461
+ }
462
+ /**
463
+ * Record a parcela as paid, for when the buyer paid the slip but the
464
+ * webhook never arrived.
465
+ *
466
+ * Garu asks the provider to confirm the charge really compensated before
467
+ * recording it, because this settles the transaction and pays affiliate and
468
+ * co-producer commissions. A provider outage refuses the action rather than
469
+ * trusting the assertion.
470
+ *
471
+ * @example
472
+ * const parcela = await garu.installmentPlans.markInstallmentPaid(uuid, 3);
473
+ * parcela.status; // 'paid'
474
+ */
475
+ async markInstallmentPaid(uuid, number) {
476
+ return this.http.call(
477
+ (signal) => this.http.client.POST(
478
+ `/api/v1/installment-plans/${uuid}/installments/${number}/mark-paid`,
479
+ { signal }
480
+ ).then((r) => r)
481
+ );
482
+ }
483
+ /**
484
+ * Cancel the carnê. Emission and reminders stop and open slips are
485
+ * cancelled at the provider.
486
+ *
487
+ * Money already collected is NOT returned — open a refund request for that.
488
+ * A cancelled carnê is never revived by a late payment; that money opens a
489
+ * refund request instead.
490
+ *
491
+ * @example
492
+ * await garu.installmentPlans.cancel(uuid, { note: 'Comprador desistiu' });
493
+ */
494
+ async cancel(uuid, params = {}) {
495
+ return this.http.call(
496
+ (signal) => this.http.client.POST(`/api/v1/installment-plans/${uuid}/cancel`, {
497
+ body: params,
498
+ signal
499
+ }).then((r) => r)
500
+ );
501
+ }
502
+ /**
503
+ * Ask for this carnê to be refunded.
504
+ *
505
+ * Garu does NOT move the money. A boleto cannot be reversed and the funds
506
+ * already settled to you, so this records the request and notifies your
507
+ * team. Transfer the money to the buyer yourself, then close it with
508
+ * `garu.refundRequests.confirm`.
509
+ *
510
+ * @example
511
+ * const request = await garu.installmentPlans.requestRefund(uuid, {
512
+ * reason: 'Produto não entregue'
513
+ * });
514
+ * request.status; // 'pending' — nothing has moved yet
515
+ * request.amount; // defaults to everything the carnê collected
516
+ */
517
+ async requestRefund(uuid, params = {}) {
518
+ return this.http.call(
519
+ (signal) => this.http.client.POST(`/api/v1/installment-plans/${uuid}/refund-requests`, {
520
+ body: params,
521
+ signal
522
+ }).then((r) => r)
523
+ );
524
+ }
525
+ };
526
+
527
+ // src/resources/refund-requests.ts
528
+ var RefundRequests = class {
529
+ constructor(http) {
530
+ this.http = http;
531
+ }
532
+ http;
533
+ /**
534
+ * List refund requests, newest first. Covers carnê and Pix/boleto alike.
535
+ *
536
+ * @example
537
+ * // Everything you still owe a buyer.
538
+ * const owed = await garu.refundRequests.list({ status: 'pending' });
539
+ * const total = owed.data.reduce((sum, r) => sum + r.amount, 0);
540
+ *
541
+ * @example
542
+ * const forThisCarne = await garu.refundRequests.list({ planId: carne.uuid });
543
+ */
544
+ async list(params = {}) {
545
+ const qs = new URLSearchParams();
546
+ if (params.page !== void 0) qs.set("page", String(params.page));
547
+ if (params.limit !== void 0) qs.set("limit", String(params.limit));
548
+ if (params.planId) qs.set("planId", params.planId);
549
+ if (params.chargeId) qs.set("chargeId", params.chargeId);
550
+ if (params.status) {
551
+ const statuses = Array.isArray(params.status) ? params.status : [params.status];
552
+ for (const s of statuses) qs.append("status", s);
553
+ }
554
+ const query = qs.toString();
555
+ const url = `/api/v1/refund-requests${query ? `?${query}` : ""}`;
556
+ return this.http.call(
557
+ (signal) => this.http.client.GET(url, { signal }).then(
558
+ (r) => r
559
+ )
560
+ );
561
+ }
562
+ /**
563
+ * Retrieve one refund request.
564
+ *
565
+ * @example
566
+ * const request = await garu.refundRequests.get(uuid);
567
+ * request.installmentPlanId ?? request.chargeId; // exactly one is set
568
+ */
569
+ async get(uuid) {
570
+ return this.http.call(
571
+ (signal) => this.http.client.GET(`/api/v1/refund-requests/${uuid}`, { signal }).then(
572
+ (r) => r
573
+ )
574
+ );
575
+ }
576
+ /**
577
+ * Record that you returned the money. Call this AFTER transferring it.
578
+ *
579
+ * Confirming closes a carnê as refunded, stops remaining parcelas, cancels
580
+ * open slips at the provider and claws back the affiliate and co-producer
581
+ * commissions on the parcelas that cleared. For a Pix or boleto charge it
582
+ * marks the charge reversed and fires `transaction.refunded`. Idempotent:
583
+ * confirming twice does not claw back twice.
584
+ *
585
+ * @example
586
+ * // 1. You send the money to the buyer, out of band.
587
+ * // 2. Then tell Garu it happened.
588
+ * await garu.refundRequests.confirm(uuid, {
589
+ * note: 'Pix devolvido em 14/08, e2e E12345678'
590
+ * });
591
+ */
592
+ async confirm(uuid, params = {}) {
593
+ return this.http.call(
594
+ (signal) => this.http.client.POST(`/api/v1/refund-requests/${uuid}/confirm`, {
595
+ body: params,
596
+ signal
597
+ }).then((r) => r)
598
+ );
599
+ }
600
+ /**
601
+ * Decline the request. The carnê is untouched and keeps running.
602
+ * Idempotent.
603
+ *
604
+ * @example
605
+ * await garu.refundRequests.reject(uuid, {
606
+ * note: 'Produto entregue e retirado na loja em 02/08'
607
+ * });
608
+ */
609
+ async reject(uuid, params = {}) {
610
+ return this.http.call(
611
+ (signal) => this.http.client.POST(`/api/v1/refund-requests/${uuid}/reject`, {
612
+ body: params,
613
+ signal
614
+ }).then((r) => r)
615
+ );
616
+ }
617
+ };
618
+
326
619
  // src/resources/customers.ts
327
620
  var Customers = class {
328
621
  constructor(http) {
@@ -340,10 +633,11 @@ var Customers = class {
340
633
  * phone: '11987654321',
341
634
  * personType: 'fisica'
342
635
  * });
636
+ * customer.uuid;
343
637
  */
344
638
  async create(params) {
345
639
  return this.http.call(
346
- (signal) => this.http.client.POST("/api/customers", {
640
+ (signal) => this.http.client.POST("/api/v1/customers", {
347
641
  body: params,
348
642
  signal
349
643
  }).then((r) => r)
@@ -353,7 +647,11 @@ var Customers = class {
353
647
  * List customers for the authenticated seller, with pagination and search.
354
648
  *
355
649
  * @example
356
- * const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
650
+ * const { data, totalCount } = await garu.customers.list({ search: 'maria', limit: 10 });
651
+ *
652
+ * @example
653
+ * // Customers with at least one overdue scheduled charge (carnê included).
654
+ * const atRisk = await garu.customers.list({ status: 'overdue' });
357
655
  */
358
656
  async list(params = {}) {
359
657
  const query = {};
@@ -362,7 +660,7 @@ var Customers = class {
362
660
  if (params.search) query.search = params.search;
363
661
  if (params.status) query.status = params.status;
364
662
  const qs = new URLSearchParams(query).toString();
365
- const url = `/api/customers${qs ? `?${qs}` : ""}`;
663
+ const url = `/api/v1/customers${qs ? `?${qs}` : ""}`;
366
664
  return this.http.call(
367
665
  (signal) => this.http.client.GET(url, { signal }).then(
368
666
  (r) => r
@@ -370,27 +668,28 @@ var Customers = class {
370
668
  );
371
669
  }
372
670
  /**
373
- * Fetch a single customer by numeric ID.
671
+ * Fetch a single customer by uuid.
374
672
  *
375
673
  * @example
376
- * const customer = await garu.customers.get(42);
674
+ * const customer = await garu.customers.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
377
675
  */
378
- async get(id) {
676
+ async get(uuid) {
379
677
  return this.http.call(
380
- (signal) => this.http.client.GET(`/api/customers/${id}`, { signal }).then(
678
+ (signal) => this.http.client.GET(`/api/v1/customers/${uuid}`, { signal }).then(
381
679
  (r) => r
382
680
  )
383
681
  );
384
682
  }
385
683
  /**
386
- * Update a customer's profile for the current seller.
684
+ * Update a customer's profile for the current seller. Partial — only the
685
+ * fields you pass change.
387
686
  *
388
687
  * @example
389
- * const updated = await garu.customers.update(42, { name: 'Maria Santos' });
688
+ * const updated = await garu.customers.update('a1b2c3d4-...', { name: 'Maria Santos' });
390
689
  */
391
- async update(id, params) {
690
+ async update(uuid, params) {
392
691
  return this.http.call(
393
- (signal) => this.http.client.PUT(`/api/customers/${id}`, {
692
+ (signal) => this.http.client.PATCH(`/api/v1/customers/${uuid}`, {
394
693
  body: params,
395
694
  signal
396
695
  }).then((r) => r)
@@ -405,30 +704,31 @@ var Customers = class {
405
704
  *
406
705
  * @example
407
706
  * // Set
408
- * await garu.customers.setBillingEmailOverride(42, {
707
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', {
409
708
  * billingEmailOverride: 'cobrancas@empresa.com.br'
410
709
  * });
411
710
  *
412
711
  * // Clear and fall back to the last-used email
413
- * await garu.customers.setBillingEmailOverride(42, { billingEmailOverride: null });
712
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', { billingEmailOverride: null });
414
713
  */
415
- async setBillingEmailOverride(id, params) {
714
+ async setBillingEmailOverride(uuid, params) {
416
715
  return this.http.call(
417
- (signal) => this.http.client.PATCH(`/api/customers/${id}/billing-email-override`, {
716
+ (signal) => this.http.client.PATCH(`/api/v1/customers/${uuid}/billing-email-override`, {
418
717
  body: params,
419
718
  signal
420
719
  }).then((r) => r)
421
720
  );
422
721
  }
423
722
  /**
424
- * Remove a customer from the current seller.
723
+ * Remove a customer from the current seller (unlinks your profile — the
724
+ * global customer and other sellers' profiles are untouched).
425
725
  *
426
726
  * @example
427
- * await garu.customers.delete(42);
727
+ * await garu.customers.delete('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
428
728
  */
429
- async delete(id) {
430
- await this.http.call(
431
- (signal) => this.http.client.DELETE(`/api/customers/${id}`, {
729
+ async delete(uuid) {
730
+ return this.http.call(
731
+ (signal) => this.http.client.DELETE(`/api/v1/customers/${uuid}`, {
432
732
  body: {},
433
733
  signal
434
734
  }).then((r) => r)
@@ -1166,6 +1466,10 @@ var DEFAULT_MAX_RETRIES = 2;
1166
1466
  var SDK_VERSION = "0.11.1";
1167
1467
  var Garu = class {
1168
1468
  charges;
1469
+ /** Boleto parcelado (carnê): one product sold as N monthly bank slips. */
1470
+ installmentPlans;
1471
+ /** Refunds Garu has been asked to make and cannot make for you. */
1472
+ refundRequests;
1169
1473
  customers;
1170
1474
  meta;
1171
1475
  products;
@@ -1187,6 +1491,8 @@ var Garu = class {
1187
1491
  fetch: options.fetch
1188
1492
  });
1189
1493
  this.charges = new Charges(http);
1494
+ this.installmentPlans = new InstallmentPlans(http);
1495
+ this.refundRequests = new RefundRequests(http);
1190
1496
  this.customers = new Customers(http);
1191
1497
  this.meta = new Meta(http);
1192
1498
  this.products = new Products(http);