MoMenu Payment API

API de pagamentos para Angola com suporte a Multicaixa Express e Referência Bancária. Inclui geração automática de faturas (FR) com conformidade SAFT-AO.

⚠️

Em vigor — instantWithdraw e obrigatorio

Desde 22 de Junho de 2026, o campo instantWithdraw e obrigatorio e tem de ser true em todas as requisicoes de pagamento (/api/payment/mcx, /api/payment/reference). Sem ele, ou com false, a requisicao e recusada com INSTANT_WITHDRAW_REQUIRED. Com o levantamento instantaneo, o valor do pagamento (deduzidos os 2%) e transferido de imediato para a conta bancaria verificada do comerciante, deixando de haver saldo retido na plataforma.

Aja ja: atualize a sua integracao para enviar "instantWithdraw": true no corpo das requisicoes e garanta que tem uma conta bancaria verificada no portal (Definicoes → Verificacao Bancaria). Sem conta verificada, a iniciacao de pagamentos e recusada com BANK_ACCOUNT_NOT_VERIFIED. Veja a seccao Novidades.

Novidades — v1.0.1

Resumo das alterações desta versão. Algumas afetam integrações existentes — reveja antes de 22/06/2026.

💵 Levantamento instantâneo (KWiK)

Com "instantWithdraw": true, o valor do pagamento — deduzidos os 2% — é transferido automaticamente para a conta bancária verificada do comerciante via KWiK, assim que o pagamento (MCX ou Referência) é confirmado. A plataforma deixa de reter saldo: o único valor que permanece em saldo é a taxa de 2%.

  • Limite por transferência: 500.000 KZ (dividido automaticamente em parcelas).
  • Tecto por levantamento: 2.000.000 KZ. O excedente fica em saldo e segue depois.
  • Limite diário por conta: 4.000.000 KZ. Acima disso, o restante fica em saldo e é transferido nos dias seguintes.
  • Aplica-se aos pagamentos MCX e Referência Bancária.

🏦 Conta bancária verificada obrigatória

Para receber pagamentos é agora obrigatório ter uma conta bancária verificada no portal (Definições → Verificação Bancária). Sem verificação aprovada, a iniciação de pagamentos é recusada com BANK_ACCOUNT_NOT_VERIFIED (HTTP 403). Compras de plano/pool (em que o comerciante é o pagador) não são afetadas.

📦 products obrigatório

O campo products passou a ser obrigatório e deve conter pelo menos um produto válido (productName, productPrice > 0, productQuantity inteiro > 0). É a fonte de verdade dos itens da fatura e do valor cobrado. Ausência → MISSING_PRODUCTS; item inválido → INVALID_PRODUCT.

⏱️ instantWithdraw obrigatório (desde 22/06/2026)

O campo instantWithdraw é obrigatório e tem de ser true em /api/payment/mcx e /api/payment/reference desde 22 de Junho de 2026. Requisições sem o campo (ou com false) são recusadas com INSTANT_WITHDRAW_REQUIRED (HTTP 400). Atualize a sua integração para o enviar.

💰 Mínimo de pagamento: 100 KZ

O valor mínimo por pagamento passou a ser 100 KZ (BELOW_MINIMUM abaixo disso). Garante que o valor líquido após os 2% fica acima do piso de transferência do KWiK, evitando saldos presos.

🧾 IVA: default agora é 0 (isento)

Quando products[].iva é omitido, o item passa a ser tratado como isento (0%) em vez de 14%. Faturas com itens isentos passam a indicar o motivo de não liquidação "M00 - Regime Simplificado". Para aplicar IVA, envie explicitamente "iva": 14 (ou a taxa aplicável: 0, 2, 5, 7 ou 14).

🧾 Cliente: nome exige NIF real

Um cliente nominal exige um NIF real. Se enviar customer.name sem um NIF verdadeiro (em falta, formato inválido ou a sequência de noves 999999999), a fatura é emitida a Consumidor Final com NIF 999999999 — o nome não é usado. Apenas quando nome e NIF reais são fornecidos é que ambos aparecem na fatura.

Início Rápido

Integre pagamentos na sua aplicação em 3 passos.

  1. 1

    Obtenha a sua API Key

    Aceda ao painel do comerciante e copie a sua chave de API. Esta chave deve ser enviada no header x-api-key de todas as requisições.

  2. 2

    Registe o seu domínio

    Configure os domínios autorizados no painel. Apenas requisições vindas de domínios registados serao aceites.

  3. 3

    Faça a primeira requisição

    Envie um pagamento de teste usando o endpoint desejado. Recomendamos comecar pelo Multicaixa Express.

