Docs / API reference

Payments

Invoa API payments endpoints: list payments and record money received against an invoice, which updates its balance and issues a receipt.

A payment is money received against an invoice. Recording one through the API confirms it straight away, updates the invoice to partially_paid or paid, and issues an official receipt.

MethodPathScope
GET/paymentsdocuments:read
POST/paymentspayments:write

Payments made online through CHIP, and "I have paid" claims you confirm in the app, are recorded by Invoa itself and appear in the same list. See Payments and receipts.

The payment object

json
{
  "id": "9a700000-0000-4000-8000-000000000018",
  "tenantId": "7e0a0000-0000-4000-8000-000000000001",
  "documentId": "d0c00000-0000-4000-8000-000000000042",
  "method": "bank_transfer",
  "amount": 135000,
  "receivedAt": "2026-10-20",
  "reference": "MBB 20OCT 884512",
  "status": "confirmed",
  "source": "manual",
  "note": null,
  "proofFileId": null,
  "receiptDocumentId": "d0c00000-0000-4000-8000-000000000043",
  "chipPurchaseId": null,
  "createdBy": null,
  "createdAt": "2026-10-20T06:31:12.000Z",
  "updatedAt": "2026-10-20T06:31:12.000Z"
}
FieldTypeDescription
idstringPayment ID (UUID).
documentIdstringThe invoice this payment is for.
methodstringchip, bank_transfer, cash, cheque or other.
amountintegerAmount received, in sen.
receivedAtdateThe date the money arrived.
referencestring or nullBank or payment reference.
statusstringpending, confirmed, failed or refunded. Payments recorded through the API are confirmed.
sourcestringHow the payment reached Invoa: manual, claim (a confirmed customer claim) or webhook (CHIP).
notestring or nullInternal note.
receiptDocumentIdstring or nullThe receipt issued for this payment.
chipPurchaseIdstring or nullSet for CHIP payments.

List payments

http
GET /api/v1/payments

Returns payments with the most recent receivedAt first. Each item adds documentNumber, contactName and receiptNumber.

Query parameterTypeDescription
documentIdstringOnly payments for this invoice.
from, todatereceivedAt range, inclusive.
statusstringpending, confirmed, failed or refunded.
limit, offsetintegerSee Pagination.
bash
curl "https://app.invoa.io/api/v1/payments?from=2026-10-01&to=2026-10-31" \
  -H "Authorization: Bearer $INVOA_API_KEY"
json
{
  "data": [
    {
      "id": "9a700000-0000-4000-8000-000000000018",
      "documentId": "d0c00000-0000-4000-8000-000000000042",
      "method": "bank_transfer",
      "amount": 135000,
      "receivedAt": "2026-10-20",
      "reference": "MBB 20OCT 884512",
      "status": "confirmed",
      "source": "manual",
      "receiptDocumentId": "d0c00000-0000-4000-8000-000000000043",
      "documentNumber": "INV-26-0042",
      "contactName": "Aina Rahman",
      "receiptNumber": "RC-26-0018"
    }
  ],
  "pagination": { "total": 1, "limit": 50, "offset": 0, "has_more": false }
}

Record a payment

http
POST /api/v1/payments
FieldTypeRequiredDescription
documentIdstringYesAn issued invoice, self-billed invoice or consolidated invoice that is not void or fully paid.
methodstringYeschip, bank_transfer, cash, cheque or other.
amountintegerYesAmount received in sen, more than 0.
receivedAtdateYesThe date the money arrived, YYYY-MM-DD.
referencestringNoBank or payment reference, up to 100 characters.
notestringNoInternal note, up to 2,000 characters.
issueReceiptbooleanNoIssue a receipt for this payment. Default true. No receipt is issued for a self-billed invoice.
sourcestringNoWhere the payment came from: manual (default) or webhook for payments your system records from its own payment gateway.

When a receipt is issued, Invoa also emails it to the contact (if they have an email address) with the PDF attached. The receipt takes the next number in your receipt series, for example RC-26-0018.

bash
curl https://app.invoa.io/api/v1/payments \
  -H "Authorization: Bearer $INVOA_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "documentId": "d0c00000-0000-4000-8000-000000000042",
    "method": "bank_transfer",
    "amount": 135000,
    "receivedAt": "2026-10-20",
    "reference": "MBB 20OCT 884512"
  }'
json
{
  "data": {
    "payment": {
      "id": "9a700000-0000-4000-8000-000000000018",
      "documentId": "d0c00000-0000-4000-8000-000000000042",
      "method": "bank_transfer",
      "amount": 135000,
      "receivedAt": "2026-10-20",
      "status": "confirmed",
      "receiptDocumentId": "d0c00000-0000-4000-8000-000000000043"
    },
    "receipt": {
      "id": "d0c00000-0000-4000-8000-000000000043",
      "type": "receipt",
      "status": "issued",
      "number": "RC-26-0018",
      "issueDate": "2026-10-20",
      "total": 135000
    },
    "document": {
      "id": "d0c00000-0000-4000-8000-000000000042",
      "status": "paid",
      "number": "INV-26-0042",
      "total": 135000,
      "paidAmount": 135000,
      "balance": 0
    }
  }
}

The response is 201 Created. payment is the payment object, receipt is the receipt's document record (without lines) or null, and document is the full document object for the invoice after the payment. All three are shortened above. Invoa sends the payment.confirmed webhook.

Important: Recording a payment is not idempotent. A retry records a second payment and issues a second receipt. If a request times out, check GET /payments?documentId=… before you try again.

Errors:

  • 400 validation, for example a decimal amount or a missing receivedAt.
  • 404 not_found if the invoice is not in this company.
  • 422 invalid_state if the document is not an invoice, is a draft, void or already paid, or receivedAt falls in a period your accountant has locked.

Something unclear or out of date? Tell us at hello@invoa.io and we'll fix the page.