Webhooks
Notificaciones de eventos de CheckoutOS en tiempo real
Última actualización: 2025-01-16
Los webhooks te permiten recibir avisos en tiempo real cuando ocurren eventos. En vez de consultar la API repetidamente, envían datos al servidor al producirse el evento.
Eventos disponibles
Eventos de webhook
- upsell.accepted — El cliente aceptó una oferta de venta adicional
- upsell.declined — El cliente rechazó una oferta de venta adicional
- bundle.purchased — Se compró un paquete
- experiment.concluded — La prueba A/B alcanzó significación
- order.edited — El cliente editó su pedido
- order.cancelled — El cliente canceló su pedido
- subscription.created — La oferta de suscripción se convirtió
Crear webhooks
1
Ir a webhooks
Ve a CheckoutOS → Settings → Webhooks.
2
Añadir endpoint
Haz clic en “Add Webhook Endpoint”.
3
Introducir URL
Introduce la URL HTTPS que recibirá los eventos.
4
Seleccionar eventos
Elige a qué eventos suscribirte.
5
Guardar
Guarda y anota el secreto de firma.
Crear un webhook mediante la API
curl -X POST "https://api.chargezen.com/v1/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourserver.com/webhooks/checkoutos",
"events": ["upsell.accepted", "bundle.purchased"],
"enabled": true
}'
# Response
{
"id": "wh_123",
"url": "https://yourserver.com/webhooks/checkoutos",
"events": ["upsell.accepted", "bundle.purchased"],
"signing_secret": "whsec_abc123...",
"enabled": true
}Contenido del webhook
upsell.accepted
Evento de venta adicional aceptada
{
"id": "evt_123456",
"type": "upsell.accepted",
"created_at": "2025-01-16T14:30:00Z",
"data": {
"upsell_id": "upsell_abc",
"upsell_name": "Premium Add-On",
"order_id": "order_789",
"shopify_order_id": "5678901234",
"customer_id": "cust_456",
"product": {
"id": "prod_xyz",
"title": "Premium Widget",
"variant_id": "var_123",
"price": 29.99
},
"discount": {
"type": "percentage",
"value": 15,
"amount": 4.50
},
"final_price": 25.49
}
}bundle.purchased
Evento de paquete comprado
{
"id": "evt_234567",
"type": "bundle.purchased",
"created_at": "2025-01-16T15:00:00Z",
"data": {
"bundle_id": "bundle_def",
"bundle_name": "Skincare Starter Kit",
"bundle_type": "fixed",
"order_id": "order_890",
"products": [
{ "id": "prod_a", "title": "Cleanser", "quantity": 1 },
{ "id": "prod_b", "title": "Toner", "quantity": 1 },
{ "id": "prod_c", "title": "Moisturizer", "quantity": 1 }
],
"original_price": 89.97,
"bundle_price": 71.98,
"savings": 17.99
}
}order.edited
Evento de pedido editado
{
"id": "evt_345678",
"type": "order.edited",
"created_at": "2025-01-16T15:30:00Z",
"data": {
"order_id": "order_901",
"shopify_order_id": "6789012345",
"edit_type": "add_items",
"changes": {
"items_added": [
{ "product_id": "prod_new", "quantity": 1, "price": 19.99 }
],
"items_removed": [],
"quantity_changes": []
},
"amount_changed": 19.99,
"new_total": 109.98
}
}Verificar webhooks
Todos incluyen una cabecera de firma para verificarlos:
Verificación en Node.js
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expectedSignature}`)
);
}
// Express middleware
app.post('/webhooks/checkoutos', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-checkoutos-signature'];
if (!verifyWebhook(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
// Handle event...
res.status(200).send('OK');
});Verificación en Python
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(
f'sha256={expected}',
signature
)
# Flask example
@app.route('/webhooks/checkoutos', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-CheckoutOS-Signature')
if not verify_webhook(request.data, signature, WEBHOOK_SECRET):
return 'Invalid signature', 401
event = request.get_json()
# Handle event...
return 'OK', 200Verifica siempre
Verifica las firmas antes de procesar webhooks. Esto impide que atacantes envíen eventos falsos a tu endpoint.
Política de reintentos
Los envíos fallidos se reintentan con intervalos crecientes de forma exponencial:
Calendario de reintentos
{
"retry_policy": {
"max_attempts": 5,
"schedule": [
{ "attempt": 1, "delay": "immediately" },
{ "attempt": 2, "delay": "5 minutes" },
{ "attempt": 3, "delay": "30 minutes" },
{ "attempt": 4, "delay": "2 hours" },
{ "attempt": 5, "delay": "24 hours" }
],
"success_codes": [200, 201, 202, 204],
"timeout": "30 seconds"
}
}Probar webhooks
Prueba el endpoint antes de ponerlo en funcionamiento:
Enviar un evento de prueba
curl -X POST "https://api.chargezen.com/v1/webhooks/wh_123/test" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event_type": "upsell.accepted"
}'Registros de webhooks
Consulta el historial de entrega en el panel o mediante la API:
Obtener registros de webhooks
curl -X GET "https://api.chargezen.com/v1/webhooks/wh_123/logs" \
-H "Authorization: Bearer YOUR_API_KEY"
# Response
{
"data": [
{
"id": "log_123",
"event_id": "evt_456",
"event_type": "upsell.accepted",
"status": "delivered",
"response_code": 200,
"duration_ms": 245,
"created_at": "2025-01-16T14:30:00Z"
}
]
}Buenas prácticas
Consejos para webhooks
- Responde rápido — Devuelve 200 en un máximo de 30 segundos
- Procesa de forma asíncrona — Pon los eventos en cola para procesarlos en segundo plano
- Gestiona duplicados — Un evento puede entregarse varias veces
- Verifica las firmas — Valida siempre antes de procesar
- Supervisa fallos — Configura alertas por entregas fallidas
Temas relacionados
¿Te resultó útil esta página?
¿Necesitas más ayuda? Contactar con soporte