@garuhq/node 0.16.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,105 @@
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
+ ## [1.1.0] — 2026-08-15
7
+
8
+
9
+ ### Added
10
+
11
+ - **`garu.installmentPlans` — boleto parcelado (carnê).** One product sold as N
12
+ monthly bank slips. This is seller-financed consumer credit, not a card
13
+ instalment: nobody guarantees a boleto, so a buyer who stops at parcela 4
14
+ leaves the seller with four parcelas and no recourse through Garu. Only the
15
+ first slip is registered at creation; the rest are emitted month by month and
16
+ the sale activates when parcela 1 compensates.
17
+ - `create` (auto-attaches `X-Idempotency-Key`, which matters more here than
18
+ anywhere else in the API — the call registers a real boleto, so a blind
19
+ retry hands one buyer two payable barcodes), `list`, `get`,
20
+ `reissueInstallment`, `postponeInstallment`, `markInstallmentPaid`,
21
+ `cancel`, `requestRefund`.
22
+ - `create` takes an optional `affiliateId`. It is fixed at sale time and every
23
+ later parcela inherits it, so omitting it pays that affiliate nothing for
24
+ the whole carnê.
25
+ - Read `totalCollected` against `totalScheduled`: they differ once a bank adds
26
+ multa or mora, and `totalCollected` can legitimately exceed what was billed.
27
+
28
+ - **`garu.refundRequests` — refunds Garu cannot make for you.** A boleto cannot
29
+ be reversed and Celcoin exposes no Pix devolução, so the funds already settled
30
+ to you and the return is a bank transfer only you can make. `list`, `get`,
31
+ `confirm`, `reject`. Confirming records that you _assert_ the money went back;
32
+ Garu never observes the transfer. Card and Woovi Pix are unaffected and keep
33
+ their real automated reversals via `garu.charges.refund`.
34
+
35
+ ## [1.0.0] — 2026-07-23
36
+
37
+ First stable release. **Breaking:** `charges` now targets the versioned public
38
+ API `/api/v1/charges`, keyed on `uuid`. If you use `garu.charges.*`, read the
39
+ migration below. Nothing else (products, customers, scheduled-charges,
40
+ webhook-events) changed.
41
+
42
+ ### Breaking
43
+
44
+ - **`charges` moved to `/api/v1/charges`** and a charge is keyed by **`uuid`**,
45
+ not a numeric `id`.
46
+ - `charges.get(id: number)` → **`charges.retrieve(uuid: string)`**.
47
+ - `charge.id` → **`charge.uuid`**.
48
+ - **`create` takes a v1 body.** `paymentMethod` uses `'creditCard'` (was
49
+ `'credit_card'`); card data goes under **`card`** (was `cardInfo`) as
50
+ `{ number, holderName, expirationDate, cvv, installments }` (was `cardNumber`).
51
+ Removed the unused `link`, `affiliateId`, `priceId` params.
52
+ - **New response shape** (`Charge`), mirroring the API:
53
+ - `amount` is now the product **base price**; the amount actually charged is
54
+ the new **`chargedTotal`** (they differ on installment card sales). Reconcile
55
+ on `chargedTotal`.
56
+ - `date`/`deadline` → **`createdAt`/`expiresAt`** (`expiresAt` is null for PIX
57
+ and card, set only for boleto).
58
+ - `paymentMethodId` → **`paymentMethod`** (`'pix' | 'boleto' | 'creditCard'`).
59
+ - New method blocks: `pix.code`, `boleto.{barcodeLine,pdfUrl}`,
60
+ `card.{brand,last4,authorizationCode}`, `refund.{amount,reason,refundedAt}`.
61
+ - **`status` is a friendly, stable set:** `pending`, `authorized`, `paid`,
62
+ `failed`, `expired`, `canceled`, `refund_pending`, `refunded`, `chargeback`.
63
+ The raw processor values (`payedPix`, `captured`, …) are gone. Note the
64
+ spelling `canceled` (one `l`).
65
+ - **`list` returns `{ data, count, totalCount, totalPages }`** (was
66
+ `{ data, meta }`), and gains `productId`, `createdAfter`, `createdBefore`,
67
+ `sort` filters.
68
+ - **`refund` amount is in reais**, not centavos, and no longer takes an
69
+ `idempotencyKey`. New **`charges.cancel(uuid)`** for unpaid charges.
70
+ - Removed the now-unused exports `PaymentMethod`, `WirePaymentMethodId`,
71
+ `CardInfo`, `toWirePaymentMethod`. Use `ChargePaymentMethod` and `CardInput`.
72
+
73
+ ### Fixed
74
+
75
+ - `charges.create()` now returns a usable charge. It previously read the raw
76
+ `/api/transactions` envelope, leaving `charge.id` undefined.
77
+ - Refund amount is reais across code, types and the README (a `1000`-for-R$10,00
78
+ example is gone). Carried over from the 0.16.x fix.
79
+
80
+ ### Migration
81
+
82
+ ```ts
83
+ // before (0.16.x)
84
+ const c = await garu.charges.create({
85
+ productId, paymentMethod: 'credit_card', customer,
86
+ cardInfo: { cardNumber: '4111…', cvv, expirationDate, holderName, installments: 2 }
87
+ });
88
+ c.id; // number
89
+ c.paymentMethodId; // 'creditcard'
90
+ const one = await garu.charges.get(c.id);
91
+ await garu.charges.refund(c.id, { amount: 1000 }); // "R$10,00" (bug: reais)
92
+
93
+ // after (1.0.0)
94
+ const c = await garu.charges.create({
95
+ productId, paymentMethod: 'creditCard', customer,
96
+ card: { number: '4111…', cvv, expirationDate, holderName, installments: 2 }
97
+ });
98
+ c.uuid; // string
99
+ c.paymentMethod; // 'creditCard'
100
+ c.chargedTotal; // what was actually charged
101
+ const one = await garu.charges.retrieve(c.uuid);
102
+ await garu.charges.refund(c.uuid, { amount: 10.0 }); // R$10,00
103
+ ```
104
+
6
105
  ## [0.16.0] — 2026-07-18