Primeiro pagamento - MCX
curl -X POST https://api.momenu.online/api/payment/mcx \
  -H "Content-Type: application/json" \
  -H "x-api-key: SUA_API_KEY" \
  -d '{
    "paymentInfo": {
      "amount": 1000,
      "phoneNumber": "244923456789"
    },
    "products": [
      { "id": "1", "productName": "Produto", "productPrice": 1000, "productQuantity": 1 }
    ],
    "instantWithdraw": true
  }'
Se o pagamento for bem-sucedido, recebera um transactionId e um invoiceUrl com o link da fatura gerada automáticamente.

Base URL

🔗 https://api.momenu.online

Autenticação e Headers

🔒

API Key Authentication

Todas as requisições devem incluir a chave de API no header.

HEADERS OBRIGATORIOS

HeaderValorDescrição
Content-Type application/json Tipo de conteúdo da requisição
x-api-key string Chave de API fornecida no painel do comerciante

HEADERS OPCIONAIS

HeaderValorDescrição
x-env-qa true | false Ativar ambiente de testes (QA). Funciona de qualquer origem.
Exemplo de Headers
Content-Type: application/json
x-api-key: sua_chave_api_aqui
x-env-qa: true     // opcional - ambiente QA (qualquer origem)
Importante: Mantenha sua API Key segura. Nunca exponha em código frontend público. Use variáveis de ambiente ou um backend proxy.

Multi API Keys

Crie até 10 API Keys para rastrear vendas de diferentes integrações separadamente. Cada key identifica a origem da venda, permitindo ver o total vendido por cada integração.

COMO FUNCIONA

PassoDescrição
1. Criar Key No painel Desenvolvedores, crie uma nova API Key com um nome descritivo (ex: "Loja Centro", "App Mobile")
2. Usar Key Envie a key gerada no header x-api-key em vez da key original
3. Ver Vendas Na página de Transações, filtre por API Key para ver vendas separadas ou o somatório total
Exemplo com API Key gerada
Content-Type: application/json
x-api-key: a1b2c3d4-e5f6-7890-abcd-ef1234567890  // key gerada no painel
🔑
Compatibilidade: A API Key original (ID do comerciante) continua a funcionar normalmente. As keys geradas são opcionais e servem apenas para rastrear vendas por integração.
Levantamento: O saldo disponível para levantar é sempre o total de todas as API Keys combinadas. A filtragem por key é apenas para visualização.

GESTÃO DE API KEYS

AcçãoDescrição
Criar Até 10 keys por conta. Cada uma com nome descritivo e chave UUID gerada automaticamente.
Activar / Desactivar Keys desactivadas rejeitam requisições com erro INVALID_API_KEY.
Remover Remove permanentemente a key. Todas as requisições com esta key passam a ser rejeitadas.

Validação de Valores

Importante: Se paymentInfo.amount e products forem ambos fornecidos, os valores devem ser iguais.

Regras de Validação

paymentInfo.amountproductsResultado
❌ Ausente ❌ Ausente Erro: AMOUNT_MISMATCH
2500 ❌ Ausente ✔ Usa 2500
❌ Ausente [{price: 2500, qty: 1}] ✔ Usa total calculado (2500)
2500 [{price: 2500, qty: 1}] ✔ Valores iguais - Válido
2500 [{price: 3000, qty: 1}] ❌ Erro: AMOUNT_MISMATCH
Resposta de Erro - AMOUNT_MISMATCH
{
  "success": false,
  "error": "paymentInfo.amount (2500) deve ser igual ao total dos produtos (3000.00)",
  "code": "AMOUNT_MISMATCH"
}
💡
Dica: Se fornecer products, o total é calculado como: SUM(productPrice * productQuantity). Certifique-se que paymentInfo.amount corresponde a este cálculo.

Multicaixa Express (MCX)

POST /api/payment/mcx Processar pagamento Multicaixa Express

O pagamento MCX é imediato. Quando bem-sucedido, cria uma ordem com estado PAID e gera a fatura automáticamente.

PARAMETROS DO BODY

