Webhooks
A SimPix envia um POST para os endpoints registrados sempre que uma transação, um saque ou uma disputa muda de estado. Para registrar, listar e remover endpoints, veja a Webhooks API.
Eventos
Seção intitulada “Eventos”| Evento | Quando é disparado |
|---|---|
transaction |
Mudanças de status em transações Pix (ex.: CONFIRMED, FAILED, EXPIRED) |
withdraw |
Mudanças de status em saques (ex.: PROCESSING, CONFIRMED, FAILED) |
dispute |
Aberturas e atualizações de disputas (MED) |
Headers do webhook
Seção intitulada “Headers do webhook”Toda entrega inclui os headers:
| Header | Descrição |
|---|---|
x-webhook-signature |
Assinatura HMAC SHA256 do payload |
x-webhook-event |
Tipo do evento (TRANSACTION, WITHDRAW) |
x-user-reference |
Identificador de referência do usuário |
Payloads de exemplo
Seção intitulada “Payloads de exemplo”Webhook de transação
Seção intitulada “Webhook de transação”{ "data": { "magic_id": "T_123JKL114HJHDKSAH1JK23", "amount": 1.0, "currency": "BRL", "status": "CONFIRMED", "decline_reason": null, "description": "optional", "payment_method": "Pix", "qr_code": "00020101021126700014br.gov.bcb.pix...", "end_to_end": "E607894312025071873189DAHJSKH12", "external_ref": "external_ref_order", "requester": { "name": "John Doe", "email": "john.doe@example.com", "phone": "11999999999", "document": "12468239008" }, "movement": { "payer": { "name": "Payer Name", "document": "12345678901", "bank": "BANCO INTER S.A.", "agency": "0001", "account": "123456-7" }, "payee": { "name": "Payee Name", "document": "12345678000190", "bank": "BANCO INTER S.A.", "agency": "0001", "account": "765432-1" } }, "created_at": "2025-12-14T01:03:06.467Z", "updated_at": "2025-12-14T01:03:06.467Z" }, "event": "TRANSACTION"}Webhook de saque
Seção intitulada “Webhook de saque”{ "data": { "magic_id": "wth_03UdoKvLNLHg", "amount": 1.0, "currency": "BRL", "status": "CONFIRMED", "fee": 0.15, "decline_reason": null, "description": "Withdrawal", "transfer_method": "Pix", "end_to_end": "E607894312025071873189DAHJSKH12", "external_ref": "withdrawal_12345", "movement": { "payer": { "name": "Payer Name", "document": "12345678901", "bank": "BANCO INTER S.A.", "agency": "0001", "account": "123456-7" }, "payee": { "name": "Payee Name", "document": "12345678000190", "bank": "BANCO INTER S.A.", "agency": "0001", "account": "765432-1" } }, "created_at": "2025-12-16T20:44:25.618Z", "updated_at": "2025-12-16T20:44:25.618Z" }, "event": "WITHDRAW"}Verificação de assinatura HMAC
Seção intitulada “Verificação de assinatura HMAC”Calcule o HMAC SHA256 do payload usando o secret do webhook (whsec_..., retornado ao registrar o webhook) e compare com o header x-webhook-signature:
const crypto = require('crypto');
const signature = req.headers['x-webhook-signature'];const payload = JSON.stringify(req.body);const hash = crypto.createHmac('sha256', webhookSecret).update(payload).digest('hex');
if (hash === signature) { // Request is verified} else { // Request could not be verified}import hmacimport hashlibimport json
signature = request.headers.get('x-webhook-signature')payload = json.dumps(request.get_json())hash = hmac.new( bytes(webhook_secret, 'ascii'), bytes(payload, 'ascii'), hashlib.sha256).hexdigest()
if hash == signature: # Request is verifiedelse: # Request could not be verified$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];$payload = file_get_contents('php://input');$hash = hash_hmac('sha256', $payload, $webhookSecret);
if (hash_equals($hash, $signature)) { // Request is verified} else { // Request could not be verified}Idempotência
Seção intitulada “Idempotência”A mesma notificação pode ser entregue mais de uma vez (retries de rede, reenvio manual). Mantenha seus handlers idempotentes:
- Use o
magic_id(ou o parmagic_id+status) como chave de deduplicação. - Se o evento já foi processado, responda
2xxe não repita os efeitos colaterais. - Use
magic_idouexternal_refpara conciliação com o seu sistema.
Reenvio de webhooks (resend=true)
Seção intitulada “Reenvio de webhooks (resend=true)”Perdeu uma notificação? Reenvie o webhook de uma transação ou saque usando o query param resend=true nos endpoints de consulta:
curl --request GET \ --url 'https://api.simpixpagamentos.com/api/transactions?magic_id=03UdoKvLNLHg&resend=true' \ --header 'x-api-key: <API_KEY>' \ --header 'x-token: <TOKEN>' \ --header 'x-timezone: America/Sao_Paulo'curl --request GET \ --url 'https://api.simpixpagamentos.com/api/withdrawals?magic_id=9Wlp_2kGy4t9&resend=true' \ --header 'Content-Type: application/json' \ --header 'x-api-key: <API_KEY>' \ --header 'x-token: <TOKEN>' \ --header 'x-timezone: America/Sao_Paulo'