Integração Moloni: 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: produto, cliente (nome, email e NIF quando o indica), valor e método de pagamento. Com o Make e a API da Moloni, isso chega para criar a fatura-recibo a cada venda.
Configuração mais técnica. A API da Moloni não usa uma chave simples: pede uma conta de programador, uma autorização OAuth e os ids de alguns registos da tua conta (empresa, série, artigo, método de pagamento). Conta com cerca de uma hora. Se ainda estás a escolher programa, o InvoiceXpress e a Vendus ligam-se só com uma chave.
Antes de começar: prepara a tua conta Moloni
- 1Conta de programador. Pede acesso à API em moloni.pt/dev. Na área de cliente defines o Developer ID e o Redirect URI, e recebes o Client Secret. Como Redirect URI, usa o endereço de retorno do Make:
https://www.integromat.com/oauth/cb/oauth2. - 2Um artigo para as vendas online. Na Moloni, cria um artigo (por exemplo «Produto digital»), com a taxa de IVA ou o motivo de isenção que se aplica a ti. Cada fatura usa este artigo, com o nome do produto vendido na Shelf.
- 3O cliente «Consumidor final». Confirma que existe um cliente com o NIF 999999990, para as vendas sem NIF.
Ligar a Shelf à Moloni
1. A ligação OAuth à Moloni
- 1No Make, cria um cenário novo e adiciona o módulo HTTP → Make an OAuth 2.0 request. Em Connection, clica em Create a connection.
- 2Flow type Authorization Code. Authorize URI
https://www.moloni.pt/ac/root/oauth/, Token URIhttps://api.moloni.pt/v1/grant/, Client ID o teu Developer ID e Client Secret o teu Client Secret. - 3Clica em Save: abre-se a Moloni, entras e autorizas. O Make guarda a ligação e renova o acesso sozinho (o acesso dura 1 hora e a renovação 14 dias).
Se passarem mais de 14 dias sem nenhum pedido à Moloni (sem vendas), a autorização expira e o Make mostra um erro na ligação: em Connections, clica em Reauthorize.
2. Os ids da tua conta
Com o mesmo módulo, faz uma vez cada um destes pedidos (Method POST) e anota os ids da resposta. Os URLs levam ?json=true, para a Moloni aceitar o corpo em JSON (Body type Raw, JSON).
https://api.moloni.pt/v1/companies/getAll/?json=true, sem corpo: ocompany_idda tua empresa.https://api.moloni.pt/v1/documentSets/getAll/?json=truecom{"company_id": ID_DA_EMPRESA}: odocument_set_idda série.https://api.moloni.pt/v1/paymentMethods/getAll/?json=true: opayment_method_iddo cartão (e do MB WAY, se o tiveres).https://api.moloni.pt/v1/products/getAll/?json=true: oproduct_iddo artigo para as vendas online.https://api.moloni.pt/v1/customers/getByVat/?json=truecom{"company_id": ID_DA_EMPRESA, "vat": "999999990"}: ocustomer_iddo consumidor final.
3. O cenário das vendas
- 1Num cenário novo, começa com Webhooks → Custom webhook: clica em Add e copia o URL (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%. - 4Junta um Router com duas saídas. Na primeira, filtro
data → buyer → nifExists, e um módulo HTTP → Make an OAuth 2.0 request (módulo 3) parahttps://api.moloni.pt/v1/customers/getByVat/?json=true, Method POST, com{"company_id": ID_DA_EMPRESA, "vat": "{{1.data.buyer.nif}}"}. Na segunda saída não há pedido: a fatura vai para o consumidor final. - 5No fim de cada saída, um módulo HTTP → Make an OAuth 2.0 request para
https://api.moloni.pt/v1/invoiceReceipts/insert/?json=true, Method POST, Body type Raw, JSON, com o corpo abaixo e os teus ids. Na saída sem NIF, troca ocustomer_idpelo id do consumidor final. - 6Clica em Run once e envia o evento de teste da Shelf. Na Moloni aparece um rascunho (
"status": 0): confirma o cliente, o valor e o IVA, e apaga-o.
{
"company_id": "ID_DA_EMPRESA",
"date": "{{formatDate(now; YYYY-MM-DD)}}",
"expiration_date": "{{formatDate(now; YYYY-MM-DD)}}",
"document_set_id": "ID_DA_SERIE",
"customer_id": "{{ifempty(3.data.customer_id; ID_CONSUMIDOR_FINAL)}}",
"our_reference": "{{1.data.order_id}}",
"products": [
{
"product_id": "ID_DO_ARTIGO",
"name": "{{1.data.product.title}}",
"qty": 1,
"price": "{{1.data.amount.total}}",
"exemption_reason": "M10"
}
],
"payments": [
{
"payment_method_id": "ID_DO_METODO",
"date": "{{formatDate(now; YYYY-MM-DD)}}",
"value": "{{1.data.amount.total}}"
}
],
"status": 0
}Se o cliente com aquele NIF ainda não existir na Moloni, o getByVat não devolve nenhum id e a fatura vai para o consumidor final. Para criar a ficha do cliente nesses casos, junta um pedido a customers/insert: a Moloni pede vários campos (morada, país, idioma, prazo de pagamento), descritos na documentação da Moloni.
4. Passar a sério
- 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. - 2Nos dois pedidos
invoiceReceipts/insert, troca"status": 0por"status": 1: a fatura-recibo fica fechada (emitida). - 3Liga o cenário no interruptor em baixo, com Immediately as data arrives.
No Zapier, a app da Moloni trata de clientes e do envio de documentos, mas não cria faturas. E o pedido HTTP do Zapier não renova sozinho a autorização da Moloni, que dura 1 hora. Para a Moloni, usa o Make (é o primeiro separador e tem plano gratuito).
- 1No n8n, cria uma credencial OAuth2 API: Grant Type Authorization Code, Authorization URL
https://www.moloni.pt/ac/root/oauth/, Access Token URLhttps://api.moloni.pt/v1/grant/, o teu Developer ID e Client Secret. Na Moloni, usa como Redirect URI o OAuth Redirect URL que o n8n mostra. - 2Cria o workflow com o nó Webhook (POST), liga o Production URL na Shelf e junta o filtro: Junta 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. - 3Nos nós HTTP Request, escolhe Authentication Generic Credential Type → OAuth2 API e faz os mesmos pedidos do separador Make (
customers/getByVateinvoiceReceipts/insert, com?json=true), trocando{{1.data…}}por{{ $json.body.data… }}. - 4O primeiro teste vai com
"status": 0(rascunho). Para passar a sério: a condiçãotestno filtro,"status": 1e ativar 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. - 2Autoriza a tua aplicação uma vez (
https://www.moloni.pt/ac/root/oauth/?response_type=code&client_id=…&redirect_uri=…) e troca o código por tokens emGET https://api.moloni.pt/v1/grant/?grant_type=authorization_code&client_id=…&client_secret=…&redirect_uri=…&code=…. O acesso dura 1 hora; renova-o comgrant_type=refresh_tokenantes de passarem 14 dias. - 3Cria a fatura-recibo:
POST https://api.moloni.pt/v1/invoiceReceipts/insert/?access_token=…&json=truecom o corpo do separador Make.status0 é rascunho, 1 é fechada. - 4O mesmo evento pode, raramente, chegar duas vezes: guarda o
data.order_idde cada venda já faturada e ignora repetidos.
O corpo vem para quem está isento de IVA pelo art. 53.º (exemption_reason M10, sem taxes). Se cobras IVA, apaga o exemption_reason e junta ao artigo "taxes": [{"tax_id": ID_DO_IVA}] (o id vem de taxes/getAll); confirma no primeiro rascunho se o price fica com ou sem IVA. A taxa e o motivo de isenção confirmam-se 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 usa a taxa ou o motivo de isenção que ele indicar.
Porque é que a Moloni dá mais trabalho do que os outros?+
Porque a API da Moloni usa OAuth em vez de uma chave, e cada fatura precisa dos ids da empresa, da série, do artigo, do cliente e do método de pagamento. Depois de configurado, funciona sozinho como os outros.