Parâmetro Tipo Descrição
paymentInfo.amountObrigatório number Valor do pagamento em Kwanzas
paymentInfo.phoneNumberObrigatório string Número de telefone (formato: 244XXXXXXXXX)
productsObrigatório array Lista de produtos da fatura (mínimo 1). É a fonte de verdade dos itens e do valor.
products[].idOpcional string ID do produto
products[].productNameObrigatório string Nome do produto
products[].productPriceObrigatório number Preço unitário em Kwanzas (> 0)
products[].productQuantityObrigatório number Quantidade (inteiro > 0)
products[].ivaOpcional number Taxa IVA (0-14, default: 0 = isento quando omitido).
instantWithdrawObrigatório boolean Levantamento instantâneo: transfere o valor (menos 2%) para a conta bancária verificada do comerciante assim que o pagamento é confirmado. Obrigatório e tem de ser true (desde 22/06/2026). Requer conta bancária verificada.
customerOpcional object Dados do cliente para a fatura
customer.nameOpcional string Nome do cliente. Exige customer.nif real (ver nota abaixo).
customer.nifOpcional* string NIF do cliente. Obrigatório se enviar o nome. Sem NIF real, a fatura sai a Consumidor Final.
customer.phoneOpcional string Telefone do cliente
simulateResultOpcional string Resultado simulado em ambiente QA. Ver Simulação de Resultados.
👤
Identificação do cliente: um cliente nominal exige NIF real. Se enviar name sem NIF verdadeiro (em falta, inválido ou a sequência de noves), a fatura é emitida a Consumidor Final (NIF 999999999). Só com nome e NIF reais é que ambos aparecem na fatura. Itens sem iva são isentos com motivo "M00 - Regime Simplificado".
Exemplo de Requisição
curl -X POST https://api.momenu.online/api/payment/mcx \
  -H "Content-Type: application/json" \
  -H "x-api-key: sua_api_key" \
  -d '{
    "paymentInfo": {
      "amount": 2500,
      "phoneNumber": "244923456789"
    },
    "products": [
      {
        "id": "1",
        "productName": "Produto Exemplo",
        "productPrice": 2500,
        "productQuantity": 1,
        "iva": 14
      }
    ],
    "customer": {
      "name": "Cliente Teste",
      "nif": "123456789"
    },
    "instantWithdraw": true
  }'
Resposta de Sucesso (200)
{
  "success": true,
  "transactionId": "abc123...",
  "invoiceUrl": "https://invoice-momenu.toquemedia.net/invoices/..."
}

Referência Bancária

POST /api/payment/reference Gerar referência de pagamento

Gera uma referência bancária para pagamento. A ordem é criada com estado OPEN. O cliente paga através do ATM ou Internet Banking usando a entidade e referência fornecida. A confirmação é enviada automaticamente via webhook. O endpoint de Status Referência está disponível como fallback.

Parâmetro Tipo Descrição
paymentInfo.amountObrigatório number Valor do pagamento em Kwanzas
productsObrigatório array Lista de produtos da fatura (mínimo 1, mesma estrutura do MCX). iva default 0 quando omitido.
customerOpcional object Dados do cliente (mesma estrutura do MCX)
instantWithdrawObrigatório boolean Levantamento instantâneo após confirmação do pagamento da referência. Obrigatório e tem de ser true (desde 22/06/2026). Requer conta bancária verificada.
Exemplo de Requisição
curl -X POST https://api.momenu.online/api/payment/reference \
  -H "Content-Type: application/json" \
  -H "x-api-key: sua_api_key" \
  -d '{
    "paymentInfo": {
      "amount": 10000
    },
    "products": [
      {
        "id": "1",
        "productName": "Produto",
        "productPrice": 10000,
        "productQuantity": 1,
        "iva": 14
      }
    ],
    "customer": {
      "name": "Cliente",
      "nif": "123456789"
    },
    "instantWithdraw": true
  }'
Resposta de Sucesso (200)
{
  "success": true,
  "operationId": "op-123...",
  "transactionId": "17066400000000",
  "referenceNumber": "123456789",
  "entity": "12345",
  "dueDate": "2024-01-20"
}

Webhook

A confirmação de pagamentos é enviada automaticamente via webhook para o URL configurado na sua conta. Funciona para a Referência Bancária. Os endpoints de status estão disponíveis como fallback.

Como funciona

  • 1. Faça login na sua conta em momenu.toquemedia.net
  • 2. Aceda ao menu Desenvolvedores
  • 3. Adicione a sua URL de webhook
  • 4. Guarde a configuração

Eventos do Webhook

Quando um pagamento é confirmado, o webhook envia dois eventos sequenciais:

  • payment.confirmed — Enviado imediatamente após o pagamento ser confirmado. Permite atualizar o estado da encomenda no seu sistema antes da fatura estar pronta.
  • invoice.created — Enviado após a fatura ser gerada e disponível para download. Inclui o campo invoiceUrl com o link para o PDF.

Fluxo de eventos

Pagamento confirmado
  |
  |-- POST webhook: { event: "payment.confirmed", ... }
  |
  Gerar fatura + Upload PDF
  |
  |-- POST webhook: { event: "invoice.created", ..., invoiceUrl }
  
Evento: payment.confirmed
{
  "event": "payment.confirmed",
  "merchantTransactionId": "abc123...",
  "ekwanzaTransactionId": "EKZ456...",
  "operationStatus": "1",
  "operationData": { ... }
}
Evento: invoice.created
{
  "event": "invoice.created",
  "merchantTransactionId": "abc123...",
  "ekwanzaTransactionId": "EKZ456...",
  "operationStatus": "1",
  "operationData": { ... },
  "invoiceUrl": "https://invoice-momenu.toquemedia.net/invoices/..."
}
💡
Valores de operationStatus: "1" Pago com sucesso · "3" Cancelado/Expirado · "4" Falhado/Recusado · "5" Erro

Nota: Eventos com status diferente de "1" (cancelado, falhado, erro) são enviados sem o campo event, mantendo compatibilidade com integrações existentes.

EXEMPLO - NODE.JS / EXPRESS

Servidor webhook
const express = require("express");
const app = express();

app.use(express.json());

app.post("/webhook/meu-webhook", (req, res) => {
  const { event, merchantTransactionId, operationStatus, invoiceUrl } = req.body;

  switch (event) {
    case "payment.confirmed":
      console.log("Pagamento confirmado:", merchantTransactionId);
      // Atualizar estado da encomenda no seu sistema
      break;

    case "invoice.created":
      console.log("Fatura disponivel:", invoiceUrl);
      // Guardar URL da fatura, enviar ao cliente
      break;

    default:
      // Eventos sem campo "event" (cancelado, falhado, erro)
      if (["3", "4", "5"].includes(operationStatus)) {
        console.log("Pagamento falhou:", operationStatus);
      }
  }

  res.status(200).json({ received: true });
});

app.listen(3000);

EXEMPLO - PYTHON / FLASK

Servidor webhook
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/webhook/meu-webhook", methods=["POST"])
def momenu_webhook():
    data = request.json
    event = data.get("event")
    transaction_id = data.get("merchantTransactionId")
    status = data.get("operationStatus")

    if event == "payment.confirmed":
        print(f"Pagamento confirmado: {transaction_id}")
        # Atualizar estado da encomenda

    elif event == "invoice.created":
        invoice_url = data.get("invoiceUrl")
        print(f"Fatura disponivel: {invoice_url}")
        # Guardar URL da fatura

    elif status in ["3", "4", "5"]:
        print(f"Pagamento falhou: {status}")

    return jsonify({"received": True}), 200
Importante: O webhook funciona para o pagamento diferido por Referência Bancária. O webhook utiliza entrega fire-and-forget (sem retentativas) — implemente os endpoints de status como fallback.

Verificar Status

Use este endpoint como fallback para verificar o estado dos pagamentos caso o webhook falhe. Funciona para a Referência Bancária.

GET /api/payment/reference/status/:operationId Status Referência
ParâmetroTipoDescrição
operationIdPath string ID da operação retornado na geração da referência
merchantTransactionIdQuery string ID da transação (transactionId) retornado na geração da referência. Recomendado para identificar a ordem correctamente.
Exemplo
curl -X GET "https://api.momenu.online/api/payment/reference/status/op-123?merchantTransactionId=17066400000000" \
  -H "x-api-key: sua_api_key"
Resposta
{
  "success": true,
  "payment": {
    "status": "paid",
    "message": "Pagamento confirmado"
  },
  "invoiceUrl": "https://invoice-momenu.toquemedia.net/invoices/..."
}

Guias de Integração

Exemplos completos de integração em diferentes linguagens. Todos os exemplos incluem tratamento de erros e confirmação de pagamentos diferidos.

JavaScript / Fetch

Pagamento MCX (Frontend)
// Pagamento simples via Multicaixa Express
async function processarPagamentoMCX(amount, phoneNumber, products) {
  const response = await fetch("https://api.momenu.online/api/payment/mcx", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": "SUA_API_KEY"
    },
    body: JSON.stringify({
      paymentInfo: { amount, phoneNumber },
      products,
      instantWithdraw: true
    })
  });

  const data = await response.json();

  if (data.success) {
    console.log("Pago! Fatura:", data.invoiceUrl);
    return data;
  } else {
    throw new Error(data.error);
  }
}

Node.js

Integração completa com Axios
const axios = require("axios");

const API_URL = "https://api.momenu.online";
const API_KEY = process.env.MOM_FACTURA_API_KEY;

const client = axios.create({
  baseURL: API_URL,
  headers: {
    "Content-Type": "application/json",
    "x-api-key": API_KEY
  }
});

// Pagamento MCX
async function pagarMCX(amount, phoneNumber, products) {
  try {
    const { data } = await client.post("/api/payment/mcx", {
      paymentInfo: { amount, phoneNumber },
      products,
      instantWithdraw: true
    });
    return data;
  } catch (error) {
    throw new Error(error.response?.data?.error || "Erro de pagamento");
  }
}