7
106
 
8
107
  ### Changed
package/README.md CHANGED
@@ -58,7 +58,7 @@ const charge = await garu.charges.create({
58
58
  }
59
59
  });
60
60
 
61
- console.log(charge.id, charge.status);
61
+ console.log(charge.uuid, charge.pix?.code);
62
62
  ```
63
63
 
64
64
  ## Setup
@@ -84,12 +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
- | `list(params?)` | List charges with pagination and filters. |
91
- | `get(id)` | Fetch a single charge by ID. |
92
- | `refund(id, params?)` | Refund a charge fully or partially. |
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. |
93
94
 
94
95
  ### Create a PIX charge
95
96
 
@@ -111,13 +112,13 @@ const charge = await garu.charges.create({
111
112
  ```ts
112
113
  const charge = await garu.charges.create({
113
114
  productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
114
- paymentMethod: 'credit_card',
115
+ paymentMethod: 'creditCard',
115
116
  card: {
116
117
  number: '4111111111111111',
117
118
  holderName: 'MARIA SILVA',
118
- expirationMonth: '12',
119
- expirationYear: '2028',
120
- cvv: '123'
119
+ expirationDate: '2030-12',
120
+ cvv: '123',
121
+ installments: 2
121
122
  },
122
123
  customer: {
123
124
  name: 'Maria Silva',
@@ -131,13 +132,13 @@ const charge = await garu.charges.create({
131
132
  ### List charges
132
133
 
133
134
  ```ts
134
- const { data, meta } = await garu.charges.list({ limit: 10 });
135
+ const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 10 });
135
136
  ```
136
137
 
137
138
  ### Refund a charge
138
139
 
139
140
  ```ts
140
- await garu.charges.refund(4472, { amount: 1000 }); // partial refund (R$10.00)
141
+ await garu.charges.refund('6f1c9b2e-…', { amount: 10.0 }); // partial refund (R$10,00, reais)
141
142
  ```
142
143
 
143
144
  > [!TIP]
@@ -425,7 +426,7 @@ import {
425
426
  } from '@garuhq/node';
426
427
 
427
428
  try {
428
- await garu.charges.refund(4472, { amount: 1000 });
429
+ await garu.charges.refund('6f1c9b2e-…', { amount: 10.0 });
429
430
  } catch (err) {
430
431
  if (err instanceof GaruNotFoundError) {
431
432
  /* 404 */