Saltar al contenido principal

Webhooks

Endpoints para recibir eventos en tiempo real de Manteca y Bridge.


1. Webhook de Manteca

POST /webhook

Endpoint para recibir eventos de webhook de Manteca.

Headers:

Content-Type: application/json
X-Manteca-Signature: <signature>

Body (Ejemplo - Validación de Documento):

{
"event": "DOCUMENT_VALIDATION",
"data": {
"numberId": "12345",
"userExternalId": "swp_98808656",
"document": "DNI_FRONT",
"validated": true,
"comment": "Documento válido",
"date": "2024-01-15T10:30:00Z",
"newLimit": 50000,
"newLimitMonth": 10000
}
}

Respuesta Exitosa (200):

{
"success": true,
"message": "Evento procesado exitosamente"
}

Respuesta de Error (200):

{
"success": false,
"message": "Error al procesar evento",
"error": "Error message"
}

2. Webhook de Bridge

POST /bridge/webhook

Endpoint para recibir eventos de webhook de Bridge.

Headers:

Content-Type: application/json
X-Bridge-Signature: <signature>
X-Bridge-Timestamp: <timestamp>

Body (Ejemplo - Customer Actualizado):

{
"event_category": "customer",
"event_type": "customer.updated",
"event_object_id": "bridge_customer_123",
"event_object": {
"id": "bridge_customer_123",
"status": "active",
"email": "user@example.com"
}
}

Respuesta Exitosa (200):

{
"success": true,
"message": "Evento procesado exitosamente"
}

🔔 Eventos de Manteca

DOCUMENT_VALIDATION

Notifica cambios en el estado de validación de documentos KYC.

{
"event": "DOCUMENT_VALIDATION",
"data": {
"numberId": "12345",
"userExternalId": "swp_98808656",
"document": "DNI_FRONT",
"validated": true,
"comment": "Documento válido",
"date": "2024-01-15T10:30:00Z",
"newLimit": 50000,
"newLimitMonth": 10000
}
}

ORDER_COMPLETED

Notifica cuando una orden se completa exitosamente.

{
"event": "ORDER_COMPLETED",
"data": {
"numberId": "67890",
"userExternalId": "swp_98808656",
"coin": "DAI_ARS",
"operation": "BUY",
"amount": "100.00",
"price": "1250.75",
"fee": "2.50",
"completedAt": "2024-01-15T10:35:00Z"
}
}

FIAT_DEPOSIT

Notifica depósitos fiat recibidos.

{
"event": "FIAT_DEPOSIT",
"data": {
"depositId": "dep_123",
"userExternalId": "swp_98808656",
"amount": "5000.00",
"currency": "ARS",
"status": "COMPLETED",
"reference": "DEP20240115001",
"completedAt": "2024-01-15T11:00:00Z"
}
}

🔵 Eventos de Bridge

customer.created

Customer creado exitosamente.

{
"event_category": "customer",
"event_type": "customer.created",
"event_object_id": "bridge_customer_123",
"event_object": {
"id": "bridge_customer_123",
"status": "pending",
"email": "user@example.com",
"first_name": "Juan",
"last_name": "Pérez",
"created_at": "2024-01-15T10:30:00Z"
}
}

customer.verified

Customer verificado tras completar KYC.

{
"event_category": "customer",
"event_type": "customer.verified",
"event_object_id": "bridge_customer_123",
"event_object": {
"id": "bridge_customer_123",
"status": "active",
"kyc_status": "verified",
"verified_at": "2024-01-15T12:00:00Z"
}
}

virtual_account.credited

Fondos recibidos en cuenta virtual.

{
"event_category": "virtual_account",
"event_type": "virtual_account.credited",
"event_object_id": "va_123456",
"event_object": {
"id": "va_123456",
"amount": "1000.00",
"currency": "usd",
"transaction_id": "tx_789",
"credited_at": "2024-01-15T14:30:00Z"
}
}

🔒 Verificación de Seguridad

Manteca Signature

const crypto = require('crypto');

function verifyMantecaWebhook(payload, signature, secret) {
const computedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');

return signature === computedSignature;
}

Bridge Signature

function verifyBridgeWebhook(payload, signature, timestamp, secret) {
const signedPayload = `${timestamp}.${payload}`;
const computedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');

return signature === `sha256=${computedSignature}`;
}

🔄 Manejo de Errores

Reintentos

  • Manteca: 3 intentos con backoff exponencial
  • Bridge: 5 intentos con backoff exponencial
  • Timeout: 30 segundos por intento

Estados de Respuesta

// Éxito - No se reintenta
return res.status(200).json({ success: true });

// Error temporal - Se reintenta
return res.status(500).json({ error: "Database unavailable" });

// Error permanente - No se reintenta
return res.status(400).json({ error: "Invalid payload format" });

📊 Logging y Monitoreo

Log Structure

{
"timestamp": "2024-01-15T10:30:00Z",
"webhook_type": "manteca",
"event": "DOCUMENT_VALIDATION",
"user_id": "swp_98808656",
"processing_time_ms": 150,
"status": "success",
"ip_address": "192.168.1.1"
}

Métricas

  • Latencia promedio: < 200ms
  • Tasa de éxito: > 99%
  • Tiempo de procesamiento: < 5s
  • Reintentos: < 1% de eventos

🛠️ Testing

Webhook Testing Tool

// Simular webhook de Manteca
const mockMantecaWebhook = {
event: "DOCUMENT_VALIDATION",
data: {
numberId: "test_123",
userExternalId: "test_user",
document: "DNI_FRONT",
validated: true
}
};

// Enviar a endpoint local
fetch('http://localhost:3000/webhook', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(mockMantecaWebhook)
});

⚠️ Errores Comunes

Webhook Failures

  • Invalid Signature: Verificar secreto y algoritmo
  • Timeout: Optimizar procesamiento de eventos
  • Duplicate Events: Implementar idempotencia
  • Missing Headers: Validar headers requeridos

Debugging Checklist

  1. ✅ Validar formato de payload
  2. ✅ Verificar signature del webhook
  3. ✅ Comprobar conectividad de base de datos
  4. ✅ Revisar logs de errores
  5. ✅ Validar respuesta HTTP

📝 Notas Importantes

  • Idempotencia: Manejar eventos duplicados con IDs únicos
  • Timeouts: Responder en < 30 segundos para evitar reintentos
  • Seguridad: Siempre validar signatures
  • Logs: Registrar todos los eventos para auditoría
  • Monitoreo: Alertas para fallos de webhook > 5%