Webhooks
Receba as mudanças de estado das transações no seu backend, com retentativa automática.
A MonkeyPay faz um POST na URL que você configurar sempre que uma transação muda para um estado com URL cadastrada.
1. Configure as URLs
PUT /webhook/resource/events cria ou atualiza a configuração de uma carteira. A configuração nova deve informar walletId; configurações antigas gravadas somente para a empresa continuam sendo usadas como fallback até que a carteira tenha uma configuração própria. Cada estado tem a própria URL; pode ser a mesma para todos.
Para configurar uma carteira, informe também walletId:
organizationIdé o mesmo valor deorganizationIdnas suas carteiras.- Campos omitidos mantêm o valor atual;
nulldesliga o envio daquele estado. - Estados disponíveis:
created,pending,processing,awaitingPayment,completed,failed,cancelled,expired,refunded,infraction. - Não existe URL para
partially_refunded: esse estado não gera webhook. Concilie-o pela consulta de transações.
Confira a configuração com GET /webhook/resource/organization-events?organizationId=<sua-organizacao>&walletId=<sua-carteira>. Se a carteira ainda não tiver configuração própria, a resposta poderá representar a configuração legada da empresa usada como fallback. Essa consulta exige monkeypay:webhooks:read, uma permissão separada de monkeypay:pix:write. Um 403 com type terminado em /auth-permission-denied indica falta dessa permissão; com /auth-organization-inactive, indica organização inativa. Confira o type antes de solicitar acesso. Um 404 pode indicar ausência de configuração ou organização fora do escopo da credencial.
2. O que chega no seu endpoint
Eventos de infração (MED) vão para a URL infraction e trazem também o objeto infraction (id, type, status, amount, reason, reportedBy, analysisResult, analysisDetails, createdAt, updatedAt). O corpo não informa o nome do evento: identifique a infração pela presença desse objeto. Veja o guia Infrações e MED.
3. Responda rápido e com 2xx
Qualquer resposta 2xx conta como entregue. Resposta diferente de 2xx ou falha de rede agenda nova tentativa, com espera de retryDelay × 2^tentativa (máximo de 15 minutos), até maxRetries (padrão 3). Sem retryDelay, a espera começa em 1 segundo.
Trate a retentativa como ajuda, não como garantia de entrega. Se o seu endpoint ficou fora do ar, confira as tentativas em Histórico de entregas e concilie as transações pela consulta por
externalId.
GET /webhook/resource/send-events?organizationId=<sua-organizacao> lista cada envio com a URL de destino, o status (completed, failed ou queued), o HTTP que o seu endpoint respondeu e o total de tentativas. Filtre por externalId ou transactionId para investigar um evento específico.
Grave o evento, responda 200 e processe depois. O mesmo evento pode chegar mais de uma vez: seu processamento precisa aceitar uma repetição sem repetir seus efeitos, como liberar o mesmo pedido duas vezes.
Para eventos de transação, compare também a versão recebida (updatedAt) e os dados já processados. Apenas transactionId + status não identificam toda atualização.
Para MED, acompanhe infraction.id, infraction.updatedAt e infraction.status. Uma infração pode mudar enquanto o status da transação continua igual; descartar o evento só por esse estado perderia a atualização. Se a versão ou a ordem dos eventos for ambígua, consulte a infração pela API antes de atualizar o seu registro. Veja Infrações e MED.
Checklist do seu endpoint: responde
2xxem poucos segundos; grava o evento antes de processar; evita repetir efeitos sem descartar novas versões da transação ou da infração; valida a assinatura quando houversecret; confirma o estado pela API antes de liberar valor.
4. Valide a assinatura
Quando a organização tem secret, cada envio leva:
x-webhook-timestamp: segundos desde 1970;x-webhook-signature: HMAC-SHA256 em hexadecimal de<timestamp>.<corpo bruto>, com osecretcomo chave.
Calcule sobre o corpo bruto, exatamente como recebido, antes de qualquer JSON.parse.
O
secret(formatowhsec_…) volta uma única vez, emdata.secret, na resposta dePUT /webhook/resource/eventsque o gerou: a primeira configuração ou umregenerateSecret: true. Nas demais respostasdataénull, eGET /organization-eventsinforma apenashasSecret. Guarde o valor no seu cofre ao recebê-lo; se perder, gere outro comregenerateSecret: truee atualize a validação. Mesmo com a assinatura válida, confirme o estado comGET /resource/transactions/external-id/{externalId}antes de liberar qualquer valor.
5. Teste antes de operar
POST /webhook/resource/test-send envia para a URL do estado informado um evento igual ao real, assinado quando houver secret. Nenhuma transação é criada.
O teste de uma carteira recebe o mesmo walletId usado na configuração.
A API responde 200 quando processa o pedido de teste. Se não houver URL para o estado enviado, nada é entregue — confira no seu endpoint se o evento chegou.