Guia de Integração: PIX Cash-Out
Este guia descreve o fluxo completo para integrar pagamentos PIX (cash-out) via API Owem.
Fluxo de Vida de um Pagamento
POST /api/external/pix/cash-out
│
▼
┌─────────────┐
│ accepted │ ← HTTP 200, worked: true, final: false
│ (pendente) │
└──────┬──────┘
│
┌─────┴─────┐
▼ ▼
┌────────┐ ┌────────┐
│settled │ │rejected│
│(final) │ │(final) │
└────────┘ └────────┘Importante
worked: truesignifica que o pagamento foi aceito para processamento, NÃO que foi liquidado.final: truesignifica que o pagamento atingiu estado terminal (settled ou rejected).final: falsesignifica que ainda está em processamento.
Enviando um Pagamento
curl -X POST https://api.owem.com.br/api/external/pix/cash-out \
-H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/json" \
-H "hmac: $HMAC_SHA512" \
-H "Idempotency-Key: order-12345" \
-d '{
"amount": 3000,
"pix_key": "12345678901",
"pix_key_type": "cpf",
"description": "Pagamento fornecedor",
"external_id": "order-12345"
}'Campos do Request
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
amount | Integer | Sim | Valor em centavos (R$ 30,00 = 3000) |
pix_key | String | Condicional | Chave PIX (CPF, CNPJ, email, telefone, EVP) |
pix_key_type | String | Recomendado | cpf, cnpj, email, phone, evp |
emv | String | Condicional | Copia e Cola (alternativa a pix_key) |
description | String | Nao | Descricao (max 140 caracteres) |
external_id | String | Nao | ID no seu sistema (max 128 chars, a-zA-Z0-9._:-) |
Idempotency-Key | Header | Recomendado | Previne duplicatas em retry |
Chaves de 11 digitos
Se a chave tem exatamente 11 digitos, pode ser CPF ou telefone. Envie pix_key_type para evitar erro pix_key_ambiguous.
Resposta de Sucesso (HTTP 200)
{
"worked": true,
"final": false,
"transaction_id": "PIXOUT20260405abc123",
"end_to_end_id": "E37839059202604051530abcdef01",
"external_id": "order-12345",
"amount": 30000000,
"fee_amount": 3500,
"net_amount": 30003500,
"status": "accepted",
"detail": "PIX enviado para processamento"
}Unidades de valor na resposta
O amount na resposta esta em unidades base (subcentavos). Para converter para reais: amount / 10000. Exemplo: 30000000 / 10000 = R$ 3.000,00.
Acompanhando o Status
Opcao 1: Webhooks (recomendado)
Configure um webhook para receber notificacoes automaticas:
| Evento | Quando | Significado |
|---|---|---|
pix.payout.confirmed | Liquidacao BACEN | Pagamento confirmado (terminal) |
pix.payout.failed | Rejeicao BACEN | Pagamento rejeitado (terminal) |
Opcao 2: Polling (GET)
# Por transaction_id
GET /api/external/transactions/{transaction_id}
# Por E2E ID
GET /api/external/transactions/e2e/{end_to_end_id}
# Por external_id
GET /api/external/transactions/ref/{external_id}Frequencia de polling
O BACEN liquida em ~1.6 segundos. Recomendamos polling a cada 2 segundos, maximo 5 tentativas. Apos isso, confie nos webhooks.
Requests Sequenciais
Requests simultaneos para a mesma conta
O sistema usa lock exclusivo por conta com backoff progressivo para garantir consistencia de saldo. Requests concorrentes sao enfileirados internamente e processados em sequencia. Se o saldo e insuficiente, o request retorna insufficient_balance.
Recomendacao: para melhor desempenho, envie requests sequencialmente quando possivel.
Codigos de Erro
Validacao (HTTP 422)
| Codigo | Descricao | Acao |
|---|---|---|
invalid_amount | Valor invalido (<=0 ou nao inteiro) | Corrigir valor |
pix_key_ambiguous | 11 digitos pode ser CPF ou telefone | Enviar pix_key_type |
destination_not_found | Chave PIX nao registrada no DICT | Verificar chave |
self_transfer | Transferencia para propria chave | Usar TEF |
same_institution_transfer | Destinatario na mesma instituicao | Usar TEF |
nighttime_limit_exceeded | Fora do horario permitido | Aguardar horario |
Integracao (HTTP 400)
| Codigo | Descricao | Acao |
|---|---|---|
insufficient_balance | Saldo insuficiente (valor + taxa) | Verificar saldo |
lock_unavailable | Outra transacao em andamento | Eliminado -- requests concorrentes agora retornam insufficient_balance se o saldo e insuficiente, ou sucedem se o saldo esta disponivel |
provider_timeout | Timeout na comunicacao BACEN | Reenviar apos 5s |
Idempotencia
Envie o header Idempotency-Key com um ID unico do seu sistema. Se o mesmo key for enviado novamente, a API retorna o resultado da primeira execucao sem processar novamente.
# Primeira chamada — processa normalmente
curl -H "Idempotency-Key: pay-001" ...
# Segunda chamada com mesmo key — retorna resultado anterior
curl -H "Idempotency-Key: pay-001" ...Circuit Breaker (recomendacao)
Implemente circuit breaker no seu cliente:
- Contagem: Apos 3 erros consecutivos (timeout ou 5xx), pare de enviar por 30 segundos
- Half-open: Apos 30s, envie 1 request de teste
- Reset: Se o teste funcionar, retome operacao normal
Comprovante
Apos liquidacao (final: true), o comprovante esta disponivel:
GET /api/external/transactions/{transaction_id}/receiptRetorna dados estruturados do comprovante (pagador, recebedor, valor, data, E2E).