@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 +99 -0
- package/README.md +15 -14
- package/dist/index.cjs +362 -70
- package/dist/index.d.cts +519 -95
- package/dist/index.d.ts +519 -95
- package/dist/index.js +362 -70
- package/package.json +1 -1
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,
|
|
196
|
+
* Create a charge (PIX, boleto, or credit card).
|
|
202
197
|
*
|
|
203
|
-
*
|
|
204
|
-
* `idempotencyKey`, the SDK generates a UUIDv4. Safe to retry: the
|
|
205
|
-
*
|
|
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: '
|
|
205
|
+
* productId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
|
|
211
206
|
* paymentMethod: 'pix',
|
|
212
207
|
* customer: {
|
|
213
208
|
* name: 'Maria Silva',
|
|
@@ -216,50 +211,187 @@ var Charges = class {
|
|
|
216
211
|
* phone: '11987654321'
|
|
217
212
|
* }
|
|
218
213
|
* });
|
|
219
|
-
*
|
|
214
|
+
* console.log(charge.uuid, charge.pix?.code);
|
|
220
215
|
*
|
|
221
216
|
* @example
|
|
222
|
-
* // Credit card
|
|
217
|
+
* // Credit card, 2 installments. Server-to-server only (PCI scope).
|
|
223
218
|
* const charge = await garu.charges.create({
|
|
224
|
-
* productId: '
|
|
225
|
-
* paymentMethod: '
|
|
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
|
-
*
|
|
228
|
-
*
|
|
229
|
-
* cvv: '123',
|
|
230
|
-
* expirationDate: '2030-12',
|
|
222
|
+
* card: {
|
|
223
|
+
* number: '4111111111111111',
|
|
231
224
|
* holderName: 'MARIA SILVA',
|
|
232
|
-
*
|
|
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 =
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
*
|
|
245
|
+
* Retrieve a charge by uuid.
|
|
249
246
|
*
|
|
250
247
|
* @example
|
|
251
|
-
* const
|
|
252
|
-
*
|
|
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
|
-
|
|
273
|
+
return this.get(`/api/v1/charges${qs ? `?${qs}` : ""}`);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
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.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* await garu.charges.refund('6f1c9b2e-...'); // full
|
|
284
|
+
* await garu.charges.refund('6f1c9b2e-...', { amount: 10.0 }); // R$10,00
|
|
285
|
+
*/
|
|
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);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Cancel an unpaid charge.
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* const { canceled } = await garu.charges.cancel('6f1c9b2e-...');
|
|
297
|
+
*/
|
|
298
|
+
async cancel(uuid) {
|
|
299
|
+
return this.http.call(
|
|
300
|
+
(signal) => this.http.client.DELETE(
|
|
301
|
+
`/api/v1/charges/${encodeURIComponent(uuid)}`,
|
|
302
|
+
{ signal }
|
|
303
|
+
)
|
|
304
|
+
);
|
|
305
|
+
}
|
|
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
|
+
);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// src/resources/installment-plans.ts
|
|
321
|
+
var InstallmentPlans = class {
|
|
322
|
+
constructor(http) {
|
|
323
|
+
this.http = http;
|
|
324
|
+
}
|
|
325
|
+
http;
|
|
326
|
+
/**
|
|
327
|
+
* Sell a product as a carnê. Auto-attaches `X-Idempotency-Key` (UUIDv4 if
|
|
328
|
+
* you don't pass `idempotencyKey`), which matters more here than anywhere
|
|
329
|
+
* else in the API: this call registers a REAL boleto at the bank, so a
|
|
330
|
+
* blind retry can put two payable barcodes in one buyer's hands.
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* const carne = await garu.installmentPlans.create({
|
|
334
|
+
* productId: '40381e8e-6ee7-4b8e-9393-766a6e2109d2',
|
|
335
|
+
* customerId: 4821,
|
|
336
|
+
* installments: 12
|
|
337
|
+
* });
|
|
338
|
+
* // A R$1.200 product at fator 1,30 bills R$130,00 a month:
|
|
339
|
+
* carne.totalScheduled; // 1560
|
|
340
|
+
* carne.installmentAmount; // 130
|
|
341
|
+
* carne.installmentsDetail?.[0]; // parcela 1, with its barcode
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* // Attribute the sale to an affiliate. Fixed at sale time: every later
|
|
345
|
+
* // parcela inherits it, so omitting it pays them nothing for the whole
|
|
346
|
+
* // carnê. The affiliate must already be active on this product.
|
|
347
|
+
* await garu.installmentPlans.create({
|
|
348
|
+
* productId: '40381e8e-6ee7-4b8e-9393-766a6e2109d2',
|
|
349
|
+
* customerId: 4821,
|
|
350
|
+
* installments: 6,
|
|
351
|
+
* firstDueDate: '2026-10-05',
|
|
352
|
+
* affiliateId: 5
|
|
353
|
+
* });
|
|
354
|
+
*/
|
|
355
|
+
async create(params) {
|
|
356
|
+
const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
|
|
357
|
+
const { idempotencyKey: _omit, ...body } = params;
|
|
358
|
+
return this.http.call(
|
|
359
|
+
(signal) => this.http.client.POST("/api/v1/installment-plans", {
|
|
360
|
+
body,
|
|
361
|
+
headers: { "X-Idempotency-Key": idempotencyKey },
|
|
362
|
+
signal
|
|
363
|
+
}).then((r) => r)
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* List carnês, newest first. `dueFrom`/`dueTo` filter on the FIRST
|
|
368
|
+
* parcela's due date, which is what identifies the plan; filtering on every
|
|
369
|
+
* parcela would return one carnê twelve times.
|
|
370
|
+
*
|
|
371
|
+
* @example
|
|
372
|
+
* const atRisk = await garu.installmentPlans.list({ status: 'defaulted' });
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* const live = await garu.installmentPlans.list({
|
|
376
|
+
* status: ['active', 'pending_activation'],
|
|
377
|
+
* customerId: 4821,
|
|
378
|
+
* limit: 50
|
|
379
|
+
* });
|
|
380
|
+
*/
|
|
381
|
+
async list(params = {}) {
|
|
382
|
+
const qs = new URLSearchParams();
|
|
383
|
+
if (params.page !== void 0) qs.set("page", String(params.page));
|
|
384
|
+
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
385
|
+
if (params.customerId !== void 0) qs.set("customerId", String(params.customerId));
|
|
386
|
+
if (params.productId) qs.set("productId", params.productId);
|
|
387
|
+
if (params.dueFrom) qs.set("dueFrom", params.dueFrom);
|
|
388
|
+
if (params.dueTo) qs.set("dueTo", params.dueTo);
|
|
389
|
+
if (params.status) {
|
|
390
|
+
const statuses = Array.isArray(params.status) ? params.status : [params.status];
|
|
391
|
+
for (const s of statuses) qs.append("status", s);
|
|
392
|
+
}
|
|
393
|
+
const query = qs.toString();
|
|
394
|
+
const url = `/api/v1/installment-plans${query ? `?${query}` : ""}`;
|
|
263
395
|
return this.http.call(
|
|
264
396
|
(signal) => this.http.client.GET(url, { signal }).then(
|
|
265
397
|
(r) => r
|
|
@@ -267,60 +399,214 @@ var Charges = class {
|
|
|
267
399
|
);
|
|
268
400
|
}
|
|
269
401
|
/**
|
|
270
|
-
*
|
|
402
|
+
* Retrieve one carnê with every parcela: due date, status, barcode line and
|
|
403
|
+
* boleto PDF.
|
|
271
404
|
*
|
|
272
405
|
* @example
|
|
273
|
-
* const
|
|
274
|
-
*
|
|
406
|
+
* const carne = await garu.installmentPlans.get(uuid);
|
|
407
|
+
* const unpaid = carne.installmentsDetail?.filter((i) => i.status !== 'paid');
|
|
408
|
+
* carne.totalCollected; // what has actually cleared, not what was billed
|
|
275
409
|
*/
|
|
276
|
-
async get(
|
|
410
|
+
async get(uuid) {
|
|
277
411
|
return this.http.call(
|
|
278
|
-
(signal) => this.http.client.GET(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
412
|
+
(signal) => this.http.client.GET(`/api/v1/installment-plans/${uuid}`, { signal }).then(
|
|
413
|
+
(r) => r
|
|
414
|
+
)
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Issue a segunda via for one parcela, once the current slip has expired.
|
|
419
|
+
*
|
|
420
|
+
* A boleto stays payable at any bank until its due date plus five days, so
|
|
421
|
+
* Garu refuses while the old barcode is still live — two live barcodes for
|
|
422
|
+
* one parcela is how a buyer pays it twice. Once per parcela per day.
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* const result = await garu.installmentPlans.reissueInstallment(uuid, 4);
|
|
426
|
+
* if (result.status === 'emitted') {
|
|
427
|
+
* send(result.installment!.boleto!.barcodeLine);
|
|
428
|
+
* }
|
|
429
|
+
*/
|
|
430
|
+
async reissueInstallment(uuid, number) {
|
|
431
|
+
return this.http.call(
|
|
432
|
+
(signal) => this.http.client.POST(
|
|
433
|
+
`/api/v1/installment-plans/${uuid}/installments/${number}/reissue`,
|
|
434
|
+
{ signal }
|
|
435
|
+
).then((r) => r)
|
|
282
436
|
);
|
|
283
437
|
}
|
|
284
438
|
/**
|
|
285
|
-
*
|
|
439
|
+
* Move one parcela to a later date. Its siblings keep theirs — this
|
|
440
|
+
* postpones a payment, it does not restructure the carnê. A slip already
|
|
441
|
+
* emitted stays payable on its original date until it expires.
|
|
286
442
|
*
|
|
287
443
|
* @example
|
|
288
|
-
*
|
|
289
|
-
*
|
|
444
|
+
* await garu.installmentPlans.postponeInstallment(uuid, 4, {
|
|
445
|
+
* newDueDate: '2026-12-20'
|
|
446
|
+
* });
|
|
447
|
+
*/
|
|
448
|
+
async postponeInstallment(uuid, number, params) {
|
|
449
|
+
return this.http.call(
|
|
450
|
+
(signal) => this.http.client.POST(
|
|
451
|
+
`/api/v1/installment-plans/${uuid}/installments/${number}/postpone`,
|
|
452
|
+
{ body: params, signal }
|
|
453
|
+
).then((r) => r)
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Record a parcela as paid, for when the buyer paid the slip but the
|
|
458
|
+
* webhook never arrived.
|
|
459
|
+
*
|
|
460
|
+
* Garu asks the provider to confirm the charge really compensated before
|
|
461
|
+
* recording it, because this settles the transaction and pays affiliate and
|
|
462
|
+
* co-producer commissions. A provider outage refuses the action rather than
|
|
463
|
+
* trusting the assertion.
|
|
290
464
|
*
|
|
291
465
|
* @example
|
|
292
|
-
*
|
|
293
|
-
*
|
|
466
|
+
* const parcela = await garu.installmentPlans.markInstallmentPaid(uuid, 3);
|
|
467
|
+
* parcela.status; // 'paid'
|
|
294
468
|
*/
|
|
295
|
-
async
|
|
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;
|
|
469
|
+
async markInstallmentPaid(uuid, number) {
|
|
300
470
|
return this.http.call(
|
|
301
|
-
(signal) => this.http.client.POST(
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
471
|
+
(signal) => this.http.client.POST(
|
|
472
|
+
`/api/v1/installment-plans/${uuid}/installments/${number}/mark-paid`,
|
|
473
|
+
{ signal }
|
|
474
|
+
).then((r) => r)
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Cancel the carnê. Emission and reminders stop and open slips are
|
|
479
|
+
* cancelled at the provider.
|
|
480
|
+
*
|
|
481
|
+
* Money already collected is NOT returned — open a refund request for that.
|
|
482
|
+
* A cancelled carnê is never revived by a late payment; that money opens a
|
|
483
|
+
* refund request instead.
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* await garu.installmentPlans.cancel(uuid, { note: 'Comprador desistiu' });
|
|
487
|
+
*/
|
|
488
|
+
async cancel(uuid, params = {}) {
|
|
489
|
+
return this.http.call(
|
|
490
|
+
(signal) => this.http.client.POST(`/api/v1/installment-plans/${uuid}/cancel`, {
|
|
491
|
+
body: params,
|
|
305
492
|
signal
|
|
306
|
-
})
|
|
493
|
+
}).then((r) => r)
|
|
307
494
|
);
|
|
308
495
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
496
|
+
/**
|
|
497
|
+
* Ask for this carnê to be refunded.
|
|
498
|
+
*
|
|
499
|
+
* Garu does NOT move the money. A boleto cannot be reversed and the funds
|
|
500
|
+
* already settled to you, so this records the request and notifies your
|
|
501
|
+
* team. Transfer the money to the buyer yourself, then close it with
|
|
502
|
+
* `garu.refundRequests.confirm`.
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* const request = await garu.installmentPlans.requestRefund(uuid, {
|
|
506
|
+
* reason: 'Produto não entregue'
|
|
507
|
+
* });
|
|
508
|
+
* request.status; // 'pending' — nothing has moved yet
|
|
509
|
+
* request.amount; // defaults to everything the carnê collected
|
|
510
|
+
*/
|
|
511
|
+
async requestRefund(uuid, params = {}) {
|
|
512
|
+
return this.http.call(
|
|
513
|
+
(signal) => this.http.client.POST(`/api/v1/installment-plans/${uuid}/refund-requests`, {
|
|
514
|
+
body: params,
|
|
515
|
+
signal
|
|
516
|
+
}).then((r) => r)
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
// src/resources/refund-requests.ts
|
|
522
|
+
var RefundRequests = class {
|
|
523
|
+
constructor(http) {
|
|
524
|
+
this.http = http;
|
|
525
|
+
}
|
|
526
|
+
http;
|
|
527
|
+
/**
|
|
528
|
+
* List refund requests, newest first. Covers carnê and Pix/boleto alike.
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* // Everything you still owe a buyer.
|
|
532
|
+
* const owed = await garu.refundRequests.list({ status: 'pending' });
|
|
533
|
+
* const total = owed.data.reduce((sum, r) => sum + r.amount, 0);
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* const forThisCarne = await garu.refundRequests.list({ planId: carne.uuid });
|
|
537
|
+
*/
|
|
538
|
+
async list(params = {}) {
|
|
539
|
+
const qs = new URLSearchParams();
|
|
540
|
+
if (params.page !== void 0) qs.set("page", String(params.page));
|
|
541
|
+
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
542
|
+
if (params.planId) qs.set("planId", params.planId);
|
|
543
|
+
if (params.chargeId) qs.set("chargeId", params.chargeId);
|
|
544
|
+
if (params.status) {
|
|
545
|
+
const statuses = Array.isArray(params.status) ? params.status : [params.status];
|
|
546
|
+
for (const s of statuses) qs.append("status", s);
|
|
321
547
|
}
|
|
322
|
-
|
|
323
|
-
|
|
548
|
+
const query = qs.toString();
|
|
549
|
+
const url = `/api/v1/refund-requests${query ? `?${query}` : ""}`;
|
|
550
|
+
return this.http.call(
|
|
551
|
+
(signal) => this.http.client.GET(url, { signal }).then(
|
|
552
|
+
(r) => r
|
|
553
|
+
)
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Retrieve one refund request.
|
|
558
|
+
*
|
|
559
|
+
* @example
|
|
560
|
+
* const request = await garu.refundRequests.get(uuid);
|
|
561
|
+
* request.installmentPlanId ?? request.chargeId; // exactly one is set
|
|
562
|
+
*/
|
|
563
|
+
async get(uuid) {
|
|
564
|
+
return this.http.call(
|
|
565
|
+
(signal) => this.http.client.GET(`/api/v1/refund-requests/${uuid}`, { signal }).then(
|
|
566
|
+
(r) => r
|
|
567
|
+
)
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Record that you returned the money. Call this AFTER transferring it.
|
|
572
|
+
*
|
|
573
|
+
* Confirming closes a carnê as refunded, stops remaining parcelas, cancels
|
|
574
|
+
* open slips at the provider and claws back the affiliate and co-producer
|
|
575
|
+
* commissions on the parcelas that cleared. For a Pix or boleto charge it
|
|
576
|
+
* marks the charge reversed and fires `transaction.refunded`. Idempotent:
|
|
577
|
+
* confirming twice does not claw back twice.
|
|
578
|
+
*
|
|
579
|
+
* @example
|
|
580
|
+
* // 1. You send the money to the buyer, out of band.
|
|
581
|
+
* // 2. Then tell Garu it happened.
|
|
582
|
+
* await garu.refundRequests.confirm(uuid, {
|
|
583
|
+
* note: 'Pix devolvido em 14/08, e2e E12345678'
|
|
584
|
+
* });
|
|
585
|
+
*/
|
|
586
|
+
async confirm(uuid, params = {}) {
|
|
587
|
+
return this.http.call(
|
|
588
|
+
(signal) => this.http.client.POST(`/api/v1/refund-requests/${uuid}/confirm`, {
|
|
589
|
+
body: params,
|
|
590
|
+
signal
|
|
591
|
+
}).then((r) => r)
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Decline the request. The carnê is untouched and keeps running.
|
|
596
|
+
* Idempotent.
|
|
597
|
+
*
|
|
598
|
+
* @example
|
|
599
|
+
* await garu.refundRequests.reject(uuid, {
|
|
600
|
+
* note: 'Produto entregue e retirado na loja em 02/08'
|
|
601
|
+
* });
|
|
602
|
+
*/
|
|
603
|
+
async reject(uuid, params = {}) {
|
|
604
|
+
return this.http.call(
|
|
605
|
+
(signal) => this.http.client.POST(`/api/v1/refund-requests/${uuid}/reject`, {
|
|
606
|
+
body: params,
|
|
607
|
+
signal
|
|
608
|
+
}).then((r) => r)
|
|
609
|
+
);
|
|
324
610
|
}
|
|
325
611
|
};
|
|
326
612
|
|
|
@@ -1167,6 +1453,10 @@ var DEFAULT_MAX_RETRIES = 2;
|
|
|
1167
1453
|
var SDK_VERSION = "0.11.1";
|
|
1168
1454
|
var Garu = class {
|
|
1169
1455
|
charges;
|
|
1456
|
+
/** Boleto parcelado (carnê): one product sold as N monthly bank slips. */
|
|
1457
|
+
installmentPlans;
|
|
1458
|
+
/** Refunds Garu has been asked to make and cannot make for you. */
|
|
1459
|
+
refundRequests;
|
|
1170
1460
|
customers;
|
|
1171
1461
|
meta;
|
|
1172
1462
|
products;
|
|
@@ -1188,6 +1478,8 @@ var Garu = class {
|
|
|
1188
1478
|
fetch: options.fetch
|
|
1189
1479
|
});
|
|
1190
1480
|
this.charges = new Charges(http);
|
|
1481
|
+
this.installmentPlans = new InstallmentPlans(http);
|
|
1482
|
+
this.refundRequests = new RefundRequests(http);
|
|
1191
1483
|
this.customers = new Customers(http);
|
|
1192
1484
|
this.meta = new Meta(http);
|
|
1193
1485
|
this.products = new Products(http);
|