Integração Vendus: faturas automáticas a cada venda na Shelf
Atualizado a 23 de outubro de 2026
Um webhook envia cada venda paga da tua loja para um endereço teu, em segundos: produto, cliente (nome, email e NIF quando o indica), valor, cupão e método de pagamento. Com uma ferramenta de automação (o Make tem plano gratuito) e a API da Vendus, isso chega para emitir a fatura-recibo (FR) a cada venda. Não precisas de saber programar: é copiar, colar e escolher campos.
Antes de começar: prepara a tua conta Vendus
A Vendus pede quatro coisas antes de emitir faturas pela API. Sem elas, o teste dá erro do lado da Vendus (mostramos esses erros no fim do guia).
- 1Acesso às Finanças. Desde 2023 as faturas precisam do ATCUD, e para isso a Vendus comunica as tuas séries à AT. No Portal das Finanças, cria um subutilizador com a permissão WSE (comunicação de séries) e põe esses dados na Vendus, em Gestão → Autoridade Tributária → Configuração → Dados de Acesso AT. A Vendus explica passo a passo, com vídeo, em Comunicação de Séries de Faturação.
- 2Uma caixa do tipo API. Em Configuração → Definições → Lojas e Caixas, clica em Editar na tua caixa (por defeito, «Caixa principal») e escolhe o tipo API.
- 3A chave da API. Em Configuração → Integrações → API Vendus, confirma que Acesso API está ligado e copia o campo API key. As faturas emitidas pela API ficam em nome do utilizador dessa chave.
- 4O ID do método de pagamento. No teu computador, abre no browser
https://www.vendus.pt/ws/v1.1/documents/paymentmethods/?api_key=A_TUA_CHAVE(com a tua chave) e anota oiddo método de cartão e, se o usas, o de MB WAY.
Guarda a chave só na ferramenta de automação: quem a tiver consegue emitir documentos em teu nome. Dúvidas sobre a configuração da tua conta Vendus (Finanças, caixas, séries) são com o apoio da Vendus, que conhece o programa por dentro.
O NIF do cliente chega em data.buyer.nif: nos checkouts pagos, quem compra pode abrir Quero fatura com NIF e escrevê-lo, se quiser (ligas ou desligas em Definições → Faturação). Sem NIF, o campo vem a null e a fatura fica para consumidor final.
Ligar a Shelf à Vendus
1. Criar o cenário no Make e ligá-lo à Shelf
- 1No Make, cria um cenário novo e adiciona o módulo Webhooks → Custom webhook. Clica em Add, dá-lhe um nome (por exemplo «Vendas Shelf») e copia o URL que o Make mostra (começa por
https://hook.). - 2Na Shelf, vai a Definições → Integrações → Webhooks, cola o URL e clica em Ligar webhook. Depois clica em Enviar evento de teste.
- 3No Make, o webhook fica a conhecer os campos da venda:
type,test, e emdatao produto, o cliente (buyer), os valores (amount) e o pagamento (payment).
2. Deixar passar só as vendas pagas
- 1Clica na ligação a seguir ao webhook e escolhe Set up a filter.
- 2Primeira condição:
type, Text operators: Equal to,sale.paid. A Shelf enviasale.paidnas vendas pagas elead.creatednos produtos gratuitos, que não levam fatura. - 3Clica em Add AND rule. Segunda condição:
data → amount → total, Numeric operators: Greater than,0. Uma venda com cupão de 100% chega com total 0.00. Clica em Save.

3. Primeiro teste: uma fatura em modo de testes
- 1Clica no + à direita do filtro, pesquisa HTTP e escolhe Make a request. Preenche: URL
https://www.vendus.pt/ws/v1.1/documents, Method POST, um cabeçalho com NameAuthorizatione ValueBearer A_TUA_CHAVE(a palavra Bearer, um espaço e a tua chave), Body type Raw e Content type JSON (application/json). - 2Em Request content, cola o corpo abaixo. Os
{{1.data…}}são os campos do webhook (o 1 é o número do módulo): se ficarem como texto simples, clica em cada um e escolhe o campo na lista. TrocaID_DO_METODOpelo id do método de cartão. - 3Só para este teste, troca o
{{1.data.buyer.nif}}pelo teu próprio NIF: o evento de teste da Shelf traz o NIF de exemplo 123456789, que a Vendus recusa. Depois do teste, volta a pôr o campo. - 4Clica em Run once no Make e, na Shelf, outra vez em Enviar evento de teste. Na Vendus aparece um documento de teste, sem validade fiscal (é o
"mode": "tests").
{
"type": "FR",
"mode": "tests",
"external_reference": "{{1.data.order_id}}",
"client": {
"name": "{{1.data.buyer.name}}",
"fiscal_id": "{{1.data.buyer.nif}}",
"email": "{{1.data.buyer.email}}",
"send_email": "yes"
},
"items": [
{
"reference": "{{1.data.product.id}}",
"title": "{{1.data.product.title}}",
"qty": 1,
"gross_price": "{{1.data.amount.original}}",
"discount_amount": "{{1.data.amount.discount}}",
"type_id": "S",
"tax_id": "NOR"
}
],
"payments": [
{
"id": "ID_DO_METODO",
"amount": "{{1.data.amount.total}}"
}
]
}O artigo vai com o preço antes do cupão (data.amount.original) e o desconto do cupão (data.amount.discount), por isso a fatura mostra, por exemplo, 15,00 − 1,50 = 13,50. O pagamento é o que o cliente pagou (data.amount.total). Sem cupão, o desconto vem a 0.00.
4. Vendas sem NIF
- 1A Vendus pede que não se envie o cliente sem NIF (e nunca com 999999990). Entre o filtro e o módulo HTTP, adiciona um Router (em Flow Control) com duas saídas.
- 2Na ligação da primeira saída, Set up a filter:
data → buyer → nif, Basic operators: Exists. Liga aqui o módulo HTTP do passo 3. - 3Na segunda saída, o mesmo campo com Basic operators: Does not exist. Adiciona outro módulo HTTP igual, mas apaga do corpo o bloco
client(de"client"até à chaveta que o fecha, com a vírgula a seguir): a fatura fica para consumidor final.
5. O método certo em cada fatura (opcional)
O método de pagamento chega em data.payment.method: card (cartão, incluindo Apple Pay e Google Pay), mb_way (MB WAY) ou revolut_pay (Revolut Pay, se o ligares). A Vendus quer o id do método da tua conta, por isso faz a correspondência no lugar do ID_DO_METODO, com os teus ids:
{{switch(1.data.payment.method; mb_way; ID_MBWAY; ID_CARTAO)}}Se for MB WAY, usa o id de MB WAY da Vendus; em todos os outros casos, o de cartão. Se preferires, usa sempre o mesmo id: é o mais simples.
6. Passar a sério
- 1No filtro do passo 2, clica em Add AND rule e junta uma terceira condição:
test, Basic operators: Does not exist. Assim, o botão de teste da Shelf nunca emite uma fatura verdadeira. - 2Nos dois módulos HTTP, troca
"tests"por"normal"e confirma que o NIF voltou a ser{{1.data.buyer.nif}}. - 3Liga o cenário no interruptor em baixo, com Immediately as data arrives. A partir daqui, cada venda paga emite a fatura-recibo na Vendus.
- 1No Zapier, cria um Zap novo com o gatilho Webhooks by Zapier → Catch Hook e copia o URL (começa por
https://hooks.zapier.com/hooks/catch/). - 2Na Shelf, vai a Definições → Integrações → Webhooks, cola o URL e clica em Ligar webhook. Depois clica em Enviar evento de teste. No Zapier, clica em Test trigger para ver a venda de exemplo.
- 3Adiciona um passo Filter by Zapier: continua só se
Typefor exatamentesale.paide seData Amount Totalfor (Number) maior que0. Assim ficam de fora os produtos gratuitos e as vendas com cupão de 100%. - 4Adiciona a ação Webhooks by Zapier → Custom Request: Method POST, URL
https://www.vendus.pt/ws/v1.1/documents, e em Headers duas linhas:AuthorizationcomBearer A_TUA_CHAVE, eContent-Typecomapplication/json. - 5Em Data, cola o corpo abaixo. Apaga cada
{{…}}e, no mesmo sítio, insere o campo com o mesmo nome do passo Catch Hook (por exemplo{{data.buyer.name}}é Data Buyer Name). TrocaID_DO_METODOpelo id do método de cartão. - 6Só para o teste, escreve o teu próprio NIF no lugar do campo do NIF (a Vendus recusa o NIF de exemplo 123456789) e testa o passo: na Vendus aparece um documento de teste, sem validade fiscal.
{
"type": "FR",
"mode": "tests",
"external_reference": "{{data.order_id}}",
"client": {
"name": "{{data.buyer.name}}",
"fiscal_id": "{{data.buyer.nif}}",
"email": "{{data.buyer.email}}",
"send_email": "yes"
},
"items": [
{
"reference": "{{data.product.id}}",
"title": "{{data.product.title}}",
"qty": 1,
"gross_price": "{{data.amount.original}}",
"discount_amount": "{{data.amount.discount}}",
"type_id": "S",
"tax_id": "NOR"
}
],
"payments": [
{
"id": "ID_DO_METODO",
"amount": "{{data.amount.total}}"
}
]
}Vendas sem NIF e passar a sério (Zapier)
- 1Para as vendas sem NIF, a Vendus quer o pedido sem o bloco
client. Usa Paths by Zapier com dois caminhos (Data Buyer NifExists / Does not exist) e, no segundo, o mesmo pedido sem o blococlient. - 2No filtro, junta uma terceira condição:
TestDoes not exist. Assim, o botão de teste da Shelf nunca emite uma fatura verdadeira. - 3Volta a pôr o campo do NIF, troca
"tests"por"normal"e publica o Zap.
- 1No n8n, cria um workflow com o nó Webhook: HTTP Method POST. Copia o Production URL.
- 2Na Shelf, vai a Definições → Integrações → Webhooks, cola o URL e clica em Ligar webhook. Depois clica em Enviar evento de teste. Para o n8n receber o teste, clica antes em Listen for test event e usa, só para isso, o Test URL.
- 3Junta um nó If com duas condições:
{{ $json.body.type }}(String) is equal tosale.paid, e{{ $json.body.data.amount.total }}(Number) is greater than0. Continua pela saída true. - 4Junta um nó HTTP Request: Method POST, URL
https://www.vendus.pt/ws/v1.1/documents, Send Headers comAuthorization=Bearer A_TUA_CHAVE, Send Body com Body Content Type JSON e Using JSON. Cola o corpo abaixo com o campo em modo Expression e trocaID_DO_METODOpelo id do método de cartão. - 5Só para o teste, troca a expressão do NIF pelo teu próprio NIF (a Vendus recusa o NIF de exemplo 123456789). Na Vendus aparece um documento de teste.
{
"type": "FR",
"mode": "tests",
"external_reference": "{{ $json.body.data.order_id }}",
"client": {
"name": "{{ $json.body.data.buyer.name }}",
"fiscal_id": "{{ $json.body.data.buyer.nif }}",
"email": "{{ $json.body.data.buyer.email }}",
"send_email": "yes"
},
"items": [
{
"reference": "{{ $json.body.data.product.id }}",
"title": "{{ $json.body.data.product.title }}",
"qty": 1,
"gross_price": "{{ $json.body.data.amount.original }}",
"discount_amount": "{{ $json.body.data.amount.discount }}",
"type_id": "S",
"tax_id": "NOR"
}
],
"payments": [
{
"id": "ID_DO_METODO",
"amount": "{{ $json.body.data.amount.total }}"
}
]
}Vendas sem NIF e passar a sério (n8n)
- 1Para as vendas sem NIF, junta antes do pedido outro nó If (
{{ $json.body.data.buyer.nif }}is not empty) e, na saída false, um segundo HTTP Request igual, sem o blococlient. - 2No nó If, junta uma terceira condição:
{{ $json.body.test }}(Boolean) is not true. Assim, o botão de teste da Shelf nunca emite uma fatura verdadeira. - 3Volta a pôr a expressão do NIF, troca
"tests"por"normal"e ativa o workflow.
- 1Recebe o
POSTda Shelf num endereçohttps://teu e responde2xxem menos de 10 segundos. Confirma o cabeçalhoShelf-Signature(o código está em Webhooks da Shelf) e trata só os eventos comtypeigual asale.paid,data.amount.totalmaior que 0 e semtest. - 2Emite o documento:
POST https://www.vendus.pt/ws/v1.1/documentscom o cabeçalhoAuthorization: Bearer A_TUA_CHAVEe o corpo do separador Make, com os valores da venda. Sem NIF, envia o pedido sem o blococlient. - 3Testa com
"mode": "tests"(um documento sem validade fiscal) e passa a"normal"quando estiver certo. Oexternal_referenceleva odata.order_id. - 4O mesmo evento pode, raramente, chegar duas vezes: guarda o
data.order_idde cada venda já faturada e ignora repetidos.
Erros da Vendus e o que fazer
Quando a Vendus recusa um pedido, a ferramenta mostra a resposta dela no passo do pedido HTTP. Estes são os erros mais comuns ao configurar:
![Erro da Vendus no Make: Register's type must be [API] and it is not](/ajuda/integracao-vendus/erro-caixa-api.webp)


Os campos da fatura
| Vendus | Campo do webhook |
|---|---|
| client.name | data.buyer.name |
| client.email | data.buyer.email |
| client.fiscal_id | data.buyer.nif (vazio: sem bloco client, consumidor final) |
| items.title | data.product.title |
| items.reference | data.product.id |
| items.gross_price (preço com IVA, antes do cupão) | data.amount.original |
| items.discount_amount (desconto em euros) | data.amount.discount (0.00 sem cupão) |
| payments.id | o id do método na Vendus |
| payments.amount (o que o cliente pagou) | data.amount.total |
| external_reference | data.order_id |
Se usas order bumps: numa venda com cupão, data.amount.original é só o preço do produto principal; sem cupão, é o total da venda, já com os order bumps. Para a fatura bater certo em todas as vendas, numa venda com order bumps (data.bumps não vazio) usa uma linha com gross_price = data.amount.total e sem discount_amount, num caminho à parte.
O IVA vai em tax_id: NOR (taxa normal), INT (intermédia), RED (reduzida), ISE (isento) ou NS (não sujeito). Se estiveres isento, usa ISE com o motivo em tax_exemption (por exemplo M10, regime de isenção). type_id é S para serviços e P para produtos. Confirma a taxa, o motivo e o tipo com o teu contabilista.
Perguntas frequentes
O que acontece se a minha automação estiver desligada?+
Tentamos de novo até 8 vezes ao longo de cerca de 45 horas. Se o endereço responder 410 (removido), o webhook é desligado; reativa-o em Definições → Integrações.
Onde vejo se os envios estão a funcionar?+
Na Shelf, em Definições → Integrações → Webhooks, na lista Últimos envios: cada evento com o estado e o código de resposta. No Make, no Zapier e no n8n, o histórico mostra cada execução e a resposta do programa de faturação.
Que taxa de IVA ou motivo de isenção devo usar?+
Depende da tua atividade e do teu regime. Confirma com o teu contabilista e escreve no corpo o tax_id (e o tax_exemption, se fores isento) que ele indicar.
O cliente recebe a fatura por email?+
No pedido com NIF, sim: send_email: yes pede à Vendus que a envie para data.buyer.email. Sem NIF a fatura fica para consumidor final, sem dados do cliente.