Saltar al contenido principal

Referencia de la API de webhooks

Referencia completa del endpoint de la API de webhooks.

URL base​

https://api.orcarail.com/api/v1

Recibir un webhook​

Recibe eventos de webhook de OrcaRail.

POST /webhooks

Autenticación​

  • Clave de API (Basic Auth): opcional, pero recomendada

Cabeceras​

CabeceraTipoObligatoriaDescripción
x-webhook-signaturestringCondicionalFirma HMAC SHA-256 (obligatoria si PAYMENTS_WEBHOOK_SECRET está definida)
Content-TypestringSíDebe ser application/json

Cuerpo de la petición​

{
"type": "payment_intent.completed",
"data": {
"object": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"amount": "100.00",
"currency": "usd",
"status": "succeeded",
"metadata": {
"order_id": "12345"
}
}
}
}

Respuesta​

Devuelve siempre 200 OK de inmediato:

{
"received": true
}

Eventos de webhook​

Tipo de eventoDescripción
payment_intent.completedEl Payment Intent se ha completado
payment_intent.processingEl Payment Intent se está procesando
payment_intent.canceledEl Payment Intent se ha cancelado
payment_intent.requires_payment_methodEl Payment Intent necesita un método de pago

Verificación de la firma​

Si PAYMENTS_WEBHOOK_SECRET está configurada, verifica la firma:

  1. Obtén la firma de la cabecera x-webhook-signature
  2. Calcula el HMAC SHA-256 del cuerpo de la petición con tu secreto
  3. Compara las firmas con una comparación de tiempo constante

Ejemplo: Node.js​

const crypto = require('crypto')

function verifySignature(receivedSignature, payload, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex')

const receivedBuffer = Buffer.from(receivedSignature)
const expectedBuffer = Buffer.from(expectedSignature)

if (receivedBuffer.length !== expectedBuffer.length) {
return false
}

return crypto.timingSafeEqual(receivedBuffer, expectedBuffer)
}

Requisitos de la respuesta​

Respuesta correcta​

Devuelve siempre 200 OK con {"received": true} de inmediato, aunque falle el procesamiento:

{
"received": true
}

Respuesta de error​

Si falla la verificación de la firma, devuelve 400 Bad Request:

{
"statusCode": 400,
"message": "Invalid webhook signature",
"error": "Bad Request"
}

Lógica de reintentos​

Si tu endpoint devuelve un código distinto de 200 o no responde, OrcaRail reintentará el webhook:

  • Intentos máximos: 3 intentos (1 inicial + 2 reintentos)
  • Estrategia de espera: backoff exponencial que empieza en 2 segundos
  • Tiempo de espera: 10 segundos por petición

Buenas prácticas​

  1. Responde rápido: devuelve 200 OK en menos de 10 segundos (el tiempo de espera es de 10 segundos)
  2. Procesa de forma asíncrona: gestiona los eventos en trabajos en segundo plano
  3. Verifica las firmas: verifica siempre las firmas de los webhooks
  4. Haz los gestores idempotentes: gestiona bien los eventos duplicados
  5. Registra los eventos: registra todos los eventos recibidos para depurar

Pruebas​

Prueba tu endpoint de webhook:

curl -X POST https://your-webhook-url.com/webhooks/orcarail \
-H "Content-Type: application/json" \
-H "x-webhook-signature: test-signature" \
-d '{
"type": "payment_intent.completed",
"data": {
"object": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"amount": "100.00",
"currency": "usd",
"status": "succeeded"
}
}
}'

Webhook de prueba​

Envía un evento de webhook de prueba a tu URL de webhook configurada.

POST /webhooks/test/:apiKeyId

Autenticación​

  • Token Bearer (JWT): obligatorio

Parámetros de ruta​

ParámetroTipoObligatorioDescripción
apiKeyIdnumberSíID de la clave de API

Respuesta​

{
"success": true
}

Respuestas de error​

404 Not Found: no se encuentra la clave de API o no hay URL de webhook configurada:

{
"statusCode": 404,
"message": "Webhook URL not configured for this API key",
"error": "Not Found"
}

Enviar un webhook personalizado​

Envía un payload de webhook personalizado a tu URL de webhook configurada.

POST /webhooks/test/:apiKeyId/custom

Autenticación​

  • Token Bearer (JWT): obligatorio

Parámetros de ruta​

ParámetroTipoObligatorioDescripción
apiKeyIdnumberSíID de la clave de API

Cuerpo de la petición​

{
"payload": {
"type": "payment_intent.completed",
"data": {
"object": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"amount": "100.00",
"currency": "usd",
"status": "succeeded"
}
}
}
}

Respuesta​

{
"success": true
}

Obtener los registros de webhooks​

Obtén los registros de entrega de webhooks de tu cuenta.

GET /webhooks/logs

Autenticación​

  • Token Bearer (JWT): obligatorio

Parámetros de consulta​

ParámetroTipoPor defectoDescripción
limitnumber50Número de registros que se devuelven
offsetnumber0Número de registros que se omiten

Respuesta​

{
"logs": [
{
"id": 1,
"apiKeyId": 1,
"userId": 1,
"event": "payment_intent.completed",
"url": "https://api.example.com/webhooks/orcarail",
"statusCode": 200,
"success": true,
"attemptNumber": 1,
"createdAt": "2024-01-01T00:00:00.000Z"
}
],
"total": 1
}

Campos del objeto de registro​

CampoTipoDescripción
idnumberIdentificador único del registro
apiKeyIdnumberID de la clave de API que disparó el webhook
userIdnumberID del usuario propietario de la clave de API
eventstringTipo de evento (por ejemplo payment_intent.completed)
urlstringURL de webhook a la que se llamó
statusCodenumberCódigo de estado HTTP devuelto por el endpoint del webhook
successbooleanSi el webhook se entregó correctamente
attemptNumbernumberNúmero de intento (1, 2 o 3)
errorstringMensaje de error si falló la entrega
responsestringCuerpo de la respuesta del endpoint del webhook
createdAtstringMarca de tiempo ISO 8601 de creación del registro

Consulta también​