@garuhq/node 0.16.0 → 1.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,76 @@
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.0.0] — 2026-07-23
7
+
8
+ First stable release. **Breaking:** `charges` now targets the versioned public
9
+ API `/api/v1/charges`, keyed on `uuid`. If you use `garu.charges.*`, read the
10
+ migration below. Nothing else (products, customers, scheduled-charges,
11
+ webhook-events) changed.
12
+
13
+ ### Breaking
14
+
15
+ - **`charges` moved to `/api/v1/charges`** and a charge is keyed by **`uuid`**,
16
+ not a numeric `id`.
17
+ - `charges.get(id: number)` → **`charges.retrieve(uuid: string)`**.
18
+ - `charge.id` → **`charge.uuid`**.
19
+ - **`create` takes a v1 body.** `paymentMethod` uses `'creditCard'` (was
20
+ `'credit_card'`); card data goes under **`card`** (was `cardInfo`) as
21
+ `{ number, holderName, expirationDate, cvv, installments }` (was `cardNumber`).
22
+ Removed the unused `link`, `affiliateId`, `priceId` params.
23
+ - **New response shape** (`Charge`), mirroring the API:
24
+ - `amount` is now the product **base price**; the amount actually charged is
25
+ the new **`chargedTotal`** (they differ on installment card sales). Reconcile
26
+ on `chargedTotal`.
27
+ - `date`/`deadline` → **`createdAt`/`expiresAt`** (`expiresAt` is null for PIX
28
+ and card, set only for boleto).
29
+ - `paymentMethodId` → **`paymentMethod`** (`'pix' | 'boleto' | 'creditCard'`).
30
+ - New method blocks: `pix.code`, `boleto.{barcodeLine,pdfUrl}`,
31
+ `card.{brand,last4,authorizationCode}`, `refund.{amount,reason,refundedAt}`.
32
+ - **`status` is a friendly, stable set:** `pending`, `authorized`, `paid`,
33
+ `failed`, `expired`, `canceled`, `refund_pending`, `refunded`, `chargeback`.
34
+ The raw processor values (`payedPix`, `captured`, …) are gone. Note the
35
+ spelling `canceled` (one `l`).
36
+ - **`list` returns `{ data, count, totalCount, totalPages }`** (was
37
+ `{ data, meta }`), and gains `productId`, `createdAfter`, `createdBefore`,
38
+ `sort` filters.
39
+ - **`refund` amount is in reais**, not centavos, and no longer takes an
40
+ `idempotencyKey`. New **`charges.cancel(uuid)`** for unpaid charges.
41
+ - Removed the now-unused exports `PaymentMethod`, `WirePaymentMethodId`,
42
+ `CardInfo`, `toWirePaymentMethod`. Use `ChargePaymentMethod` and `CardInput`.
43
+
44
+ ### Fixed
45
+
46
+ - `charges.create()` now returns a usable charge. It previously read the raw
47
+ `/api/transactions` envelope, leaving `charge.id` undefined.
48
+ - Refund amount is reais across code, types and the README (a `1000`-for-R$10,00
49
+ example is gone). Carried over from the 0.16.x fix.
50
+
51
+ ### Migration
52
+
53
+ ```ts
54
+ // before (0.16.x)
55
+ const c = await garu.charges.create({
56
+ productId, paymentMethod: 'credit_card', customer,
57
+ cardInfo: { cardNumber: '4111…', cvv, expirationDate, holderName, installments: 2 }
58
+ });
59
+ c.id; // number
60
+ c.paymentMethodId; // 'creditcard'
61
+ const one = await garu.charges.get(c.id);
62
+ await garu.charges.refund(c.id, { amount: 1000 }); // "R$10,00" (bug: reais)
63
+
64
+ // after (1.0.0)
65
+ const c = await garu.charges.create({
66
+ productId, paymentMethod: 'creditCard', customer,
67
+ card: { number: '4111…', cvv, expirationDate, holderName, installments: 2 }
68
+ });
69
+ c.uuid; // string
70
+ c.paymentMethod; // 'creditCard'
71
+ c.chargedTotal; // what was actually charged
72
+ const one = await garu.charges.retrieve(c.uuid);
73
+ await garu.charges.refund(c.uuid, { amount: 10.0 }); // R$10,00
74
+ ```
75
+
6
76
  ## [0.16.0] — 2026-07-18
7
77
 
8
78
  ### 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 */
package/dist/index.cjs CHANGED
@@ -192,11 +192,6 @@ function generateIdempotencyKey() {
192
192
  return crypto.randomUUID();
193
193
  }
194
194
 
195
- // src/types.ts
196
- function toWirePaymentMethod(pm) {
197
- return pm === "credit_card" ? "creditcard" : pm;
198
- }
199
-
200
195
  // src/resources/charges.ts
