Como funciona
- 1Cadastre o webhook
No painel de webhooks ou por
POST /webhooks, com a URL HTTPS do seu servidor e os eventos que quer receber. - 2Guarde o segredo de assinatura
Ele vem na resposta da criação, no formato
whsec_…, e pode ser consultado de novo comGET /webhooks/{id}?include_signing_secret=true. Não há como gerar outro: se vazar, exclua o webhook e crie um novo. Não confunda com a chave de API. - 3Receba o POST
Cada evento chega com os cabeçalhos
svix-id,svix-timestampesvix-signaturee o evento em JSON no corpo. - 4Valide, grave e responda 2xx
Confira a assinatura, grave o evento e só então responda. Qualquer resposta fora de 2xx gera novas tentativas.
Eventos
| Evento | Quando é enviado |
|---|---|
order.created | Ordem criada, com valores definitivos e link de pagamento. |
order.updated | A ordem mudou: estado, valor reembolsado ou valor retido. |
refund.created | Reembolso registrado. |
refund.updated | O reembolso mudou de estado. |
webhook.test | Evento de teste, enviado só para o webhook que você testou. |
data traz a ordem ou o reembolso completo, no mesmo formato das consultas. version aumenta a cada mudança.
{
"id": "evt_example",
"type": "order.created",
"api_version": "v1",
"occurred_at": "2026-09-10T13:05:00.000Z",
"data": {
"id": "ord_example",
"version": "1",
"status": "pending_payment",
"source_currency": "BRL",
"source_amount_atomic": "10000",
"target_currency": "CNY",
"target_amount_atomic": "12500000000",
"refunded_source_amount_atomic": "0",
"blocked_source_amount_atomic": "0",
"payment": {
"url": "https://bytemax.exchange/pay/example",
"pix_copy_paste": null
},
"created_at": "2026-09-10T13:05:00.000Z"
}
}Receber e verificar
Valide com o segredo e o corpo bruto da requisição, antes de interpretar o JSON. Use a biblioteca oficial do Svix na sua linguagem: ela confere a assinatura e a tolerância de tempo do svix-timestamp. Não implemente a verificação à mão.
Como verificar assinaturas com a biblioteca oficial (docs.svix.com)
POST /webhooks/bytemax HTTP/1.1
Content-Type: application/json
svix-id: msg_2gkQ7Wc9cD6yYq1xkKz7GJb3wQm
svix-timestamp: 1757509500
svix-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhUjM8G3xRk2w1vNq4T0=
{ "id": "evt_example", "type": "order.updated", ... }Processar sem duplicar
Eventos podem chegar mais de uma vez e fora de ordem. Cinco regras evitam efeitos duplicados:
- Use o
iddo evento como chave única: grave antes de responder e ignore repetidos. - Compare
versionda ordem ou do reembolso: um evento com versão menor que a já gravada não substitui o estado mais novo. - Grave o efeito do evento e a marca de processado na mesma transação.
- Responda 2xx só depois de gravar. Se a gravação falhar, responda 5xx para receber de novo.
- Trabalho demorado fica fora da resposta: enfileire e responda rápido.
Testar e reenviar
POST /webhooks/{id}/test-events, sem corpo, envia um webhook.test para esse webhook. Acompanhe a publicação em GET /events/{id} e confira no seu servidor se o evento chegou e a assinatura foi aceita. O teste comprova a entrega e a assinatura; para testar o tratamento de ordens e reembolsos, acompanhe uma ordem real.
Entregas que falham recebem novas tentativas automáticas. O histórico de cada tentativa fica no painel e em GET /webhooks/{id}/deliveries. Para reenviar eventos específicos, use POST /webhooks/{id}/redeliveries com até 20 ids: a resposta diz, evento por evento, se o reenvio foi aceito.
Limites
- Até 200 webhooks por conta, um por URL.
- Eventos ficam consultáveis por 30 dias.
- Listas usam
itemsenext_cursor: 30 por página, no máximo 100. - Exportação de entregas até 1.000 tentativas;
truncatedavisa quando há mais. - Estatísticas de entregas por até 30 dias.
Referência
Doze operações, todas com Authorization: Bearer <API_KEY>. As três mais usadas aparecem completas; as demais seguem o mesmo formato.
/webhooksCriar webhook
Cria o webhook e devolve o segredo de assinatura.
curl --request POST "https://bytemax.exchange/api/v1/webhooks" \
--header "Authorization: Bearer <API_KEY>" \
--header "Content-Type: application/json" \
--data '{"url":"https://merchant.example/webhooks/bytemax","events":["order.created","order.updated","refund.created","refund.updated"],"enabled":true}'{
"id": "ep_example",
"url": "https://merchant.example/webhooks/bytemax",
"events": [
"order.created",
"order.updated",
"refund.created",
"refund.updated"
],
"enabled": true,
"api_version": "v1",
"signing_secret": "<WEBHOOK_SIGNING_SECRET>"
}/webhooks/{id}/test-eventsEnviar teste
Envia um webhook.test para este webhook. Sem corpo.
| Parâmetro | Onde | Obrigatório |
|---|---|---|
id | caminho | Sim |
curl --request POST "https://bytemax.exchange/api/v1/webhooks/ep_example/test-events" \
--header "Authorization: Bearer <API_KEY>"{
"id": "evt_test_example",
"type": "webhook.test",
"api_version": "v1",
"occurred_at": "2026-09-10T13:05:00.000Z",
"data": {
"message": "ByteMax webhook test."
},
"publication_status": "pending"
}/webhooks/{id}/redeliveriesReenviar eventos
Reenvia até 20 eventos para este webhook. A resposta traz o resultado de cada um.
| Parâmetro | Onde | Obrigatório |
|---|---|---|
id | caminho | Sim |
curl --request POST "https://bytemax.exchange/api/v1/webhooks/ep_example/redeliveries" \
--header "Authorization: Bearer <API_KEY>" \
--header "Content-Type: application/json" \
--data '{"event_ids":["evt_example"]}'{
"items": [
{
"event_id": "evt_example",
"status": "queued"
}
]
}Outras operações
| Operação | Nome | O que faz |
|---|---|---|
GET/webhooks | Listar webhooks | Todos os webhooks da conta. |
GET/webhooks/{id} | Consultar webhook | Um webhook. Com include_signing_secret=true, inclui o segredo de assinatura. |
PATCH/webhooks/{id} | Alterar webhook | URL, eventos ou ativação. |
DELETE/webhooks/{id} | Excluir webhook | Exclui o webhook. |
GET/events | Listar eventos | Eventos dos últimos 30 dias e seu estado de publicação. |
GET/events/{id} | Consultar evento | Um evento e seu estado de publicação. |
GET/webhooks/{id}/deliveries | Listar entregas | Tentativas de entrega de um webhook, com filtros por estado e tipo. |
GET/webhooks/{id}/deliveries/export | Exportar entregas | Até 1.000 tentativas; truncated avisa quando há mais. |
GET/webhooks/statistics | Estatísticas | Sucessos e falhas por até 30 dias. |