// Gerar referência bancária
async function gerarReferência(amount, products, customer) {
  try {
    const { data } = await client.post("/api/payment/reference", {
      paymentInfo: { amount },
      products,
      customer,
      instantWithdraw: true
    });
    return data;
  } catch (error) {
    throw new Error(error.response?.data?.error || "Erro ao gerar referência");
  }
}

// Verificar status de referência
async function verificarReferência(operationId, merchantTransactionId) {
  try {
    const { data } = await client.get(
      `/api/payment/reference/status/${operationId}?merchantTransactionId=${merchantTransactionId}`
    );
    return data;
  } catch (error) {
    throw new Error(error.response?.data?.error || "Erro ao verificar status");
  }
}

Python

Integração com requests
import requests
import time
import os

API_URL = "https://api.momenu.online"
API_KEY = os.environ["MOM_FACTURA_API_KEY"]

headers = {
    "Content-Type": "application/json",
    "x-api-key": API_KEY
}

# Pagamento MCX
def pagar_mcx(amount, phone_number, products=None):
    payload = {
        "paymentInfo": {
            "amount": amount,
            "phoneNumber": phone_number
        },
        "instantWithdraw": True
    }
    if products:
        payload["products"] = products

    response = requests.post(
        f"{API_URL}/api/payment/mcx",
        json=payload,
        headers=headers
    )
    data = response.json()

    if not data.get("success"):
        raise Exception(data.get("error", "Erro desconhecido"))

    return data

Ambiente de Testes (QA)

A API suporta um ambiente de testes para validar a integração sem processar pagamentos reais. O modo QA está disponível para Multicaixa Express e Referência Bancária.

Como ativar o modo QA

Adicione o header x-env-qa: true nas suas requisições. Este header funciona de qualquer origem (não requer localhost).

Requisição em modo QA
curl -X POST https://api.momenu.online/api/payment/mcx \
  -H "Content-Type: application/json" \
  -H "x-api-key: sua_api_key" \
  -H "x-env-qa: true" \
  -d '{
    "paymentInfo": {
      "amount": 1000,
      "phoneNumber": "244923456789"
    },
    "simulateResult": "success"
  }'
Atenção: No modo QA, as transações são processadas contra o ambiente de testes do provedor de pagamento. Nenhum valor real é cobrado.

Simulação de Resultados

Em modo QA, pode simular diferentes cenários de pagamento usando o campo simulateResult no body da requisição MCX. Cada valor simula um comportamento diferente do provedor de pagamento.

success Pagamento bem-sucedido. Simula um pagamento completo e retorna transactionId.
insufficient_balance Saldo insuficiente. O cliente não tem saldo para completar o pagamento.
timeout Timeout. A requisição expira sem resposta do provedor de pagamento.
rejected Rejeitado. O pagamento e explicitamente rejeitado pelo provedor.
invalid_number Número inválido. O número de telefone não está registado no serviço de pagamento.
Exemplo - Simular saldo insuficiente
curl -X POST https://api.momenu.online/api/payment/mcx \
  -H "Content-Type: application/json" \
  -H "x-api-key: sua_api_key" \
  -H "x-env-qa: true" \
  -d '{
    "paymentInfo": {
      "amount": 5000,
      "phoneNumber": "244923456789"
    },
    "simulateResult": "insufficient_balance"
  }'
💡
Nota: O campo simulateResult só é utilizado quando o header x-env-qa: true está presente. Em produção, este campo é ignorado.

Códigos de Erro

Todas as respostas de erro seguem o formato padrão com success: false, error (mensagem) e code (código de erro).

Formato de erro padrão
{
  "success": false,
  "error": "Descrição do erro",
  "code": "ERROR_CODE"
}
MISSING_API_KEY API Key não fornecida no header x-api-key
INVALID_API_KEY API Key invalida ou desativada
DOMAIN_NOT_ALLOWED Origem da requisição não autorizada. Registe o domínio no painel.
INVALID_AMOUNT Valor de pagamento inválido ou negativo
AMOUNT_MISMATCH paymentInfo.amount não corresponde ao total dos produtos
MISSING_PHONE Número de telefone obrigatório para MCX
MISSING_RESTAURANT_ID Comerciante não identificado. Verifique a API Key.
RATE_LIMIT_EXCEEDED Limite geral de 100 requisições/minuto excedido
PAYMENT_RATE_LIMIT_EXCEEDED Limite de 20 pagamentos/minuto excedido
INTERNAL_ERROR Erro interno do servidor. Tente novamente.
MISSING_PRODUCTS O campo products é obrigatório e deve conter pelo menos um produto.
INVALID_PRODUCT Um item de products é inválido (productName, productPrice > 0, productQuantity inteiro > 0, iva 0-14).
BELOW_MINIMUM Valor abaixo do mínimo de pagamento (100 KZ).
BANK_ACCOUNT_NOT_VERIFIED Conta bancária não verificada. Obrigatória para receber pagamentos (Definições → Verificação Bancária).
INSTANT_WITHDRAW_REQUIRED O campo instantWithdraw é obrigatório e tem de ser true em MCX e Referência (desde 22/06/2026).

