Recibe notificaciones en tiempo real cuando ocurren eventos en tu organización. Los webhooks te permiten construir integraciones reactivas que responden inmediatamente a los escaneos de códigos QR y otros eventos.
Recibe notificaciones al instante cuando ocurren eventos, sin necesidad de sondear
Las firmas HMAC verifican que los webhooks provienen de iloveQR
Reintentos automáticos con retroceso exponencial para entregas fallidas
Configura webhooks a través del panel o API para comenzar a recibir eventos.
Configura un endpoint HTTPS en tu servidor para recibir las cargas útiles de los webhooks.
Agrega la URL de tu endpoint y selecciona a qué eventos suscribirte.
Implementa la verificación de firmas para asegurar que las cargas útiles sean auténticas.
curl -X POST \
"https://api.iloveqr.com/api/v1/organizations/org_abc123/webhooks" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/iloveqr",
"events": ["qr.scanned", "qr.created", "qr.updated"],
"secret": "your_webhook_secret"
}'Suscríbete a los eventos que necesitas. Cada tipo de evento tiene una estructura de carga útil específica.
qr.createdSe creó un nuevo código QRqr.updatedSe actualizó un código QRqr.deletedSe eliminó un código QRqr.scannedSe escaneó un código QRqr.archivedSe archivó un código QRqr.restoredSe restauró un código QR del archivosubscription.createdSe creó una nueva suscripciónsubscription.updatedSe actualizó una suscripciónsubscription.cancelledSe canceló una suscripciónsubscription.payment_succeededUn pago fue exitososubscription.payment_failedUn pago fallómember.joinedUn miembro se unió a la organizaciónmember.leftUn miembro dejó la organizaciónmember.role_changedSe cambió el rol de un miembroTodas las cargas útiles de los webhooks siguen una estructura consistente con metadatos de eventos y datos.
{
"id": "evt_1a2b3c4d5e6f",
"event": "qr.scanned",
"createdAt": "2024-01-15T14:30:00Z",
"organizationId": "org_abc123",
"data": {
"qrCodeId": "qr_xyz789",
"qrCodeName": "Product Landing Page",
"shortCode": "xyz789",
"destinationUrl": "https://example.com/product",
"scan": {
"id": "scan_123abc",
"timestamp": "2024-01-15T14:30:00Z",
"location": {
"country": "US",
"city": "New York",
"latitude": 40.7128,
"longitude": -74.0060
},
"device": {
"type": "mobile",
"os": "iOS",
"browser": "Safari"
},
"isUnique": true
}
}
}{
"id": "evt_7g8h9i0j1k2l",
"event": "qr.created",
"createdAt": "2024-01-15T10:00:00Z",
"organizationId": "org_abc123",
"data": {
"qrCode": {
"id": "qr_newcode",
"type": "URL",
"name": "New Campaign QR",
"shortUrl": "https://ilqr.co/newcode",
"destinationUrl": "https://example.com/campaign",
"createdBy": "user_abc123"
}
}
}Siempre verifica las firmas de los webhooks para asegurar que la carga útil provino de iloveQR y no fue alterada en tránsito.
Cada solicitud de webhook incluye un encabezado X-Webhook-Signature que contiene una firma HMAC-SHA256 del cuerpo de la solicitud.
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// In your webhook handler
app.post('/webhooks/iloveqr', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook
const event = req.body;
console.log('Received event:', event.event);
res.status(200).send('OK');
});import hmac
import hashlib
def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# In your Flask handler
@app.route('/webhooks/iloveqr', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-Webhook-Signature')
payload = request.get_data()
if not verify_webhook_signature(payload, signature, WEBHOOK_SECRET):
return 'Invalid signature', 401
event = request.get_json()
print(f"Received event: {event['event']}")
return 'OK', 200Devuelve una respuesta 2xx dentro de los 5 segundos. Procesa los webhooks de manera asíncrona si tu manejo toma más tiempo.
Almacena el ID del evento y verifica duplicados. Los webhooks pueden ser entregados más de una vez en casos raros.
Siempre usa endpoints HTTPS. No entregamos webhooks a URLs HTTP.
Configura monitoreo para fallos en la entrega de webhooks. Revisa los registros de webhooks en el panel para depuración.
Si tu endpoint devuelve un error o no responde, automáticamente reintentamos la entrega con retroceso exponencial:
| Intento | Retraso |
|---|---|
| 1er reintento | 1 minuto |
| 2do reintento | 5 minutos |
| 3er reintento | 30 minutos |
| 4to reintento | 2 horas |
| 5to reintento (final) | 24 horas |
Nota: Después de 5 intentos fallidos, el webhook se marca como fallido y dejamos de reintentar. Recibirás una notificación por correo electrónico sobre la falla.
¿Listo para comenzar? Explora más recursos: