Pular para o conteúdo

Receber webhooks

A Avexus envia um POST para os endpoints registrados sempre que uma cobrança, um saque ou uma disputa muda de estado. Para registrar, testar e remover endpoints, veja a API de webhooks.

Evento (assinatura) Header x-webhook-event Quando dispara
transaction TRANSACTION Mudanças de status de cobrança (CONFIRMED, FAILED, EXPIRED, REFUNDED…)
withdraw WITHDRAW Mudanças de status de saque (PROCESSING, CONFIRMED, FAILED…)
dispute DISPUTE Abertura e atualização de disputas (MED)
Header Descrição
x-webhook-signature HMAC SHA256 do corpo, em hexadecimal
x-webhook-event Tipo do evento, em maiúsculas
x-user-reference Identificador da sua conta na Avexus
Content-Type application/json
User-Agent Avexus-Webhooks/1.0
event: TRANSACTION
{
"data": {
"magic_id": "rU1w01Ct6QL3",
"amount": 197.0,
"currency": "BRL",
"status": "CONFIRMED",
"decline_reason": null,
"description": "Mentoria Pro",
"payment_method": "Pix",
"qr_code": "00020101021126700014br.gov.bcb.pix...",
"end_to_end": "E60789431202607241838V2JYEP7TUZ6",
"external_ref": "pedido_1042",
"requester": {
"name": "Maria Souza",
"email": "maria@example.com",
"phone": "11999999999",
"document": "12468239008"
},
"movement": {
"payer": {
"name": "Maria Souza",
"document": "12468239008",
"bank": "BANCO INTER S.A.",
"agency": "0001",
"account": "123456-7"
},
"payee": {
"name": "Sua Loja LTDA",
"document": "12345678000190",
"bank": "BANCO INTER S.A.",
"agency": "0001",
"account": "765432-1"
}
},
"created_at": "2026-07-24T18:38:25.688Z",
"updated_at": "2026-07-24T18:41:06.467Z"
},
"event": "TRANSACTION"
}
event: WITHDRAW
{
"data": {
"magic_id": "wth_03UdoKvLNLHg",
"amount": 300.0,
"currency": "BRL",
"status": "CONFIRMED",
"fee": 0.15,
"decline_reason": null,
"description": "Repasse semanal",
"transfer_method": "Pix",
"end_to_end": "E60789431202607241838V2JYEP7TUZ6",
"external_ref": "repasse_2026_30",
"movement": {
"payer": {
"name": "Sua Loja LTDA",
"document": "12345678000190",
"bank": "BANCO INTER S.A.",
"agency": "0001",
"account": "765432-1"
},
"payee": {
"name": "Maria Souza",
"document": "95876150096",
"bank": "BANCO INTER S.A.",
"agency": "0001",
"account": "123456-7"
}
},
"created_at": "2026-07-24T20:44:25.618Z",
"updated_at": "2026-07-24T20:46:11.902Z"
},
"event": "WITHDRAW"
}

A assinatura é o HMAC SHA256 do corpo bruto da requisição, em hexadecimal, usando o secret (whsec_…) devolvido ao registrar o webhook.

Express — corpo bruto + comparação em tempo constante
const crypto = require('crypto');
const express = require('express');
const app = express();
// express.raw() preserva os bytes originais — express.json() os perderia.
app.post(
'/webhooks/avexus',
express.raw({ type: 'application/json' }),
(req, res) => {
const assinatura = req.get('x-webhook-signature') ?? '';
const esperada = crypto
.createHmac('sha256', process.env.AVEXUS_WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
const a = Buffer.from(assinatura, 'utf8');
const b = Buffer.from(esperada, 'utf8');
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.sendStatus(401);
}
const evento = JSON.parse(req.body.toString('utf8'));
// processe de forma idempotente e responda 2xx rápido
res.sendStatus(200);
},
);
Regra Valor
Resposta considerada sucesso Qualquer 2xx
Timeout da requisição 10 segundos
Tentativas Até 8
Espera entre tentativas Backoff exponencial a partir de 5 s, teto de 10 min, com jitter
Depois da última tentativa A entrega vai para a dead-letter e pode ser reenviada pelo operador
Endpoint removido ou inativo A entrega é descartada na hora, sem retentativa

A mesma notificação pode chegar mais de uma vez (retentativa de rede, reenvio manual, resend=true). Deixe o handler idempotente:

  • Use o magic_id — ou o par magic_id + status — como chave de deduplicação.
  • Se o evento já foi processado, responda 2xx e não repita os efeitos colaterais.
  • Concilie pelo external_ref que você mesmo enviou.

Perdeu uma notificação? A consulta com resend=true reenfileira o webhook dos registros retornados:

Reenviar o webhook de uma cobrança
curl --request GET \
--url 'https://api.avexus.app/api/transactions?magic_id=rU1w01Ct6QL3&resend=true' \
--header 'x-api-key: <API_KEY>' \
--header 'x-token: <TOKEN>' \
--header 'x-timezone: America/Sao_Paulo'
Reenviar o webhook de um saque
curl --request GET \
--url 'https://api.avexus.app/api/withdrawals?magic_id=wth_03UdoKvLNLHg&resend=true' \
--header 'x-api-key: <API_KEY>' \
--header 'x-token: <TOKEN>' \
--header 'x-timezone: America/Sao_Paulo'

Para exercitar a integração sem esperar um pagamento, use a entrega de teste: POST /api/webhooks/{magic_id}/test.