Criar Fatura Standalone (Pro)

POST /api/invoices Criar fatura independente (FR, FT ou PROFORMA)

Cria uma fatura standalone (não vinculada a pagamento) com todos os campos obrigatórios e opcionais. Suporta formato A4 (padrão) ou C7 (compacto). Retorna a URL da fatura gerada.

Para emitir uma proforma (documento sem valor fiscal), use invoiceType: "PROFORMA". A proforma recebe um número próprio (ex.: PRF-MOM2026-001), não tem hash SAFT, é renderizada em A4 e pode incluir uma data de validade.

Idempotência: envie um header Idempotency-Key (UUID gerado pelo cliente) para garantir que tentativas repetidas do mesmo POST não criam faturas duplicadas. Repetições retornam a mesma resposta cacheada.

PARAMETROS DO BODY

Parâmetro Tipo Descrição
invoiceTypeObrigatório string Tipo de documento: FR (Fatura-Recibo), FT (Fatura) ou PROFORMA (sem valor fiscal)
customer.nameObrigatório string Nome do cliente
customer.nifObrigatório string NIF do cliente
customer.phoneOpcional string Telefone do cliente
customer.addressOpcional string Endereço do cliente
itemsObrigatório array Lista de itens da fatura (mínimo 1)
items[].descriptionObrigatório string Descrição do item
items[].quantityObrigatório number Quantidade (deve ser > 0)
items[].unitPriceObrigatório number Preço unitário em Kwanzas
items[].ivaOpcional number Taxa IVA (0-14, default: 0 = isento quando omitido).
paymentMethodObrigatório (FR/FT) string Método de pagamento: Multicaixa Express, E-Kwanza, Referência Bancária, Dinheiro, Transferência Bancária. Para PROFORMA é opcional.
notesOpcional string Notas adicionais na fatura
discountOpcional number Valor do desconto em Kwanzas
formatOpcional string Formato do PDF: A4 (padrão) ou C7. PROFORMA é sempre A4.
validUntilOpcional (PROFORMA) string (ISO 8601) Data limite de validade da proforma. Ignorado para FR/FT.
validityDaysOpcional (PROFORMA) number Validade em dias a partir da emissão. Default 30. Ignorado se validUntil for fornecido.
Exemplo de Requisição
curl -X POST https://api.momenu.online/api/invoices \
  -H "Content-Type: application/json" \
  -H "x-api-key: sua_api_key_pro" \
  -d '{
    "invoiceType": "FR",
    "customer": {
      "name": "João Silva",
      "nif": "123456789",
      "phone": "244923456789"
    },
    "items": [
      {
        "description": "Consultoria de TI",
        "quantity": 2,
        "unitPrice": 50000,
        "iva": 14
      },
      {
        "description": "Suporte Técnico",
        "quantity": 1,
        "unitPrice": 25000,
        "iva": 0
      }
    ],
    "paymentMethod": "Transferência Bancária",
    "notes": "Pagamento até 30 dias",
    "discount": 5000,
    "format": "A4"
  }'
Resposta de Sucesso (201)
{
  "success": true,
  "invoiceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "invoiceNumber": "FR-MOM2025-001",
  "invoiceType": "FR",
  "invoiceFile": "JVBERi0xLjcK...",
  "invoiceUrl": "https://invoice-momenu.toquemedia.net/invoices/2025/01/merchant123/FR-MOM2025-001.pdf",
  "total": 120000,
  "format": "A4",
  "createdAt": "2025-01-15T10:30:00.000Z"
}
Exemplo de Proforma
curl -X POST https://api.momenu.online/api/invoices \
  -H "Content-Type: application/json" \
  -H "x-api-key: sua_api_key_pro" \
  -d '{
    "invoiceType": "PROFORMA",
    "customer": {
      "name": "Empresa XYZ, Lda",
      "nif": "5417123456"
    },
    "items": [
      {
        "description": "Consultoria — Fase 1",
        "quantity": 1,
        "unitPrice": 250000,
        "iva": 14
      }
    ],
    "validityDays": 15,
    "notes": "Aguarda aprovação do cliente"
  }'
