Guia de Notas de Débito
Natureza do documento (negócio): Nota de Débito (ND)
Os valores nos exemplos JSON (ex. "documentTypeId": 8) são ilustrativos; o mesmo número pode representar um tipo de documento diferente noutra base de dados. Resolva o id correcto com GET /gateway/document-type e faça corresponder description / keyId a uma nota de débito na base de dados do cliente. Consulte Resolução de IDs de tipo de documento.
As notas de débito são emitidas com o mesmo endpoint de qualquer documento de venda:
POST /gateway/invoice/invoices
Content-Type: application/json
Authorization: Bearer {token}
X-Timezone: Europe/Lisbon
Defina documentTypeId com o tipo de nota de débito (invoiceType ND).
Visão geral
Uma nota de débito (ND) cobra um montante adicional a um cliente, normalmente quando existe uma diferença ou subcobrança numa factura anteriormente emitida. Utilizações típicas:
- Correcção de diferença de facturação (montante subcarregado)
- Encargos adicionais (transporte, manuseamento, penalizações)
- Ajuste de preço após entrega
- Encargos suplementares acordados após a facturação
Regras de emissão (ND)
| Regra | Detalhe |
|---|---|
| Endpoint | POST /gateway/invoice/invoices com documentTypeId de ND |
emissionReason | Obrigatório para Portugal e Angola (máx. 50 caracteres) |
| Quantidades por linha | Sempre positivas — o tipo de documento define a semântica de débito |
quantity | Obrigatório e tem de ser maior que zero |
| Movimento de stock | Controlado pela configuração do tipo de documento ND |
payments[] | Obrigatório ao nível do cabeçalho juntamente com currencyId |
| Referência à origem | originBodyGuid + relationType por linha — identifica a linha da factura de origem |
| Mesmo cliente | A ND deve ser emitida ao mesmo cliente do documento de origem |
Use quantity positivo nas linhas de ND. O montante cobrado é sempre um valor positivo.
Fluxo passo a passo
Passo 1 — Obter a factura original
Consulte a factura que pretende debitar. Indique referencedQuantitiesRelationType=1 para receber, em cada linha, a quantidade já debitada por notas de débito anteriores:
GET /gateway/invoice/invoices/{documentTypeId}/{serieId}/{number}/flat?referencedQuantitiesRelationType=1
Authorization: Bearer {token}
Na resposta, recolha os seguintes campos de cada linha que pretende referenciar:
| Campo | Localização | Utilizado como |
|---|---|---|
documentBodies[].guid | Cada linha | originBodyGuid na linha da ND |
documentBodies[].quantity | Cada linha | Quantidade original na linha da factura |
documentBodies[].referencedQuantity | Cada linha | Quantidade já debitada (null = nenhuma ainda) |
Quantidade debitável restante por linha = quantity − (referencedQuantity ?? 0)
Exemplo de resposta (factura FAC 1/5, documentTypeId=7, serieId=3, number=123):
{
"id": 1001,
"documentNumber": "FAC 1/5",
"entityVat": "123456789",
"documentBodies": [
{
"guid": "660e8400-e29b-41d4-a716-446655440001",
"itemKeyId": "PROD001",
"quantity": 10,
"retailPrice": 20,
"netPrice": 16.26,
"taxId": 1,
"totalAmount": 200,
"totalNetAmount": 162.60,
"referencedQuantity": null
}
]
}
PROD001 ainda não foi debitado — as 10 unidades estão disponíveis.
Passo 2 — Criar a nota de débito
Monte o payload da ND:
- Defina
documentTypeIdeserieIdde ND. - Use o mesmo cliente (
entityKeyId) da factura original. - Defina
emissionReason(PT/AO — máx. 50 caracteres). - Defina
currencyIdepayments[](a soma deve corresponder ao total da ND). - Em cada linha debitada, defina
originBodyGuiderelationTypeem conjunto. - Use
quantitypositivo.
Campos de referência por linha (ambos obrigatórios juntos, ou ambos omitidos):
| Campo | Valor |
|---|---|
originBodyGuid | guid da linha da factura original |
relationType | 1 (ReferenceOrigin) |
Campos derivados em linhas referenciadas
Quando uma linha contém originBodyGuid + relationType, os seguintes campos são opcionais — a API deriva-os da linha de origem quando omitidos:
| Campo | Comportamento quando omitido | Comportamento quando fornecido |
|---|---|---|
itemKeyId | Derivado da origem | Deve coincidir com a origem (→ DocumentReference.ItemMismatch se diferente) |
taxId | Derivado da origem | Aceite — a taxa pode diferir da origem |
retailPrice | Derivado como totalOrigem / quantidadeOrigem | Aceite; bloqueado à origem em vendas angolanas (→ DocumentReference.PriceMismatch se diferente) |
netPrice | Derivado como totalLíquidoOrigem / quantidadeOrigem | Aceite; bloqueado à origem em vendas angolanas (→ DocumentReference.PriceMismatch se diferente) |
discountPercentage | Assume zero | Aceite |
Em Angola, o preço unitário das linhas referenciadas está bloqueado ao valor da origem. A API garante isso: se retailPrice ou netPrice for fornecido, deve corresponder exactamente a totalAmount / quantity — não ao campo retailPrice devolvido pelo GET /flat.
O retailPrice no GET /flat é o preço unitário armazenado na linha; totalAmount / quantity é o preço efectivamente cobrado e pode diferir por várias razões (ex. descontos de linha). Fornecer o retailPrice bruto quando diverge de totalAmount / quantity causará DocumentReference.PriceMismatch.
Omita sempre retailPrice e netPrice em linhas de NC/ND angolanas. A API deriva o valor fiscal correcto a partir dos totais da origem automaticamente.
Se não conseguir omitir os preços por razão técnica (por ex. integração legada que preenche sempre todos os campos), use:
retailPrice=totalAmount / quantitynetPrice=totalNetAmount / quantity
Correcção de diferença de facturação (com referências por linha)
O cliente foi subcarregado numa factura anterior — 2 unidades adicionais do mesmo artigo.
{
"serieId": 4,
"documentTypeId": 8,
"entityVat": "123456789",
"entityDescription": "Cliente Exemplo, Lda",
"currencyId": 1,
"emissionReason": "Correcção de facturação - 2 unidades omitidas de FAC 1/5",
"obs": "Encargo suplementar à factura FAC 1/5",
"payments": [
{
"paymentTypeId": 1,
"amount": 48.4
}
],
"documentBodies": [
{
"quantity": 2,
"originBodyGuid": "660e8400-e29b-41d4-a716-446655440001",
"relationType": 1
}
]
}
O artigo, a taxa e os preços são derivados automaticamente da linha de origem. Pode substituí-los seguindo as regras da tabela de campos derivados acima.
Ajuste de preço (com preços explícitos)
Use quando o encargo adicional reflecte um preço diferente do da factura original.
{
"serieId": 4,
"documentTypeId": 8,
"entityVat": "123456789",
"currencyId": 1,
"emissionReason": "Encargos adicionais de transporte",
"obs": "Encargo suplementar à factura FAC 1/5",
"payments": [
{
"paymentTypeId": 1,
"amount": 25
}
],
"documentBodies": [
{
"quantity": 1,
"retailPrice": 25,
"netPrice": 20.33,
"originBodyGuid": "660e8400-e29b-41d4-a716-446655440001",
"relationType": 1
}
]
}
O comportamento de stock é determinado pela configuração do tipo de documento ND.
Pedido mínimo (totalmente derivado)
O pedido de ND mais simples e válido — toda a informação de artigo/preço/taxa é derivada da linha de origem; não é necessário repetir itemKeyId, taxId, retailPrice ou netPrice:
{
"serieId": 4,
"documentTypeId": 8,
"entityVat": "123456789",
"currencyId": 1,
"emissionReason": "Encargo suplementar",
"payments": [
{
"paymentTypeId": 1,
"amount": 40
}
],
"documentBodies": [
{
"originBodyGuid": "660e8400-e29b-41d4-a716-446655440001",
"relationType": 1,
"quantity": 2
}
]
}
Erros comuns
| Código de erro | Causa | Resolução |
|---|---|---|
SaleDocumentRules.NCND.MissingReferences | Sem referências por linha (origem interna) (PT/AO) | Use referências GUID por linha para facturas Soba |
SaleDocumentRules.NCND.MissingEmissionReason | emissionReason vazio (PT/AO) | Defina emissionReason (máx. 50 caracteres) |
DocumentReference.OriginBodyNotFound | originBodyGuid não existe ou foi eliminado | Verifique os GUIDs via GET /gateway/invoice/invoices/{id} |
DocumentReference.BalanceExceeded | quantity + qtd. já referenciada > qtd. linha de origem | Reduza quantity ou verifique NDs anteriores sobre a mesma linha |
DocumentReference.ItemMismatch | itemKeyId fornecido não coincide com o artigo da linha de origem | Omita itemKeyId ou envie o mesmo artigo que a origem |
DocumentReference.PriceMismatch | Preço fornecido difere do preço derivado da origem num documento rectificativo angolano | Para Angola, omita sempre retailPrice/netPrice — a API deriva os preços a partir dos totais da origem. Se fornecidos, os valores devem ser iguais a totalAmount / quantity e totalNetAmount / quantity, não os preços unitários brutos do GET /flat |
DocumentReference.EntityMismatch | Cliente da ND diferente do cliente do documento de origem | Use o mesmo entityKeyId da factura de origem |
Payment.InsufficientValue | Soma de payments[].amount ≠ total da ND | Recalcule o total e ajuste os montantes de pagamento |
A validação também rejeita pares de referência incompletos — originBodyGuid e relationType devem ambos estar presentes ou ambos omitidos.
Guias relacionados
- Guia de Utilização — Campos de cabeçalho/linha, pagamentos e tratamento de erros
- Guia de Facturas — Emissão da factura de venda original
- Guia de Notas de Crédito — Reversão ou correcção de uma factura
Última actualização: 30 de Junho de 2026