MoMenu Payment API

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

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. Para desenvolvimento local, use o header x-dev-mode: true (funciona apenas em localhost).

  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"
    }
  }'
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) do E-kwanza. Funciona de qualquer origem.
x-dev-mode true | false Bypass da validação de domínio. Apenas funciona de localhost.
Exemplo de Headers
Content-Type: application/json
x-api-key: sua_chave_api_aqui
x-env-qa: true     // opcional - ambiente QA (qualquer origem)
x-dev-mode: true   // opcional - bypass domínio (apenas localhost)
Importante: Mantenha sua API Key segura. Nunca exponha em código frontend público. Use variáveis de ambiente ou um backend proxy.
🔒
x-dev-mode: Este header só funciona quando a requisição vem de localhost ou 127.0.0.1. Em produção, o domínio deve estar registado no sistema.

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)
productsOpcional array Lista de produtos para a fatura
products[].idOpcional string ID do produto
products[].productNameOpcional string Nome do produto
products[].productPriceOpcional number Preço unitário em Kwanzas
products[].productQuantityOpcional number Quantidade
products[].ivaOpcional number Taxa IVA (0-14, default: 14). Use 0 para isento.
customerOpcional object Dados do cliente para a fatura
customer.nameOpcional string Nome do cliente
customer.nifOpcional string NIF do cliente
customer.phoneOpcional string Telefone do cliente
simulateResultOpcional string Resultado simulado em ambiente QA. Ver Simulação de Resultados.
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"
    }
  }'
Resposta de Sucesso (200)
{
  "success": true,
  "transactionId": "abc123...",
  "invoiceUrl": "https://invoice-momenu.toquemedia.net/invoices/..."
}

E-kwanza

POST /api/payment/ekwanza Iniciar pagamento E-kwanza

O pagamento E-kwanza é diferido. A ordem é criada com estado OPEN e um QR code é retornado para o cliente. A confirmação é enviada via webhook. O endpoint de status está disponível como fallback.

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 do cliente
productsOpcional array Lista de produtos (mesma estrutura do MCX)
customerOpcional object Dados do cliente (mesma estrutura do MCX)
Exemplo de Requisição
curl -X POST https://api.momenu.online/api/payment/ekwanza \
  -H "Content-Type: application/json" \
  -H "x-api-key: sua_api_key" \
  -d '{
    "paymentInfo": {
      "amount": 5000,
      "phoneNumber": "244923456789"
    },
    "products": [
      {
        "id": "1",
        "productName": "Serviço",
        "productPrice": 5000,
        "productQuantity": 1,
        "iva": 14
      }
    ]
  }'
Resposta de Sucesso (200)
{
  "success": true,
  "merchantTransactionId": "17066400000000",
  "code": "EKZ123456",
  "qrCode": "data:image/png;base64,...",
  "expirationDate": "2024-01-15T12:00:00Z",
  "paymentTimeout": 180
}
💡
paymentTimeout: O cliente tem 180 segundos (3 minutos) para completar o pagamento. Use o endpoint de status com o merchantTransactionId como query param e o code como path param para verificar a confirmação.

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
productsOpcional array Lista de produtos (mesma estrutura do MCX)
customerOpcional object Dados do cliente (mesma estrutura do MCX)
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"
    }
  }'
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 todos os métodos de pagamento (Referência Bancária e E-kwanza). 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 todos os métodos de pagamento diferido (Referência Bancária e E-kwanza). O webhook utiliza entrega fire-and-forget (sem retentativas) — implemente os endpoints de status como fallback.

Verificar Status

Use estes endpoints como fallback para verificar o estado dos pagamentos caso o webhook falhe. Funciona para E-kwanza e Referência Bancária.

