Payloads dos Webhooks
Exemplos dos payloads enviados para cada tipo de evento. Todos os webhooks são enviados como HTTP POST com Content-Type: application/json.
Headers de segurança
Cada notificação inclui os headers X-Minha Konta-Signature (HMAC-SHA256), X-Minha Konta-Timestamp, X-Minha Konta-Event-Id e X-Minha Konta-Event-Type. Consulte Webhooks - Visão Geral para detalhes sobre validação.
Referência de Status
Nem todos os eventos significam que a transação está concluída. Use a tabela abaixo para saber quando o dinheiro foi efetivamente liquidado.
| Evento | Status | Significado | Dinheiro liquidado? |
|---|---|---|---|
pix.charge.created | created | QR code gerado ou cash-in iniciado. Aguardando pagamento. | Não - apenas criado |
pix.charge.paid | paid | PIX recebido e liquidado em conta. Saldo atualizado, taxa cobrada. | Sim |
pix.charge.expired | expired | QR code expirou sem pagamento. | N/A |
pix.charge.cancelled | cancelled | QR code cancelado explicitamente pelo merchant antes do pagamento. | N/A |
pix.payout.queued | queued | PIX enviado aguardando reprocessamento automático por limite DICT. Sem débito ainda. | Não -- aguardando disponibilidade |
pix.payout.processing | processing | PIX enviado, aguardando confirmação do destino. Saldo reservado (hold). | Não - pode reverter |
pix.payout.confirmed | settled | PIX enviado confirmado pelo destino. Débito definitivo. | Sim |
pix.payout.failed | rejected | PIX enviado rejeitado pelo destino. Hold liberado, saldo restaurado. | Não |
pix.payout.returned | returned | PIX enviado devolvido após liquidação. | Sim (reverso) |
pix.refund.requested | requested | Devolução PIX solicitada (MED). Bloqueio cautelar criado. | Parcial |
pix.refund.completed | settled / completed | Devolução PIX concluída e liquidada. Débito definitivo. | Sim |
pix.return.received | settled | Devolução PIX recebida e liquidada (crédito na conta). | Sim |
pix.infraction.created | ACKNOWLEDGED | Infração PIX reportada contra você. Requer ação. | Parcial - pode haver valor em disputa |
pix.infraction.resolved | CLOSED / CANCELLED | Infração resolvida (devolução executada ou negada). | N/A - efeito em outro evento |
pix.infraction.defense_submitted | defense_submitted | Defesa submetida pelo merchant. Aguardando BACEN. | N/A |
webhook.test | test | Evento de teste disparado manualmente via portal Admin/Merchant. | N/A |
Regras de reconciliação:
- Considere entradas de saldo apenas nos status:
paid(crédito PIX IN) ereturned(reversão de um PIX OUT previamente enviado). - Considere saídas de saldo apenas nos status:
settled(débito PIX OUT confirmado) ecompleted(débito MED refund definitivo), esettledempix.return.received(reversão de um PIX IN previamente recebido). - Todos os demais status (
created,queued,processing,rejected,expired,requested,ACKNOWLEDGED,defense_submitted, etc.) são intermediários - não disparam movimento contábil do seu lado. - Não tratar
pix.payout.processingcomo confirmação; aguarde o evento terminal (pix.payout.confirmedoupix.payout.failed).
Campos comuns
Todos os payloads de webhook incluem estes campos:
| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Tipo do evento que disparou o webhook (ex: pix.charge.paid) |
status | string | Status da operação - consulte a Referência de Status |
account_id | integer | Número da sua conta na Minha Konta |
entity_id | string (UUID) | Identificador da entidade Minha Konta |
Valores monetários: Todos os valores são em subcentavos (1 BRL = 10.000 subcentavos). Para converter para reais: valor / 10000. Exemplo: 300000 / 10000 = R$ 30,00.
pix.charge.paid
Enviado quando um PIX é recebido e liquidado na conta. Este é o evento que confirma que o dinheiro entrou.
Exemplo - vinculado a QR code
{
"event_type": "pix.charge.paid",
"status": "paid",
"account_id": 10014,
"amount": 300000,
"fee_amount": 400,
"end_to_end_id": "E9040088820260402095758709999671",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"tx_id": "u5f26sfyrq4plkw7tjwa",
"qr_code_id": "f401d5e3-a2b1-4c8e-9f3d-1234567890ab",
"counterparty_name": "MARIA SANTOS",
"payer_document": "12345678901",
"payer_ispb": "60701190",
"payer_bank_name": "Itau Unibanco S.A.",
"external_id": "order-9876",
"paid_at": "2026-04-02T09:58:05Z",
"recipient_key": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"recipient_key_type": "evp",
"receiver": {
"name": "PENHOTA GESTAO E INTERMEDIACAO LTDA",
"document": "62188010000150",
"account": "0000000019",
"ispb": "04838403",
"institution_name": "AVIVPAY IP"
}
}Exemplo - transferência direta (sem QR)
{
"event_type": "pix.charge.paid",
"status": "paid",
"account_id": 10014,
"amount": 300000,
"fee_amount": 400,
"end_to_end_id": "E9040088820260402095758709999671",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"tx_id": null,
"qr_code_id": null,
"counterparty_name": "JOAO SILVA",
"payer_document": "98765432100",
"payer_ispb": "00000000",
"payer_bank_name": "Banco do Brasil S.A.",
"external_id": null,
"paid_at": "2026-04-02T10:15:22Z",
"recipient_key": "12345678901",
"recipient_key_type": "cpf",
"receiver": {
"name": "PENHOTA GESTAO E INTERMEDIACAO LTDA",
"document": "62188010000150",
"account": "0000000019",
"ispb": "04838403",
"institution_name": "AVIVPAY IP"
}
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.charge.paid |
status | string | Sempre paid |
account_id | integer | Número da conta que recebeu o PIX |
amount | integer | Valor recebido em subcentavos. 300000 = R$ 30,00 |
fee_amount | integer | Tarifa cobrada em subcentavos. 400 = R$ 0,04 |
end_to_end_id | string | Identificador E2E do BACEN (único por transação PIX) |
entity_id | string (UUID) | Identificador da entidade Minha Konta |
tx_id | string ou null | ID da transação. Presente quando vinculado a um QR code. null para transferências diretas |
qr_code_id | string ou null | UUID do QR code vinculado. null para transferências diretas |
counterparty_name | string ou null | Nome do pagador (remetente) |
payer_document | string ou null | CPF/CNPJ do pagador (somente dígitos) |
payer_ispb | string ou null | ISPB (8 dígitos) da instituição do pagador |
payer_bank_name | string ou null | Nome da instituição do pagador, resolvido via cache BCB (896 bancos) |
external_id | string ou null | Seu identificador externo. Presente quando o QR code foi criado via API com external_id. null para transferências diretas ou QR sem external_id |
paid_at | string (ISO 8601) | Data/hora da liquidação (UTC) |
recipient_key | string ou null | Chave PIX que recebeu o pagamento (EVP, CPF, CNPJ, email ou telefone) |
recipient_key_type | string ou null | Tipo da chave PIX recebedora: evp, phone, email, cpf, cnpj |
receiver | object | Dados completos do recebedor (você). Inclui name, document, account, ispb, institution_name |
Variação de payload: reconciliação operacional
Em cenários raros de reconciliação operacional ou replay retroativo após incidente, pix.charge.paid pode chegar com campos reduzidos - tipicamente sem receiver, payer_ispb, payer_bank_name, recipient_key nem recipient_key_type. Os campos que sempre estão presentes: event_type, status, account_id, amount, end_to_end_id, fee_amount, counterparty_name, payer_document, external_id, paid_at, tx_id (quando vinculado a QR).
Seu consumidor deve tratar todos os campos não-obrigatórios como opcionais (nil/ausente) e reconciliar pelo end_to_end_id.
qr_code_id é um UUID v4 canônico
O campo qr_code_id é sempre serializado como UUID v4 em formato canônico (36 caracteres com hífens: f401d5e3-a2b1-4c8e-9f3d-1234567890ab) - nunca como binário cru, base64 ou hex sem hífens. Use para correlação direta com a resposta de POST /api/external/pix/cash-in (campo transaction_id no seu request retorna o tx_id do QR, e qr_code_id aqui é a chave primária interna).
pix.charge.expired
Disparado automaticamente quando QR code expira sem pagamento. A verificação de expiração roda periodicamente e pode registrar o evento alguns minutos após o expires_at real.
{
"event_type": "pix.charge.expired",
"status": "expired",
"account_id": 10014,
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"tx_id": "abc123def456ghi789",
"amount": 500000,
"external_id": "order-9876",
"expired_at": "2026-04-02T14:30:00Z"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.charge.expired |
status | string | Sempre expired |
account_id | integer | Conta que emitiu o QR code |
entity_id | string (UUID) | Identificador da entidade Minha Konta |
tx_id | string | ID da cobrança/QR code |
amount | integer | Valor esperado em subcentavos (não cobrado) |
external_id | string ou null | Seu identificador externo, se enviado na criação |
expired_at | string (ISO 8601) | Momento em que a API registrou a expiração (UTC) - pode ser posterior ao expires_at real do QR em alguns minutos |
pix.charge.cancelled
Enviado quando um QR code é cancelado explicitamente pelo merchant antes de ser pago, via ação no portal. Não é disparado em expiração automática (use pix.charge.expired) nem em pagamento (pix.charge.paid).
{
"event_type": "pix.charge.cancelled",
"status": "cancelled",
"tx_id": "abc123def456ghi789",
"amount": 500000,
"account_id": 10014,
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"external_id": "order-9876",
"cancelled_at": "2026-04-23T12:30:00Z"
}| Campo | Tipo | Descrição |
|---|---|---|
tx_id | string | ID da cobrança/QR code |
amount | integer | Valor esperado em subcentavos (não cobrado) |
external_id | string ou null | Seu identificador externo, se enviado na criação |
cancelled_at | string (ISO 8601) | Momento em que o cancelamento foi efetivado (UTC) |
Distinção entre cancelled, expired e paid
pix.charge.cancelled: merchant cancelou intencionalmente antes do pagamentopix.charge.expired: tempo de vida do QR esgotoupix.charge.paid: cobrança liquidou com sucesso
pix.charge.created
Enviado quando um QR code é gerado ou um cash-in é iniciado. Nenhum movimento financeiro ocorreu.
{
"event_type": "pix.charge.created",
"status": "created",
"account_id": 10014,
"amount": 500000,
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"tx_id": "abc123def456ghi789",
"external_id": "order-9876"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.charge.created |
status | string | Sempre created |
amount | integer | Valor esperado em subcentavos |
tx_id | string | ID da cobrança/QR code |
external_id | string ou null | Seu identificador externo, retornado tal como enviado. null se não informado ou QR gerado pelo portal |
pix.payout.held
Enviado quando um PIX enviado fica retido para análise no agente de liquidação (fila de autorização/anti-fraude, status SPI AGUARDANDO_AUTORIZACAO). A operação NÃO falhou: ela liquida (pix.payout.confirmed) ou é rejeitada (pix.payout.failed) quando o agente decide — tipicamente em minutos. Não reenvie o pagamento: o valor segue reservado e um reenvio criaria um pagamento duplicado. O evento é emitido no máximo uma vez por operação, após ~2 minutos sem confirmação.
{
"event_type": "pix.payout.held",
"status": "processing",
"account_id": 10014,
"amount": 500000,
"end_to_end_id": "E0483840320260402101500000001",
"transaction_id": "PIXOUT1027803798e62a0f502761008061",
"external_id": "payment-456",
"reason": "held_at_settlement_agent",
"spi_status": "AGUARDANDO_AUTORIZACAO",
"held_since": "2026-06-10T16:45:36Z"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.payout.held |
status | string | Sempre processing — estado não-terminal |
reason | string | Sempre held_at_settlement_agent |
spi_status | string | Status SPI consultado no momento da emissão (ex.: AGUARDANDO_AUTORIZACAO) |
held_since | string (ISO 8601) | Momento do envio da PACS.008 (início da retenção) |
amount | integer | Valor em subcentavos |
external_id | string ou null | Seu identificador externo |
pix.payout.confirmed
Enviado quando um PIX enviado é confirmado pela instituição destino. Débito definitivo.
{
"event_type": "pix.payout.confirmed",
"status": "settled",
"account_id": 10014,
"amount": 500000,
"fee_amount": 200,
"end_to_end_id": "E0483840320260402101500000001",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"external_id": "payment-456",
"pix_key": "destinatario@email.com",
"pix_key_type": "EMAIL",
"description": "Pagamento fornecedor",
"initiated_at": "2026-04-02T10:14:59Z",
"recipient": {
"name": "EMPRESA DESTINO LTDA",
"document": "12345678000199",
"ispb": "60701190",
"account": "12345678",
"agency": "0001",
"institution_name": "Itau Unibanco S.A."
},
"sender": {
"name": "MINHA EMPRESA LTDA",
"document": "98765432000100",
"ispb": "04838403",
"account": "00001234",
"agency": "0001"
}
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.payout.confirmed |
status | string | Sempre settled - débito definitivo |
amount | integer | Valor enviado em subcentavos |
fee_amount | integer | Tarifa cobrada em subcentavos |
end_to_end_id | string | Identificador E2E do BACEN |
transaction_id | string (UUID) | Identificador único da transação |
external_id | string ou null | Seu identificador externo |
pix_key | string | Chave PIX do destinatário |
pix_key_type | string | Tipo da chave: CPF, CNPJ, EMAIL, PHONE, EVP |
description | string ou null | Descrição informada pelo remetente |
initiated_at | string (ISO 8601) | Momento em que este webhook foi disparado (UTC). Não é o timestamp do request original de cash-out nem do settlement BACEN. Para correlacionar com o momento que você enviou o POST, use o created_at do GET /api/external/transactions/ref/{external_id}; para o momento exato da entrega do webhook, use o header X-Minha Konta-Timestamp |
recipient | object | Dados bancários do destinatário (resolvidos via DICT) |
recipient.name | string ou null | Nome do titular da conta destino |
recipient.document | string ou null | CPF/CNPJ do destinatário (somente dígitos) |
recipient.ispb | string ou null | ISPB da instituição destino |
recipient.account | string ou null | Número da conta destino |
recipient.agency | string ou null | Agência da conta destino |
recipient.institution_name | string ou null | Nome da instituição destino (resolvido via cache BCB) |
sender | object | Dados bancários da conta remetente (sua conta Minha Konta) |
sender.name | string ou null | Nome do titular da conta remetente |
sender.document | string ou null | CPF/CNPJ do remetente (somente dígitos) |
sender.ispb | string ou null | ISPB da Minha Konta (04838403) |
sender.account | string ou null | Número da conta remetente |
sender.agency | string ou null | Agência da conta remetente |
pix.payout.processing
Enviado quando um PIX enviado está sendo processado. O saldo está reservado (hold) mas não é definitivo. Este evento é opcional - se você só quer ser notificado no estado terminal, ignore-o e espere pelo pix.payout.confirmed ou pix.payout.failed.
{
"event_type": "pix.payout.processing",
"status": "processing",
"account_id": 10014,
"amount": 500000,
"fee_amount": 200,
"end_to_end_id": "E0483840320260402101500000001",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"external_id": "payment-456",
"pix_key": "destinatario@email.com",
"pix_key_type": "EMAIL",
"description": "Pagamento fornecedor",
"initiated_at": "2026-04-02T10:14:59Z",
"recipient": {
"name": "EMPRESA DESTINO LTDA",
"document": "12345678000199",
"ispb": "60701190",
"account": "12345678",
"agency": "0001",
"institution_name": "Itau Unibanco S.A."
},
"sender": {
"name": "MINHA EMPRESA LTDA",
"document": "98765432000100",
"ispb": "04838403",
"account": "00001234",
"agency": "0001"
}
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.payout.processing |
status | string | Sempre processing - saldo reservado, pode reverter |
amount | integer | Valor em subcentavos |
fee_amount | integer | Tarifa em subcentavos (mesma tarifa que aparece em confirmed/failed posteriormente - é calculada na criação do cash-out, não após) |
end_to_end_id | string | Identificador E2E do BACEN |
transaction_id | string (UUID) | Identificador único da transação |
external_id | string ou null | Seu identificador externo |
pix_key | string | Chave PIX do destinatário |
pix_key_type | string | Tipo da chave: CPF, CNPJ, EMAIL, PHONE, EVP |
description | string ou null | Descrição informada pelo remetente |
initiated_at | string (ISO 8601) | Momento do dispatch deste webhook (UTC) - ver nota em pix.payout.confirmed |
recipient | object | Dados bancários do destinatário (resolvidos via DICT) |
recipient.name | string ou null | Nome do titular da conta destino |
recipient.document | string ou null | CPF/CNPJ do destinatário (somente dígitos) |
recipient.ispb | string ou null | ISPB da instituição destino |
recipient.account | string ou null | Número da conta destino |
recipient.agency | string ou null | Agência da conta destino |
recipient.institution_name | string ou null | Nome da instituição destino |
sender | object | Dados bancários da conta remetente (sua conta Minha Konta) |
sender.name | string ou null | Nome do titular da conta remetente |
sender.document | string ou null | CPF/CNPJ do remetente (somente dígitos) |
sender.ispb | string ou null | ISPB da Minha Konta (04838403) |
sender.account | string ou null | Número da conta remetente |
sender.agency | string ou null | Agência da conta remetente |
Ordem dos eventos
Um pix.payout.processing é sempre seguido (segundos a minutos depois) por um pix.payout.confirmed ou pix.payout.failed. Em transações rápidas (settlement imediato), o processing pode ser omitido e você recebe diretamente o terminal.
pix.payout.failed
Enviado quando um PIX enviado é rejeitado. Hold liberado, saldo restaurado.
Atualizado em 10/04/2026
O payload inclui os campos estruturados reason_code (código BACEN SPI de 2-6 caracteres) e reason_description (descrição em inglês). Novas integrações devem usar esses campos para roteamento programático de falhas.
Exclusão mútua: quando a API identifica um código BACEN na rejeição (ex: "rejected: AC03"), o payload envia apenas reason_code + reason_description - o campo legacy reason é removido. Quando a falha não tem código BACEN parseável (ex: timeout interno, erro de provider sem código), o payload envia apenas reason (string livre) - sem reason_code. Trate ambos os formatos no seu consumidor.
{
"event_type": "pix.payout.failed",
"status": "rejected",
"account_id": 10014,
"amount": 500000,
"fee_amount": 200,
"end_to_end_id": "E0483840320260402101500000001",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"external_id": "payment-456",
"pix_key": "destinatario@email.com",
"pix_key_type": "EMAIL",
"description": "Pagamento fornecedor",
"initiated_at": "2026-04-02T10:14:59Z",
"reason_code": "AC03",
"reason_description": "Invalid creditor account number",
"reason": "Conta destinatario nao encontrada",
"recipient": {
"name": "EMPRESA DESTINO LTDA",
"document": "12345678000199",
"ispb": "60701190",
"account": "12345678",
"agency": "0001",
"institution_name": "Itau Unibanco S.A."
},
"sender": {
"name": "MINHA EMPRESA LTDA",
"document": "98765432000100",
"ispb": "04838403",
"account": "00001234",
"agency": "0001"
}
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.payout.failed |
status | string | Sempre rejected - hold liberado, saldo restaurado |
amount | integer | Valor em subcentavos |
fee_amount | integer | Tarifa em subcentavos. A tarifa mostrada é o valor que teria sido cobrado - no ledger TB a transferência pending é revertida automaticamente, então na prática não há débito de tarifa em transações rejeitadas |
end_to_end_id | string | Identificador E2E do BACEN |
transaction_id | string (UUID) | Identificador único da transação |
external_id | string ou null | Seu identificador externo |
pix_key | string | Chave PIX do destinatário |
pix_key_type | string | Tipo da chave: CPF, CNPJ, EMAIL, PHONE, EVP |
description | string ou null | Descrição informada pelo remetente |
initiated_at | string (ISO 8601) | Momento do dispatch deste webhook (UTC) |
reason_code | string ou ausente | Código BACEN SPI estruturado (2-6 caracteres). Exemplos: AC03, ED05, AM02, BE01, MD06, FOCR. Presente quando a API identificou código BACEN na rejeição. Use este campo para roteamento programático |
reason_description | string ou ausente | Descrição em inglês do reason_code. Presente junto com reason_code. Exemplo: "Invalid creditor account number" |
reason | string ou ausente | [Legacy] Descrição livre do motivo. Presente apenas quando a rejeição não tem código BACEN parseável - mutuamente exclusivo com reason_code |
recipient | object | Dados bancários do destinatário (resolvidos via DICT) |
recipient.name | string ou null | Nome do titular da conta destino |
recipient.document | string ou null | CPF/CNPJ do destinatário (somente dígitos) |
recipient.ispb | string ou null | ISPB da instituição destino |
recipient.account | string ou null | Número da conta destino |
recipient.agency | string ou null | Agência da conta destino |
recipient.institution_name | string ou null | Nome da instituição destino |
sender | object | Dados bancários da conta remetente (sua conta Minha Konta) |
sender.name | string ou null | Nome do titular da conta remetente |
sender.document | string ou null | CPF/CNPJ do remetente (somente dígitos) |
sender.ispb | string ou null | ISPB da Minha Konta (04838403) |
sender.account | string ou null | Número da conta remetente |
sender.agency | string ou null | Agência da conta remetente |
Variações de payload
pix.payout.failed pode ser emitido por mais de um fluxo operacional. Em alguns cenários, o payload pode enviar tanto reason quanto reason_code, ou apenas reason sem estrutura. Trate sempre os dois campos como opcionais e prefira reason_code quando presente.
Códigos reason_code mais comuns (BACEN SPI)
| Código | Significado em inglês | Ação recomendada |
|---|---|---|
AC03 | Invalid creditor account number | Confirmar dados bancários do destinatário com o cliente final |
AC06 | Creditor account blocked | Conta destino bloqueada - não retentar |
AM02 | Not allowed amount (limit exceeded) | Valor excede limite de PIX do destino ou origem |
AM04 | Insufficient funds | Saldo insuficiente na origem |
BE01 | End customer not in whitelist | Identificador do destinatário não reconhecido |
ED05 | Settlement failed | Falha no settlement - pode retentar após investigação |
MD06 | Refund requested by end customer | Devolução solicitada pelo cliente final |
FOCR | Forbidden credit return | Devolução de crédito proibida |
Lista completa: consulte o Catálogo de Mensagens do SPI do BACEN.
pix.payout.returned
Enviado quando um PIX que você enviou é devolvido pelo banco destino após liquidação. Raro, mas pode ocorrer até vários dias depois. O saldo do merchant aumenta (entrada).
Distinção de nomenclatura
Três fluxos diferentes podem ser confundidos:
pix.return.received: um PIX que você recebeu está sendo devolvido ao pagador original. Saldo DIMINUI.pix.payout.returned(este): um PIX que você enviou está voltando a você. Saldo AUMENTA.pix.refund.requested: bloqueio cautelar MED em um PIX que você recebeu. Fundos congelados.
Mesmo payload, dois eventos, dois status diferentes
A API pode disparar pix.return.received e pix.payout.returned para a mesma devolução usando o mesmo payload base com o campo status ajustado para cada evento:
pix.return.received→status: "settled"(PIX que você recebeu está sendo devolvido → saldo diminui)pix.payout.returned→status: "returned"(PIX que você enviou está voltando → saldo aumenta)
Se sua lógica de reconciliação filtra por status ou dedup por (e2e, event_type), certifique-se de distinguir event_type primeiro - o payload é quase idêntico.
{
"event_type": "pix.payout.returned",
"status": "returned",
"account_id": 10014,
"amount": 500000,
"original_amount": 500000,
"refunded_amount": 500000,
"fee_amount": 0,
"net_amount": 500000,
"is_partial": false,
"total_refunded": 500000,
"remaining_refundable": 0,
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"return_e2e_id": "D0483840320260410111500000001",
"end_to_end_id": "E0483840320260402101500000001",
"original_transaction_id": "PIXOUTa1b2c3d4e5f67890abcdef1234567890",
"external_id": "payment-456",
"return_reason": "MD06",
"return_reason_description": "Refund requested by end customer",
"counterparty_ispb": "60701190",
"counterparty_name": "EMPRESA DESTINO LTDA",
"counterparty_document": "12345678000199",
"counterparty_institution_name": "Itau Unibanco S.A.",
"returned_at": "2026-04-10T11:15:00Z"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.payout.returned |
status | string | Sempre returned - devolução liquidada e creditada em sua conta |
amount | integer | Mesmo valor que refunded_amount (mantido para compatibilidade) |
original_amount | integer | Valor do PIX OUT original em subcentavos |
refunded_amount | integer | Valor efetivamente devolvido nesta devolução (pode ser parcial) |
fee_amount | integer | Tarifa cobrada nesta devolução (geralmente 0) |
net_amount | integer | refunded_amount - fee_amount |
is_partial | boolean | true quando refunded_amount < original_amount ou ainda restar saldo a devolver |
total_refunded | integer | Soma de todas as devoluções já recebidas para esta transação original (inclui esta) |
remaining_refundable | integer | max(original_amount - total_refunded, 0) - saldo ainda passível de devolução |
return_e2e_id | string | E2E da devolução (prefixo D) |
end_to_end_id | string | E2E da transação PIX OUT original (prefixo E) |
original_transaction_id | string | transaction_id do PIX OUT original. Use para correlação com seu sistema |
external_id | string ou null | Seu identificador externo da transação original (se aplicável) |
return_reason | string | Código BACEN da devolução: MD06, BE08, FR01, SL02 |
return_reason_description | string | Descrição em inglês do return_reason |
counterparty_ispb | string | ISPB da instituição que iniciou a devolução |
counterparty_name | string | Nome da contraparte (instituição destino do PIX original) |
counterparty_document | string ou null | CPF/CNPJ da contraparte |
counterparty_institution_name | string ou null | Nome da instituição contraparte (cache BCB) |
returned_at | string (ISO 8601) | Momento do dispatch deste webhook (UTC) |
Tarifa não é reembolsada
A tarifa do cash-out original não é reembolsada em pix.payout.returned. A tarifa foi cobrada pelo envio bem-sucedido, que realmente aconteceu. Se a regra de negócio exigir reembolso da tarifa ao cliente final, o merchant deve fazer isso separadamente.
pix.refund.requested
Enviado quando uma devolução PIX é solicitada via MED (Mecanismo Especial de Devolução). Fundos foram bloqueados cautelarmente na conta do merchant que recebeu o PIX original.
Somente PIX In
Este evento só se aplica a PIX recebidos (cash-in). Se você enviou um PIX e ele foi devolvido, receberá pix.return.received em vez de pix.refund.*.
{
"event_type": "pix.refund.requested",
"status": "requested",
"account_id": 10014,
"requested_amount": 300000,
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"block_id": "b1c2d3e4-f5g6-7890-hijk-lm1234567890",
"infraction_report_id": "INF20260402001",
"e2e_id": "E9040088820260402095758709999671",
"external_id": null,
"blocked_amount": 300000,
"fee_amount": 0,
"fraud_category": "OTHER",
"deadline": "2026-04-09T14:30:00Z",
"scenario": "cautelar",
"created_at": "2026-04-02T14:30:00Z"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.refund.requested |
status | string | Sempre requested - bloqueio cautelar ativo |
requested_amount | integer | Valor solicitado para devolução em subcentavos |
block_id | string (UUID) | Identificador do bloqueio cautelar |
infraction_report_id | string | Identificador da infração no provedor PIX |
e2e_id | string | E2E da transação PIX original que está sendo contestada |
external_id | string ou null | Seu identificador externo (se aplicável) |
blocked_amount | integer | Valor efetivamente bloqueado em subcentavos |
fee_amount | integer | Tarifa MED em subcentavos |
fraud_category | string | Categoria da fraude alegada. Valores possíveis: SCAM, ACCOUNT_TAKEOVER, COERCION, FRAUDULENT_ACCESS, OTHER. Quando a contraparte não envia um FraudType específico, o valor é OTHER (padrão para REFUND_REQUEST). |
deadline | string (ISO 8601) | Prazo para análise/defesa (UTC) |
scenario | string | Cenário MED: cautelar ou fraude |
created_at | string (ISO 8601) | Data/hora do bloqueio (UTC) |
pix.refund.completed
Disparado quando uma devolução MED é efetivada com sucesso. Dispara via med/processor.ex:915 durante o ciclo de MED aceito.
Formato do payload (confirmado pela code path med/processor.ex:900-920):
{
"event_type": "pix.refund.completed",
"status": "settled",
"account_id": 10014,
"amount": 300000,
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"block_id": "b1c2d3e4-f5g6-7890-hijk-lm1234567890",
"infraction_report_id": "INF20260402001",
"e2e_id": "E9040088820260402095758709999671",
"external_id": null,
"reason": "analysis_unfounded",
"completed_at": "2026-04-02T14:30:00Z"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.refund.completed |
status | string | Sempre completed - devolução MED finalizada |
amount | integer | Valor devolvido em subcentavos |
block_id | string (UUID) | Identificador do bloqueio cautelar |
infraction_report_id | string | Identificador da infração no provedor PIX |
e2e_id | string | E2E da transação PIX original |
external_id | string ou null | Seu identificador externo (se aplicável) |
reason | string | Motivo da liberação (ex: analysis_unfounded, manual_release) |
completed_at | string (ISO 8601) | Data/hora da conclusão (UTC) |
pix.return.received
Enviado quando uma devolução PIX é recebida. Este evento é gerado quando um PIX que você recebeu anteriormente (cash-in) está sendo devolvido ao pagador original. O saldo do merchant diminui.
Distinção de nomenclatura
pix.return.received(este): um PIX que você recebeu está sendo devolvido ao pagador original. Saldo DIMINUI.pix.payout.returned: um PIX que você enviou está voltando a você. Saldo AUMENTA.
Os nomes são inversos ao que o significado comum sugere - preste atenção.
{
"event_type": "pix.return.received",
"status": "settled",
"account_id": 10014,
"amount": 300000,
"original_amount": 300000,
"refunded_amount": 300000,
"fee_amount": 0,
"net_amount": 300000,
"is_partial": false,
"total_refunded": 300000,
"remaining_refundable": 0,
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"return_e2e_id": "D9040088820260402111500000001",
"end_to_end_id": "E9040088820260402095758709999671",
"original_transaction_id": "PIXINE9040088820260402095758709999671",
"external_id": null,
"return_reason": "MD06",
"return_reason_description": "Refund requested by end customer",
"counterparty_ispb": "60701190",
"counterparty_name": "EMPRESA X LTDA",
"counterparty_document": "98765432100",
"counterparty_institution_name": "Itau Unibanco S.A.",
"returned_at": "2026-04-02T11:15:00Z"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.return.received |
status | string | Sempre settled - devolução liquidada |
amount | integer | Mesmo valor que refunded_amount (mantido para compatibilidade) |
original_amount | integer | Valor do PIX IN original em subcentavos |
refunded_amount | integer | Valor efetivamente devolvido nesta devolução (pode ser parcial) |
fee_amount | integer | Tarifa cobrada nesta devolução |
net_amount | integer | refunded_amount - fee_amount |
is_partial | boolean | true quando a devolução não cobre o valor total do PIX IN original |
total_refunded | integer | Soma de todas as devoluções já enviadas para esta transação (inclui esta) |
remaining_refundable | integer | Saldo ainda passível de devolução |
return_e2e_id | string | E2E da devolução (prefixo D) |
end_to_end_id | string | E2E da transação PIX IN original (prefixo E) |
original_transaction_id | string | transaction_id do PIX IN original. Use para correlação com seu sistema |
external_id | string ou null | Seu identificador externo da transação original (se aplicável) |
return_reason | string | Código BACEN da devolução: MD06, BE08, FR01, SL02 |
return_reason_description | string | Descrição em inglês do return_reason |
counterparty_ispb | string | ISPB da instituição que está recebendo a devolução |
counterparty_name | string | Nome da contraparte (pagador original do PIX IN) |
counterparty_document | string ou null | CPF/CNPJ da contraparte |
counterparty_institution_name | string ou null | Nome da instituição contraparte (cache BCB) |
returned_at | string (ISO 8601) | Momento do dispatch deste webhook (UTC) |
Deduplicação
Para deduplicar retries de webhook, use o header X-Minha Konta-Event-Id OU a combinação (return_e2e_id, end_to_end_id). O return_e2e_id começa com D (devolução) e o end_to_end_id começa com E (original).
webhook.test
Evento de teste disparado manualmente para validar a configuração do webhook.
{
"event_type": "webhook.test",
"status": "test",
"account_id": 10014,
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"message": "Webhook test event"
}pix.infraction.created
Disparado quando uma infração PIX é reportada pela contraparte (via BACEN DICT). Use o defense_deadline para acompanhar o prazo de resposta.
{
"event_type": "pix.infraction.created",
"infraction_id": "e7f4d23a-6f2a-4d1e-a3e6-fe8b32bba95d",
"e2e_id": "E0416201020260404113012abcdef1234",
"status": "ACKNOWLEDGED",
"infraction_type": "REFUND_REQUEST",
"amount": 1500000,
"analysis_result": null,
"analysis_details": null,
"defense_deadline": "2026-04-21T23:59:59Z",
"counterpart_ispb": "60701190",
"account_id": 10011,
"merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.infraction.created |
infraction_id | string (UUID) | ID interno da infração |
e2e_id | string | E2E da transação contestada |
status | string | Status BACEN: ACKNOWLEDGED, CLOSED, CANCELLED |
infraction_type | string | Tipo BACEN: REFUND_REQUEST, REFUND_CANCELLED, FRAUD |
amount | integer | Valor em subcentavos |
defense_deadline | string (ISO 8601) | Prazo para submissão de defesa |
counterpart_ispb | string (8 dígitos) | ISPB da instituição contraparte |
account_id | integer | Sua conta afetada |
merchant_id | string (UUID) | Seu merchant_id |
Ação necessária
Infrações com status ACKNOWLEDGED podem exigir análise MED. Responda pelo portal ou pela API externa (POST /api/external/med/:id/defense) antes do defense_deadline quando houver defesa e evidências.
pix.infraction.resolved
Disparado quando uma infração é resolvida. Informa o resultado final e libera o fluxo financeiro aplicável.
{
"event_type": "pix.infraction.resolved",
"infraction_id": "e7f4d23a-6f2a-4d1e-a3e6-fe8b32bba95d",
"e2e_id": "E0416201020260404113012abcdef1234",
"status": "CLOSED",
"infraction_type": "REFUND_REQUEST",
"amount": 1500000,
"analysis_result": "DISAGREED",
"analysis_details": "Verificado pelo time de compliance e sem evidencias concretas nao temos como fazer devolucao",
"defense_deadline": "2026-04-21T23:59:59Z",
"counterpart_ispb": "60701190",
"account_id": 10011,
"merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7"
}| Campo | Tipo | Descrição |
|---|---|---|
analysis_result | string | AGREED (devolve), DISAGREED (nega) |
analysis_details | string | Justificativa da decisão |
| Demais campos | Idênticos a pix.infraction.created |
pix.infraction.defense_submitted
Disparado quando uma defesa é registrada contra infração/MED via portais Minha Konta ou API externa.
{
"event_type": "pix.infraction.defense_submitted",
"infraction_id": "e7f4d23a-6f2a-4d1e-a3e6-fe8b32bba95d",
"block_id": "3f1e2c41-c269-4fa8-a151-49e739f8d37d",
"e2e_id": "E0416201020260404113012abcdef1234",
"end_to_end_id": "E0416201020260404113012abcdef1234",
"status": "defense_submitted",
"account_id": 10011,
"merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.infraction.defense_submitted |
status | string | Sempre defense_submitted |
infraction_id | string (UUID) | ID da infração sendo defendida |
block_id | string (UUID) | ID do bloqueio MED cautelar, quando aplicável |
e2e_id / end_to_end_id | string | E2E da transação contestada |
Evidências armazenadas
Os anexos da defesa ficam armazenados na Minha Konta para análise e auditoria. O fechamento enviado ao provider usa AnalysisResult e AnalysisDetails; o resultado final chega via pix.infraction.resolved.
pix.payout.queued
Disparado quando PIX OUT é automaticamente colocado em fila de nova tentativa. Motivos comuns: limite operacional por merchant ou indisponibilidade temporária de capacidade DICT BACEN.
{
"event_type": "pix.payout.queued",
"status": "queued",
"account_id": 10011,
"merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
"transaction_id": "PIXOUT0200806193e0984f830569",
"end_to_end_id": "E0483840320260421133012abcdef1234",
"amount": 200,
"external_id": "payment-456",
"reason": "dict_client_rate_limited",
"reason_code": "DICT_CLIENT_RATE_LIMITED",
"reason_description": "Merchant exceeded per-minute DICT lookup quota",
"queued_at": "2026-04-21T13:30:12Z",
"estimated_retry_seconds": 3,
"queue_ttl_seconds": 7200
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre pix.payout.queued |
status | string | Sempre queued |
account_id | integer | Conta que originou o PIX OUT |
merchant_id | string (UUID) | Seu merchant_id |
transaction_id | string | Identificador da transação Minha Konta |
end_to_end_id | string | E2E BACEN gerado para o PIX OUT |
amount | integer | Valor em subcentavos |
external_id | string ou null | Seu identificador externo (se enviado no request original) |
reason | string | Motivo do enfileiramento (snake_case). Valores conhecidos: dict_client_rate_limited (limite por merchant), dict_bucket_exhausted (bucket DICT BACEN compartilhado esgotado), dict_rate_limited (fallback genérico) |
reason_code | string | Código interno em UPPERCASE correlato ao reason. Valores: DICT_CLIENT_RATE_LIMITED, DICT_BUCKET_EXHAUSTED, DICT_RATE_LIMITED. Não é um código BACEN SPI (como AC03, AM02) - o enfileiramento acontece antes do envio ao BACEN, por isso os códigos são internos da Minha Konta |
reason_description | string | Descrição em inglês do motivo |
queued_at | string (ISO 8601) | Momento em que entrou na fila (UTC) |
estimated_retry_seconds | integer | Intervalo estimado de nova tentativa; a fila não garante esse tempo e pode demorar se a capacidade externa demorar para liberar |
queue_ttl_seconds | integer | TTL máximo na fila em segundos (7200 = 2 h). Após expirar, request vai para failed com motivo queue_ttl_expired |
reason_code aqui não é BACEN SPI
Note que em pix.payout.queued o reason_code é um código interno Minha Konta em UPPERCASE (DICT_CLIENT_RATE_LIMITED, etc.). Em pix.payout.failed o reason_code é código BACEN SPI (ex: AC03, AM02, ED05). Os dois campos têm o mesmo nome mas vocabulários diferentes - trate cada evento separadamente no seu consumidor.
Retry automático
Requests enfileiradas são retentadas automaticamente enquanto houver TTL. Em condições normais o processamento volta assim que o limite por merchant ou o bucket DICT BACEN liberar capacidade, mas isso não é SLA de 3-10 min. Próximo evento: pix.payout.processing (quando sair da fila e for enviado ao BACEN). Caso o TTL de 2 h expire sem sucesso, você recebe pix.payout.failed com reason="queue_ttl_expired".
tef.transfer.sent
Disparado quando uma TEF entre contas Minha Konta é liquidada para a conta de origem.
Disparado quando a TED/TEF de saída é efetivamente registrada para processamento.
{
"event_type": "tef.transfer.sent",
"transaction_id": "TEF202605300001",
"account_id": 10011,
"sender_account_id": 10011,
"receiver_account_id": 10012,
"merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"amount": 20000,
"description": "Repasse interno",
"settled_at": "2026-05-30T13:30:12Z"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre tef.transfer.sent |
account_id | integer | Conta de origem assinante do webhook |
sender_account_id | integer | Conta que enviou a TEF |
receiver_account_id | integer | Conta que recebeu a TEF |
transaction_id | string | Identificador da transação Minha Konta |
amount | integer | Valor em subcentavos |
settled_at | string (ISO 8601) | Momento de liquidação em UTC |
tef.transfer.received
Disparado quando uma TEF entre contas Minha Konta é liquidada para a conta de destino.
{
"event_type": "tef.transfer.received",
"transaction_id": "TEF202605300001_RCV",
"account_id": 10012,
"sender_account_id": 10011,
"receiver_account_id": 10012,
"merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"amount": 20000,
"description": "Repasse interno",
"settled_at": "2026-05-30T13:30:12Z"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre tef.transfer.received |
account_id | integer | Conta de destino assinante do webhook |
transaction_id | string | Identificador da transação Minha Konta com sufixo _RCV |
| Demais campos | Iguais a tef.transfer.sent |
tef.transfer.failed
Disparado quando uma TEF entre contas Minha Konta é rejeitada ou não liquidada.
{
"event_type": "tef.transfer.failed",
"transaction_id": "TEF202605300001",
"account_id": 10011,
"receiver_account_id": 10012,
"merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
"entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
"amount": 20000,
"failure_reason": "insufficient_funds",
"failed_at": "2026-05-30T13:30:12Z"
}| Campo | Tipo | Descrição |
|---|---|---|
event_type | string | Sempre tef.transfer.failed |
account_id | integer | Conta de origem da tentativa |
failure_reason | string | Motivo técnico registrado pela API |
failed_at | string (ISO 8601) | Momento da falha em UTC |
Como interpretar os webhooks
Para confirmar que dinheiro entrou na conta: Aguarde pix.charge.paid com status: "paid". Este é o único evento que garante que o valor foi creditado e a taxa cobrada.
Para confirmar que dinheiro saiu da conta: Aguarde pix.payout.confirmed com status: "settled". O status processing é intermediário - o saldo está reservado mas pode ser revertido se rejeitado.
Para devoluções: pix.return.received com status: "settled" confirma devolução liquidada e creditada na conta.
Para TEF entre contas Minha Konta: tef.transfer.sent confirma a saída liquidada na origem e tef.transfer.received confirma a entrada liquidada no destino.
Deduplicação: Use o header X-Minha Konta-Event-Id ou o campo end_to_end_id como chave de idempotência.
