Guia de Cash Out (PIX Out)
Este guia explica passo a passo como realizar transferências PIX (cash out) com consulta prévia de chave.
Visão Geral
O Cash Out permite enviar dinheiro via PIX para qualquer chave cadastrada no sistema PIX brasileiro. O fluxo recomendado é:
- Consultar a chave - Validar e obter os dados do destinatário
- Confirmar os dados - Exibir para o usuário para confirmação
- Executar a transferência - Enviar o PIX
Fluxo de Integração
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Consultar │ │ Confirmar │ │ Executar │
│ Chave │ ───► │ Dados │ ───► │ Transferência│
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
Nome, Banco, Usuário E2E gerado,
Conta, CPF/CNPJ Confirma Webhook enviado
Tipos de Chave PIX
| Tipo | Formato | Exemplo |
|---|---|---|
CPF | 11 dígitos | 12345678901 |
CNPJ | 14 dígitos | 12345678000199 |
EMAIL | E-mail válido | joao@email.com |
PHONE | +55 + DDD + número | +5511999998888 |
EVP | UUID | 123e4567-e89b-12d3-a456-426614174000 |
Passo 1: Consultar a Chave PIX (Opcional mas Recomendado)
Antes de transferir, consulte a chave para validar o destinatário e exibir os dados para confirmação do usuário:
curl -X GET "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/key/12345678901" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-suaempresa"
A API consulta a chave automaticamente durante a transferência — a consulta prévia é opcional, mas melhora a experiência do usuário. O resultado fica em cache por 24 h (use ?noCache=true para forçar uma consulta nova ao DICT) e consome cota de consultas conforme as políticas do tenant.
O que a transferência devolve
A resposta da transferência não repete os dados do destinatário: ela traz o desfecho da operação (status, paymentId, endToEndId). Nome e documento de quem recebeu aparecem no extrato e no lookup do pagamento.
Passo 2: Executar a Transferência
Execute a transferência PIX via chave:
Request
curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/out" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-suaempresa" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: transfer-order-12345" \
-d '{
"amount": 100.00,
"keyType": "CPF",
"key": "12345678901",
"description": "Service payment",
"identifier": "order-12345"
}'
Parâmetros do Body
A conta de origem vem do path ({accountId}) e a moeda é sempre BRL — nenhum dos dois é enviado no body.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
amount | number | Sim | Valor em BRL (ex.: 100.00) |
keyType | string | Sim | Tipo da chave: CPF, CNPJ, EMAIL, PHONE, EVP |
key | string | Sim | Chave PIX do destinatário |
description | string | Não | Descrição da transferência (máximo 140 caracteres) |
identifier | string | Não | Identificador fornecido pelo integrador para rastreamento e conciliação. Aparece no extrato quando o pagamento é conciliado. |
Resposta de Sucesso
O status HTTP reflete o desfecho: 200 (COMPLETED), 422 (FAILED),
202 (TIMEOUT/PENDING — indeterminado; confira o extrato antes de
reenviar).
Rejeições imediatas do liquidante (antifraude ou saldo insuficiente na
liquidação) retornam 422 FAILED na hora, com errorCode
(partner_rejected / insufficient_funds) e errorReason preenchidos.
Transferências retidas para análise de risco aparecem como
PENDING_APPROVAL nas consultas e aguardam o desfecho por até ~30 minutos
antes de marcar TIMEOUT; o resultado chega pelos webhooks
pix.out.completed / pix.out.failed / pix.out.timeout.
{
"paymentId": "pay_2f4a0f88-2147-49f2-a4e2-4f7b9f6c0f7a",
"transactionId": "txn-abc123-def456",
"endToEndId": "E12345678202301011234abcdefghijkl",
"status": "COMPLETED",
"completedAt": "2026-01-28T15:00:02Z",
"identifier": "order-12345",
"workflowId": "pix-out-{accountId}-{identifier}"
}
| Campo | Descrição |
|---|---|
paymentId | ID interno da intenção de pagamento (rastreio/conciliação) |
transactionId | ID da transação |
endToEndId | ID E2E BACEN (presente após liquidar) |
status | COMPLETED, FAILED, TIMEOUT, PENDING, PROCESSING |
errorCode / errorReason | preenchidos quando FAILED |
Resposta de Erro
{
"errorCode": "insufficient_funds",
"message": "Saldo insuficiente na conta do liquidante para concluir a operação."
}
Timeout no fluxo síncrono
Se o liquidante não confirmar dentro da janela, a API responde 202 com
status: "TIMEOUT" e um campo warning — não existe 207. O PIX pode ter
sido enviado: consulte o extrato ou o lookup do pagamento antes de reenviar.
O desfecho tardio chega por webhook (pix.out.completed / pix.out.failed).
Fluxo assíncrono (recomendado para alto volume)
Use POST /v1/accounts/{accountId}/pix/out/async para agendar o pagamento e receber 202 imediato:
curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/out/async" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-suaempresa" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: transfer-order-async-12345" \
-d '{
"amount": 100.00,
"keyType": "CPF",
"key": "12345678901",
"description": "Service payment",
"identifier": "order-12345-async"
}'
Resposta:
{
"paymentId": "pay_2f4a0f88-2147-49f2-a4e2-4f7b9f6c0f7a",
"workflowId": "pix-out-{accountId}-{identifier}",
"runId": "b7c1f0e2-...",
"idempotencyKey": "transfer-order-async-12345",
"identifier": "order-12345-async",
"status": "ACCEPTED"
}
A resposta 202 inclui o header Location apontando para
/v1/accounts/{accountId}/payments/{identifier} — um alias mantido por
compatibilidade, que responde com headers Deprecation. A rota canônica de
consulta é GET /v1/accounts/{accountId}/pix/payments/lookup?identifier=.
O resultado final (sucesso/falha) é entregue por webhook e também pode ser
consultado por identifier/paymentId.
Passo 3: Consultar Status da Transferência
Após executar uma transferência, você pode consultar seu status usando o ID E2E:
Request
curl -X GET "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/transactions?endToEndId=E12345678202301011234abcdefghijkl" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-suaempresa"
Parâmetros de Query
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
endToEndId | string | Sim* | ID E2E da transação |
identifier | string | Sim* | Identificador da cobrança ou referência |
*Pelo menos um dos dois (endToEndId ou identifier) é obrigatório. O accountId vai no path, não na query.
Resposta de Sucesso (200 OK)
Esta rota responde no mesmo envelope do extrato (items[]), com 0 ou 1
item. Os horários (timestamp) saem em horário de Brasília (-03:00).
{
"accountId": "{accountId}",
"source": "live",
"page": 0,
"size": 1,
"totalElements": 1,
"totalPages": 1,
"hasNext": false,
"items": [
{
"partnerId": "a697b489-681a-451c-a043-d4ae65be8c80",
"endToEndId": "E12345678202301011234abcdefghijkl",
"direction": "OUT",
"transactionType": "D",
"operation": "PIX",
"status": "COMPLETED",
"amount": -100.00,
"currency": "BRL",
"description": "PIX - MARIA DA SILVA",
"identifier": "order-12345",
"timestamp": "2026-01-28T15:00:00-03:00",
"counterParty": {
"name": "MARIA DA SILVA",
"document": "123***01",
"bankCode": "001"
}
}
],
"fetchedAt": "2026-01-28T18:00:05Z"
}
Para receber um único objeto (em vez do envelope items[]), use
GET /v1/accounts/{accountId}/pix/payments/lookup?identifier=... (ou
?endToEnd=...).
Status Possíveis
| Status | Descrição |
|---|---|
COMPLETED | Liquidada com sucesso |
PROCESSING | Em processamento no parceiro |
PENDING_APPROVAL | Em esteira de aprovação interna |
FAILED | Falhou / rejeitada |
REVERSED | Estornada / devolvida |
UNKNOWN | Status do parceiro fora do mapeamento |
Fluxo de estados
- O resultado final chega pelos webhooks
pix.out.completed/pix.out.failed. Em caso deTIMEOUT, a API também emitepix.out.timeout(estado indeterminado — confira o extrato; umcompleted/failedtardio ainda pode chegar depois). - Reenvio com a mesma
Idempotency-Keydepende do desfecho anterior: se o pagamento terminou emFAILED, a chave é liberada e a nova requisição reexecuta o pagamento (desde v2.43.3); se terminou emTIMEOUT, o reenvio não acontece — o estado é indeterminado e a API devolve o resultado registrado. Com uma chave nova, você pode duplicar o envio. Detalhes em Idempotência.
Sempre salve o identifier das transferências e consulte o status por ele — é o ID que você define, estável e disponível desde a criação (o endToEndId só existe após a liquidação).
Exemplo Completo: Script de Cash Out
#!/bin/bash
# Configuration
API_URL="https://tenant.api.corpx.com"
TOKEN="your_token_here"
TENANT_ID="tenant-suaempresa"
ACCOUNT_ID="your_account"
# Transfer details
PIX_KEY="12345678901"
PIX_KEY_TYPE="CPF"
AMOUNT=100.00
echo "=== PIX CASH OUT ==="
echo ""
echo "PIX Key: $PIX_KEY ($PIX_KEY_TYPE)"
echo "Amount: R$ $AMOUNT"
echo ""
# 1. Confirm (in production, wait for user confirmation)
read -p "Confirm transfer? (y/n): " confirm
if [ "$confirm" != "y" ]; then
echo "Transfer cancelled"
exit 0
fi
# 2. Execute transfer
echo ""
echo "Executing transfer..."
IDEMPOTENCY_KEY="cashout-$(date +%s)-$RANDOM"
transfer_response=$(curl -s -X POST "$API_URL/v1/accounts/$ACCOUNT_ID/pix/out" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-Id: $TENANT_ID" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-d "{
\"amount\": $AMOUNT,
\"keyType\": \"$PIX_KEY_TYPE\",
\"key\": \"$PIX_KEY\",
\"description\": \"Transfer via script\"
}")
# Check result
STATUS=$(echo "$transfer_response" | jq -r '.status')
E2E=$(echo "$transfer_response" | jq -r '.endToEndId')
if [ "$STATUS" = "COMPLETED" ]; then
echo ""
echo "=== TRANSFER COMPLETED ==="
echo "Status: $STATUS"
echo "E2E: $E2E"
echo "$transfer_response" | jq
else
echo ""
echo "=== RESULT ==="
echo "$transfer_response" | jq
fi
Consultar QR Code (Decode)
Antes de pagar, você pode decodificar o QR Code para exibir os dados do beneficiário ao usuário:
curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/out/qr-code/decode" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-suaempresa" \
-H "Content-Type: application/json" \
-d '{
"emv": "00020126580014br.gov.bcb.pix0136123e4567-e89b-12d3-a456-426614174000..."
}'
Resposta (QR dinâmico imediato):
{
"key": "123e4567-e89b-12d3-a456-426614174000",
"amount": 150.00,
"originalAmount": 150.00,
"identifier": "8e4d8c19-1d3f-4b22-bf6f-79a4d0e1f001",
"decodeId": "8e4d8c19-1d3f-4b22-bf6f-79a4d0e1f001",
"qrCodeType": "dynamic-immediate",
"qrCodeTypeId": 1,
"allowChange": false,
"description": "Compra online",
"payeeName": "EMPRESA EXEMPLO LTDA",
"payeeDocument": "12345678000190",
"bankIspb": "50871921",
"bankBranch": "0001",
"bankAccount": "123456-7",
"accountType": "CHECKING"
}
Para QR de cobrança com vencimento (dynamic-due-date), o response
inclui também os componentes do valor (discount, deduction,
interest, penalty), originalAmount (valor de face antes dos
ajustes), dueDate, paymentDeadline e payeeTradeName (nome
fantasia da PJ). Veja o exemplo correspondente no OpenAPI.
Você pode reutilizar decodeId no body do POST /pix/out/qr-code/async
para pular um segundo decode na hora do pagamento.
Após confirmar, use o endpoint de pagamento abaixo para executar.
Pagar QR Code (PIX Out via EMV)
Se você possui um código EMV (QR Code copia e cola), use o endpoint assíncrono (canônico):
Fluxo assíncrono (recomendado)
POST /v1/accounts/{accountId}/pix/out/qr-code/async — resposta 202 imediata:
curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/out/qr-code/async" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-suaempresa" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pay-qr-async-12345" \
-d '{
"emv": "00020126580014br.gov.bcb.pix...",
"amount": 150.00,
"description": "QR Code payment",
"identifier": "pay-qr-async-12345"
}'
Resposta:
{
"paymentId": "pay_2f4a0f88-2147-49f2-a4e2-4f7b9f6c0f7a",
"workflowId": "pix-out-{accountId}-{identifier}",
"runId": "b7c1f0e2-...",
"idempotencyKey": "pay-qr-async-12345",
"identifier": "pay-qr-async-12345",
"status": "ACCEPTED"
}
A resposta 202 inclui o header Location apontando para o lookup do
pagamento. O resultado final (sucesso/falha/timeout) chega por webhook
(pix.out.completed, pix.out.failed, pix.out.timeout) e também pode
ser consultado por identifier/paymentId.
Endpoint síncrono (deprecated)
POST /v1/accounts/{accountId}/pix/out/qr-code (sync) está deprecated.
Continue funcionando por compatibilidade e devolve headers Deprecation,
Sunset e Link (sunset previsto: 2026-11-21). Migre para
/pix/out/qr-code/async.
Webhook de Transferência
Após a transferência, você receberá um webhook no envelope canônico
(id, type, occurredAt, schemaVersion, data):
{
"id": "evt_out_123",
"type": "pix.out.completed",
"occurredAt": "2026-01-28T15:00:02.900Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-suaempresa",
"accountId": "{accountId}",
"data": {
"endToEnd": "E36741675202601281500001234567",
"key": {
"type": "CPF",
"key": "12345678901"
},
"identifier": "order-12345",
"amount": 100.00,
"payee": {
"name": "MARIA DA SILVA",
"document": "12345678901",
"bankCode": "001"
},
"completedAt": "2026-01-28T15:00:02.900Z"
}
}
O evento equivalente de falha é pix.out.failed (com error no data) e o
de estado indeterminado é pix.out.timeout. A referência completa dos campos
está em Webhooks.
BigPix (descontinuado)
O limite de R$ 15.000 por transação foi removido — POST /v1/accounts/{accountId}/pix/out
agora aceita qualquer valor em uma única transação. O BigPix (que dividia valores
grandes em múltiplos PIX) não é mais necessário e está descontinuado.
Os endpoints /pix/out/bigpix e /pix/out/bank-account/bigpix continuam funcionais
por retrocompatibilidade, mas retornam o header Deprecation: true. Migre para
POST /pix/out (ou /pix/out/bank-account). A data de remoção definitiva será
anunciada no changelog com antecedência.
Erros Comuns
| Erro | HTTP | Causa | Solução |
|---|---|---|---|
key_not_found | 404 | Chave PIX não existe no DICT | Verifique a chave e seu tipo |
invalid_pix_key | 422 | Chave malformada ou incompatível com o tipo informado | Use: CPF, CNPJ, EMAIL, PHONE, EVP |
insufficient_funds | 422 | Saldo insuficiente apurado pelo liquidante | Verifique o saldo da conta |
limit_exceeded_daily / limit_exceeded_nightly / limit_exceeded_monthly / limit_exceeded_transaction | 422 | Limite da conta excedido na janela indicada | Aguarde a virada da janela ou solicite aumento |
partner_rejected | 422 | Recusa do liquidante por risco/antifraude | Veja o bloco partner com o motivo |
policy_denied | 422 | Uma regra de política do tenant/conta recusou a transferência | Veja violations no corpo e ajuste a regra no painel — Políticas e Regras |
A lista completa com mensagens e semântica está em Erros.
Reenviar a mesma Idempotency-Key em PIX out não devolve 409: a API
retorna o resultado já registrado (ou reexecuta, se o desfecho anterior foi
FAILED).
Boas Práticas
- Sempre consulte a chave antes de transferir para validar o destinatário
- Confirme com o usuário os dados antes de executar
- Use uma Idempotency Key única por transferência — e reutilize a mesma chave ao repetir a requisição, nunca uma nova
- Salve o E2E para rastreamento e suporte
- Configure webhooks para receber confirmações assíncronas
- Implemente retry com exponential backoff para falhas temporárias
Limites
| Tipo | Limite Padrão |
|---|---|
| Por transação | Sem limite fixo |
| Diário | R$ 100.000,00 |
| Mensal | Sem limite |
Não há mais limite fixo por transação — o valor é limitado apenas pelos
limites operacionais da conta (consulte GET /v1/accounts/{accountId}/pix/limits).
Os limites podem ser personalizados. Entre em contato com o suporte para mais informações.
Próximos Passos
- Guia de Devolução - Estornar transferências recebidas
- Webhooks - Configurar notificações
- Erros - Lista completa de códigos de erro