@garuhq/node 0.1.1 → 0.3.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 +14 -0
- package/README.md +150 -50
- package/dist/index.cjs +157 -4
- package/dist/index.d.cts +205 -3
- package/dist/index.d.ts +205 -3
- package/dist/index.js +157 -4
- package/package.json +4 -2
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
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.3.0] — 2026-04-28
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- `products` resource on the `Garu` client.
|
|
11
|
+
- `products.list({ page, limit, search, tab })` — paginated listing of the
|
|
12
|
+
authenticated seller's products (`GET /api/products/seller`).
|
|
13
|
+
- `products.get(uuid)` — fetch a single product by UUID
|
|
14
|
+
(`GET /api/products/uuid/{uuid}`). The UUID is the same identifier
|
|
15
|
+
accepted by `charges.create({ productId })`, so `products.list` is
|
|
16
|
+
the discovery path before creating a charge.
|
|
17
|
+
- `Product`, `ProductList`, `ListProductsParams` types exported from the
|
|
18
|
+
package root.
|
|
19
|
+
|
|
6
20
|
## [0.1.1] — 2026-04-08
|
|
7
21
|
|
|
8
22
|
### Security
|
package/README.md
CHANGED
|
@@ -1,15 +1,32 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# @garuhq/node
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
The official Node.js / TypeScript SDK for the [Garu](https://garu.com.br) payment gateway.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@garuhq/node)
|
|
8
|
+
[](https://github.com/Garu-Pagamentos/garu-node/actions)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://nodejs.org)
|
|
11
|
+
|
|
12
|
+
<p>
|
|
13
|
+
<a href="#quickstart">Quickstart</a> ·
|
|
14
|
+
<a href="#charges">Charges</a> ·
|
|
15
|
+
<a href="#customers">Customers</a> ·
|
|
16
|
+
<a href="#webhooks">Webhooks</a> ·
|
|
17
|
+
<a href="#error-handling">Errors</a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
</div>
|
|
4
21
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- **
|
|
10
|
-
|
|
11
|
-
- **Safe to retry** — automatic idempotency keys on every mutation, exponential backoff with
|
|
12
|
-
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
Brazilian payments (PIX, credit card, boleto) in a few lines of code.
|
|
25
|
+
|
|
26
|
+
- **Typed end-to-end** — wire types generated from the backend's OpenAPI spec; the SDK can never drift from the API.
|
|
27
|
+
- **Tiny footprint** — one runtime dependency ([`openapi-fetch`](https://openapi-ts.dev/openapi-fetch/), ~4 KB). Native `fetch`, native `crypto`.
|
|
28
|
+
- **Safe to retry** — automatic idempotency keys on every mutation, exponential backoff with full jitter, honors `Retry-After`.
|
|
29
|
+
- **LLM-friendly** — every public method has JSDoc `@example` blocks for agent autocomplete.
|
|
13
30
|
- **ESM + CJS** dual build.
|
|
14
31
|
|
|
15
32
|
## Install
|
|
@@ -22,7 +39,7 @@ pnpm add @garuhq/node
|
|
|
22
39
|
yarn add @garuhq/node
|
|
23
40
|
```
|
|
24
41
|
|
|
25
|
-
##
|
|
42
|
+
## Quickstart
|
|
26
43
|
|
|
27
44
|
```ts
|
|
28
45
|
import { Garu } from '@garuhq/node';
|
|
@@ -37,53 +54,129 @@ const charge = await garu.charges.create({
|
|
|
37
54
|
name: 'Maria Silva',
|
|
38
55
|
email: 'maria@exemplo.com.br',
|
|
39
56
|
document: '12345678909', // CPF, digits only
|
|
40
|
-
phone: '11987654321'
|
|
41
|
-
}
|
|
57
|
+
phone: '11987654321',
|
|
58
|
+
},
|
|
42
59
|
});
|
|
43
60
|
|
|
44
61
|
console.log(charge.id, charge.status);
|
|
45
62
|
```
|
|
46
63
|
|
|
47
|
-
##
|
|
64
|
+
## Setup
|
|
48
65
|
|
|
49
|
-
Get your API key from the [Garu dashboard](https://garu.com.br/inicio) → **API Keys**.
|
|
50
|
-
`sk_test_…` for test mode and `sk_live_…` for production.
|
|
66
|
+
Get your API key from the [Garu dashboard](https://garu.com.br/inicio) → **API Keys**.
|
|
51
67
|
|
|
52
68
|
```ts
|
|
53
69
|
const garu = new Garu({ apiKey: process.env.GARU_API_KEY });
|
|
54
70
|
```
|
|
55
71
|
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
> [!NOTE]
|
|
73
|
+
> Use `sk_test_…` for test mode and `sk_live_…` for production. Public endpoints like `meta.get` work without a key.
|
|
74
|
+
|
|
75
|
+
## Configuration
|
|
58
76
|
|
|
59
|
-
|
|
77
|
+
```ts
|
|
78
|
+
const garu = new Garu({
|
|
79
|
+
apiKey: process.env.GARU_API_KEY,
|
|
80
|
+
timeoutMs: 30_000, // default
|
|
81
|
+
maxRetries: 2, // default (3 total attempts)
|
|
82
|
+
});
|
|
83
|
+
```
|
|
60
84
|
|
|
61
|
-
|
|
85
|
+
## Charges
|
|
62
86
|
|
|
63
|
-
| Method |
|
|
87
|
+
| Method | Description |
|
|
64
88
|
| --------------------- | -------------------------------------------- |
|
|
65
89
|
| `create(params)` | Create a PIX, credit-card, or boleto charge. |
|
|
90
|
+
| `list(params?)` | List charges with pagination and filters. |
|
|
66
91
|
| `get(id)` | Fetch a single charge by ID. |
|
|
67
92
|
| `refund(id, params?)` | Refund a charge fully or partially. |
|
|
68
93
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
94
|
+
### Create a PIX charge
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const charge = await garu.charges.create({
|
|
98
|
+
productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
|
|
99
|
+
paymentMethod: 'pix',
|
|
100
|
+
customer: {
|
|
101
|
+
name: 'Maria Silva',
|
|
102
|
+
email: 'maria@exemplo.com.br',
|
|
103
|
+
document: '12345678909',
|
|
104
|
+
phone: '11987654321',
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
```
|
|
72
108
|
|
|
73
|
-
###
|
|
109
|
+
### Create a credit card charge
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
const charge = await garu.charges.create({
|
|
113
|
+
productId: 'b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f',
|
|
114
|
+
paymentMethod: 'credit_card',
|
|
115
|
+
card: {
|
|
116
|
+
number: '4111111111111111',
|
|
117
|
+
holderName: 'MARIA SILVA',
|
|
118
|
+
expirationMonth: '12',
|
|
119
|
+
expirationYear: '2028',
|
|
120
|
+
cvv: '123',
|
|
121
|
+
},
|
|
122
|
+
customer: {
|
|
123
|
+
name: 'Maria Silva',
|
|
124
|
+
email: 'maria@exemplo.com.br',
|
|
125
|
+
document: '12345678909',
|
|
126
|
+
phone: '11987654321',
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### List charges
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
const { data, meta } = await garu.charges.list({ limit: 10 });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Refund a charge
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
await garu.charges.refund(4472, { amount: 1000 }); // partial refund (R$10.00)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
> [!TIP]
|
|
144
|
+
> Every mutation automatically attaches an `X-Idempotency-Key` header (UUIDv4) unless you provide one via `params.idempotencyKey`. Safe to retry — the backend caches the first response for 24h.
|
|
145
|
+
|
|
146
|
+
## Customers
|
|
147
|
+
|
|
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
|
+
|
|
156
|
+
```ts
|
|
157
|
+
const customer = await garu.customers.create({
|
|
158
|
+
name: 'Maria Silva',
|
|
159
|
+
email: 'maria@exemplo.com.br',
|
|
160
|
+
document: '12345678909',
|
|
161
|
+
phone: '11987654321',
|
|
162
|
+
personType: 'fisica',
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Meta
|
|
169
|
+
|
|
170
|
+
Discover available payment methods and webhook events. No authentication required.
|
|
74
171
|
|
|
75
172
|
```ts
|
|
76
173
|
const meta = await garu.meta.get();
|
|
77
174
|
console.log(meta.version, meta.payment_methods, meta.webhook_events);
|
|
78
175
|
```
|
|
79
176
|
|
|
80
|
-
|
|
81
|
-
currently supported.
|
|
82
|
-
|
|
83
|
-
### `Garu.webhooks.verify`
|
|
177
|
+
## Webhooks
|
|
84
178
|
|
|
85
|
-
Verify
|
|
86
|
-
comparison.
|
|
179
|
+
Verify incoming webhooks with HMAC-SHA256 and constant-time comparison.
|
|
87
180
|
|
|
88
181
|
```ts
|
|
89
182
|
import express from 'express';
|
|
@@ -96,10 +189,9 @@ app.post('/webhooks/garu', express.raw({ type: 'application/json' }), (req, res)
|
|
|
96
189
|
const { event } = Garu.webhooks.verify({
|
|
97
190
|
payload: req.body, // raw Buffer — do NOT re-serialize parsed JSON
|
|
98
191
|
signature: req.header('x-garu-signature') ?? '',
|
|
99
|
-
secret: process.env.GARU_WEBHOOK_SECRET
|
|
192
|
+
secret: process.env.GARU_WEBHOOK_SECRET!,
|
|
100
193
|
});
|
|
101
194
|
|
|
102
|
-
// handle event
|
|
103
195
|
console.log('Received', event);
|
|
104
196
|
res.sendStatus(200);
|
|
105
197
|
} catch (err) {
|
|
@@ -109,16 +201,19 @@ app.post('/webhooks/garu', express.raw({ type: 'application/json' }), (req, res)
|
|
|
109
201
|
});
|
|
110
202
|
```
|
|
111
203
|
|
|
112
|
-
|
|
204
|
+
> [!IMPORTANT]
|
|
205
|
+
> Always pass the raw request body to `verify()`. Parsing and re-serializing JSON will break the signature check.
|
|
113
206
|
|
|
114
|
-
|
|
207
|
+
## Error handling
|
|
208
|
+
|
|
209
|
+
Every error extends `GaruError`. API errors include `status`, `requestId`, and `body`.
|
|
115
210
|
|
|
116
211
|
```ts
|
|
117
212
|
import {
|
|
118
213
|
GaruAPIError,
|
|
119
214
|
GaruNotFoundError,
|
|
120
215
|
GaruRateLimitError,
|
|
121
|
-
GaruValidationError
|
|
216
|
+
GaruValidationError,
|
|
122
217
|
} from '@garuhq/node';
|
|
123
218
|
|
|
124
219
|
try {
|
|
@@ -128,7 +223,7 @@ try {
|
|
|
128
223
|
/* 404 */
|
|
129
224
|
}
|
|
130
225
|
if (err instanceof GaruValidationError) {
|
|
131
|
-
/* 400/422 */
|
|
226
|
+
/* 400 / 422 */
|
|
132
227
|
}
|
|
133
228
|
if (err instanceof GaruRateLimitError) {
|
|
134
229
|
console.log('Retry in', err.retryAfterSec, 'seconds');
|
|
@@ -139,23 +234,24 @@ try {
|
|
|
139
234
|
}
|
|
140
235
|
```
|
|
141
236
|
|
|
237
|
+
| Error class | HTTP status |
|
|
238
|
+
| ----------------------------------- | ------------------ |
|
|
239
|
+
| `GaruAuthenticationError` | `401` |
|
|
240
|
+
| `GaruPermissionError` | `403` |
|
|
241
|
+
| `GaruNotFoundError` | `404` |
|
|
242
|
+
| `GaruValidationError` | `400` / `422` |
|
|
243
|
+
| `GaruRateLimitError` | `429` |
|
|
244
|
+
| `GaruServerError` | `5xx` |
|
|
245
|
+
| `GaruConnectionError` | Network failure |
|
|
246
|
+
| `GaruSignatureVerificationError` | Webhook mismatch |
|
|
247
|
+
|
|
142
248
|
## Retries
|
|
143
249
|
|
|
144
|
-
The SDK retries
|
|
145
|
-
`5xx` responses. Exponential backoff with full jitter. Honors `Retry-After`. Never retries
|
|
146
|
-
`4xx` validation errors.
|
|
147
|
-
|
|
148
|
-
```ts
|
|
149
|
-
const garu = new Garu({
|
|
150
|
-
apiKey: process.env.GARU_API_KEY,
|
|
151
|
-
timeoutMs: 30_000, // default
|
|
152
|
-
maxRetries: 2 // default (so 3 total attempts)
|
|
153
|
-
});
|
|
154
|
-
```
|
|
250
|
+
The SDK retries automatically on connection errors, `408`, `429`, and `5xx` responses. Exponential backoff with full jitter. Honors `Retry-After`. Never retries `4xx` validation errors.
|
|
155
251
|
|
|
156
252
|
## TypeScript
|
|
157
253
|
|
|
158
|
-
Ships with full `.d.ts` and strict types. All public types are exported from the root:
|
|
254
|
+
Ships with full `.d.ts` and strict types. All public types are re-exported from the root:
|
|
159
255
|
|
|
160
256
|
```ts
|
|
161
257
|
import type {
|
|
@@ -165,10 +261,14 @@ import type {
|
|
|
165
261
|
Customer,
|
|
166
262
|
CardInfo,
|
|
167
263
|
PaymentMethod,
|
|
168
|
-
MetaResponse
|
|
264
|
+
MetaResponse,
|
|
169
265
|
} from '@garuhq/node';
|
|
170
266
|
```
|
|
171
267
|
|
|
268
|
+
## Security
|
|
269
|
+
|
|
270
|
+
To report a vulnerability, **do not open a public issue**. See [SECURITY.md](SECURITY.md) for responsible disclosure instructions.
|
|
271
|
+
|
|
172
272
|
## License
|
|
173
273
|
|
|
174
|
-
MIT.
|
|
274
|
+
MIT — see [LICENSE](LICENSE) for details.
|
package/dist/index.cjs
CHANGED
|
@@ -222,7 +222,7 @@ var Charges = class {
|
|
|
222
222
|
* phone: '11987654321'
|
|
223
223
|
* }
|
|
224
224
|
* });
|
|
225
|
-
*
|
|
225
|
+
* // charge.id, charge.status
|
|
226
226
|
*
|
|
227
227
|
* @example
|
|
228
228
|
* // Credit card charge, 3 installments
|
|
@@ -250,6 +250,28 @@ var Charges = class {
|
|
|
250
250
|
})
|
|
251
251
|
);
|
|
252
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* List charges for the authenticated seller, with pagination and filters.
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* const { data, meta } = await garu.charges.list({ status: 'paid', limit: 10 });
|
|
258
|
+
* // meta.total paid charges
|
|
259
|
+
*/
|
|
260
|
+
async list(params = {}) {
|
|
261
|
+
const query = {};
|
|
262
|
+
if (params.page !== void 0) query.page = String(params.page);
|
|
263
|
+
if (params.limit !== void 0) query.limit = String(params.limit);
|
|
264
|
+
if (params.status) query.status = params.status;
|
|
265
|
+
if (params.search) query.search = params.search;
|
|
266
|
+
if (params.paymentMethod) query.paymentMethod = params.paymentMethod;
|
|
267
|
+
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
|
+
);
|
|
274
|
+
}
|
|
253
275
|
/**
|
|
254
276
|
* Fetch a single charge by numeric ID.
|
|
255
277
|
*
|
|
@@ -308,6 +330,93 @@ var Charges = class {
|
|
|
308
330
|
}
|
|
309
331
|
};
|
|
310
332
|
|
|
333
|
+
// src/resources/customers.ts
|
|
334
|
+
var Customers = class {
|
|
335
|
+
constructor(http) {
|
|
336
|
+
this.http = http;
|
|
337
|
+
}
|
|
338
|
+
http;
|
|
339
|
+
/**
|
|
340
|
+
* Create a customer and link it to the current seller.
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* const customer = await garu.customers.create({
|
|
344
|
+
* name: 'Maria Silva',
|
|
345
|
+
* email: 'maria@exemplo.com.br',
|
|
346
|
+
* document: '12345678909',
|
|
347
|
+
* phone: '11987654321',
|
|
348
|
+
* personType: 'fisica'
|
|
349
|
+
* });
|
|
350
|
+
*/
|
|
351
|
+
async create(params) {
|
|
352
|
+
return this.http.call(
|
|
353
|
+
(signal) => this.http.client.POST("/api/customers", {
|
|
354
|
+
body: params,
|
|
355
|
+
signal
|
|
356
|
+
}).then((r) => r)
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* List customers for the authenticated seller, with pagination and search.
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
|
|
364
|
+
*/
|
|
365
|
+
async list(params = {}) {
|
|
366
|
+
const query = {};
|
|
367
|
+
if (params.page !== void 0) query.page = String(params.page);
|
|
368
|
+
if (params.limit !== void 0) query.limit = String(params.limit);
|
|
369
|
+
if (params.search) query.search = params.search;
|
|
370
|
+
const qs = new URLSearchParams(query).toString();
|
|
371
|
+
const url = `/api/customers${qs ? `?${qs}` : ""}`;
|
|
372
|
+
return this.http.call(
|
|
373
|
+
(signal) => this.http.client.GET(url, { signal }).then(
|
|
374
|
+
(r) => r
|
|
375
|
+
)
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Fetch a single customer by numeric ID.
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* const customer = await garu.customers.get(42);
|
|
383
|
+
*/
|
|
384
|
+
async get(id) {
|
|
385
|
+
return this.http.call(
|
|
386
|
+
(signal) => this.http.client.GET(`/api/customers/${id}`, { signal }).then(
|
|
387
|
+
(r) => r
|
|
388
|
+
)
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Update a customer's profile for the current seller.
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* const updated = await garu.customers.update(42, { name: 'Maria Santos' });
|
|
396
|
+
*/
|
|
397
|
+
async update(id, params) {
|
|
398
|
+
return this.http.call(
|
|
399
|
+
(signal) => this.http.client.PUT(`/api/customers/${id}`, {
|
|
400
|
+
body: params,
|
|
401
|
+
signal
|
|
402
|
+
}).then((r) => r)
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Remove a customer from the current seller.
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* await garu.customers.delete(42);
|
|
410
|
+
*/
|
|
411
|
+
async delete(id) {
|
|
412
|
+
await this.http.call(
|
|
413
|
+
(signal) => this.http.client.DELETE(`/api/customers/${id}`, { signal }).then(
|
|
414
|
+
(r) => r
|
|
415
|
+
)
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
|
|
311
420
|
// src/resources/meta.ts
|
|
312
421
|
var Meta = class {
|
|
313
422
|
constructor(http) {
|
|
@@ -328,6 +437,48 @@ var Meta = class {
|
|
|
328
437
|
);
|
|
329
438
|
}
|
|
330
439
|
};
|
|
440
|
+
|
|
441
|
+
// src/resources/products.ts
|
|
442
|
+
var Products = class {
|
|
443
|
+
constructor(http) {
|
|
444
|
+
this.http = http;
|
|
445
|
+
}
|
|
446
|
+
http;
|
|
447
|
+
/**
|
|
448
|
+
* List products for the authenticated seller, with pagination and search.
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* const { data, meta } = await garu.products.list({ search: 'curso', limit: 10 });
|
|
452
|
+
*/
|
|
453
|
+
async list(params = {}) {
|
|
454
|
+
const query = {};
|
|
455
|
+
if (params.page !== void 0) query.page = String(params.page);
|
|
456
|
+
if (params.limit !== void 0) query.limit = String(params.limit);
|
|
457
|
+
if (params.search) query.search = params.search;
|
|
458
|
+
if (params.tab) query.tab = params.tab;
|
|
459
|
+
const qs = new URLSearchParams(query).toString();
|
|
460
|
+
const url = `/api/products/seller${qs ? `?${qs}` : ""}`;
|
|
461
|
+
return this.http.call(
|
|
462
|
+
(signal) => this.http.client.GET(url, { signal }).then(
|
|
463
|
+
(r) => r
|
|
464
|
+
)
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Fetch a single product by UUID — the same identifier used by
|
|
469
|
+
* `charges.create({ productId })`.
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* const product = await garu.products.get('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
473
|
+
*/
|
|
474
|
+
async get(uuid) {
|
|
475
|
+
return this.http.call(
|
|
476
|
+
(signal) => this.http.client.GET(`/api/products/uuid/${uuid}`, { signal }).then(
|
|
477
|
+
(r) => r
|
|
478
|
+
)
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
};
|
|
331
482
|
var webhooks = {
|
|
332
483
|
verify(params) {
|
|
333
484
|
const { signature, secret, payload } = params;
|
|
@@ -387,10 +538,12 @@ function parseSignatureHeader(header) {
|
|
|
387
538
|
var DEFAULT_BASE_URL = "https://garu.com.br";
|
|
388
539
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
389
540
|
var DEFAULT_MAX_RETRIES = 2;
|
|
390
|
-
var SDK_VERSION = "0.
|
|
541
|
+
var SDK_VERSION = "0.3.0";
|
|
391
542
|
var Garu = class {
|
|
392
543
|
charges;
|
|
544
|
+
customers;
|
|
393
545
|
meta;
|
|
546
|
+
products;
|
|
394
547
|
/**
|
|
395
548
|
* Webhook helpers. Available both as an instance member and as a static —
|
|
396
549
|
* `Garu.webhooks.verify(...)` works without constructing a client.
|
|
@@ -407,7 +560,9 @@ var Garu = class {
|
|
|
407
560
|
fetch: options.fetch
|
|
408
561
|
});
|
|
409
562
|
this.charges = new Charges(http);
|
|
563
|
+
this.customers = new Customers(http);
|
|
410
564
|
this.meta = new Meta(http);
|
|
565
|
+
this.products = new Products(http);
|
|
411
566
|
}
|
|
412
567
|
};
|
|
413
568
|
|
|
@@ -423,5 +578,3 @@ exports.GaruServerError = GaruServerError;
|
|
|
423
578
|
exports.GaruSignatureVerificationError = GaruSignatureVerificationError;
|
|
424
579
|
exports.GaruValidationError = GaruValidationError;
|
|
425
580
|
exports.webhooks = webhooks;
|
|
426
|
-
//# sourceMappingURL=index.cjs.map
|
|
427
|
-
//# sourceMappingURL=index.cjs.map
|