# RF-MGN-016-001: Integración MercadoPago

**Módulo:** MGN-016 - Integraciones de Pagos y POS
**Prioridad:** P1
**Story Points:** 13
**Estado:** Definido
**Fecha:** 2025-12-05

## Descripción

El sistema debe permitir a los tenants conectar su cuenta de MercadoPago para procesar pagos de sus clientes finales. Esto incluye pagos con tarjeta (presencial y online), pagos en efectivo (OXXO), transferencias SPEI, y el uso de terminales Point de MercadoPago.

## Actores

- **Actor Principal:** Tenant Admin (configura integración)
- **Actores Secundarios:**
  - Vendedor/Cajero (procesa pagos)
  - Cliente final (realiza pago)
  - MercadoPago API (procesa transacción)

## Precondiciones

1. Tenant debe tener suscripción activa con feature `mercadopago_enabled`
2. Tenant Admin debe tener credenciales de MercadoPago (o crearlas vía OAuth)
3. Cuenta MercadoPago debe estar verificada

## Flujo Principal - Configurar Integración

1. Tenant Admin accede a "Configuración > Integraciones > Pagos"
2. Sistema muestra proveedores disponibles
3. Admin selecciona "Conectar MercadoPago"
4. Sistema redirige a MercadoPago OAuth
5. Admin autoriza acceso a la aplicación
6. MercadoPago retorna `access_token` y `refresh_token`
7. Sistema almacena tokens encriptados
8. Sistema verifica conexión exitosa
9. Admin configura opciones adicionales (terminales, notificaciones)

## Flujo Alternativo - Procesar Pago con Terminal Point

1. Vendedor crea venta en sistema (o selecciona orden existente)
2. Vendedor selecciona "Cobrar con MercadoPago"
3. Sistema crea Payment Intent via API
4. Sistema envía intent a terminal Point vinculada
5. Cliente presenta tarjeta/NFC en terminal
6. Terminal procesa y envía resultado a MercadoPago
7. MercadoPago envía webhook con confirmación
8. Sistema actualiza estado de pago
9. Sistema genera recibo

## Flujo Alternativo - Pago con OXXO

1. Vendedor crea cobro con método "OXXO"
2. Sistema genera referencia de pago via API
3. Sistema muestra/imprime ficha de pago con:
   - Referencia OXXO
   - Monto
   - Fecha de vencimiento
4. Cliente paga en tienda OXXO
5. MercadoPago envía webhook de confirmación (24-48h)
6. Sistema actualiza estado de pago

## Métodos de Pago Soportados

| Método | Tipo | Comisión | Tiempo de Acreditación |
|--------|------|----------|------------------------|
| Tarjeta Crédito (presencial) | card_present | 3.49% + IVA | Inmediato |
| Tarjeta Débito (presencial) | card_present | 2.49% + IVA | Inmediato |
| Tarjeta Online | card_not_present | 3.49% + IVA | Inmediato |
| OXXO | ticket | $10 MXN + IVA | 24-48h |
| SPEI | bank_transfer | $7 MXN + IVA | Inmediato |
| Mercado Crédito | credit | 4.99% + IVA | Inmediato |

## Reglas de Negocio

- **RN-1:** Tokens OAuth se refrescan automáticamente antes de expirar
- **RN-2:** Pagos fallidos se reintentan hasta 3 veces
- **RN-3:** Webhooks deben validar firma HMAC
- **RN-4:** Montos se expresan en centavos (int) para la API
- **RN-5:** IPN URL debe ser HTTPS con certificado válido
- **RN-6:** Reembolsos solo hasta 180 días después del pago
- **RN-7:** Un tenant puede tener múltiples terminales Point

## Criterios de Aceptación

- [ ] Tenant Admin puede conectar cuenta MercadoPago vía OAuth
- [ ] Sistema almacena tokens de forma segura (encriptados)
- [ ] Sistema refresca tokens automáticamente
- [ ] Vendedor puede procesar pago con tarjeta presencial
- [ ] Vendedor puede generar ficha de pago OXXO
- [ ] Sistema recibe y procesa webhooks correctamente
- [ ] Dashboard muestra transacciones de MercadoPago
- [ ] Admin puede desconectar integración
- [ ] Logs de todas las transacciones disponibles

## Entidades Involucradas

### integrations.payment_providers

```sql
CREATE TABLE integrations.payment_providers (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES core_tenants.tenants(id),
    provider_code VARCHAR(50) NOT NULL, -- 'mercadopago', 'clip', 'stripe'
    display_name VARCHAR(100),
    is_active BOOLEAN DEFAULT true,
    is_default BOOLEAN DEFAULT false,
    config JSONB DEFAULT '{}', -- Configuración específica
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT uq_provider_tenant UNIQUE (tenant_id, provider_code)
);
```

### integrations.payment_credentials

