Eventos
Webhooks
Os webhooks avisam você em tempo real sobre eventos na sua conta. Configure um endpoint HTTPS e receba atualizações automáticas.
Tipos de eventos
Pagamentos
payment.createdpayment.succeededpayment.failedpayment.refunded
Links de pagamento
payment_link.createdpayment_link.paidpayment_link.expired
Assinaturas
subscription.createdsubscription.updatedsubscription.canceledsubscription.pausedsubscription.resumedsubscription.trial_ending
Faturas
invoice.createdinvoice.paidinvoice.payment_failedinvoice.upcoming
Formato dos dados
{
"id": "evt_1a2b3c4d5e6f",
"object": "event",
"type": "payment.succeeded",
"api_version": "2024-01-01",
"created": 1705312200,
"data": {
"object": {
"id": "pi_abc123xyz",
"object": "payment_intent",
"amount": 500.00,
"currency": "MXN",
"status": "succeeded",
"customer_id": "8e250c25-9d84-4892-98ec-d71fc1fcd3c7",
...
}
}
}
Verificação de assinatura (HMAC)
Cada webhook inclui um cabeçalho X-Recaudo-Signature que você deve verificar para garantir que a mensagem vem do Recaudo.
<?php
// Obtener el payload y la firma
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_RECAUDO_SIGNATURE'];
$secret = 'whsec_tu_webhook_secret';
// Extraer timestamp y firma del header
// Formato: t=timestamp,v1=signature
$parts = explode(',', $signature);
$timestamp = substr($parts[0], 2);
$receivedSignature = substr($parts[1], 3);
// Calcular la firma esperada
$signedPayload = $timestamp . '.' . $payload;
$expectedSignature = hash_hmac('sha256', $signedPayload, $secret);
// Verificar
if (hash_equals($expectedSignature, $receivedSignature)) {
// Firma valida - procesar el evento
$event = json_decode($payload, true);
switch ($event['type']) {
case 'payment.succeeded':
// Manejar pago exitoso
break;
case 'subscription.canceled':
// Manejar cancelacion
break;
}
http_response_code(200);
} else {
// Firma invalida
http_response_code(400);
}
const crypto = require('crypto');
app.post('/webhooks/recaudo', express.raw({type: 'application/json'}), (req, res) => {
const payload = req.body;
const signature = req.headers['x-recaudo-signature'];
const secret = 'whsec_tu_webhook_secret';
// Extraer timestamp y firma
const parts = signature.split(',');
const timestamp = parts[0].split('=')[1];
const receivedSignature = parts[1].split('=')[1];
// Calcular firma esperada
const signedPayload = `${timestamp}.${payload}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
// Verificar
if (crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(receivedSignature)
)) {
const event = JSON.parse(payload);
switch (event.type) {
case 'payment.succeeded':
// Manejar pago exitoso
break;
case 'subscription.canceled':
// Manejar cancelacion
break;
}
res.status(200).send('OK');
} else {
res.status(400).send('Invalid signature');
}
});
import hmac
import hashlib
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhooks/recaudo', methods=['POST'])
def webhook():
payload = request.data
signature = request.headers.get('X-Recaudo-Signature')
secret = 'whsec_tu_webhook_secret'
# Extraer timestamp y firma
parts = signature.split(',')
timestamp = parts[0].split('=')[1]
received_signature = parts[1].split('=')[1]
# Calcular firma esperada
signed_payload = f"{timestamp}.{payload.decode()}"
expected_signature = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
# Verificar
if hmac.compare_digest(expected_signature, received_signature):
event = request.json
if event['type'] == 'payment.succeeded':
# Manejar pago exitoso
pass
elif event['type'] == 'subscription.canceled':
# Manejar cancelacion
pass
return 'OK', 200
else:
return 'Invalid signature', 400
Boas práticas
- Sempre verifique a assinatura HMAC antes de processar o evento
- Responda com 200 rapidamente e processe de forma assíncrona
- Implemente idempotência usando o ID do evento
- Use HTTPS com um certificado válido
- Os webhooks são reenviados automaticamente se falharem (até 3 vezes)
API de Webhook Endpoints
Gerencie seus webhook endpoints de forma programática.
/v1/webhook-endpoints
Criar um novo webhook endpoint.
{
"url": "https://tu-servidor.com/webhooks/recaudo",
"events": ["payment.succeeded", "invoice.paid", "customer.created"],
"description": "Webhook principal de producción",
"is_active": true
}
/v1/webhook-endpoints
Listar todos os webhook endpoints configurados.
/v1/webhook-endpoints/{'{id}'}
Ver os detalhes do endpoint incluindo o secret para verificar assinaturas.
{
"id": "we_abc123",
"url": "https://tu-servidor.com/webhooks/recaudo",
"events": ["payment.succeeded", "invoice.paid"],
"secret": "whsec_tu_webhook_secret",
"is_active": true,
"description": "Webhook principal",
"created_at": "2026-04-01T00:00:00Z"
}
/v1/webhook-endpoints/{'{id}'}
Atualizar a URL, os eventos ou o status do endpoint.
{
"url": "https://nueva-url.com/webhooks",
"events": ["payment.succeeded", "payment.failed"],
"is_active": false
}
/v1/webhook-endpoints/{'{id}'}
Excluir um webhook endpoint.
/v1/webhook-endpoints/{'{id}'}/test
Enviar um evento de teste ao endpoint para verificar a conectividade.
/v1/webhook-endpoints/{'{id}'}/rotate-secret
Gerar um novo secret para o endpoint. O secret anterior deixa de valer imediatamente.
/v1/webhook-endpoints/{'{id}'}/deliveries
Ver o histórico de entregas do endpoint com status e códigos de resposta.
/v1/webhook-endpoints/{'{id}'}/deliveries/{'{delivery_id}'}/resend
Reenviar uma entrega com falha.