Webhooks
Receba no seu servidor os eventos reais de pagamento da loja, assinados pela Mivy e com tentativas automáticas de entrega.
#Cadastre seu endpoint
A URL cadastrada é a URL do seu sistema. O endereço api.mivy.com.br/api/webhooks/discord pertence à integração do Discord e não deve ser usado como destino para seus pagamentos. A conexão acompanha automaticamente os Pix gerados pelas chaves da mesma loja.
- Prepare um endpoint HTTPS público no seu servidor, na porta 443, para receber POSTs.
- Abra Integrações → Webhooks no painel da Mivy e crie um endpoint.
- Informe a URL real da sua aplicação e selecione os eventos desejados.
- Salve o segredo whsec_ exibido uma única vez como MIVY_WEBHOOK_SECRET no seu servidor.
- Use Enviar teste no painel e confira a entrega no histórico.
#Eventos de recebimento
Pedidos da loja também usam eventos de pagamento e trazem data.orderId. Para Pix da API, use data.paymentId e data.source=api. O evento deposit.approved também pode acompanhar o crédito: não some payment.approved e deposit.approved como dois pagamentos diferentes.
| Evento | Quando é enviado | Status da API |
|---|---|---|
| payment.created | Pix gerado pela API. | PENDING |
| payment.approved | Pagamento confirmado e crédito líquido registrado. | PAID |
| payment.expired | Expiração confirmada pelo processamento. | EXPIRED |
| payment.failed | Falha ou cancelamento confirmado. | FAILED |
| endpoint.test | Teste enviado pelo proprietário no painel. | Não é uma cobrança. |
#Corpo do evento
Exemplo ilustrativo. O corpo não inclui token da API, QR Code ou código Pix. O ID em data.paymentId pode ser consultado na API.
{
"id": "payment.approved:ID_DO_PAGAMENTO",
"type": "payment.approved",
"createdAt": "2026-10-17T22:05:00.000Z",
"storeId": "ID_DA_SUA_LOJA",
"data": {
"id": "ID_DO_PAGAMENTO",
"status": "PAID",
"amount": 100,
"requestedAmount": 100,
"fee": 1.35,
"netAmount": 98.65,
"currency": "BRL",
"description": "Pedido 123",
"passFee": false,
"validityMinutes": 30,
"expiresAt": "2026-10-17T22:30:00.000Z",
"paidAt": "2026-10-17T22:05:00.000Z",
"createdAt": "2026-10-17T22:00:00.000Z",
"paymentId": "ID_DO_PAGAMENTO",
"source": "api"
}
} #Valide a assinatura
Calcule HMAC-SHA256 com o segredo whsec_ sobre TIMESTAMP.CORPO_ORIGINAL. Preserve os bytes recebidos antes de converter para JSON e use tolerância de cinco minutos para o timestamp. O verificador disponível abaixo implementa exatamente esse formato.
| Cabeçalho | Conteúdo |
|---|---|
| X-Mivy-Event | Nome do evento. |
| X-Mivy-Delivery | ID da entrega, preservado nos reenvios. |
| X-Mivy-Signature | t=TIMESTAMP,v1=HMAC_SHA256_HEXADECIMAL. |
import { verifyMivyWebhook } from './mivy-webhook-signature.mjs';
const valid = verifyMivyWebhook(
rawBody, // Buffer com os bytes originais do POST.
request.headers['x-mivy-signature'],
process.env.MIVY_WEBHOOK_SECRET
);
// Se valid for false, responda 401 sem processar o evento. #Receba e persista antes de responder
O receptor de exemplo usa Node.js 20+, verifica o HMAC e grava cada entrega em disco antes de responder 204. Instale também o arquivo de verificação na mesma pasta. Hospede-o atrás de HTTPS e mantenha MIVY_WEBHOOK_DIR em um volume persistente. Seu processamento de negócio deve consumir os arquivos e deduplicar também pelo id do evento. endpoint.test serve apenas para testar o transporte.
# No ambiente do seu servidor:
# MIVY_WEBHOOK_SECRET=whsec_SEGREDO_DO_PAINEL
# MIVY_WEBHOOK_DIR=/data/mivy-webhooks
node --env-file=.env mivy-webhook-receiver.mjs
# Cadastre a URL pública HTTPS do seu servidor seguida de /webhooks/mivy. #Reenvios e confirmação
Responda 2xx somente após persistir a entrega. O mesmo X-Mivy-Delivery pode ser recebido novamente: armazene-o com unicidade. Eventos podem chegar repetidos ou fora de ordem; consulte o pagamento para obter o status atual.
A fila possui até cinco tentativas: inicial, aproximadamente um minuto, cinco minutos, quinze minutos e uma hora depois. O processamento ocorre em ciclos de cerca de 30 segundos. Você pode reenviar uma falha pelo histórico, preservando o identificador e o corpo original.
Pausar ou excluir a conexão cancela a fila pendente desse endpoint. Uma requisição que já saiu ainda pode chegar ao seu servidor. Até dez conexões são permitidas por loja.