---
title: "Collect an invoice you already issued | Timbro"
description: "Send a payment link for an accepted invoice, collect it in partial payments, or refund an invoiced sale"
canonical: "https://timbro.do/en/docs/comprobantes/cobrar-una-factura/"
---

Collect and invoice

# Collect an invoice you already issued

When your system has already issued the invoice with Timbro, you can send the customer a payment link for that invoice or show a QR at the register. Timbro takes the total, items, and taxes from the invoice, so the customer pays exactly what the invoice says, and the payment is linked to it.

To collect an invoice you need:

- An API key for the same business and the same mode you issued the invoice with, with Collect and Invoicing access. These examples store it in `TIMBRO_API_KEY`.
- An Azul, CardNet, or Portal merchant account connected in that mode.
- The invoice in `accepted` or `acceptedWithObservations` and in Dominican pesos. Issue it with cash terms if the customer pays on the spot with the link or the QR, or with credit terms if they will pay you later. If you have not issued it yet, follow [Issue an invoice from your system](https://timbro.do/en/docs/comprobantes/facturar-desde-pos-erp/).

## Create the payment link

Send only the payment reference and the invoice’s `invoiceId`. Do not send an amount, currency, or items, because Timbro takes them from the invoice:

- [TypeScript](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-0-0)
- [Python](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-0-1)

```ts
import { createTimbroPayments } from "@timbro/payments";

const timbro = createTimbroPayments({ apiKey: process.env.TIMBRO_API_KEY! });
const payment = await timbro.payments.create({
  paymentReference: "sale-842-payment",
  returnUrl: "https://merchant.example/sales/842",
  invoicing: { mode: "existing", invoiceId: "f35b7ae4-c484-4c63-981e-4f0f15e913b5" },
});
const paymentLink = payment.checkout.url;
```

```python
import os

from timbro_payments import TimbroPayments

timbro = TimbroPayments(api_key=os.environ["TIMBRO_API_KEY"])
payment = timbro.payments.create({
    "paymentReference": "sale-842-payment",
    "returnUrl": "https://merchant.example/sales/842",
    "invoicing": {"mode": "existing", "invoiceId": "f35b7ae4-c484-4c63-981e-4f0f15e913b5"},
})
payment_link = payment["checkout"]["url"]
```

`checkout.url` is the payment link. Send it to the customer by WhatsApp or email, or turn it into a QR for the register. Store the payment’s `id` with the sale.

The payment amount is the invoice’s total payable, including charges that are not invoiced. If you enabled tips, the customer can add a voluntary tip when paying. Timbro does not issue another invoice for this payment.

If you want Timbro to email the invoice to the customer, add `recipientEmail` inside `invoicing`. If your system already emails the invoice, do not add `recipientEmail`, so the customer does not receive it twice.

## Confirm the payment

When you receive the `payment.succeeded` [webhook](https://timbro.do/en/docs/cobros/webhooks/), or when the customer returns to `returnUrl`, retrieve the payment from your server. Mark the invoice as paid in your system only if `status` is `succeeded`, and do it only once even if you receive the notification more than once. The payment keeps the `invoiceId`, so you can tell which invoice it collected.

If the bank declines the card, the payment stays open and the customer can try again with the same link. The other statuses are in [Payment statuses](https://timbro.do/en/docs/cobros/estados-del-pago/).

## Send a new link

If you collect the invoice in full with one payment, that invoice can have only one open or paid payment at a time. If the customer lost the link, retrieve the payment: while its status is `requires_customer_action`, send the same `checkout.url` again.

If the payment expired or you canceled it, create another payment for the same invoice with a new `paymentReference`. The new payment is linked to the invoice. To replace a link that is still open, for example because you sent it to the wrong person, cancel the previous payment first:

- [TypeScript](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-1-0)
- [Python](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-1-1)

```ts
await timbro.payments.cancel({ paymentId: payment.id });
const replacement = await timbro.payments.create({
  paymentReference: "sale-842-payment-2",
  invoicing: { mode: "existing", invoiceId: "f35b7ae4-c484-4c63-981e-4f0f15e913b5" },
});
```

```python
timbro.payments.cancel(payment["id"])
replacement = timbro.payments.create({
    "paymentReference": "sale-842-payment-2",
    "invoicing": {"mode": "existing", "invoiceId": "f35b7ae4-c484-4c63-981e-4f0f15e913b5"},
})
```

If the invoice already has another open payment, or is already paid, the API responds `409 payment_invoice_not_allowed`. If you repeat the same request with the same reference, you get the same payment.

## When the API does not accept the invoice

The API responds with an error at `/invoicing/invoiceId` when the invoice cannot be collected by its `invoiceId`:

- If the DGII has not accepted the invoice yet, wait for the `invoice.accepted` webhook and create the payment afterward.
- If the invoice belongs to another business, or your key is for another mode, use the key of the business and mode that issued the invoice.
- If the invoice is in another currency, Timbro cannot collect it, because Timbro only collects in Dominican pesos (DOP).
- If the invoice is free (`paymentTerms.type: "free"`), there is nothing to collect.
- If the invoice has withholdings or other taxes that a payment cannot carry, create an amount payment, without `invoiceId`, with the invoice’s total and ITBIS.
- If the payment methods declared on the invoice do not add up to its total, correct `paymentTerms.allocations` in your system before issuing.

## Collect an invoice in partial payments

If the customer will pay the invoice in partial payments, for example in a credit sale, or in a sale where they pay some in cash and the rest with a QR, create one payment for each partial payment the customer makes with Timbro. Send the invoice’s `invoiceId` and, in `amount`, what the customer pays in that partial payment. Each partial payment stays linked to the invoice:

- [TypeScript](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-2-0)
- [Python](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-2-1)

```ts
const firstPartialPayment = await timbro.payments.create({
  paymentReference: "sale-850-partial-1",
  amount: { currency: "DOP", value: "5900.00" },
  returnUrl: "https://merchant.example/sales/850",
  invoicing: { mode: "existing", invoiceId: "f35b7ae4-c484-4c63-981e-4f0f15e913b5" },
});
const partialPayments = await timbro.payments.list({ invoiceId: "f35b7ae4-c484-4c63-981e-4f0f15e913b5" });
```

```python
first_partial_payment = timbro.payments.create({
    "paymentReference": "sale-850-partial-1",
    "amount": {"currency": "DOP", "value": "5900.00"},
    "returnUrl": "https://merchant.example/sales/850",
    "invoicing": {"mode": "existing", "invoiceId": "f35b7ae4-c484-4c63-981e-4f0f15e913b5"},
})
partial_payments = timbro.payments.list(invoice_id="f35b7ae4-c484-4c63-981e-4f0f15e913b5")
```

Without `tax.includedAmount`, Timbro gives each partial payment the ITBIS proportional to its amount, rounded to the cent. For example, if an invoice of RD$ 11,800.00 includes RD$ 1,800.00 of ITBIS, a partial payment of RD$ 5,900.00 carries RD$ 900.00. When every partial payment uses that calculation, the one that completes the total takes the ITBIS left, and together they carry exactly the invoice’s ITBIS. If your accounting computes a different ITBIS for a partial payment, send it in `tax.includedAmount`. Your system then makes sure the partial payments add up to the invoice’s ITBIS. The API rejects an ITBIS larger than what is still uncovered. Without `description`, the partial payment is described as `Factura <e-NCF>`.

Several partial payments can be open at once, but Timbro never lets the open or paid ones add up to more than the invoice’s total to pay. A canceled or expired partial payment frees its amount. While the invoice has open or paid partial payments, the API rejects a payment for the full invoice with `409 payment_invoice_not_allowed`. While a payment for the full invoice is open, the API also rejects partial payments.

A partial payment does not accept `recipientEmail`. To have Timbro email the invoice to the customer, follow [Email the invoice](https://timbro.do/en/docs/comprobantes/entregar-comprobante/#email-the-invoice).

Your system still keeps the invoice’s balance, because the customer can also pay in cash or by transfer outside Timbro. `payments.list` filtered by `invoiceId` finds every payment of that invoice, in any status. To know how much Timbro collected, add up only those whose `status` is `succeeded`. Use a different `paymentReference` for each partial payment.

If the invoice has withholdings, Timbro cannot collect it by its `invoiceId`, neither in full nor in partial payments. In that case, create an amount payment without `invoiceId` for each partial payment, with its ITBIS in `tax.includedAmount`. Those payments are not linked to the invoice, so send the invoice’s `invoiceReference` in `saleReference` to find them later with `payments.list`.

## Refund an invoiced sale

Refunding the payment and correcting the invoice with the DGII are two separate steps. When the customer returns a purchase they paid with Timbro:

1. [Create the refund](https://timbro.do/en/docs/cobros/reembolsos/) for the payment. For a partial refund, send the amount and its ITBIS in `amount` and `taxAmount`. If you also return the voluntary tip, include it in the refund.
2. Issue a [credit note](https://timbro.do/en/docs/comprobantes/corregir-ecf/) (E34) that modifies the original invoice. The note carries only what the customer returned, without the voluntary tip.
3. When the DGII accepts the note, link it to the refund:

- [TypeScript](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-3-0)
- [Python](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-3-1)

```ts
await timbro.refunds.attachInvoice({
  refundId: "refund_123456789abcdefghjkmnpqr",
  invoiceId: "0c1f8d6e-5b7a-4e0f-9a51-3f8e2d7c6b10",
  idempotencyKey: "sale-842-return-1-note",
});
```

```python
timbro.refunds.attach_invoice(
    "refund_123456789abcdefghjkmnpqr",
    {"invoiceId": "0c1f8d6e-5b7a-4e0f-9a51-3f8e2d7c6b10"},
    idempotency_key="sale-842-return-1-note",
)
```

Timbro checks that the note’s total is the refunded amount minus the returned voluntary tip, and that its ITBIS matches the refund’s. This link does not change the refund’s result. When it completes, Timbro sends the `refund.invoiceAttached` webhook.

Collect an invoice issued on a dedicated Timbro server

Some businesses issue their invoices on a dedicated Timbro server, other than `https://api.timbro.do`. The Collect key cannot read those invoices. On the server that issued the invoice, create limited access to it:

- [TypeScript](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-4-0)
- [Python](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/#tab-panel-4-1)

```ts
import { createTimbroInvoices } from "@timbro/invoices";

const issuer = createTimbroInvoices({
  apiKey: process.env.ISSUER_TIMBRO_INVOICES_API_KEY!,
  baseUrl: process.env.ISSUER_TIMBRO_INVOICES_ORIGIN!,
});
const access = await issuer.invoices.shareReceipt("f35b7ae4-c484-4c63-981e-4f0f15e913b5");
const externalInvoicePayment = await timbro.payments.create({
  paymentReference: "sale-126-payment",
  currency: "DOP",
  items: [{
    description: "Service",
    quantity: "1",
    unit: "unit",
    kind: "service",
    unitPrice: "1250.00",
    tax: { kind: "itbis_18", included: true },
  }],
  returnUrl: "https://merchant.example/sales/126",
  invoicing: {
    mode: "existing",
    invoiceId: access.invoiceId,
    receipt: { id: access.id, accessToken: access.accessToken },
  },
});
```

```python
from timbro_invoices import TimbroInvoices

issuer = TimbroInvoices(
    api_key=os.environ["ISSUER_TIMBRO_INVOICES_API_KEY"],
    base_url=os.environ["ISSUER_TIMBRO_INVOICES_ORIGIN"],
)
access = issuer.invoices.share_receipt("f35b7ae4-c484-4c63-981e-4f0f15e913b5")
external_invoice_payment = timbro.payments.create({
    "paymentReference": "sale-126-payment",
    "currency": "DOP",
    "items": [{
        "description": "Service",
        "quantity": "1",
        "unit": "unit",
        "kind": "service",
        "unitPrice": "1250.00",
        "tax": {"kind": "itbis_18", "included": True},
    }],
    "returnUrl": "https://merchant.example/sales/126",
    "invoicing": {
        "mode": "existing",
        "invoiceId": access["invoiceId"],
        "receipt": {"id": access["id"], "accessToken": access["accessToken"]},
    },
})
```

Send the invoice’s real items; Timbro checks that they match it. The Timbro team must first register that origin as trusted. Store `accessToken` as a secret and do not send it to the browser or write it in URLs or logs. With this access, Timbro can read the invoice and download its PDF, but not its signed XML. The server that issued the invoice sends it to the customer, so do not add `recipientEmail`.

[Previous\
Respond to your suppliers' invoices](https://timbro.do/en/docs/comprobantes/facturas-de-suplidores/)[Next\
Invoice at the time of payment](https://timbro.do/en/docs/comprobantes/emitir-ecf/)

Sell, serve your customers, and collect payments from your phone

© 2026 Timbro. All rights reserved

[Español](https://timbro.do/docs/comprobantes/cobrar-una-factura/)[English](https://timbro.do/en/docs/comprobantes/cobrar-una-factura/)

## Products

[Invoicing](https://timbro.do/en/facturacion-electronica/)[Serve](https://timbro.do/en/atiende/)[Collect](https://timbro.do/en/pagos/)[Portal Timbro](https://timbro.do/en/portal-timbro/)[Integrations](https://timbro.do/en/integraciones/)[Cuenta Timbro](https://timbro.do/en/cuenta-timbro/)[Pricing](https://timbro.do/en/precios/)

## Developers

[SDKs and API](https://timbro.do/en/desarrolladores/)[Documentation](https://timbro.do/en/docs/)[API reference](https://timbro.do/en/docs/reference/payments/)

## Company

[INDEXA, the company behind Timbro](https://indexa.do/)[Presentations](https://timbro.do/en/presentaciones/)

## Help

[How to start](https://timbro.do/en/como-empezar/)[Electronic invoicing guide](https://timbro.do/en/guias/facturacion-electronica-republica-dominicana/)[Contact](https://timbro.do/en/contacto/)<hola@timbro.do>

## Legal

[Business Terms](https://timbro.do/en/politicas/negocios/)[Terms of use](https://timbro.do/en/politicas/uso/)[Privacy](https://timbro.do/en/politicas/privacidad/)[Security](https://timbro.do/en/politicas/seguridad/)[All documents](https://timbro.do/en/politicas/)
