Idempotência
Uma factura não se apaga. Se um pedido der timeout, não sabes se a factura foi emitida, e repeti-lo sem protecção pode emitir duas. Com uma idempotencyKey, podes repetir em segurança.
Como usar
Envia idempotencyKey no corpo do pedido, com um valor que identifique a venda no teu sistema, como o ID da encomenda. O campo é opcional, mas sem ele a API não detecta repetições: envia-o sempre.
curl -X POST https://api.vero.ao/v1/organisations/$ORG_ID/invoices \
-H "Authorization: Bearer vero_live_sk_..." \
-H "Content-Type: application/json" \
-d '{
"customerId": "CUSTOMER_ID",
"documentType": "FR",
"items": [{ "description": "Plano Pro", "quantity": 1, "unitPrice": 500000 }],
"idempotencyKey": "order_789"
}'Usa um valor estável, ligado à venda. Um valor novo em cada tentativa, como a data e hora ou um UUID gerado na altura, não protege de nada.
O que a API responde
| Situação | Estado | Resultado |
|---|---|---|
| Primeiro pedido com a chave | 201 | Emite a factura. |
| Mesma chave, mesma empresa | 201 | Devolve a factura já existente. Nada é emitido. |
| Mesma chave, outra empresa | 201 | Emite outra factura: a chave só é única dentro de cada empresa. |
| Mesma chave, dados diferentes | 201 | Devolve a factura antiga, sem erro. Os dados novos são ignorados. |
| Mesma chave, dois pedidos ao mesmo tempo | 201 ou erro | Só um deles emite. O outro pode receber erro: repete-o com a mesma chave. |
| Emissão falhou antes de haver número | erro | Nada fica guardado: repete com a mesma chave. |
Uma repetição também responde 201, por isso o estado não diz se a factura é nova: compara o id se precisares de saber. A chave devolve a factura em qualquer estado, mesmo que a AGT a tenha rejeitado. Confirma o agtStatus e, para emitir de novo, usa uma chave nova.
Onde funciona
| Endpoint | Aceita a chave | Nota |
|---|---|---|
| POST /invoices | Sim | FT, FR e FA |
| POST /proformas/:id/advance | Sim | Factura de Adiantamento a partir de uma pro-forma |
| POST /invoices/:id/receipt | Não | Antes de repetir, confirma se o recibo foi criado |
| POST /debit-notes/:id/receipt | Não | Antes de repetir, confirma se o recibo foi criado |
| POST /invoices/:id/credit-note | Não | Antes de repetir, confirma se a nota foi criada |
| POST /debit-notes | Não | Antes de repetir, confirma se a nota foi criada |
Com o SDK Node
Em invoices.create(), o SDK gera uma chave e usa-a nas tentativas automáticas que faz após um erro 5xx ou de rede. Se o teu código voltar a chamar create(), é gerada outra chave e pode sair outra factura. Para cobrir esse caso, passa a tua própria chave.
const invoice = await vero.invoices.create(ORG_ID, {
customerId: customer.id,
items: [...],
idempotencyKey: `order_${order.id}`,
})Em sandbox
Com uma chave vero_test_sk_... nada é guardado, por isso não há deduplicação: cada pedido gera um documento de teste novo, mesmo com a mesma chave. A idempotência só funciona com uma chave vero_live_sk_....