201
196
  var Charges = class {
202
197
  constructor(http) {
@@ -204,16 +199,16 @@ var Charges = class {
204
199
  }
205
200
  http;
206
201
  /**
207
- * Create a charge (PIX, credit card, or boleto).
202
+ * Create a charge (PIX, boleto, or credit card).
208
203
  *
209
- * Automatically attaches an `X-Idempotency-Key` header — if you don't pass
210
- * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the backend
211
- * caches the first response for 24h.
204
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
205
+ * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the same key
206
+ * returns the original charge for 24h.
212
207
  *
213
208
  * @example
214
- * // PIX charge
209
+ * // PIX — render charge.pix.code as a QR in your own checkout
215
210
  * const charge = await garu.charges.create({
216
- * productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
211
+ * productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
217
212
  * paymentMethod: 'pix',
218
213
  * customer: {
219
214
  * name: 'Maria Silva',
@@ -222,111 +217,109 @@ var Charges = class {
222
217
  * phone: '11987654321'
223
218
  * }
224
219
  * });
225
- * // charge.id, charge.status
220
+ * console.log(charge.uuid, charge.pix?.code);
226
221
  *
227
222
  * @example
228
- * // Credit card charge, 3 installments
223
+ * // Credit card, 2 installments. Server-to-server only (PCI scope).
229
224
  * const charge = await garu.charges.create({
230
- * productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
231
- * paymentMethod: 'credit_card',
225
+ * productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
226
+ * paymentMethod: 'creditCard',
232
227
  * customer: { name: 'Maria Silva', email: 'maria@exemplo.com.br', document: '12345678909', phone: '11987654321' },
233
- * cardInfo: {
234
- * cardNumber: '4111111111111111',
235
- * cvv: '123',
236
- * expirationDate: '2030-12',
228
+ * card: {
229
+ * number: '4111111111111111',
237
230
  * holderName: 'MARIA SILVA',
238
- * installments: 3
231
+ * expirationDate: '2030-12',
232
+ * cvv: '123',
233
+ * installments: 2
239
234
  * }
240
235
  * });
236
+ * // charge.amount is the base price; charge.chargedTotal is what was charged.
241
237
  */
242
238
  async create(params) {
243
239
  const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
244
- const body = this.buildCreateBody(params);
245
- return this.http.call(
246
- (signal) => this.http.client.POST("/api/transactions", {
247
- body,
248
- headers: { "X-Idempotency-Key": idempotencyKey },
249
- signal
250
- })
251
- );
240
+ const body = {
241
+ productId: params.productId,
242
+ paymentMethod: params.paymentMethod,
243
+ customer: params.customer
244
+ };
245
+ if (params.card) body.card = params.card;
246
+ if (params.checkoutSessionToken) body.checkoutSessionToken = params.checkoutSessionToken;
247
+ if (params.additionalInfo !== void 0) body.additionalInfo = params.additionalInfo;
248
+ return this.post("/api/v1/charges", body, { "X-Idempotency-Key": idempotencyKey });
252
249
  }
253
250
  /**
254
- * List charges for the authenticated seller, with pagination and filters.
251
+ * Retrieve a charge by uuid.
255
252
  *
256
253
  * @example
257
- * const { data, meta } = await garu.charges.list({ status: 'paid', limit: 10 });
258
- * // meta.total paid charges
254
+ * const charge = await garu.charges.retrieve('6f1c9b2e-4a7d-4f0b-9a3e-1d2c3b4a5e6f');
255
+ * if (charge.status === 'paid') fulfil(charge);
256
+ */
257
+ async retrieve(uuid) {
258
+ return this.get(`/api/v1/charges/${encodeURIComponent(uuid)}`);
259
+ }
260
+ /**
261
+ * List charges for the authenticated account, newest first by default.
262
+ *
263
+ * @example
264
+ * const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
265
+ * console.log(`${data.length} of ${totalCount} paid charges`);
259
266
  */
260
267
  async list(params = {}) {
261
268
  const query = {};
262
269
  if (params.page !== void 0) query.page = String(params.page);
263
270
  if (params.limit !== void 0) query.limit = String(params.limit);
264
271
  if (params.status) query.status = params.status;
265
- if (params.search) query.search = params.search;
266
272
  if (params.paymentMethod) query.paymentMethod = params.paymentMethod;
273
+ if (params.productId) query.productId = params.productId;
274
+ if (params.createdAfter) query.createdAfter = params.createdAfter;
275
+ if (params.createdBefore) query.createdBefore = params.createdBefore;
276
+ if (params.search) query.search = params.search;
277
+ if (params.sort) query.sort = params.sort;
267
278
  const qs = new URLSearchParams(query).toString();
268
- const url = `/api/transactions${qs ? `?${qs}` : ""}`;
269
- return this.http.call(
270
- (signal) => this.http.client.GET(url, { signal }).then(
271
- (r) => r
272
- )
273
- );
279
+ return this.get(`/api/v1/charges${qs ? `?${qs}` : ""}`);
274
280
  }
275
281
  /**
276
- * Fetch a single charge by numeric ID.
282
+ * Refund a charge, fully or partially. `amount` is in reais.
283
+ *
284
+ * For a Pix Automático charge the refund is a devolução: it returns with the
285
+ * charge in `refund_pending`, reaching `refunded` only once the transfer
286
+ * settles.
277
287
  *
278
288
  * @example
279
- * const charge = await garu.charges.get(4472);
280
- * if (charge.status === 'paid') { ... }
289
+ * await garu.charges.refund('6f1c9b2e-...'); // full
290
+ * await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
281
291
  */
282
- async get(id) {
283
- return this.http.call(
284
- (signal) => this.http.client.GET("/api/transactions/{id}", {
285
- params: { path: { id } },
286
- signal
287
- })
288
- );
292
+ async refund(uuid, params = {}) {
293
+ const body = {};
294
+ if (params.amount !== void 0) body.amount = params.amount;
295
+ if (params.reason !== void 0) body.reason = params.reason;
296
+ return this.post(`/api/v1/charges/${encodeURIComponent(uuid)}/refund`, body);
289
297
  }
290
298
  /**
291
- * Refund a charge — fully, or partially by passing `amount` in centavos.
299
+ * Cancel an unpaid charge.
292
300
  *
293
301
  * @example
294
- * // Full refund
295
- * await garu.charges.refund(4472);
296
- *
297
- * @example
298
- * // Partial refund of R$ 10,00
299
- * await garu.charges.refund(4472, { amount: 1000, reason: 'customer_request' });
302
+ * const { canceled } = await garu.charges.cancel('6f1c9b2e-...');
300
303
  */
301
- async refund(id, params = {}) {
302
- const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
303
- const body = {};
304
- if (params.amount !== void 0) body.amount = params.amount;
305
- if (params.reason !== void 0) body.reason = params.reason;
304
+ async cancel(uuid) {
306
305
  return this.http.call(
307
- (signal) => this.http.client.POST("/api/transactions/{id}/refund", {
308
- params: { path: { id } },
309
- body,
310
- headers: { "X-Idempotency-Key": idempotencyKey },
311
- signal
312
- })
306
+ (signal) => this.http.client.DELETE(
307
+ `/api/v1/charges/${encodeURIComponent(uuid)}`,
308
+ { signal }
309
+ )
313
310
  );
314
311
  }
315
- buildCreateBody(params) {
316
- const body = {
317
- customer: params.customer,
318
- productId: params.productId,
319
- paymentMethodId: toWirePaymentMethod(params.paymentMethod),
320
- link: params.link ?? null,
321
- affiliateId: params.affiliateId ?? null
322
- };
323
- if (params.additionalInfo !== void 0) body.additionalInfo = params.additionalInfo;
324
- if (params.priceId !== void 0) body.priceId = params.priceId;
325
- if (params.checkoutSessionToken !== void 0) {
326
- body.checkoutSessionToken = params.checkoutSessionToken;
327
- }
328
- if (params.cardInfo) body.CardInfo = params.cardInfo;
329
- return body;
312
+ // v1 charge routes are not in the generated OpenAPI schema (it is regenerated
313
+ // from a live deploy), so these use the client's untyped path.
314
+ get(url) {
315
+ return this.http.call(
316
+ (signal) => this.http.client.GET(url, { signal })
317
+ );
318
+ }
319
+ post(url, body, headers) {
320
+ return this.http.call(
321
+ (signal) => this.http.client.POST(url, { body, headers, signal })
322
+ );
330
323
  }
331
324
  };
332
325
 
package/dist/index.d.cts CHANGED
@@ -98,15 +98,13 @@ declare class HttpClient {
98
98
  * The resource layer maps friendly → wire at the edge.
99
99
  */
100
100
 
101
- type PaymentMethod = 'pix' | 'credit_card' | 'boleto';
102
101
  /**
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.
102
+ * Stable, friendly charge status. Mirrors what /api/v1/charges returns — the
103
+ * raw processor statuses (payedPix, pendingBoleto, ) are normalized server-side
104
+ * and never surface here. Act on `paid`; `authorized` is card money held but not
105
+ * captured, `refund_pending` is a Pix devolução requested but not yet settled.
107
106
  */
108
- type WirePaymentMethodId = 'pix' | 'creditcard' | 'boleto' | 'pix_automatic';
109
- type ChargeStatus = 'pending' | 'authorized' | 'paid' | 'failed' | 'refunded' | 'cancelled' | 'expired';
107
+ type ChargeStatus = 'pending' | 'authorized' | 'paid' | 'failed' | 'expired' | 'canceled' | 'refund_pending' | 'refunded' | 'chargeback';
110
108
  interface Customer {
111
109
  /** Full legal name. 3–255 chars. */
112
110
  name: string;
@@ -125,78 +123,122 @@ interface Customer {
125
123
  /** 2-letter uppercase state code, e.g. `SP`. */
126
124
  state?: string;
127
125
  }
128
- interface CardInfo {
129
- /** 1319 digits, no spaces or hyphens. */
130
- cardNumber: string;
131
- /** 3 or 4 digits. */
132
- cvv: string;
133
- /** `YYYY-MM`. */
134
- expirationDate: string;
135
- /** As printed on the card. */
126
+ interface CardInput {
127
+ /** PAN, 13-19 digits, no spaces. Server-to-server only (PCI scope). */
128
+ number: string;
129
+ /** Holder name exactly as printed. */
136
130
  holderName: string;
137
- /** 1–12. */
131
+ /** Expiry as `YYYY-MM`. */
132
+ expirationDate: string;
133
+ /** 3 or 4 digits. Never stored by Garu. */
134
+ cvv: string;
135
+ /** 1-12. */
138
136
  installments: number;
139
137
  }
140
138
  interface CreateChargeParams {
141
- /** Customer buying the product. */
142
- customer: Customer;
143
139
  /** UUID of the product being charged. */
144
140
  productId: string;
145
141
  /** Payment method. */
146
- paymentMethod: PaymentMethod;
147
- /** Required when `paymentMethod` is `credit_card`. */
148
- cardInfo?: CardInfo;
149
- /** Free-form metadata attached to the charge. */
150
- additionalInfo?: string;
151
- /** Original checkout link, if any. */
152
- link?: string | null;
153
- /** Associated affiliate ID, if any. */
154
- affiliateId?: number | null;
155
- /** Subscription price ID (`price_*`), for subscription charges only. */
156
- priceId?: string | null;
157
- /** Optional pre-created checkout session token. */
158
- checkoutSessionToken?: string;
142
+ paymentMethod: ChargePaymentMethod;
143
+ /** Customer buying the product. */
144
+ customer: Customer;
159
145
  /**
160
- * Idempotency key. If omitted, the SDK generates a UUIDv4.
161
- * Keys are valid for 24h on the backend.
146
+ * Required when `paymentMethod` is `creditCard`. This is a raw PAN + CVV, so
147
+ * call the SDK only from your server, never a browser or app — it puts you in
148
+ * PCI DSS scope.
162
149
  */
150
+ card?: CardInput;
151
+ /** Optional pre-created checkout session token, for attribution. */
152
+ checkoutSessionToken?: string;
153
+ /** Free-form metadata attached to the charge. */
154
+ additionalInfo?: string;
155
+ /** Idempotency key. If omitted, the SDK generates a UUIDv4. Valid 24h. */
163
156
  idempotencyKey?: string;
164
157
  }
158
+ type ChargePaymentMethod = 'pix' | 'boleto' | 'creditCard';
165
159
  interface Charge {
166
- id: number;
160
+ /** Public identifier. Use this everywhere; there is no numeric id. */
161
+ uuid: string;
167
162
  status: ChargeStatus;
163
+ paymentMethod: ChargePaymentMethod;
164
+ /** Product base price, in decimal BRL / reais. */
168
165
  amount: number;
169
- paymentMethodId: WirePaymentMethodId;
170
- /** ISO-8601. */
171
- date: string;
166
+ /**
167
+ * What the customer is actually charged, in reais. Equals `amount` for PIX,
168
+ * boleto and 1x card; higher for installment card sales (fator markup). Use
169
+ * this to reconcile, not `amount`.
170
+ */
171
+ chargedTotal: number;
172
+ installments: number;
173
+ product: {
174
+ uuid: string;
175
+ name: string;
176
+ } | null;
177
+ /** `document` is partially masked. */
178
+ customer: {
179
+ name: string;
180
+ email: string;
181
+ document: string;
182
+ } | null;
183
+ /** Present for PIX: the copy-paste EMV code to render as a QR. */
184
+ pix: {
185
+ code: string;
186
+ } | null;
187
+ /** Present for boleto: the barcode line and a Garu-hosted PDF URL. */
188
+ boleto: {
189
+ barcodeLine: string;
190
+ pdfUrl: string;
191
+ } | null;
192
+ /** Present for card: only brand, last4 and the authorization code. */
193
+ card: {
194
+ brand: string | null;
195
+ last4: string | null;
196
+ authorizationCode: string | null;
197
+ } | null;
198
+ /** Set once refunded. `refundedAt` is null while a Pix devolução is unsettled. */
199
+ refund: {
200
+ amount: number;
201
+ reason: string | null;
202
+ refundedAt: string | null;
203
+ } | null;
172
204
  /** ISO-8601. */
173
- deadline?: string;
174
- /** Product this charge belongs to. */
175
- product?: {
176
- id: number;
177
- uuid?: string;
178
- name?: string;
179
- };
180
- [key: string]: unknown;
205
+ createdAt: string;
206
+ /** ISO-8601. Only set for boleto (due date); null for PIX and card. */
207
+ expiresAt: string | null;
181
208
  }
182
209
  interface RefundChargeParams {
183
- /** Partial refund in centavos. Omit for full refund. */
210
+ /**
211
+ * Partial refund in **decimal BRL / reais** (e.g. `10.00`) — NOT centavos.
212
+ * Omit for a full refund. Passing `1000` for "R$ 10,00" refunds a thousand
213
+ * reais.
214
+ *
215
+ * For a Pix Automático charge this starts an asynchronous devolução: the
216
+ * charge moves to `refund_pending` and only reaches `refunded` once the
217
+ * transfer settles.
218
+ */
184
219
  amount?: number;
185
220
  /** Free-form reason stored on the refund. */
186
221
  reason?: string;
187
- idempotencyKey?: string;
188
222
  }
189
223
  interface ListChargesParams {
190
224
  /** Page number (1-based). Default: 1. */
191
225
  page?: number;
192
- /** Items per page (1100). Default: 20. */
226
+ /** Items per page (1-100). Default: 20. */
193
227
  limit?: number;
194
- /** Filter by status (e.g. `paid`, `pending`). */
195
- status?: string;
228
+ /** Filter by friendly status (e.g. `paid`, `pending`). */
229
+ status?: ChargeStatus;
230
+ /** Filter by payment method. */
231
+ paymentMethod?: ChargePaymentMethod;
232
+ /** Filter by product UUID. */
233
+ productId?: string;
234
+ /** Charges created at or after this ISO-8601 instant. */
235
+ createdAfter?: string;
236
+ /** Charges created at or before this ISO-8601 instant. */
237
+ createdBefore?: string;
196
238
  /** Search by customer name, email, or document. */
197
239
  search?: string;
198
- /** Filter by payment method (`pix`, `creditcard`, `boleto`). */
199
- paymentMethod?: string;
240
+ /** Sort order. Default `-createdAt` (newest first). */
241
+ sort?: 'createdAt' | '-createdAt' | 'amount' | '-amount';
200
242
  }
201
243
  interface PaginatedList<T> {
202
244
  data: T[];
@@ -207,7 +249,18 @@ interface PaginatedList<T> {
207
249
  totalPages: number;
208
250
  };
209
251
  }
210
- type ChargeList = PaginatedList<Charge>;
252
+ interface ChargeList {
253
+ data: Charge[];
254
+ /** Items on this page. */
255
+ count: number;
256
+ /** Total matches across all pages. */
257
+ totalCount: number;
258
+ totalPages: number;
259
+ }
260
+ /** Result of cancelling a charge. */
261
+ interface CancelChargeResult {
262
+ canceled: boolean;
263
+ }
211
264
  interface CustomerRecord {
212
265
  id: number;
213
266
  name: string;
@@ -814,27 +867,27 @@ interface SetProductPortalConfigParams {
814
867
  }
815
868
 
816
869
  /**
817
- * Charges — the core of the Garu API.
870
+ * Charges — create and manage payments against a product.
818
871
  *
819
- * A charge represents a single payment attempt against a product. The SDK
820
- * surfaces charges under `garu.charges` even though the backend route is
821
- * `/api/transactions` this matches Stripe convention and is the name every
822
- * other Garu surface (MCP, CLI, docs) uses.
872
+ * Backed by `/api/v1/charges`, the versioned public contract. A charge is keyed
873
+ * by `uuid`; there is no numeric id. Create returns everything needed to render
874
+ * a transparent checkout: the PIX EMV (`pix.code`), the boleto line and a
875
+ * Garu-hosted PDF (`boleto`), or the card authorization (`card`).
823
876
  */
824
877
  declare class Charges {
825
878
  private readonly http;
826
879
  constructor(http: HttpClient);
827
880
  /**
828
- * Create a charge (PIX, credit card, or boleto).
881
+ * Create a charge (PIX, boleto, or credit card).
829
882
  *
830
- * Automatically attaches an `X-Idempotency-Key` header — if you don't pass
831
- * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the backend
832
- * caches the first response for 24h.
883
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
884
+ * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the same key
885
+ * returns the original charge for 24h.
833
886
  *
834
887
  * @example
835
- * // PIX charge
888
+ * // PIX — render charge.pix.code as a QR in your own checkout
836
889
  * const charge = await garu.charges.create({
837
- * productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
890
+ * productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
838
891
  * paymentMethod: 'pix',
839
892
  * customer: {
840
893
  * name: 'Maria Silva',
@@ -843,53 +896,62 @@ declare class Charges {
843
896
  * phone: '11987654321'
844
897
  * }
845
898
  * });
846
- * // charge.id, charge.status
899
+ * console.log(charge.uuid, charge.pix?.code);
847
900
  *
848
901
  * @example
849
- * // Credit card charge, 3 installments
902
+ * // Credit card, 2 installments. Server-to-server only (PCI scope).
850
903
  * const charge = await garu.charges.create({
851
- * productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
852
- * paymentMethod: 'credit_card',
904
+ * productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
905
+ * paymentMethod: 'creditCard',
853
906
  * customer: { name: 'Maria Silva', email: 'maria@exemplo.com.br', document: '12345678909', phone: '11987654321' },
854
- * cardInfo: {
855
- * cardNumber: '4111111111111111',
856
- * cvv: '123',
857
- * expirationDate: '2030-12',
907
+ * card: {
908
+ * number: '4111111111111111',
858
909
  * holderName: 'MARIA SILVA',
859
- * installments: 3
910
+ * expirationDate: '2030-12',
911
+ * cvv: '123',
912
+ * installments: 2
860
913
  * }
861
914
  * });
915
+ * // charge.amount is the base price; charge.chargedTotal is what was charged.
862
916
  */
863
917
  create(params: CreateChargeParams): Promise<Charge>;
864
918
  /**
865
- * List charges for the authenticated seller, with pagination and filters.
919
+ * Retrieve a charge by uuid.
866
920
  *
867
921
  * @example
868
- * const { data, meta } = await garu.charges.list({ status: 'paid', limit: 10 });
869
- * // meta.total paid charges
922
+ * const charge = await garu.charges.retrieve('6f1c9b2e-4a7d-4f0b-9a3e-1d2c3b4a5e6f');
923
+ * if (charge.status === 'paid') fulfil(charge);
870
924
  */
871
- list(params?: ListChargesParams): Promise<ChargeList>;
925
+ retrieve(uuid: string): Promise<Charge>;
872
926
  /**
873
- * Fetch a single charge by numeric ID.
927
+ * List charges for the authenticated account, newest first by default.
874
928
  *
875
929
  * @example
876
- * const charge = await garu.charges.get(4472);
877
- * if (charge.status === 'paid') { ... }
930
+ * const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
931
+ * console.log(`${data.length} of ${totalCount} paid charges`);
878
932
  */
879
- get(id: number): Promise<Charge>;
933
+ list(params?: ListChargesParams): Promise<ChargeList>;
880
934
  /**
881
- * Refund a charge fully, or partially by passing `amount` in centavos.
935
+ * Refund a charge, fully or partially. `amount` is in reais.
936
+ *
937
+ * For a Pix Automático charge the refund is a devolução: it returns with the
938
+ * charge in `refund_pending`, reaching `refunded` only once the transfer
939
+ * settles.
882
940
  *
883
941
  * @example
884
- * // Full refund
885
- * await garu.charges.refund(4472);
942
+ * await garu.charges.refund('6f1c9b2e-...'); // full
943
+ * await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
944
+ */
945
+ refund(uuid: string, params?: RefundChargeParams): Promise<Charge>;
946
+ /**
947
+ * Cancel an unpaid charge.
886
948
  *
887
949
  * @example
888
- * // Partial refund of R$ 10,00
889
- * await garu.charges.refund(4472, { amount: 1000, reason: 'customer_request' });
950
+ * const { canceled } = await garu.charges.cancel('6f1c9b2e-...');
890
951
  */
891
- refund(id: number, params?: RefundChargeParams): Promise<Charge>;
892
- private buildCreateBody;
952
+ cancel(uuid: string): Promise<CancelChargeResult>;
953
+ private get;
954
+ private post;
893
955
  }
894
956
 
895
957
  /**
@@ -1505,4 +1567,4 @@ declare class GaruServerError extends GaruAPIError {
1505
1567
  constructor(message: string, status: number, requestId: string | null, body: unknown);
1506
1568
  }
1507
1569
 
1508
- 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 };
1570
+ export { type CancelAtPeriodEndScheduledChargeParams, type CancelChargeResult, type CancelRecurrenceScheduledChargeParams, type CardInput, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeNowOutcome, type ChargeNowReason, type ChargeNowResult, type ChargePaymentMethod, 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 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, webhooks };
package/dist/index.d.ts CHANGED
@@ -98,15 +98,13 @@ declare class HttpClient {
98
98
  * The resource layer maps friendly → wire at the edge.
99
99
  */
100
100
 
101
- type PaymentMethod = 'pix' | 'credit_card' | 'boleto';
102
101
  /**
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.
102
+ * Stable, friendly charge status. Mirrors what /api/v1/charges returns — the
103
+ * raw processor statuses (payedPix, pendingBoleto, ) are normalized server-side
104
+ * and never surface here. Act on `paid`; `authorized` is card money held but not
105
+ * captured, `refund_pending` is a Pix devolução requested but not yet settled.
107
106
  */
108
- type WirePaymentMethodId = 'pix' | 'creditcard' | 'boleto' | 'pix_automatic';
109
- type ChargeStatus = 'pending' | 'authorized' | 'paid' | 'failed' | 'refunded' | 'cancelled' | 'expired';
107
+ type ChargeStatus = 'pending' | 'authorized' | 'paid' | 'failed' | 'expired' | 'canceled' | 'refund_pending' | 'refunded' | 'chargeback';
110
108
  interface Customer {
111
109
  /** Full legal name. 3–255 chars. */
112
110
  name: string;
@@ -125,78 +123,122 @@ interface Customer {
125
123
  /** 2-letter uppercase state code, e.g. `SP`. */
126
124
  state?: string;
127
125
  }
128
- interface CardInfo {
129
- /** 1319 digits, no spaces or hyphens. */
130
- cardNumber: string;
131
- /** 3 or 4 digits. */
132
- cvv: string;
133
- /** `YYYY-MM`. */
134
- expirationDate: string;
135
- /** As printed on the card. */
126
+ interface CardInput {
127
+ /** PAN, 13-19 digits, no spaces. Server-to-server only (PCI scope). */
128
+ number: string;
129
+ /** Holder name exactly as printed. */
136
130
  holderName: string;
137
- /** 1–12. */
131
+ /** Expiry as `YYYY-MM`. */
132
+ expirationDate: string;
133
+ /** 3 or 4 digits. Never stored by Garu. */
134
+ cvv: string;
135
+ /** 1-12. */
138
136
  installments: number;
139
137
  }
140
138
  interface CreateChargeParams {
141
- /** Customer buying the product. */
142
- customer: Customer;
143
139
  /** UUID of the product being charged. */
144
140
  productId: string;
145
141
  /** Payment method. */
146
- paymentMethod: PaymentMethod;
147
- /** Required when `paymentMethod` is `credit_card`. */
148
- cardInfo?: CardInfo;
149
- /** Free-form metadata attached to the charge. */
150
- additionalInfo?: string;
151
- /** Original checkout link, if any. */
152
- link?: string | null;
153
- /** Associated affiliate ID, if any. */
154
- affiliateId?: number | null;
155
- /** Subscription price ID (`price_*`), for subscription charges only. */
156
- priceId?: string | null;
157
- /** Optional pre-created checkout session token. */
158
- checkoutSessionToken?: string;
142
+ paymentMethod: ChargePaymentMethod;
143
+ /** Customer buying the product. */
144
+ customer: Customer;
159
145
  /**
160
- * Idempotency key. If omitted, the SDK generates a UUIDv4.
161
- * Keys are valid for 24h on the backend.
146
+ * Required when `paymentMethod` is `creditCard`. This is a raw PAN + CVV, so
147
+ * call the SDK only from your server, never a browser or app — it puts you in
148
+ * PCI DSS scope.
162
149
  */
150
+ card?: CardInput;
151
+ /** Optional pre-created checkout session token, for attribution. */
152
+ checkoutSessionToken?: string;
153
+ /** Free-form metadata attached to the charge. */
154
+ additionalInfo?: string;
155
+ /** Idempotency key. If omitted, the SDK generates a UUIDv4. Valid 24h. */
163
156
  idempotencyKey?: string;
164
157
  }
158
+ type ChargePaymentMethod = 'pix' | 'boleto' | 'creditCard';
165
159
  interface Charge {
166
- id: number;
160
+ /** Public identifier. Use this everywhere; there is no numeric id. */
161
+ uuid: string;
167
162
  status: ChargeStatus;
163
+ paymentMethod: ChargePaymentMethod;
164
+ /** Product base price, in decimal BRL / reais. */
168
165
  amount: number;
169
- paymentMethodId: WirePaymentMethodId;
170
- /** ISO-8601. */
171
- date: string;
166
+ /**
167
+ * What the customer is actually charged, in reais. Equals `amount` for PIX,
168
+ * boleto and 1x card; higher for installment card sales (fator markup). Use
169
+ * this to reconcile, not `amount`.
170
+ */
171
+ chargedTotal: number;
172
+ installments: number;
173
+ product: {
174
+ uuid: string;
175
+ name: string;
176
+ } | null;
177
+ /** `document` is partially masked. */
178
+ customer: {
179
+ name: string;
180
+ email: string;
181
+ document: string;
182
+ } | null;
183
+ /** Present for PIX: the copy-paste EMV code to render as a QR. */
184
+ pix: {
185
+ code: string;
186
+ } | null;
187
+ /** Present for boleto: the barcode line and a Garu-hosted PDF URL. */
188
+ boleto: {
189
+ barcodeLine: string;
190
+ pdfUrl: string;
191
+ } | null;
192
+ /** Present for card: only brand, last4 and the authorization code. */
193
+ card: {
194
+ brand: string | null;
195
+ last4: string | null;
196
+ authorizationCode: string | null;
197
+ } | null;
198
+ /** Set once refunded. `refundedAt` is null while a Pix devolução is unsettled. */
199
+ refund: {
200
+ amount: number;
201
+ reason: string | null;
202
+ refundedAt: string | null;
203
+ } | null;
172
204
  /** ISO-8601. */
173
- deadline?: string;
174
- /** Product this charge belongs to. */
175
- product?: {
176
- id: number;
177
- uuid?: string;
178
- name?: string;
179
- };
180
- [key: string]: unknown;
205
+ createdAt: string;
206
+ /** ISO-8601. Only set for boleto (due date); null for PIX and card. */
207
+ expiresAt: string | null;
181
208
  }
182
209
  interface RefundChargeParams {
183
- /** Partial refund in centavos. Omit for full refund. */
210
+ /**
211
+ * Partial refund in **decimal BRL / reais** (e.g. `10.00`) — NOT centavos.
212
+ * Omit for a full refund. Passing `1000` for "R$ 10,00" refunds a thousand
213
+ * reais.
214
+ *
215
+ * For a Pix Automático charge this starts an asynchronous devolução: the
216
+ * charge moves to `refund_pending` and only reaches `refunded` once the
217
+ * transfer settles.
218
+ */
184
219
  amount?: number;
185
220
  /** Free-form reason stored on the refund. */
186
221
  reason?: string;
187
- idempotencyKey?: string;
188
222
  }
189
223
  interface ListChargesParams {
190
224
  /** Page number (1-based). Default: 1. */
191
225
  page?: number;
192
- /** Items per page (1100). Default: 20. */
226
+ /** Items per page (1-100). Default: 20. */
193
227
  limit?: number;
194
- /** Filter by status (e.g. `paid`, `pending`). */
195
- status?: string;
228
+ /** Filter by friendly status (e.g. `paid`, `pending`). */
229
+ status?: ChargeStatus;
230
+ /** Filter by payment method. */
231
+ paymentMethod?: ChargePaymentMethod;
232
+ /** Filter by product UUID. */
233
+ productId?: string;
234
+ /** Charges created at or after this ISO-8601 instant. */
235
+ createdAfter?: string;
236
+ /** Charges created at or before this ISO-8601 instant. */
237
+ createdBefore?: string;
196
238
  /** Search by customer name, email, or document. */
197
239
  search?: string;
198
- /** Filter by payment method (`pix`, `creditcard`, `boleto`). */
199
- paymentMethod?: string;
240
+ /** Sort order. Default `-createdAt` (newest first). */
241
+ sort?: 'createdAt' | '-createdAt' | 'amount' | '-amount';
200
242
  }
201
243
  interface PaginatedList<T> {
202
244
  data: T[];
@@ -207,7 +249,18 @@ interface PaginatedList<T> {
207
249
  totalPages: number;
208
250
  };
209
251
  }
210
- type ChargeList = PaginatedList<Charge>;
252
+ interface ChargeList {
253
+ data: Charge[];
254
+ /** Items on this page. */
255
+ count: number;
256
+ /** Total matches across all pages. */
257
+ totalCount: number;
258
+ totalPages: number;
259
+ }
260
+ /** Result of cancelling a charge. */
261
+ interface CancelChargeResult {
262
+ canceled: boolean;
263
+ }
211
264
  interface CustomerRecord {
212
265
  id: number;
213
266
  name: string;
@@ -814,27 +867,27 @@ interface SetProductPortalConfigParams {
814
867
  }
815
868
 
816
869
  /**
817
- * Charges — the core of the Garu API.
870
+ * Charges — create and manage payments against a product.
818
871
  *
819
- * A charge represents a single payment attempt against a product. The SDK
820
- * surfaces charges under `garu.charges` even though the backend route is
821
- * `/api/transactions` this matches Stripe convention and is the name every
822
- * other Garu surface (MCP, CLI, docs) uses.
872
+ * Backed by `/api/v1/charges`, the versioned public contract. A charge is keyed
873
+ * by `uuid`; there is no numeric id. Create returns everything needed to render
874
+ * a transparent checkout: the PIX EMV (`pix.code`), the boleto line and a
875
+ * Garu-hosted PDF (`boleto`), or the card authorization (`card`).
823
876
  */
824
877
  declare class Charges {
825
878
  private readonly http;
826
879
  constructor(http: HttpClient);
827
880
  /**
828
- * Create a charge (PIX, credit card, or boleto).
881
+ * Create a charge (PIX, boleto, or credit card).
829
882
  *
830
- * Automatically attaches an `X-Idempotency-Key` header — if you don't pass
831
- * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the backend
832
- * caches the first response for 24h.
883
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
884
+ * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the same key
885
+ * returns the original charge for 24h.
833
886
  *
834
887
  * @example
835
- * // PIX charge
888
+ * // PIX — render charge.pix.code as a QR in your own checkout
836
889
  * const charge = await garu.charges.create({
837
- * productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
890
+ * productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
838
891
  * paymentMethod: 'pix',
839
892
  * customer: {
840
893
  * name: 'Maria Silva',
@@ -843,53 +896,62 @@ declare class Charges {
843
896
  * phone: '11987654321'
844
897
  * }
845
898
  * });
846
- * // charge.id, charge.status
899
+ * console.log(charge.uuid, charge.pix?.code);
847
900
  *
848
901
  * @example
849
- * // Credit card charge, 3 installments
902
+ * // Credit card, 2 installments. Server-to-server only (PCI scope).
850
903
  * const charge = await garu.charges.create({
851
- * productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
852
- * paymentMethod: 'credit_card',
904
+ * productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
905
+ * paymentMethod: 'creditCard',
853
906
  * customer: { name: 'Maria Silva', email: 'maria@exemplo.com.br', document: '12345678909', phone: '11987654321' },
854
- * cardInfo: {
855
- * cardNumber: '4111111111111111',
856
- * cvv: '123',
857
- * expirationDate: '2030-12',
907
+ * card: {
908
+ * number: '4111111111111111',
858
909
  * holderName: 'MARIA SILVA',
859
- * installments: 3
910
+ * expirationDate: '2030-12',
911
+ * cvv: '123',
912
+ * installments: 2
860
913
  * }
861
914
  * });
915
+ * // charge.amount is the base price; charge.chargedTotal is what was charged.
862
916
  */
863
917
  create(params: CreateChargeParams): Promise<Charge>;
864
918
  /**
865
- * List charges for the authenticated seller, with pagination and filters.
919
+ * Retrieve a charge by uuid.
866
920
  *
867
921
  * @example
868
- * const { data, meta } = await garu.charges.list({ status: 'paid', limit: 10 });
869
- * // meta.total paid charges
922
+ * const charge = await garu.charges.retrieve('6f1c9b2e-4a7d-4f0b-9a3e-1d2c3b4a5e6f');
923
+ * if (charge.status === 'paid') fulfil(charge);
870
924
  */
871
- list(params?: ListChargesParams): Promise<ChargeList>;
925
+ retrieve(uuid: string): Promise<Charge>;
872
926
  /**
873
- * Fetch a single charge by numeric ID.
927
+ * List charges for the authenticated account, newest first by default.
874
928
  *
875
929
  * @example
876
- * const charge = await garu.charges.get(4472);
877
- * if (charge.status === 'paid') { ... }
930
+ * const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
931
+ * console.log(`${data.length} of ${totalCount} paid charges`);
878
932
  */
879
- get(id: number): Promise<Charge>;
933
+ list(params?: ListChargesParams): Promise<ChargeList>;
880
934
  /**
881
- * Refund a charge fully, or partially by passing `amount` in centavos.
935
+ * Refund a charge, fully or partially. `amount` is in reais.
936
+ *
937
+ * For a Pix Automático charge the refund is a devolução: it returns with the
938
+ * charge in `refund_pending`, reaching `refunded` only once the transfer
939
+ * settles.
882
940
  *
883
941
  * @example
884
- * // Full refund
885
- * await garu.charges.refund(4472);
942
+ * await garu.charges.refund('6f1c9b2e-...'); // full
943
+ * await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
944
+ */
945
+ refund(uuid: string, params?: RefundChargeParams): Promise<Charge>;
946
+ /**
947
+ * Cancel an unpaid charge.
886
948
  *
887
949
  * @example
888
- * // Partial refund of R$ 10,00
889
- * await garu.charges.refund(4472, { amount: 1000, reason: 'customer_request' });
950
+ * const { canceled } = await garu.charges.cancel('6f1c9b2e-...');
890
951
  */
891
- refund(id: number, params?: RefundChargeParams): Promise<Charge>;
892
- private buildCreateBody;
952
+ cancel(uuid: string): Promise<CancelChargeResult>;
953
+ private get;
954
+ private post;
893
955
  }
894
956
 
895
957
  /**
@@ -1505,4 +1567,4 @@ declare class GaruServerError extends GaruAPIError {
1505
1567
  constructor(message: string, status: number, requestId: string | null, body: unknown);
1506
1568
  }
1507
1569
 
1508
- 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 };
1570
+ export { type CancelAtPeriodEndScheduledChargeParams, type CancelChargeResult, type CancelRecurrenceScheduledChargeParams, type CardInput, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeNowOutcome, type ChargeNowReason, type ChargeNowResult, type ChargePaymentMethod, 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 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, webhooks };
package/dist/index.js CHANGED
@@ -186,11 +186,6 @@ function generateIdempotencyKey() {
186
186
  return randomUUID();
187
187
  }
188
188
 
189
- // src/types.ts
190
- function toWirePaymentMethod(pm) {
191
- return pm === "credit_card" ? "creditcard" : pm;
192
- }
193
-
194
189
  // src/resources/charges.ts
195
190
  var Charges = class {
196
191
  constructor(http) {
@@ -198,16 +193,16 @@ var Charges = class {
198
193
  }
199
194
  http;
200
195
  /**
201
- * Create a charge (PIX, credit card, or boleto).
196
+ * Create a charge (PIX, boleto, or credit card).
202
197
  *
203
- * Automatically attaches an `X-Idempotency-Key` header — if you don't pass
204
- * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the backend
205
- * caches the first response for 24h.
198
+ * Attaches an `X-Idempotency-Key` header automatically — if you don't pass
199
+ * `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the same key
200
+ * returns the original charge for 24h.
206
201
  *
207
202
  * @example
208
- * // PIX charge
203
+ * // PIX — render charge.pix.code as a QR in your own checkout
209
204
  * const charge = await garu.charges.create({
210
- * productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
205
+ * productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
211
206
  * paymentMethod: 'pix',
212
207
  * customer: {
213
208
  * name: 'Maria Silva',
@@ -216,111 +211,109 @@ var Charges = class {
216
211
  * phone: '11987654321'
217
212
  * }
218
213
  * });
219
- * // charge.id, charge.status
214
+ * console.log(charge.uuid, charge.pix?.code);
220
215
  *
221
216
  * @example
222
- * // Credit card charge, 3 installments
217
+ * // Credit card, 2 installments. Server-to-server only (PCI scope).
223
218
  * const charge = await garu.charges.create({
224
- * productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
225
- * paymentMethod: 'credit_card',
219
+ * productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
220
+ * paymentMethod: 'creditCard',
226
221
  * customer: { name: 'Maria Silva', email: 'maria@exemplo.com.br', document: '12345678909', phone: '11987654321' },
227
- * cardInfo: {
228
- * cardNumber: '4111111111111111',
229
- * cvv: '123',
230
- * expirationDate: '2030-12',
222
+ * card: {
223
+ * number: '4111111111111111',
231
224
  * holderName: 'MARIA SILVA',
232
- * installments: 3
225
+ * expirationDate: '2030-12',
226
+ * cvv: '123',
227
+ * installments: 2
233
228
  * }
234
229
  * });
230
+ * // charge.amount is the base price; charge.chargedTotal is what was charged.
235
231
  */
236
232
  async create(params) {
237
233
  const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
238
- const body = this.buildCreateBody(params);
239
- return this.http.call(
240
- (signal) => this.http.client.POST("/api/transactions", {
241
- body,
242
- headers: { "X-Idempotency-Key": idempotencyKey },
243
- signal
244
- })
245
- );
234
+ const body = {
235
+ productId: params.productId,
236
+ paymentMethod: params.paymentMethod,
237
+ customer: params.customer
238
+ };
239
+ if (params.card) body.card = params.card;
240
+ if (params.checkoutSessionToken) body.checkoutSessionToken = params.checkoutSessionToken;
241
+ if (params.additionalInfo !== void 0) body.additionalInfo = params.additionalInfo;
242
+ return this.post("/api/v1/charges", body, { "X-Idempotency-Key": idempotencyKey });
246
243
  }
247
244
  /**
248
- * List charges for the authenticated seller, with pagination and filters.
245
+ * Retrieve a charge by uuid.
249
246
  *
250
247
  * @example
251
- * const { data, meta } = await garu.charges.list({ status: 'paid', limit: 10 });
252
- * // meta.total paid charges
248
+ * const charge = await garu.charges.retrieve('6f1c9b2e-4a7d-4f0b-9a3e-1d2c3b4a5e6f');
249
+ * if (charge.status === 'paid') fulfil(charge);
250
+ */
251
+ async retrieve(uuid) {
252
+ return this.get(`/api/v1/charges/${encodeURIComponent(uuid)}`);
253
+ }
254
+ /**
255
+ * List charges for the authenticated account, newest first by default.
256
+ *
257
+ * @example
258
+ * const { data, totalCount } = await garu.charges.list({ status: 'paid', limit: 50 });
259
+ * console.log(`${data.length} of ${totalCount} paid charges`);
253
260
  */
254
261
  async list(params = {}) {
255
262
  const query = {};
256
263
  if (params.page !== void 0) query.page = String(params.page);
257
264
  if (params.limit !== void 0) query.limit = String(params.limit);
258
265
  if (params.status) query.status = params.status;
259
- if (params.search) query.search = params.search;
260
266
  if (params.paymentMethod) query.paymentMethod = params.paymentMethod;
267
+ if (params.productId) query.productId = params.productId;
268
+ if (params.createdAfter) query.createdAfter = params.createdAfter;
269
+ if (params.createdBefore) query.createdBefore = params.createdBefore;
270
+ if (params.search) query.search = params.search;
271
+ if (params.sort) query.sort = params.sort;
261
272
  const qs = new URLSearchParams(query).toString();
262
- const url = `/api/transactions${qs ? `?${qs}` : ""}`;
263
- return this.http.call(
264
- (signal) => this.http.client.GET(url, { signal }).then(
265
- (r) => r
266
- )
267
- );
273
+ return this.get(`/api/v1/charges${qs ? `?${qs}` : ""}`);
268
274
  }
269
275
  /**
270
- * Fetch a single charge by numeric ID.
276
+ * Refund a charge, fully or partially. `amount` is in reais.
277
+ *
278
+ * For a Pix Automático charge the refund is a devolução: it returns with the
279
+ * charge in `refund_pending`, reaching `refunded` only once the transfer
280
+ * settles.
271
281
  *
272
282
  * @example
273
- * const charge = await garu.charges.get(4472);
274
- * if (charge.status === 'paid') { ... }
283
+ * await garu.charges.refund('6f1c9b2e-...'); // full
284
+ * await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
275
285
  */
276
- async get(id) {
277
- return this.http.call(
278
- (signal) => this.http.client.GET("/api/transactions/{id}", {
279
- params: { path: { id } },
280
- signal
281
- })
282
- );
286
+ async refund(uuid, params = {}) {
287
+ const body = {};
288
+ if (params.amount !== void 0) body.amount = params.amount;
289
+ if (params.reason !== void 0) body.reason = params.reason;
290
+ return this.post(`/api/v1/charges/${encodeURIComponent(uuid)}/refund`, body);
283
291
  }
284
292
  /**
285
- * Refund a charge — fully, or partially by passing `amount` in centavos.
293
+ * Cancel an unpaid charge.
286
294
  *
287
295
  * @example
288
- * // Full refund
289
- * await garu.charges.refund(4472);
290
- *
291
- * @example
292
- * // Partial refund of R$ 10,00
293
- * await garu.charges.refund(4472, { amount: 1000, reason: 'customer_request' });
296
+ * const { canceled } = await garu.charges.cancel('6f1c9b2e-...');
294
297
  */
295
- async refund(id, params = {}) {
296
- const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
297
- const body = {};
298
- if (params.amount !== void 0) body.amount = params.amount;
299
- if (params.reason !== void 0) body.reason = params.reason;
298
+ async cancel(uuid) {
300
299
  return this.http.call(
301
- (signal) => this.http.client.POST("/api/transactions/{id}/refund", {
302
- params: { path: { id } },
303
- body,
304
- headers: { "X-Idempotency-Key": idempotencyKey },
305
- signal
306
- })
300
+ (signal) => this.http.client.DELETE(
301
+ `/api/v1/charges/${encodeURIComponent(uuid)}`,
302
+ { signal }
303
+ )
307
304
  );
308
305
  }
309
- buildCreateBody(params) {
310
- const body = {
311
- customer: params.customer,
312
- productId: params.productId,
313
- paymentMethodId: toWirePaymentMethod(params.paymentMethod),
314
- link: params.link ?? null,
315
- affiliateId: params.affiliateId ?? null
316
- };
317
- if (params.additionalInfo !== void 0) body.additionalInfo = params.additionalInfo;
318
- if (params.priceId !== void 0) body.priceId = params.priceId;
319
- if (params.checkoutSessionToken !== void 0) {
320
- body.checkoutSessionToken = params.checkoutSessionToken;
321
- }
322
- if (params.cardInfo) body.CardInfo = params.cardInfo;
323
- return body;
306
+ // v1 charge routes are not in the generated OpenAPI schema (it is regenerated
307
+ // from a live deploy), so these use the client's untyped path.
308
+ get(url) {
309
+ return this.http.call(
310
+ (signal) => this.http.client.GET(url, { signal })
311
+ );
312
+ }
313
+ post(url, body, headers) {
314
+ return this.http.call(
315
+ (signal) => this.http.client.POST(url, { body, headers, signal })
316
+ );
324
317
  }
325
318
  };
326
319
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@garuhq/node",
3
- "version": "0.16.0",
3
+ "version": "1.0.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",