Saltar al contenido principal

Webhooks

Los webhooks permiten que tu servidor reciba notificaciones en tiempo real cuando se completa un pago. Esta es la forma recomendada de confirmar pagos en producción, ya que proporciona una comunicación confiable de servidor a servidor.

Cómo Funcionan los Webhooks

Cuando un cliente completa un pago a través del botón SmartPay:

  1. ApoloPay envía una petición HTTP POST a la URL de tu webhook configurada
  2. Tu servidor recibe la petición con los detalles del pago
  3. Tu servidor verifica la autenticidad del webhook usando el secreto de webhook (webhook secret)
  4. Tu servidor procesa la confirmación del pago (ej., actualiza el estado del pedido)

Configurar Webhooks

  1. Ve al Panel de ApoloPay
  2. Navega a la configuración de tu botón de pago
  3. En la sección Webhook, ingresa la URL de tu endpoint
  4. Guarda — Se generará un Secreto de Webhook para ti
tip

El endpoint de tu webhook debe ser públicamente accesible mediante HTTPS. Durante el desarrollo, puedes usar herramientas como ngrok para exponer tu servidor local.

Payload del Webhook

Cuando se completa un pago, ApoloPay envía una petición POST a la URL de tu webhook con la siguiente estructura:

{
"event": "payment.completed",
"processId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amount": 25.50,
"metadata": {
"orderId": "ORD-9821",
"customerEmail": "[email protected]"
},
"timestamp": "2026-03-19T12:00:00Z"
}

Manejo de Webhooks

Node.js (Express)

const express = require('express');
const crypto = require('crypto');
const app = express();

const WEBHOOK_SECRET = process.env.APOLOPAY_WEBHOOK_SECRET;

// Usa el raw body para verificar la firma
app.post(
'/api/webhooks/apolopay',
express.raw({ type: 'application/json' }),
(req, res) => {
const signature = req.headers['x-apolopay-signature'];
const payload = req.body.toString();

// Verifica la firma del webhook
const expectedSignature = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');

if (signature !== expectedSignature) {
console.error('Firma de webhook inválida');
return res.status(401).json({ error: 'Firma inválida' });
}

// Procesa el webhook
const event = JSON.parse(payload);
console.log('Pago completado:', event.processId);

// Actualiza el estado de tu pedido en la base de datos
// ...

// Responde con 200 para confirmar la recepción
res.status(200).json({ received: true });
}
);

Python (FastAPI)

import hmac
import hashlib
from fastapi import FastAPI, Request, HTTPException
import os

app = FastAPI()

WEBHOOK_SECRET = os.getenv("APOLOPAY_WEBHOOK_SECRET")

@app.post("/api/webhooks/apolopay")
async def handle_webhook(request: Request):
payload = await request.body()
signature = request.headers.get("x-apolopay-signature")

# Verifica la firma del webhook
expected_signature = hmac.new(
WEBHOOK_SECRET.encode(),
payload,
hashlib.sha256,
).hexdigest()

if signature != expected_signature:
raise HTTPException(status_code=401, detail="Firma inválida")

# Procesa el webhook
event = await request.json()
print(f"Pago completado: {event['processId']}")

# Actualiza el estado de tu pedido en la base de datos
# ...

return {"received": True}

Mejores Prácticas

PrácticaDescripción
Siempre verifica las firmasUsa el secreto del webhook para validar que las peticiones provienen de ApoloPay
Responde rápidamenteDevuelve un código 200 lo antes posible. Procesa tareas pesadas asincrónicamente
Maneja duplicadosTu endpoint debe ser idempotente — el mismo evento puede ser enviado múltiples veces
Usa HTTPSSiempre usa HTTPS para el endpoint de tu webhook en producción
Registra (log) eventosMantén un registro de los eventos webhook recibidos para depuración

Política de Reintentos

Si tu servidor no responde con un estado 2xx, ApoloPay reintentará procesar la entrega del webhook con retroceso exponencial (exponential backoff).

Siguientes Pasos