Documentação pública da API
Produção e teste
Integre pagamentos M-Pesa usando a sua chave API. As rotas são iguais nos dois ambientes; muda apenas o endpoint base.
Base API
https://mpesa-sandbox.lodging.co.mz/api/v1
Base API
https://mpesa-sandbox.lodging.co.mz/api/v1
Exemplo: para criar pagamentos em produção use https://mpesa-sandbox.lodging.co.mz/api/v1/payments. No ambiente de teste, use os mesmos paths e formato de dados; as transações ficam isoladas.
Autenticação
Use a secret key criada no painel em Chaves API. A public key identifica a integração, mas não autentica chamadas server-to-server.
Headers
Authorization: Bearer sk_live_xxx X-API-Key: sk_live_xxx Content-Type: application/json
https://mpesa-sandbox.lodging.co.mz/api/v1/authenticate
Resposta autenticada
{
"authenticated": true,
"message": "Authenticated.",
"data": {
"api_key": {
"id": 1,
"name": "Checkout",
"public_key": "pk_live_xxx",
"secret_prefix": "sk_live_xxxxx",
"is_active": true
}
}
}
Resposta não autenticada
{
"authenticated": false,
"message": "Invalid API key, IP or host."
}
Criar pagamento C2B
Cria uma cobrança M-Pesa para o número indicado.
https://mpesa-sandbox.lodging.co.mz/api/v1/payments
Body
{
"reference": "ORDER-1001",
"amount": 250,
"currency": "MZN",
"phone": "848000000",
"customer": {
"external_id": "cust_1",
"name": "Cliente Exemplo",
"email": "cliente@example.com",
"phone": "848000000"
},
"billing_address": {
"line1": "Av. 24 de Julho",
"city": "Maputo",
"country": "MZ"
},
"callback_url": "https://sua-app.co.mz/webhooks/mpesa",
"return_url": "https://sua-app.co.mz/orders/1001"
}
Resposta: pagamento iniciado
{
"id": "9d6bd2e2-8df2-4d9a-9d9a-4f690b6f1c31",
"reference": "ORDER-1001",
"status": "initiated",
"amount": "250.00",
"currency": "MZN",
"phone": "848000000",
"transaction_id": null,
"message": "Pedido de pagamento iniciado.",
"created_at": "2026-09-23T18:30:00Z"
}
Resposta: pagamento confirmado
{
"id": "9d6bd2e2-8df2-4d9a-9d9a-4f690b6f1c31",
"reference": "ORDER-1001",
"status": "paid",
"amount": "250.00",
"currency": "MZN",
"phone": "848000000",
"transaction_id": "MP250923.1830.A12345",
"paid_at": "2026-09-23T18:31:20Z"
}
Resposta: pagamento falhado
{
"id": "9d6bd2e2-8df2-4d9a-9d9a-4f690b6f1c31",
"reference": "ORDER-1001",
"status": "failed",
"amount": "250.00",
"currency": "MZN",
"phone": "848000000",
"error": {
"code": "PAYMENT_FAILED",
"message": "O pagamento não foi concluído."
}
}
Consultar pagamento
Consulta o estado atual de um pagamento pelo identificador devolvido na criação.
https://mpesa-sandbox.lodging.co.mz/api/v1/payments/{payment_uuid}
Resposta
{
"id": "9d6bd2e2-8df2-4d9a-9d9a-4f690b6f1c31",
"reference": "ORDER-1001",
"direction": "c2b",
"status": "paid",
"amount": "250.00",
"currency": "MZN",
"phone": "848000000",
"transaction_id": "MP250923.1830.A12345",
"created_at": "2026-09-23T18:30:00Z",
"paid_at": "2026-09-23T18:31:20Z"
}
Criar payout B2C
Cria um pedido de envio de dinheiro para o número indicado. O processamento pode ser assíncrono.
https://mpesa-sandbox.lodging.co.mz/api/v1/payouts/b2c
Body
{
"reference": "PAYOUT-1001",
"amount": 100,
"currency": "MZN",
"phone": "848000000",
"callback_url": "https://sua-app.co.mz/webhooks/payouts"
}
Resposta
{
"id": "49c40b06-75d4-43f7-9e5f-02ff0af71d2f",
"reference": "PAYOUT-1001",
"direction": "b2c",
"status": "queued",
"amount": "100.00",
"currency": "MZN",
"phone": "848000000",
"message": "Pedido de payout recebido e colocado em fila."
}
Webhooks
Configure webhooks em Chaves API > Webhooks. Cada API key tem uma chave webhook propria (whsec_...) e pode receber apenas os eventos selecionados.
O seu endpoint recebe o header X-Mpesa-Signature, um HMAC SHA-256 do corpo JSON usando a chave webhook.
Payload enviado
{
"event": "payment.paid",
"payment": {
"id": "9d6bd2e2-8df2-4d9a-9d9a-4f690b6f1c31",
"reference": "ORDER-1001",
"direction": "c2b",
"status": "paid",
"amount": "250.00",
"currency": "MZN",
"phone": "848000000",
"transaction_id": "MP250923.1830.A12345",
"paid_at": "2026-09-23T18:31:20Z"
}
}
Resposta esperada do seu endpoint
Responda com qualquer código HTTP 2xx para marcar o evento como entregue.
HTTP/1.1 200 OK
{
"received": true
}
Eventos de webhook
| Evento | Descrição |
|---|---|
payment.created | Pagamento criado na API. |
payment.initiated | Pedido de pagamento iniciado. |
payment.pending | Pagamento ainda aguarda confirmação. |
payment.paid | Pagamento confirmado com sucesso. |
payment.failed | Pagamento falhou. |
payout.queued | Payout B2C colocado na fila. |
payout.initiated | Payout B2C iniciado. |
payout.paid | Payout B2C confirmado com sucesso. |
payout.failed | Payout B2C falhou. |
Estados possíveis
Erros comuns
| HTTP | Código | Descrição |
|---|---|---|
| 401 | UNAUTHENTICATED | Chave API ausente ou inválida. |
| 403 | FORBIDDEN | IP ou host não permitido para a chave API. |
| 422 | VALIDATION_ERROR | Campos obrigatórios ausentes ou inválidos. |
| 500 | PAYMENT_ERROR | O pagamento não pôde ser processado. |
Formato de erro
{
"message": "O pagamento não pôde ser processado.",
"error": {
"code": "PAYMENT_ERROR"
}
}