Resposta de Proforma (201)
{
  "success": true,
  "invoiceId": "...",
  "invoiceNumber": "PRF-MOM2026-001",
  "invoiceType": "PROFORMA",
  "invoiceUrl": "https://invoice-momenu.toquemedia.net/...",
  "total": 250000,
  "format": "A4",
  "validUntil": "2026-05-21T...",
  "status": "ACTIVE",
  "createdAt": "2026-05-06T..."
}
💡
Cálculo Automático: O total é calculado automaticamente: SUM(quantity * unitPrice) - discount. O IVA é incluído no preço unitário.

Listar Faturas (Pro)

GET /api/invoices Listar todas as faturas standalone

Retorna lista paginada com todas as faturas do comerciante autenticado — facturas standalone (FR, FT, PROFORMA) e facturas geradas automaticamente por pagamentos. Para proformas, a resposta inclui também validUntil e status.

QUERY PARAMETERS

Parâmetro Tipo Descrição
limitOpcional number Número de resultados por página (default: 50, max: 100)
offsetOpcional number Número de resultados a saltar (default: 0)
Exemplo de Requisição
curl -X GET "https://api.momenu.online/api/invoices?limit=10&offset=0" \
  -H "x-api-key: sua_api_key_pro"
Resposta de Sucesso (200)
{
  "success": true,
  "invoices": [
    {
      "invoiceId": "a1b2c3d4...",
      "invoiceNumber": "FR-MOM2025-001",
      "invoiceType": "FR",
      "customerName": "João Silva",
      "customerNif": "123456789",
      "total": 120000,
      "createdAt": "2025-01-15T10:30:00.000Z",
      "invoiceUrl": "https://invoice-momenu.toquemedia.net/..."
    }
  ],
  "total": 1,
  "limit": 10,
  "offset": 0
}

Buscar Fatura Específica (Pro)

GET /api/invoices/:invoiceNumber Buscar fatura pelo número

Retorna os detalhes completos de uma fatura, incluindo o PDF codificado em Base64.

PATH PARAMETERS

Parâmetro Tipo Descrição
invoiceNumberObrigatório string Número da fatura devolvido na criação (ex.: FR-MOM2026-001)
Exemplo de Requisição
curl -X GET https://api.momenu.online/api/invoices/FR-MOM2026-001 \
  -H "x-api-key: sua_api_key_pro"
Resposta de Sucesso (200)
{
  "success": true,
  "invoice": {
    "invoiceId": "a1b2c3d4...",
    "invoiceNumber": "FR-MOM2025-001",
    "invoiceType": "FR",
    "customer": {
      "name": "João Silva",
      "nif": "123456789",
      "phone": "244923456789"
    },
    "items": [
      {
        "description": "Consultoria de TI",
        "quantity": 2,
        "unitPrice": 50000,
        "iva": 14,
        "subtotal": 100000
      }
    ],
    "paymentMethod": "Transferência Bancária",
    "total": 120000,
    "totalTaxes": 14736.84,
    "partialTotal": 105263.16,
    "createdAt": "2025-01-15T10:30:00.000Z",
    "invoiceFile": "JVBERi0xLjcK...",
    "invoiceUrl": "https://invoice-momenu.toquemedia.net/..."
  }
}
Resposta de Erro - Fatura Não Encontrada (404)
{
  "success": false,
  "error": "Fatura não encontrada",
  "code": "INVOICE_NOT_FOUND"
}

Rate Limiting

A API aplica limites de requisições para garantir a estabilidade do serviço. Existem dois níveis de limitação:

100

Limite Geral

Máximo de 100 requisições por minuto por IP. Aplica-se a todos os endpoints da API.

20

Limite de Pagamentos

Máximo de 20 requisições de pagamento por minuto por IP. Aplica-se aos endpoints POST de pagamento.

Resposta - Rate Limit Excedido (429)
{
  "success": false,
  "error": "Demasiadas requisições. Tente novamente em breve.",
  "code": "RATE_LIMIT_EXCEEDED"
}
💡
Recomendação: Ao usar os endpoints de status como fallback, use um intervalo mínimo de 5 segundos entre requisições para evitar atingir o limite.

Agent Skills

Agent Skills são capacidades reutilizáveis para agentes de IA. Instale-os com um único comando para equipar o seu agente com conhecimento especializado sobre a MoMenu API.

Seguem a especificação aberta Agent Skills e funcionam com qualquer LLM agent compatível.

🤖
LLM? Aceda a /llms.txt para a documentação completa em texto plano, optimizada para consumo por agentes de IA.

AGENTES COMPATIVEIS

Claude Code, TM Code, OpenAI Codex, GitHub Copilot, Cursor, Cline, Gemini, Windsurf, e qualquer agente que suporte a especificação agentskills.io.

Skills Disponíveis

