Appearance
Ejemplo: Integración con MercadoPago
Resumen
Implementación del adapter para MercadoPago Checkout Pro. Este documento sirve como ejemplo de cómo integrar un medio de pago específico con el sistema genérico.
Pasos de Configuración
1. Obtener Credenciales
- Registrarse en MercadoPago
- Ir a Tus integraciones → Credentials
- Obtener:
- Access Token (producción)
- Access Token de prueba (sandbox)
- Webhook Secret (para validar webhooks)
2. Configurar en Backend
Instalar SDK:
bash
composer require mercadopago/dx-phpVariables de entorno:
MERCADOPAGO_ACCESS_TOKENMERCADOPAGO_WEBHOOK_SECRET
3. Configurar Tenant
Cada tenant puede tener configurado su propio medio de pago en la base de datos:
json
{
"payment_gateway": "mercadopago",
"payment_gateway_config": {
"access_token": "APP_USR-xxx",
"webhook_secret": "secret",
"environment": "production"
}
}Implementación del Adapter
El adapter debe implementar la interfaz PaymentGatewayInterface:
Método: createPayment()
Propósito: Crear una preferencia de pago en MercadoPago.
Entrada:
json
{
"payment_id": "portal_payment_abc123",
"total": 15000.00,
"tenant_name": "Empresa A",
"domain": "ctacte.empresaa.com"
}Proceso:
- Crear objeto
Preferencedel SDK de MercadoPago - Configurar item con título, cantidad y precio
- Configurar URLs de retorno (success, failure, pending)
- Configurar
external_referencecon nuestropayment_id - Guardar preferencia en MercadoPago
- Retornar
preference_idyinit_point(URL checkout)
Salida:
json
{
"external_id": "1234567890",
"redirect_url": "https://www.mercadopago.com.ar/checkout/v1/redirect?pref_id=..."
}Método: processWebhook()
Propósito: Procesar notificación de MercadoPago cuando el pago cambia de estado.
Entrada: Payload del webhook de MercadoPago
json
{
"type": "payment",
"data": {
"id": "1234567890"
}
}Proceso:
- Verificar que el tipo es "payment"
- Obtener
payment_iddel payload - Consultar API de MercadoPago para obtener detalles del pago
- Extraer estado, monto, fecha, tipo de pago
- Retornar información normalizada
Salida:
json
{
"status": "approved",
"external_id": "1234567890",
"amount": 15000.00,
"payment_date": "2026-01-20T14:30:00Z",
"payment_type": "credit_card",
"raw_response": { /* respuesta completa */ }
}Método: validateWebhook()
Propósito: Validar que el webhook realmente proviene de MercadoPago (seguridad).
Proceso:
- Extraer headers
x-signatureyx-request-id - Parsear signature para obtener
ts(timestamp) yv1(hash) - Construir manifest:
"id:{request_id};request-id:{request_id};ts:{ts};" - Calcular HMAC-SHA256 del manifest con el webhook_secret
- Comparar hash calculado con hash recibido
Retorna: true si es válido, false si es fraudulento.
Método: getPaymentStatus()
Propósito: Consultar estado actual de un pago en MercadoPago.
Entrada: external_id (ID de MercadoPago)
Proceso:
- Consultar API de MercadoPago con el payment_id
- Mapear estado de MercadoPago a estado del sistema
Mapeo de estados:
approved→approvedrejected→rejectedrefunded→refunded- Otros →
pending
Flujo Completo de Pago
1. Cliente selecciona facturas en frontend
↓
2. Frontend llama POST /portal/pagos/iniciar
↓
3. PaymentGatewayService → MercadoPagoAdapter::createPayment()
↓
4. MercadoPago API crea Preference y retorna init_point
↓
5. Backend retorna redirect_url al frontend
↓
6. Frontend redirige a MercadoPago Checkout
↓
7. Cliente completa pago en MercadoPago
↓
8. MercadoPago envía webhook a /portal/pagos/webhook
↓
9. Backend valida firma con validateWebhook()
↓
10. Backend procesa webhook con processWebhook()
↓
11. Si aprobado, PaymentGatewayService crea recibo en CtaCte
↓
12. Cliente es redirigido a /pagar/exitoConfigurar Webhook en MercadoPago
- Panel MercadoPago → Tus integraciones → Webhooks
- URL:
https://api.bautista.com/portal/pagos/webhook - Eventos a escuchar:
payment.createdpayment.updated
Importante: MercadoPago enviará el webhook cada vez que el estado del pago cambie.
Frontend Integration
Botón de pago:
- Usuario selecciona facturas
- Click en "Pagar Online"
- Frontend llama API
/portal/pagos/iniciar - API retorna
redirect_url - Frontend redirige con
window.location.href = redirect_url
URLs de retorno:
/pagar/exito- Pago aprobado/pagar/error- Pago rechazado/pagar/pendiente- Pago pendiente
Testing
Ambiente Sandbox
Usar Access Token de prueba en lugar del de producción.
Tarjetas de prueba de MercadoPago:
| Tarjeta | Número | Resultado |
|---|---|---|
| Visa | 4509 9535 6623 3704 | Aprobado |
| Mastercard | 5031 7557 3453 0604 | Rechazado |
CVV: 123 | Vencimiento: 11/25
Simular Webhook
Para probar el flujo de webhook localmente:
- Crear pago de prueba en MercadoPago
- Obtener
payment_id - Enviar POST a
/portal/pagos/webhookcon payload simulado - Verificar que el pago se procesa correctamente
Particularidades de MercadoPago
Validación de Firma HMAC-SHA256
MercadoPago usa un formato específico:
Manifest:
id:{request-id};request-id:{request-id};ts:{timestamp};Firma:
HMAC-SHA256(manifest, webhook_secret)El header x-signature viene con formato:
ts=1234567890,v1=abcdef1234567890Estados de Pago
| Status MercadoPago | Estado Sistema | Acción |
|---|---|---|
approved | approved | Acreditar en CtaCte |
rejected | rejected | Marcar como rechazado |
pending | pending | Esperar confirmación |
refunded | refunded | Revertir acreditación |
Timeout de Webhook
Crítico: MercadoPago espera respuesta en < 5 segundos.
Si el procesamiento es lento:
- Responder 200 OK inmediatamente
- Procesar webhook en background
URLs de Retorno
Después del pago, MercadoPago redirige al usuario a:
success: Pago aprobadofailure: Pago rechazadopending: Pago pendiente
Configurar con el dominio del tenant actual.
Monitoreo
Logs importantes:
- Inicio de pago con
preference_idy monto - Recepción de webhook con
payment_idy estado - Validación fallida de webhook (posible ataque)
- Errores de comunicación con API de MercadoPago
Recursos Oficiales
Implementar Otro Gateway
Para implementar otro gateway (PagoTIC, PagoMisCuentas, etc.):
- Crear adapter que implemente
PaymentGatewayInterface - Implementar los 4 métodos requeridos
- Agregar al Factory (
PaymentGatewayFactory) - Configurar credenciales por tenant
- Testing con sandbox del gateway
- Configurar webhooks
- Deploy a producción
Cada gateway tiene su propia forma de validar webhooks y estados de pago, pero la interfaz es la misma.