GET /api/payment/ekwanza/status/:code Status E-kwanza
ParâmetroTipoDescrição
codePath string Código E-kwanza retornado na criação do pagamento
merchantTransactionIdQuery string ID da transação retornado na criação do pagamento. Recomendado para identificar a ordem correctamente.
Exemplo
curl -X GET "https://api.momenu.online/api/payment/ekwanza/status/EKZ123456?merchantTransactionId=17066400000000" \
  -H "x-api-key: sua_api_key"
Resposta - Pago
{
  "success": true,
  "status": "paid",
  "operationCode": "OP123...",
  "invoiceUrl": "https://invoice-momenu.toquemedia.net/invoices/..."
}
Resposta - Pendente
{
  "success": true,
  "status": "pending",
  "operationCode": "OP123..."
}
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) {
  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 }
    })
  });

  const data = await response.json();

  if (data.success) {
    console.log("Pago! Fatura:", data.invoiceUrl);
    return data;
  } else {
    throw new Error(data.error);
  }
}
Pagamento E-kwanza com Status Polling
// 1. Iniciar pagamento E-kwanza
async function iniciarEkwanza(amount, phoneNumber) {
  const response = await fetch("https://api.momenu.online/api/payment/ekwanza", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": "SUA_API_KEY"
    },
    body: JSON.stringify({
      paymentInfo: { amount, phoneNumber }
    })
  });

  const data = await response.json();

  if (data.success) {
    // Exibir QR code ao utilizador
    exibirQRCode(data.qrCode);
    // Verificar status com polling
    return data;
  }

  throw new Error(data.error);
}

// 2. Verificar status do pagamento (polling)
async function verificarStatusEkwanza(code, merchantTransactionId) {
  const url = `https://api.momenu.online/api/payment/ekwanza/status/${code}?merchantTransactionId=${merchantTransactionId}`;
  const response = await fetch(
    url,
    { headers: { "x-api-key": "SUA_API_KEY" } }
  );

  const data = await response.json();

  if (data.status === "paid") {
    console.log("Pago! Fatura:", data.invoiceUrl);
  }

  return data;
}

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
    });
    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
    });
    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
        }
    }
    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

# Pagamento E-kwanza (confirmação via status polling)
def pagar_ekwanza(amount, phone_number):
    response = requests.post(
        f"{API_URL}/api/payment/ekwanza",
        json={
            "paymentInfo": {
                "amount": amount,
                "phoneNumber": phone_number
            }
        },
        headers=headers
    )
    data = response.json()

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

    # Exibir QR code: data["qrCode"]
    # Verificar status: data["code"] (path) + data["merchantTransactionId"] (query)
    return data

# Verificar status E-kwanza (polling)
def verificar_status_ekwanza(code, merchant_transaction_id):
    response = requests.get(
        f"{API_URL}/api/payment/ekwanza/status/{code}",
        params={"merchantTransactionId": merchant_transaction_id},
        headers=headers
    )
    data = response.json()

    if data.get("status") == "paid":
        print(f"Pago! Fatura: {data['invoiceUrl']}")

    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.
💡
Desenvolvimento local: Combine x-env-qa: true com x-dev-mode: true para desenvolvimento local completo sem restrições de domínio.

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 e E-kwanza
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.

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: 14). Use 0 para isento.
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, 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, E-kwanza, Referência) Implementar checkout, processar pagamentos, gerar faturas
mom-factura-webhooks Webhooks com eventos sequenciais (payment.confirmed + invoice.created) Receber notificações de E-kwanza ou 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 / Codex CLI
# Claude Code: .claude/skills/
git clone https://github.com/ithustle/momenu-skills.git
cp -r momenu-skills/skills/mom-factura-payments .claude/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, x-dev-mode)
  • 💳 MCX - Pagamento imediato com fatura automática
  • 💳 E-kwanza - Pagamento diferido com QR code
  • 💳 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 e E-kwanza) 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 (E-kwanza e Referência)
  • ⚠ 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) e modo desenvolvimento (x-dev-mode)
  • 🎯 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