Receipts API

Recibo (RC) de quitação para uma Factura (FT) ou uma Nota de Débito (ND) já emitida, total ou parcial. Tal como a FT, NC e ND, o recibo é assinado e comunicado à AGT em tempo real. Passo a passo no guia Recibos e pagamentos.

Emitir Recibo

POST/v1/organisations/:orgId/invoices/:invoiceId/receipt

A factura de origem tem de ser uma FT no estado issued. Não se aplica a FR (já vem quitada na emissão). Sem amount, o recibo liquida o que falta pagar; pode emitir vários recibos parciais até cobrir o total (um recibo anulado não conta).

Request Body

JSON
{
  "receivedIn": "0b1c2d3e-...",
  "receivedAt": "2026-07-01"
}
amountinteger?Valor recebido em cêntimos (com IVA). Default: o que falta pagar. Um valor menor emite um recibo parcial (sempre disponível); a factura fica paga quando os recibos cobrem o total
receivedInstring (uuid)?Conta onde o dinheiro entrou (GET /treasury-accounts). Sem valor: escolhida pelo paymentMethod ou a conta por omissão
receivedAtstring?Data do recebimento (AAAA-MM-DD ou ISO 8601). Default: agora
paymentMethod'transfer' | 'cash' | 'check' | 'card'Opcional - deduz-se da conta (caixa = cash, TPA = card, banco = transfer; 'check' marca cheque num banco). Sem receivedIn: cash → Caixa, card → TPA, transfer/check → banco por omissão

Resposta (201 Created)

JSON
{
  "id": "f6a7b8c9-...",
  "orgId": "779b90ce-...",
  "invoiceId": "a1b2c3d4-...",
  "customerId": "b2c3d4e5-...",
  "number": "RC 2026/000001",
  "displayCode": "B6B402",
  "total": 15000000,
  "currency": "AOA",
  "paymentMethod": "transfer",
  "receivedAccountId": "0b1c2d3e-...",
  "receivedAt": "2026-07-01T12:00:00.000Z",
  "atcud": "0-1",
  "hash": "3jK8Lp...",
  "pdfUrl": "/v1/organisations/779b90ce-.../receipts/f6a7b8c9-.../pdf",
  "issuedAt": "2026-07-01T10:00:00.000Z"
}

Recibo de Nota de Débito

POST/v1/organisations/:orgId/debit-notes/:debitNoteId/receipt

O cliente pagou uma nota de débito. O DS-120 permite que o recibo liquide "a factura ou documento rectificativo", por isso o RC aponta para a ND (debitNoteId) em vez da factura. O corpo e as regras são os mesmos do recibo da factura: amount, receivedIn, receivedAt e paymentMethod, todos opcionais.

  • A ND tem de estar issued (não anulada).
  • A ND não muda de status: o que foi pago está em paidAmount (GET /debit-notes/:id). Está paga quando paidAmount === total.
  • Uma ND com recibo activo não pode ser anulada (409 debit_note_has_receipts): anule primeiro o recibo.
  • Na API OAuth, precisa da permissão de emitir documentos (a mesma do recibo da factura).

Request Body (pagamento parcial)

JSON
{
  "amount": 500000,
  "paymentMethod": "cash",
  "receivedAt": "2026-10-19"
}

Com o SDK (@veroao/node 1.4+)

TypeScript
const rc = await vero.receipts.createForDebitNote(orgId, debitNoteId, { amount: 500000 })
rc.paymentInfo?.remainingAfter // o que falta pagar da ND

Resposta (201 Created)

JSON
{
  "id": "c1d2e3f4-...",
  "invoiceId": null,
  "debitNoteId": "d4e5f6a7-...",
  "number": "RC 2026/000002",
  "total": 500000,
  "currency": "AOA",
  "paymentMethod": "cash",
  "paymentInfo": {
    "invoiceNumber": "ND 2026/000003",
    "invoiceTotal": 1200000,
    "paidBefore": 0,
    "remainingAfter": 700000
  },
  "pdfUrl": "/v1/organisations/779b90ce-.../receipts/c1d2e3f4-.../pdf",
  "issuedAt": "2026-10-19T10:00:00.000Z"
}

Factura com adiantamento

Numa FT que descontou adiantamentos (FA), o adiantamento conta como já pago: faltatotal - advanceNet - advanceTax. O recibo sem amount liquida só isso, e opaymentInfo.paidBefore inclui o adiantamento. Se o adiantamento cobre a factura toda, ela já sai paga e não leva recibo.

Listar / Ver / Descarregar PDF

GET/v1/organisations/:orgId/receiptsLista todos os recibos
GET/v1/organisations/:orgId/receipts/:idDetalhes de um recibo
GET/v1/organisations/:orgId/receipts/:id/pdfDescarrega o PDF

Anular Recibo

POST/v1/organisations/:orgId/receipts/:id/cancel

Para um recibo emitido por engano. A AGT só permite anular por um de dois motivos legais (DS-120 documentCancelReason; Decreto Presidencial 71/25, art. 8.º n.º 8 e 9). Se o recibo já foi entregue ao cliente e os dados estão certos, não pode ser anulado.

  • O recibo fica status: "cancelled" e o PDF passa a ter a marca ANULADO.
  • O valor do recibo volta a ficar por pagar na factura ou na ND: pode emitir o recibo certo a seguir.
  • Se o recibo já estava validado pela AGT, a anulação é comunicada à AGT (o mesmo documento com estado "A"). Acompanhe em agtCancelStatus: pending → validated (ou error / timeout). Sem nada a comunicar: not_required.

Request Body

JSON
{
  "reason": "N",
  "note": "emitido por engano no lugar de uma FR"
}
reason'N' | 'I'Obrigatório. N: não foi enviado ao cliente · I: cliente identificado incorrectamente
notestringOpcional. Nota interna (máx. 500 caracteres)

Com o SDK (@veroao/node 1.2+)

TypeScript
const rc = await vero.receipts.cancel(orgId, receiptId, { reason: 'N' })
rc.status          // 'cancelled'
rc.agtCancelStatus // 'pending' → 'validated'

Resposta (200 OK)

JSON
{
  "id": "f6a7b8c9-...",
  "invoiceId": "a1b2c3d4-...",
  "number": "RC 2026/000001",
  "total": 15000000,
  "status": "cancelled",
  "cancelledAt": "2026-09-27T10:00:00.000Z",
  "cancelReason": "N",
  "cancelNote": "emitido por engano no lugar de uma FR",
  "agtStatus": "validated",
  "agtCancelStatus": "pending"
}

Erros comuns

400invoice_not_issuedA factura não está no estado issued
400debit_note_not_issuedA nota de débito está anulada
400invalid_amountamount maior do que o que falta pagar, ou não inteiro
400treasury_account_not_foundreceivedIn não é uma conta de tesouraria desta organização
404debit_note_not_foundNota de débito não encontrada nesta organização
400fr_already_paidFacturas FR já vêm quitadas - não precisam de recibo
404invoice_not_foundFactura não encontrada nesta organização
409receipt_already_existsA factura ou a ND já está totalmente paga
400invalid_reasonAnulação: motivo diferente de 'N' ou 'I'
404receipt_not_foundAnulação: recibo não encontrado nesta organização
409already_cancelledAnulação: o recibo já estava anulado
409agt_pendingAnulação: a AGT ainda está a validar o recibo - tente daqui a alguns minutos