@timbro/payments 0.2.0-next.0 → 0.2.0-next.2

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/README.md CHANGED
@@ -1,92 +1,160 @@
1
1
  # `@timbro/payments`
2
2
 
3
- Create a payment on your server and send the customer to Checkout. Read the Payment state from your server; signed webhooks notify you when it changes. Use `@timbro/invoices` to issue, retrieve, and deliver invoices independently. This SDK coordinates invoices with Payments and Refunds through their canonical `invoiceId`.
3
+ Create a payment on your server and send the customer to Checkout. Retrieve the Payment to confirm collection; signed webhooks notify you when it changes. Use `@timbro/invoices` to issue and deliver invoices. Payments and Refunds coordinate with invoices through the canonical `invoiceId`.
4
4
 
5
- Requires Node.js 24.19 or later and ESM. Install the stable `0.1.0` release:
5
+ Requires Node.js 24.19 or later and ESM. These examples use the prerelease API:
6
6
 
7
7
  ```sh
8
- npm install @timbro/payments
8
+ npm install @timbro/payments@0.2.0-next.2
9
9
  ```
10
10
 
11
- Keep the API key on your server. Its granted capabilities determine which Payment, Invoice coordination, and Business setup tasks it can perform. This example assumes the merchant has an explicit amount-only tax default configured. Timbro does not infer a tax rate. For an amount-only override, pass `tax: { includedAmount: "190.68" }`; see [taxes and sale items](https://timbro.do/en/docs/cobros/impuestos-y-articulos/) for setup and itemized sales.
11
+ The stable `0.1.0` package uses the earlier fiscal coordination interface. Do not mix its methods with these examples. Check [capabilities and enablement](https://timbro.do/en/docs/produccion/capacidades/) before using a function for a merchant or environment.
12
+
13
+ ## Create and confirm a payment
14
+
15
+ Keep the merchant API key on your server. Its capabilities determine which tasks it can perform. For an amount-only payment, configure a tax default or send `tax.includedAmount`; Timbro does not infer the tax rate.
12
16
 
13
17
  ```ts
14
18
  import { createTimbroPayments } from "@timbro/payments";
15
19
 
16
- const timbro = createTimbroPayments({
17
- apiKey: process.env.TIMBRO_PAYMENTS_SECRET_KEY,
18
- });
20
+ const apiKey = process.env.TIMBRO_PAYMENTS_SECRET_KEY;
21
+ if (!apiKey) throw new Error("TIMBRO_PAYMENTS_SECRET_KEY is required");
22
+ const timbro = createTimbroPayments({ apiKey });
19
23
 
20
24
  export async function POST(): Promise<Response> {
21
25
  const payment = await timbro.payments.create({
22
26
  paymentReference: "order-123-payment-1",
23
27
  amount: { currency: "DOP", value: "1250.00" },
24
28
  description: "Service",
29
+ tax: { includedAmount: "190.68" },
25
30
  returnUrl: "https://shop.example.com/orders/123",
26
31
  });
27
-
28
32
  return Response.redirect(payment.checkout.url);
29
33
  }
30
34
  ```
31
35
 
32
- Replace `order-123-payment-1` with a stable reference for your order and persist it before collecting payment. Reuse the same reference and request after a timeout to recover that Payment; changing the request under that reference conflicts. `returnUrl` returns the customer from Checkout and does not confirm payment. See [retries and idempotency](https://timbro.do/en/docs/cobros/reintentos-e-idempotencia/) and [signed webhooks](https://timbro.do/en/docs/cobros/webhooks/).
36
+ Persist a unique `paymentReference` and the request before sending it. Reuse both after a timeout to recover the same Payment; changing its intent conflicts. The customer's return to `returnUrl` does not confirm payment.
37
+
38
+ ```ts
39
+ const payment = await timbro.payments.retrieve("payment_123456789abcdefghjkmnpqr");
40
+ if (payment.status === "succeeded") {
41
+ // Apply the matching reference, currency, and amount to your order once.
42
+ }
43
+ ```
33
44
 
34
- ## Read, cancel, or refund
45
+ ## Collect and issue an invoice
35
46
 
36
- Retrieve a Payment from your server to read its current state:
47
+ Automatic and merchant invoicing require itemized DOP sales. Supply each item's fiscal unit and kind. An amount-only Payment cannot be changed into an invoice-capable sale through `updateInvoiceChoice`.
37
48
 
38
49
  ```ts
39
- const payment = await timbro.payments.retrieve("payment_123");
50
+ const invoicePayment = await timbro.payments.create({
51
+ paymentReference: "order-124-payment-1",
52
+ currency: "DOP",
53
+ items: [{
54
+ description: "Service",
55
+ quantity: "1",
56
+ unit: "unit",
57
+ kind: "service",
58
+ unitPrice: "1250.00",
59
+ tax: { kind: "itbis_18", included: true },
60
+ }],
61
+ invoicing: { mode: "automatic", type: "E32" },
62
+ });
63
+
64
+ await timbro.payments.updateInvoiceChoice({
65
+ paymentId: invoicePayment.id,
66
+ idempotencyKey: "order-124-buyer-1",
67
+ type: "E31",
68
+ buyer: { kind: "domestic", taxId: "130123456" },
69
+ });
40
70
  ```
41
71
 
42
- Cancel only a Payment that is still unpaid and eligible for cancellation:
72
+ Choose the Invoice type and buyer before submission, using the buyer's real tax identity. Locked choices and changes after submission or split creation are refused. Where permitted, `buyer: { kind: "anonymous" }` clears an earlier recipient. A captured Payment's `invoiceId` identifies its invoice; retrieve it through Invoices to confirm acceptance and file readiness.
73
+
74
+ For merchant-issued or existing invoices and independent installations, follow [collect and issue an e-CF](https://timbro.do/en/docs/comprobantes/emitir-ecf/). An independent installation supplies restricted receipt access; Payments never needs its Source key.
75
+
76
+ ## Cancel or refund
77
+
78
+ Cancel an unpaid Payment only while cancellation is permitted:
43
79
 
44
80
  ```ts
45
- await timbro.payments.cancel({ paymentId: "payment_123" });
81
+ await timbro.payments.cancel({ paymentId: "payment_123456789abcdefghjkmnpqr" });
46
82
  ```
47
83
 
48
- Refund only after capture. Omitting `amount` reserves the remaining refundable balance once:
84
+ Refund after capture. Omitting `amount` reserves the remaining refundable balance once. For a partial refund, `amount` is the total returned money and `voluntaryTipAmount` is the portion returning a voluntary tip. Omitting the tip portion declares zero; returning the entire remaining balance includes the remaining tip.
49
85
 
50
86
  ```ts
51
87
  const refund = await timbro.refunds.create({
52
- paymentId: "payment_123",
88
+ paymentId: "payment_123456789abcdefghjkmnpqr",
53
89
  refundReference: "order-123-refund-1",
90
+ amount: { currency: "DOP", value: "135.00" },
91
+ voluntaryTipAmount: { currency: "DOP", value: "10.00" },
54
92
  });
55
93
  ```
56
94
 
57
- Before the customer submits a payment, choose its Invoice type and buyer:
95
+ Reuse `refundReference` and the request for retries. Automatic provider refunds currently cover full, unsplit DOP card payments in TEST with Azul. CardNet refund and inquiry qualification remain pending. Partial, split, LIVE, wallet, and sandbox paths require an operator and return `operator_required` before remote money movement.
96
+
97
+ ## Associate the credit note separately
98
+
99
+ A provider refund does not create an E34 credit note. In this example, RD$125.00 is the commercial portion and RD$10.00 is the voluntary tip, which is excluded from the credit-note amount. Replace `originalInvoiceId` with the accepted invoice for this payment and use its actual fiscal facts. Install the fiscal SDK before this step:
100
+
101
+ ```sh
102
+ npm install @timbro/invoices@0.9.0-next.1
103
+ ```
58
104
 
59
105
  ```ts
60
- await timbro.payments.updateInvoiceChoice({
61
- paymentId: payment.id,
62
- idempotencyKey: "buyer-1",
63
- type: "E31",
64
- buyer: { kind: "domestic", taxId: "130123456" },
106
+ import { createTimbroInvoices } from "@timbro/invoices";
107
+
108
+ const invoiceApiKey = process.env.TIMBRO_INVOICES_API_KEY;
109
+ if (!invoiceApiKey) throw new Error("TIMBRO_INVOICES_API_KEY is required");
110
+ const invoices = createTimbroInvoices({
111
+ apiKey: invoiceApiKey,
112
+ baseUrl: process.env.TIMBRO_INVOICES_ORIGIN,
113
+ });
114
+ const creditNote = await invoices.invoices.create({
115
+ invoiceReference: "order-123-credit-note-1",
116
+ type: "E34",
117
+ originalInvoiceId: "f35b7ae4-c484-4c63-981e-4f0f15e913b5",
118
+ modificationCode: "3",
119
+ reason: "Partial return",
120
+ currency: "DOP",
121
+ incomeType: "01",
122
+ paymentTerms: { type: "immediate" },
123
+ items: [{
124
+ description: "Returned service",
125
+ quantity: "1",
126
+ unit: "unit",
127
+ kind: "service",
128
+ unitPrice: "125.00",
129
+ tax: { kind: "itbis_18", included: true },
130
+ }],
65
131
  });
66
132
  ```
67
133
 
68
- Use `buyer: { kind: "anonymous" }` to clear an earlier recipient. The operation preserves locked choices and refuses changes after submission or split creation.
69
-
70
- For a partial refund, pass exact `amount` and, when returning a voluntary tip, `voluntaryTipAmount`, each as `{ currency, value }`. Omitting the tip portion declares zero; refunding the entire remaining balance includes its remaining tip. `Refund.voluntaryTipAmount` records the reserved portion. Issue the credit note through the Invoices API for the commercial portion, then associate it separately:
134
+ For an independent installation, set `TIMBRO_INVOICES_ORIGIN` to its trusted origin and use its own key. Omit the origin for the hosted Gateway. Once the credit note is accepted, associate it with the Refund. For an Invoice from an independent installation, obtain its restricted receipt there and keep the token on your server:
71
135
 
72
136
  ```ts
137
+ const currentCreditNote = await invoices.invoices.retrieve(creditNote.id);
138
+ if (
139
+ currentCreditNote?.status !== "accepted" &&
140
+ currentCreditNote?.status !== "acceptedWithObservations"
141
+ ) throw new Error("The credit note is not accepted yet");
142
+ const receipt = await invoices.invoices.shareReceipt(creditNote.id);
73
143
  await timbro.refunds.attachInvoice({
74
144
  refundId: refund.id,
75
145
  invoiceId: creditNote.id,
76
- idempotencyKey: "order-123-credit-note",
77
146
  receipt: { id: receipt.id, accessToken: receipt.accessToken },
147
+ idempotencyKey: "order-123-credit-note-association",
78
148
  });
79
149
  ```
80
150
 
81
- Use the restricted receipt when the ERP owns the Invoice through an independent Source. The Gateway verifies the original Invoice, issuer, environment, currency, acceptance, and amount before setting `Refund.invoiceId`; it never changes the provider outcome.
82
-
83
- Reuse a `refundReference` for retries. Automatic refunds currently cover full, unsplit DOP card payments in TEST with Azul. CardNet refund qualification remains open in [issue #587](https://github.com/indexa-labs/checkout/issues/587); partial, split, LIVE, wallet, and sandbox refunds require an operator and return `operator_required`. See [refunds](https://timbro.do/en/docs/cobros/reembolsos/).
151
+ For an Invoice in the same hosted business, omit `receipt`. The Gateway verifies the original Invoice, issuer, environment, currency, acceptance, and amount before setting `Refund.invoiceId`. This association does not change the provider outcome.
84
152
 
85
153
  ## Guides and API reference
86
154
 
87
155
  - [Retrieve payments](https://timbro.do/en/docs/cobros/consultar-pagos/) and [payment states](https://timbro.do/en/docs/cobros/estados-del-pago/)
88
- - [Taxes and sale items](https://timbro.do/en/docs/cobros/impuestos-y-articulos/) and [request an e-CF](https://timbro.do/en/docs/comprobantes/emitir-ecf/)
89
- - [Webhooks](https://timbro.do/en/docs/cobros/webhooks/) and [refunds](https://timbro.do/en/docs/cobros/reembolsos/)
90
- - [Payments API reference](https://timbro.do/en/docs/reference/payments/) and [error handling](https://timbro.do/en/docs/produccion/errores/)
156
+ - [Taxes and sale items](https://timbro.do/en/docs/cobros/impuestos-y-articulos/) and [signed webhooks](https://timbro.do/en/docs/cobros/webhooks/)
157
+ - [Refunds](https://timbro.do/en/docs/cobros/reembolsos/) and [credit or debit notes](https://timbro.do/en/docs/comprobantes/corregir-ecf/)
158
+ - [REST reference](https://timbro.do/en/docs/reference/payments/) and [error handling](https://timbro.do/en/docs/produccion/errores/)
91
159
 
92
- Use `PaymentsError.code` to classify API failures. The [Payments API reference](https://timbro.do/en/docs/reference/payments/) documents the complete surface; see [error handling](https://timbro.do/en/docs/produccion/errores/) for recovery guidance.
160
+ `PaymentsError` exposes the error code, HTTP status, request ID, field problems, retry timing, and cause. Check the operation's recovery rules before retrying. The generated transport and internal coordination modules are not public entrypoints.