SkillDescriçãoQuando usar
mom-factura-payments Integração completa de pagamentos (MCX, Referência) Implementar checkout, processar pagamentos, gerar faturas
mom-factura-webhooks Webhooks com eventos sequenciais (payment.confirmed + invoice.created) Receber notificações de Referência Bancária
mom-factura-testing Testes e depuração com ambiente QA Simular resultados, testar erros, validar integração

INSTALACAO

npx skills add (recomendado)
# Instalar todos os skills
npx skills add ithustle/momenu-skills --all

# Ou instalar skills especificos
npx skills add ithustle/momenu-skills --skill mom-factura-payments -y
npx skills add ithustle/momenu-skills --skill mom-factura-webhooks -y
npx skills add ithustle/momenu-skills --skill mom-factura-testing -y
Manual - Claude Code / TM Code / Codex CLI
# Claude Code: .claude/skills/ (global: ~/.claude/skills/)
git clone https://github.com/ithustle/momenu-skills.git
cp -r momenu-skills/skills/mom-factura-payments .claude/skills/

# TM Code: .tms/skills/ (global: ~/.toquemedia-studio/skills/)
git clone https://github.com/ithustle/momenu-skills.git
cp -r momenu-skills/skills/mom-factura-payments .tms/skills/

# OpenAI Codex CLI: .codex/skills/
git clone https://github.com/ithustle/momenu-skills.git
cp -r momenu-skills/skills/mom-factura-payments .codex/skills/

# Cursor / Copilot / Outros: consulte a documentação do agente
💡
O agente detecta os skills automáticamente ao iniciar. Basta pedir para "integrar pagamentos MoMenu" e o skill relevante e activado.

Skill: mom-factura-payments

Conhecimento completo sobre todos os endpoints de pagamento, validação de valores, formatos de request/response e padrões de integração em JavaScript, Node.js e Python.

💡
Ideal para: Implementar pagamentos pela primeira vez ou adicionar um novo método de pagamento ao projecto.
Instalação rápida
npx skills add ithustle/momenu-skills --skill mom-factura-payments -y

CONTEÚDO

  • 📄 Autenticação e headers (x-api-key, x-env-qa)
  • 💳 MCX - Pagamento imediato com fatura automática
  • 💳 Referência Bancária - Pagamento via ATM/Internet Banking
  • 🔧 Validação de valores (amount vs products)
  • 💻 Exemplos em JavaScript, Node.js e Python
  • ⚠ Códigos de erro e taxas
  • 📄 references/STATUS-POLLING.md - Referência de webhook e status (fallback)

ESTRUTURA DO SKILL

Directorio
mom-factura-payments/
  SKILL.md                        # Instruções principais
  references/
    STATUS-POLLING.md             # Referência de webhook e status (fallback)

Skill: mom-factura-webhooks

Webhooks para receber confirmações de pagamentos (Referência Bancária) com dois eventos sequenciais. Endpoints de status disponíveis como fallback.

💡
Ideal para: Receber notificações de pagamento em tempo real ou implementar o fallback via status endpoints.
Instalação rápida
npx skills add ithustle/momenu-skills --skill mom-factura-webhooks -y

CONTEÚDO

  • 📨 Payload do webhook e estados de pagamento
  • 💻 Exemplos de servidor webhook em Node.js, Python e Serverless
  • 🔄 Endpoints de status como fallback (Referência Bancária)
  • ⚠ Rate limiting nos endpoints de fallback

Skill: mom-factura-testing

Tudo sobre o ambiente de testes: modo QA, simulação de 5 cenários para MCX, depuração de erros comuns e checklist de 10 pontos pré-produção.

💡
Ideal para: Validar a integração antes de ir para produção, testar cenários de erro, ou depurar problemas.
Instalação rápida
npx skills add ithustle/momenu-skills --skill mom-factura-testing -y

CONTEÚDO

  • 🔧 Modo QA (x-env-qa)
  • 🎯 5 cenários: success, insufficient_balance, timeout, rejected, invalid_number
  • 💻 Helpers de teste em JavaScript e Python
  • 🔍 Depuração de erros comuns com causas e soluções
  • ✔ Checklist de 10 pontos antes de ir para produção
Segurança: Revise sempre o conteúdo do SKILL.md antes de instalar skills de terceiros. Skills podem instruir agentes a executar código e aceder a ficheiros do sistema.

Taxas

Taxa de Processamento: 2%

Uma taxa de 2% é aplicada a todos os pagamentos processados através da API. A taxa é calculada automáticamente e deduzida do valor total.

feeAmount = totalAmount * 0.02
netAmount = totalAmount - feeAmount

Exemplo de cálculo

DescriçãoValor (KZ)
Valor do pagamento 10.000,00
Taxa (2%) 200,00
Valor líquido 9.800,00