```sql
CREATE TABLE integrations.payment_credentials (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    provider_id UUID NOT NULL REFERENCES integrations.payment_providers(id),
    credential_type VARCHAR(50) NOT NULL, -- 'oauth', 'api_key'
    -- Todos los campos sensibles encriptados con AES-256
    access_token_encrypted BYTEA,
    refresh_token_encrypted BYTEA,
    expires_at TIMESTAMPTZ,
    merchant_id VARCHAR(100), -- ID de cuenta en MercadoPago
    environment VARCHAR(20) DEFAULT 'sandbox', -- 'sandbox', 'production'
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
```

### integrations.payment_transactions

```sql
CREATE TABLE integrations.payment_transactions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,
    provider_id UUID NOT NULL REFERENCES integrations.payment_providers(id),

    -- Referencias internas
    order_id UUID, -- Orden de venta relacionada
    invoice_id UUID, -- Factura relacionada

    -- Datos de MercadoPago
    external_id VARCHAR(100), -- ID en MercadoPago
    external_reference VARCHAR(100), -- Nuestra referencia enviada
    payment_type VARCHAR(50), -- card, ticket, bank_transfer
    payment_method VARCHAR(50), -- visa, mastercard, oxxo, spei

    -- Montos
    amount DECIMAL(15,2) NOT NULL,
    currency VARCHAR(3) DEFAULT 'MXN',
    fee_amount DECIMAL(15,2), -- Comisión cobrada
    net_amount DECIMAL(15,2), -- Monto neto recibido

    -- Estado
    status VARCHAR(50) NOT NULL, -- pending, approved, rejected, refunded
    status_detail VARCHAR(100),

    -- Tarjeta (si aplica)
    card_last_four VARCHAR(4),
    card_brand VARCHAR(20),

    -- Terminal (si aplica)
    terminal_id UUID REFERENCES integrations.payment_terminals(id),

    -- Timestamps
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    approved_at TIMESTAMPTZ,

    -- Metadata
    raw_response JSONB, -- Respuesta completa de la API

    CONSTRAINT chk_status CHECK (status IN ('pending', 'approved', 'rejected', 'cancelled', 'refunded', 'in_process'))
);
```

## API de MercadoPago

### Crear Payment Intent

```typescript
// POST https://api.mercadopago.com/v1/payments
const paymentData = {
  transaction_amount: 1500.00,
  description: "Venta #ORD-2025-001",
  payment_method_id: "visa",
  payer: {
    email: "cliente@email.com"
  },
  external_reference: "ORD-2025-001",
  notification_url: "https://erp.example.com/webhooks/mercadopago",
  metadata: {
    tenant_id: "uuid-tenant",
    order_id: "uuid-order"
  }
};
```

### Procesar Webhook

```typescript
// POST /webhooks/mercadopago
interface MercadoPagoWebhook {
  id: string;
  type: 'payment' | 'merchant_order';
  action: 'payment.created' | 'payment.updated';
  data: {
    id: string; // Payment ID
  };
}

// Validar firma
const isValid = validateMercadoPagoSignature(
  request.headers['x-signature'],
  request.body,
  webhookSecret
);
```

## Terminales Point

### Modelos Soportados

| Modelo | Conectividad | Características |
|--------|--------------|-----------------|
| Point Smart | WiFi, 4G | Pantalla táctil, impresora |
| Point Pro 2 | Bluetooth | Portable, NFC |
| Point Mini | Bluetooth | Básico, económico |

### Vincular Terminal

```typescript
// POST /api/v1/integrations/mercadopago/terminals
{
  serialNumber: "MP-123456789",
  displayName: "Caja 1",
  locationId: "uuid-sucursal"
}
```

## Seguridad

1. **OAuth Tokens:** Encriptados con AES-256-GCM
2. **Webhook Signature:** HMAC-SHA256 validation
3. **HTTPS:** Obligatorio para todos los endpoints
4. **Rate Limiting:** Respeto de límites de API
5. **Audit Log:** Todas las transacciones logueadas

## Manejo de Errores

| Código | Descripción | Acción |
|--------|-------------|--------|
| `cc_rejected_insufficient_amount` | Fondos insuficientes | Notificar, solicitar otro método |
| `cc_rejected_bad_filled_card_number` | Número inválido | Solicitar re-ingreso |
| `cc_rejected_call_for_authorize` | Llamar al banco | Contactar emisor |
| `pending_contingency` | En revisión | Esperar webhook |

## Referencias

- [MercadoPago Developers](https://www.mercadopago.com.mx/developers)
- [API Reference](https://www.mercadopago.com.mx/developers/es/reference)
- [Point Integrations](https://www.mercadopago.com.mx/developers/es/docs/mp-point/landing)

## Dependencias

- **RF Requeridos:** Ninguno (módulo base)
- **Bloqueante para:** RF-MGN-016-004 (Gestión de Terminales), RF-MGN-016-005 (Conciliación)
