Integração InvoiceXpress: 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 isso, o InvoiceXpress emite a fatura-recibo a cada venda.
Antes de começar
- Uma conta InvoiceXpress (a API está em todos os planos).
- Para o Make, o n8n ou código: a chave da API e o nome da conta. A chave está nas definições da API da tua conta InvoiceXpress; o nome da conta é a primeira parte do endereço com que entras,
NOME.app.invoicexpress.com. - Para o Zapier: basta ligar a conta InvoiceXpress dentro do Zapier.
A chave da API do InvoiceXpress dá acesso a toda a conta. Guarda-a só na ferramenta de automação e não a partilhes.
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 ao InvoiceXpress
- 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.
- 3Clica na ligação a seguir ao webhook e escolhe Set up a filter. Primeira condição:
type, Text operators: Equal to,sale.paid. Clica em Add AND rule; segunda condição:data → amount → total, Numeric operators: Greater than,0. Assim ficam de fora os produtos gratuitos (lead.created) e as vendas com cupão de 100%. - 4Clica no + à direita do filtro, pesquisa HTTP e escolhe Make a request. URL:
https://NOME.app.invoicexpress.com/invoice_receipts.json?api_key=A_TUA_CHAVE(com o nome da tua conta e a tua chave), Method POST, Body type Raw, Content type JSON (application/json). Liga Parse response. - 5Em 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. - 6Clica em Run once e, na Shelf, outra vez em Enviar evento de teste. No InvoiceXpress aparece uma fatura-recibo em rascunho: confirma o cliente, o valor e o IVA, e apaga o rascunho.
{
"invoice": {
"date": "{{formatDate(now; DD/MM/YYYY)}}",
"due_date": "{{formatDate(now; DD/MM/YYYY)}}",
"reference": "{{1.data.order_id}}",
"client": {
"name": "{{1.data.buyer.name}}",
"code": "{{ifempty(1.data.buyer.nif; 1.data.buyer.email)}}",
"email": "{{1.data.buyer.email}}",
"fiscal_id": "{{1.data.buyer.nif}}",
"country": "Portugal"
},
"items": [
{
"name": "{{1.data.product.title}}",
"description": "Venda na Shelf",
"unit_price": "{{1.data.amount.total}}",
"quantity": "1",
"tax": {
"name": "IVA0"
}
}
],
"tax_exemption": "M10"
}
}O code identifica o cliente no InvoiceXpress: o NIF, ou o email quando não há NIF. Se já existir um cliente com esse código, o InvoiceXpress usa a ficha dele.
Passar a sério (Make)
- 1No filtro, 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. - 2Para a fatura ficar emitida, junta outro módulo HTTP → Make a request depois do primeiro: Method PUT, URL
https://NOME.app.invoicexpress.com/invoice_receipts/{{2.data.invoice_receipt.id}}/change-state.json?api_key=A_TUA_CHAVE(o 2 é o número do primeiro módulo HTTP; escolhe oidna lista), Body type Raw, JSON, e o corpo{"invoice": {"state": "finalized"}}. - 3Para o cliente receber a fatura por email (opcional), mais um módulo HTTP: Method PUT, URL
https://NOME.app.invoicexpress.com/invoice_receipts/{{2.data.invoice_receipt.id}}/email-document.json?api_key=A_TUA_CHAVEe o corpo abaixo. - 4Liga o cenário no interruptor em baixo, com Immediately as data arrives. A partir daqui, cada venda paga emite a fatura-recibo.
{
"message": {
"client": {
"email": "{{1.data.buyer.email}}",
"save": "0"
},
"subject": "A tua fatura",
"body": "Obrigado pela tua compra. Segue a fatura-recibo."
}
}- 1No Zapier, cria um Zap novo e escolhe o gatilho Webhooks by Zapier → Catch Hook. Continua até o Zapier mostrar o URL do webhook (começa por
https://hooks.zapier.com/hooks/catch/) e copia-o. - 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 Zapier, clica em Test trigger: aparece a venda de exemplo (Cliente Teste, NIF 123456789) com todos os campos para mapear.
- 4Adiciona 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%. - 5Adiciona a ação InvoiceXpress → Create Invoice-Receipt, liga a tua conta InvoiceXpress e mapeia os campos (tabela abaixo). Escolhe a taxa de IVA ou o motivo de isenção que se aplica a ti.
- 6Testa o passo: no InvoiceXpress aparece uma fatura-recibo em rascunho. Confirma o cliente, o valor e o IVA, e apaga o rascunho.
Passar a sério (Zapier)
- 1No filtro, junta uma terceira condição:
TestDoes not exist. Assim, o botão de teste da Shelf nunca emite uma fatura verdadeira. - 2Adiciona InvoiceXpress → Finalize Invoice-Receipt para a fatura ficar emitida e, se quiseres, Sends Invoice by Email para o cliente a receber.
- 3Publica o Zap.
- 1No n8n, cria um workflow com o nó Webhook: HTTP Method POST. Copia o Production URL (o Test URL só funciona enquanto o n8n está à escuta).
- 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://NOME.app.invoicexpress.com/invoice_receipts.json?api_key=A_TUA_CHAVE, Send Body ligado, Body Content Type JSON, Using JSON, e cola o corpo abaixo com o campo em modo Expression. - 5Corre o teste: no InvoiceXpress aparece uma fatura-recibo em rascunho. Confirma-a e apaga o rascunho.
{
"invoice": {
"date": "{{ $now.toFormat('dd/MM/yyyy') }}",
"due_date": "{{ $now.toFormat('dd/MM/yyyy') }}",
"reference": "{{ $json.body.data.order_id }}",
"client": {
"name": "{{ $json.body.data.buyer.name }}",
"code": "{{ $json.body.data.buyer.nif || $json.body.data.buyer.email }}",
"email": "{{ $json.body.data.buyer.email }}",
"fiscal_id": "{{ $json.body.data.buyer.nif }}",
"country": "Portugal"
},
"items": [
{
"name": "{{ $json.body.data.product.title }}",
"description": "Venda na Shelf",
"unit_price": "{{ $json.body.data.amount.total }}",
"quantity": "1",
"tax": {
"name": "IVA0"
}
}
],
"tax_exemption": "M10"
}
}Passar a sério (n8n)
- 1No 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. - 2Junta outro nó HTTP Request: Method PUT, URL
https://NOME.app.invoicexpress.com/invoice_receipts/{{ $json.invoice_receipt.id }}/change-state.json?api_key=A_TUA_CHAVE, corpo JSON{"invoice": {"state": "finalized"}}. - 3Ativa 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. - 2Cria a fatura-recibo:
POST https://NOME.app.invoicexpress.com/invoice_receipts.json?api_key=…com o corpo do separador Make (a raiz éinvoice, as datas emdd/mm/aaaa, ounit_pricesem IVA). Fica em rascunho; a resposta trazinvoice_receipt.id. - 3Emite-a:
PUT …/invoice_receipts/ID/change-state.jsoncom{"invoice": {"state": "finalized"}}. Para testes, usa"deleted"em vez de"finalized": o rascunho é apagado. - 4Para a enviar ao cliente:
PUT …/invoice_receipts/ID/email-document.jsoncom{"message": {"client": {"email": "…", "save": "0"}}}. - 5O mesmo evento pode, raramente, chegar duas vezes: guarda o
data.order_idde cada venda já faturada e ignora repetidos.
Os campos da fatura
| InvoiceXpress | Campo do webhook |
|---|---|
| Nome do cliente | data.buyer.name |
| Email do cliente | data.buyer.email |
| NIF | data.buyer.nif (vazio: consumidor final) |
| Descrição do artigo | data.product.title |
| Preço | data.amount.total |
| Referência | data.order_id |
O corpo vem para quem está isento de IVA pelo art. 53.º: IVA0 com o motivo M10. Se cobras IVA a 23%, usa "tax": {"name": "IVA23"}, apaga a linha tax_exemption e lembra-te de que o unit_price do InvoiceXpress é sem IVA: no Make, {{parseNumber(1.data.amount.total; ".") / 1.23}}. Se a tua loja cobra o IVA pela Shelf, o valor sem IVA já chega em data.tax.taxable_amount. Confirma no primeiro rascunho e com o teu contabilista.
O preço é o que o cliente pagou (data.amount.total), já com o cupão e os order bumps. Todos os campos da venda estão em Webhooks da Shelf.
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 usa a taxa ou o motivo de isenção que ele indicar.
Quantos webhooks posso ligar?+
Um por loja, por agora.
E se o meu produto já tem um campo personalizado «NIF»?+
Continua a funcionar. Nesse produto a Shelf não mostra o Quero fatura com NIF, e o que o cliente escrever no teu campo também chega em data.buyer.nif, se for um NIF válido.