Skip to content

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

  1. Registrarse en MercadoPago
  2. Ir a Tus integracionesCredentials
  3. 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-php

Variables de entorno:

  • MERCADOPAGO_ACCESS_TOKEN
  • MERCADOPAGO_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:

  1. Crear objeto Preference del SDK de MercadoPago
  2. Configurar item con título, cantidad y precio
  3. Configurar URLs de retorno (success, failure, pending)
  4. Configurar external_reference con nuestro payment_id
  5. Guardar preferencia en MercadoPago
  6. Retornar preference_id y init_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:

  1. Verificar que el tipo es "payment"
  2. Obtener payment_id del payload
  3. Consultar API de MercadoPago para obtener detalles del pago
  4. Extraer estado, monto, fecha, tipo de pago
  5. 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:

  1. Extraer headers x-signature y x-request-id
  2. Parsear signature para obtener ts (timestamp) y v1 (hash)
  3. Construir manifest: "id:{request_id};request-id:{request_id};ts:{ts};"
  4. Calcular HMAC-SHA256 del manifest con el webhook_secret
  5. 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:

  1. Consultar API de MercadoPago con el payment_id
  2. Mapear estado de MercadoPago a estado del sistema

Mapeo de estados:

  • approvedapproved
  • rejectedrejected
  • refundedrefunded
  • 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/exito

Configurar Webhook en MercadoPago

  1. Panel MercadoPagoTus integracionesWebhooks
  2. URL: https://api.bautista.com/portal/pagos/webhook
  3. Eventos a escuchar:
    • payment.created
    • payment.updated

Importante: MercadoPago enviará el webhook cada vez que el estado del pago cambie.

Frontend Integration

Botón de pago:

  1. Usuario selecciona facturas
  2. Click en "Pagar Online"
  3. Frontend llama API /portal/pagos/iniciar
  4. API retorna redirect_url
  5. 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:

TarjetaNúmeroResultado
Visa4509 9535 6623 3704Aprobado
Mastercard5031 7557 3453 0604Rechazado

CVV: 123 | Vencimiento: 11/25

Simular Webhook

Para probar el flujo de webhook localmente:

  1. Crear pago de prueba en MercadoPago
  2. Obtener payment_id
  3. Enviar POST a /portal/pagos/webhook con payload simulado
  4. 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=abcdef1234567890

Estados de Pago

Status MercadoPagoEstado SistemaAcción
approvedapprovedAcreditar en CtaCte
rejectedrejectedMarcar como rechazado
pendingpendingEsperar confirmación
refundedrefundedRevertir acreditación

Timeout de Webhook

Crítico: MercadoPago espera respuesta en < 5 segundos.

Si el procesamiento es lento:

  1. Responder 200 OK inmediatamente
  2. Procesar webhook en background

URLs de Retorno

Después del pago, MercadoPago redirige al usuario a:

  • success: Pago aprobado
  • failure: Pago rechazado
  • pending: Pago pendiente

Configurar con el dominio del tenant actual.

Monitoreo

Logs importantes:

  • Inicio de pago con preference_id y monto
  • Recepción de webhook con payment_id y 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.):

  1. Crear adapter que implemente PaymentGatewayInterface
  2. Implementar los 4 métodos requeridos
  3. Agregar al Factory (PaymentGatewayFactory)
  4. Configurar credenciales por tenant
  5. Testing con sandbox del gateway
  6. Configurar webhooks
  7. Deploy a producción

Cada gateway tiene su propia forma de validar webhooks y estados de pago, pero la interfaz es la misma.