REST API v1

Integre pagamentos com uma chamada HTTP

Autenticação por Api-Key. Base: https://api.payzeno.io

REST API v1

Fluxo em 3 passos

Do pedido ao webhook confirmado.

1 Criar sessão

Envie amount, currency, customer e URLs de retorno.

2 Pagar

Redireccione para checkout_url ou use pagamento directo na API.

3 Webhook

Receba notificação HTTP quando o estado mudar.

Api-Key

Autenticação

Todas as rotas exigem o header Api-Key com a chave criada em app.payzeno.io → Integração → API Keys.

  • Formato: pk_live_… (produção) ou pk_test_… (sandbox, quando disponível)
  • A conta merchant tem de estar activa e com KYC aprovado
  • Configure o webhook URL na API key antes de criar sessões
cURL
curl https://api.payzeno.io/v1/checkout/sessions/abc123/status \
  -H "Api-Key: pk_live_xxx"
Idempotency-Key

Idempotência

Em todos os POST, envie Idempotency-Key com um valor único por operação (ex.: ID do pedido na sua loja).

  • Repetir o mesmo key + mesmo body devolve a resposta original (sem duplicar cobrança)
  • Key diferente com body igual → erro 409
  • Recomendado: UUID ou -checkout
cURL
curl -X POST https://api.payzeno.io/v1/checkout/sessions \
  -H "Api-Key: pk_live_xxx" \
  -H "Idempotency-Key: order-123-unique" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
REST API v1

Endpoints principais

Rotas essenciais para checkout hosted e pagamentos directos.

POST /v1/checkout/sessions

Cria sessão de checkout e devolve checkout_url e checkout_id.

GET /v1/checkout/sessions/:id/status

Consulta estado da sessão (pending, paid, expired, etc.).

POST /v1/payment/mpesa

Pagamento directo M-Pesa com checkout_id e phone (+258…).

POST /v1/payment/emola

Pagamento directo e-Mola com checkout_id e phone.

POST /v1/checkout/sessions

Criar sessão de checkout

amount em unidades menores (centavos): 2500 = 25,00 MZN.

Campos obrigatórios: amount, currency, customer (name, phone E.164; email opcional), success_url.

Opcional: reference, description, cancel_url, payment_methods (mpesa, emola, …).

Schema completo no Swagger →
Request
curl -X POST https://api.payzeno.io/v1/checkout/sessions \
  -H "Api-Key: pk_live_xxx" \
  -H "Idempotency-Key: order-123-unique" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 2500,
    "currency": "MZN",
    "reference": "order-123",
    "description": "Pedido #123",
    "payment_methods": ["mpesa", "emola"],
    "customer": {
      "name": "Maria Silva",
      "email": "maria@example.com",
      "phone": "+258840000000"
    },
    "success_url": "https://loja.com/sucesso",
    "cancel_url": "https://loja.com/cancelado"
  }'

Resposta (201)

JSON
{
  "success": true,
  "checkout_id": "674a1b2c3d4e5f678901234",
  "checkout_url": "https://checkout.payzeno.io/payment/674a1b2c...",
  "status": "pending",
  "amount": 2500,
  "currency": "MZN",
  "expires_at": "2026-06-16T14:30:00+02:00"
}
POST /v1/payment/*

Pagamento directo na API

Dispara o STK/USSD no telemóvel do cliente sem abrir o browser. Use após criar a sessão.

Telefone: formato Moçambique +25884… ou 84… (normalizado automaticamente).

Request
curl -X POST https://api.payzeno.io/v1/payment/mpesa \
  -H "Api-Key: pk_live_xxx" \
  -H "Idempotency-Key: order-123-mpesa" \
  -H "Content-Type: application/json" \
  -d '{
    "checkout_id": "674a1b2c3d4e5f678901234",
    "phone": "+258840000000"
  }'

Resposta assíncrona (202)

JSON
{
  "success": true,
  "checkout_id": "674a1b2c3d4e5f678901234",
  "status": "pending",
  "message": "Payment initiated. Await webhook or poll status."
}

Confirme o pagamento via webhook payment.succeeded ou polling em GET …/status.

REST API v1

Webhooks

POST JSON para o URL configurado na API key. Responda 2xx rapidamente; reentregas em caso de falha.

event

payment.succeeded

Pagamento confirmado. Estado succeeded.

event

payment.refunded

Reembolso processado.

event

payment.chargeback

Chargeback / disputa registada.

Exemplo — payment.succeeded

Webhook payload
{
  "event": "payment.succeeded",
  "payment_id": "674a1b2c3d4e5f678901234",
  "checkout_id": "674a1b2c3d4e5f678901234",
  "reference": "order-123",
  "amount": 2500,
  "currency": "MZN",
  "status": "succeeded",
  "paid_at": "2026-06-15T12:34:56+02:00",
  "payment_method": "mpesa",
  "customer": {
    "name": "Maria Silva",
    "email": "maria@example.com"
  }
}

amount está sempre em unidades menores. reference é o valor que enviou em reference ao criar a sessão.

REST API v1

Erros e códigos HTTP

Corpo JSON: { "success": false, "message": "…" }

HTTP Situação
400 Body inválido, amount ≤ 0, telefone inválido, sessão expirada
401 Api-Key em falta ou inválida
404 checkout_id não encontrado ou de outro merchant
409 Conflito de idempotência (mesmo key, body diferente)
422 Gateway recusou o pagamento (saldo, timeout, etc.)

Estados da sessão

  • pending — aguarda pagamento
  • paid — pago com sucesso
  • expired — sessão expirou
  • cancelled — cancelado pelo cliente
  • refunded — reembolsado

Links de pagamento (/l/pl_xxx) no dashboard não exigem API — ideal para testes rápidos.

cURL
curl https://api.payzeno.io/v1/checkout/sessions/674a1b2c/status \
  -H "Api-Key: pk_live_xxx"
OpenAPI

Swagger interactivo

Explore todos os endpoints, schemas e teste chamadas na documentação OpenAPI.

Abrir Swagger
WhatsApp