Proformas API

Orçamento sem valor fiscal, enviado ao cliente antes da factura real. Não é submetido à AGT.

Criar Proforma

POST/v1/organisations/:orgId/proformas

Com vários estabelecimentos, passa establishmentId (sem ele, a sede): a factura da conversão sai no mesmo estabelecimento. Ver Estabelecimentos API.

Request Body

JSON
{
  "customerId": "b2c3d4e5-...",
  "items": [
    { "description": "Serviços de Consultoria TI", "quantity": 1, "unitPrice": 15000000, "taxRate": 14, "withholdingTax": true },
    { "description": "Licença de software", "quantity": 1, "unitPrice": 5000000, "taxRate": 14 }
  ],
  "notes": "Válido para pagamento em 30 dias",
  "validUntil": "2026-12-31"
}

items[].taxRate é opcional - se omitido, é resolvido a partir do regime de IVA da organização (ver Facturas API). Organizações em regime isento/simplificado não podem ter linhas com taxa ≠ 0 (422 se enviares uma taxa incompatível).

Resposta (201 Created)

JSON
{
  "id": "c3d4e5f6-...",
  "orgId": "779b90ce-...",
  "customerId": "b2c3d4e5-...",
  "displayCode": "A3B2C1",
  "status": "draft",
  "subtotal": 13157895,
  "taxAmount": 1842105,
  "total": 15000000,
  "currency": "AOA",
  "convertedInvoiceId": null,
  "notes": "Válido para pagamento em 30 dias",
  "validUntil": "2026-12-31",
  "withholdingTax": null,
  "pdfUrl": "/v1/organisations/779b90ce-.../proformas/c3d4e5f6-.../pdf",
  "createdAt": "2026-07-01T10:00:00.000Z"
}

status é draft, converted ou cancelled - nunca "issued", já que a proforma não tem valor fiscal.

Retenção na fonte (Art. 67º do Código do Imposto Industrial)

Marque as linhas sujeitas com items[].withholdingTax: true (como nas facturas). Está sempre disponível, sem nada para activar. applyWithholdingTax é a forma antiga, para todas as linhas. O cálculo é feito inteiramente no servidor - a proforma não vai à AGT, por isso a retenção aqui é apenas informativa até à conversão em factura.

withholdingTax é transportado para a factura final quando converteres (POST .../convert) - não precisas de o pedir de novo nessa chamada. Também podes activar/mudar isto numa proforma já criada via PATCH .../proformas/:id, enquanto estiver em draft.

Converter em Factura

POST/v1/organisations/:orgId/proformas/:id/convert

Usa o cliente e os itens já guardados na proforma. Corpo opcional: documentType (FT por omissão, ou FR) e, só para FR, receivedIn (conta de tesouraria onde o dinheiro entrou) e receivedAt (data do recebimento). Se recebeste adiantamentos, desconta-os em advances ([{ invoiceId, amount? }], ver abaixo).

Resposta (201 Created - objecto Invoice)

JSON
{
  "id": "a1b2c3d4-...",
  "orgId": "779b90ce-...",
  "customerId": "b2c3d4e5-...",
  "origin": "proforma",
  "proformaId": "c3d4e5f6-...",
  "status": "issued",
  "number": "FT FT6326S62896N/1",
  "total": 15000000,
  "withholdingTax": null,
  "pdfUrl": "https://storage.vero.ao/invoices/a1b2c3d4.pdf",
  "issuedAt": "2026-07-01T11:00:00.000Z"
}

Se a proforma tinha withholdingTax (retenção pedida e a organização com isso activado), esse valor é transportado directamente para a factura resultante - não precisas de pedir applyWithholdingTax outra vez aqui.

Adiantamento (FA) da pro-forma

POST/v1/organisations/:orgId/proformas/:id/advance

O cliente aceitou a pro-forma e pagou um sinal. Emite uma Factura de Adiantamento (FA), paga no acto, com percent (percentagem do total) ou amount (valor com IVA, em kwanzas × 100). Opcionais: description, receivedIn, receivedAt, idempotencyKey. A pro-forma continua em draft; ao convertê-la, desconta o adiantamento.

TypeScript
// Sinal de 50%
await vero.proformas.advance(ORG_ID, proforma.id, { percent: 50 })

// ...na entrega, factura final com o sinal descontado
const [fa] = await vero.invoices.advances(ORG_ID, { proformaId: proforma.id })
const invoice = await vero.proformas.convert(ORG_ID, proforma.id, {
  advances: [{ invoiceId: fa.id }],
})

Erros: 400 percent_or_amount (nenhum ou os dois), 409 proforma_not_editable (já convertida ou cancelada), 422 advance_exceeds_proforma (os adiantamentos passariam o total; vem available).

Actualizar / Eliminar

PATCH/v1/organisations/:orgId/proformas/:idActualiza itens (com a retenção de cada linha), notas ou validade - só enquanto status for draft (409 caso contrário)
DELETE/v1/organisations/:orgId/proformas/:idCancela a proforma - draft ou já cancelada; bloqueado se já convertida

Listar / Ver / Descarregar PDF

GET/v1/organisations/:orgId/proformasLista proformas - paginado (data/meta)
GET/v1/organisations/:orgId/proformas/:idDetalhes de uma proforma
GET/v1/organisations/:orgId/proformas/:id/pdfDescarrega o PDF