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