PSP Gateway - API Documentation

Plataforma multi-merchant para procesar pagos con Openpay y Stripe. Compatible con el flujo de Vivenu para máxima reutilización de código.

Introducción

PSP Gateway es una pasarela de pagos que permite a múltiples comercios procesar transacciones usando sus propias credenciales de Openpay o Stripe. El sistema está diseñado para ser compatible con integraciones existentes de Vivenu.

Características principales

Arquitectura

El PSP actúa como intermediario entre tu comercio y los procesadores de pago. El flujo es similar al de Stripe Checkout o PayPal: creas un pago via API, rediriges al cliente a nuestra página de checkout, y recibes una notificación cuando el pago se completa.

Compatibilidad con Vivenu Este PSP es un fork de vivenu-own-payment y mantiene compatibilidad con sus endpoints legacy (/api/pay, /api/pay/process, etc.) mientras añade la nueva API multi-merchant (/api/v1/payments).

Autenticación

La API usa dos tipos de claves. Es importante usar la correcta según el contexto:

Tipo Formato Uso
Secret Key sk_test_* / sk_live_* Llamadas backend-to-backend (crear pagos, consultas)
Public Key pk_test_* / pk_live_* Solo para inicializar SDKs en frontend (Openpay.js)
⚠️ Seguridad importante La Secret Key debe usarse SOLO en tu backend. Nunca la expongas en HTML, JavaScript o código cliente. Las llamadas a la API para crear pagos SIEMPRE deben hacerse desde tu servidor.
Header de autenticación
X-API-Key: sk_test_demo_merchant_secret_key_67890

Inicio Rápido

Integra pagos en tu aplicación en 3 pasos:

1
Tu Backend → PSP API
POST /api/v1/payments con datos del pedido
Recibes: checkout_url
2
Tu Frontend → PSP Checkout
Rediriges al cliente a checkout_url
Cliente completa pago en página segura del PSP
3
PSP → Tu sitio
Redirige a tu success_url o cancel_url
Webhook notifica el resultado (opcional)

Flujo Completo de Pago

Este es el flujo detallado de una transacción, similar al patrón usado por Stripe Checkout y compatible con Vivenu:

Diagrama de secuencia
┌──────────┐       ┌──────────────┐       ┌─────────┐       ┌─────────────┐
│ Cliente  │       │  Tu Backend  │       │   PSP   │       │ Openpay/    │
│ (Browser)│       │  (tu server) │       │ Gateway │       │ Stripe      │
└────┬─────┘       └──────┬───────┘       └────┬────┘       └──────┬──────┘
     │                    │                    │                   │
     │ 1. Checkout        │                    │                   │
     │───────────────────>│                    │                   │
     │                    │                    │                   │
     │                    │ 2. POST /payments  │                   │
     │                    │ (X-API-Key: sk_*)  │                   │
     │                    │───────────────────>│                   │
     │                    │                    │                   │
     │                    │ 3. {checkout_url}  │                   │
     │                    │<───────────────────│                   │
     │                    │                    │                   │
     │ 4. Redirect 302    │                    │                   │
     │<───────────────────│                    │                   │
     │                    │                    │                   │
     │ 5. GET checkout_url│                    │                   │
     │────────────────────────────────────────>│                   │
     │                    │                    │                   │
     │ 6. Formulario pago │                    │                   │
     │<────────────────────────────────────────│                   │
     │                    │                    │                   │
     │ 7. Datos tarjeta   │                    │                   │
     │────────────────────────────────────────>│                   │
     │                    │                    │                   │
     │                    │                    │ 8. Procesar pago  │
     │                    │                    │──────────────────>│
     │                    │                    │                   │
     │                    │                    │ 9. Resultado      │
     │                    │                    │<──────────────────│
     │                    │                    │                   │
     │ 10. Redirect success_url               │                   │
     │<────────────────────────────────────────│                   │
     │                    │                    │                   │
     │                    │ 11. Webhook (async)│                   │
     │                    │<───────────────────│                   │
     │                    │                    │                   │

Paso 1: Crear Pago (Backend)

POST /api/v1/payments

Crea una nueva transacción y obtiene la URL de checkout. Esta llamada debe hacerse desde tu backend.

Ejemplo en PHP

PHP
<?php
// Configuración (en producción usar variables de entorno)
$PSP_URL = 'https://gateway-own-payment:8891';
$PSP_SECRET_KEY = 'sk_test_demo_merchant_secret_key_67890';

// Datos del pedido (del carrito del cliente)
$paymentData = [
    'order_id' => 'ORD-' . time(),
    'amount' => 29900,  // En centavos ($299.00)
    'currency' => 'MXN',
    'description' => 'Compra en mi tienda',
    'customer' => [
        'name' => $_POST['customer_name'],
        'email' => $_POST['customer_email']
    ],
    'items' => [
        ['name' => 'Producto 1', 'price' => 29900, 'quantity' => 1]
    ],
    'success_url' => 'https://mitienda.com/success.php',
    'cancel_url' => 'https://mitienda.com/cancel.php'
];

// Llamada a la API del PSP
$ch = curl_init($PSP_URL . '/api/v1/payments');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($paymentData),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-API-Key: ' . $PSP_SECRET_KEY  // Secret key en backend
    ]
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

// Redirigir al checkout del PSP
if ($response['success'] && isset($response['checkout_url'])) {
    header('Location: ' . $response['checkout_url']);
    exit;
} else {
    // Manejar error
    echo "Error: " . ($response['message'] ?? 'Unknown error');
}

Parámetros del Request

Parámetro Tipo Descripción
order_id requerido string ID único del pedido en tu sistema (max 100 chars)
amount requerido integer Monto en centavos (29900 = $299.00). Mínimo 100.
currency opcional string Código ISO 4217: MXN, USD, EUR. Default: MXN
description opcional string Descripción del pago (aparece en estado de cuenta)
customer.name requerido string Nombre completo del cliente
customer.email requerido string Email del cliente (para notificaciones)
items opcional array Lista de productos [{name, price, quantity}]
success_url opcional string URL de redirección tras pago exitoso
cancel_url opcional string URL de redirección si se cancela
webhook_url opcional string URL para notificaciones asíncronas
metadata opcional object Datos adicionales que se devuelven en webhooks

Response

JSON - 201 Created
{
  "success": true,
  "payment_id": "PAY-ABC123XYZ789",
  "order_id": "ORD-1706389200",
  "checkout_url": "https://gateway-own-payment:8891/api/checkout/PAY-ABC123XYZ789",
  "amount": 29900,
  "currency": "MXN",
  "status": "pending",
  "expires_at": "2026-01-28T21:00:00+00:00"
}

Paso 2: Redirigir al Checkout

Una vez que recibes checkout_url, redirige al cliente a esa URL. El PSP mostrará un formulario de pago seguro donde el cliente ingresa los datos de su tarjeta.

✓ Seguridad Los datos de tarjeta nunca pasan por tu servidor. El cliente los ingresa directamente en el checkout del PSP, que los tokeniza con Openpay/Stripe.

Paso 3: Callback y Verificación

Después del pago, el PSP redirige al cliente a tu success_url o cancel_url con parámetros adicionales:

URL de redirección exitosa
https://mitienda.com/success.php?payment_id=PAY-ABC123&order_id=ORD-123&status=success
⚠️ Siempre verifica el estado No confíes solo en los parámetros de la URL. Siempre consulta la API para verificar el estado real del pago antes de entregar el producto.
PHP - Verificar pago
<?php
// success.php
$paymentId = $_GET['payment_id'] ?? '';

// Verificar estado real via API
$ch = curl_init($PSP_URL . '/api/v1/payments/' . $paymentId);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['X-API-Key: ' . $PSP_SECRET_KEY]
]);
$payment = json_decode(curl_exec($ch), true);

if ($payment['status'] === 'success') {
    // Pago confirmado - entregar producto
    echo "¡Gracias por tu compra!";
} else {
    // Estado inesperado - investigar
    echo "Estado del pago: " . $payment['status'];
}

API: Crear Pago

POST /api/v1/payments

Crea una nueva transacción de pago.

Ver Paso 1: Crear Pago para detalles completos.

API: Consultar Pago

GET /api/v1/payments/{payment_id}

Obtiene el estado actual de una transacción.

Response

JSON
{
  "payment_id": "PAY-ABC123XYZ789",
  "order_id": "ORD-1706389200",
  "status": "success",
  "amount": 29900,
  "currency": "MXN",
  "customer": {
    "name": "Juan Pérez",
    "email": "juan@email.com"
  },
  "gateway": "openpay",
  "gateway_reference": "trzx_abc123xyz",
  "created_at": "2026-01-27T21:00:00+00:00",
  "completed_at": "2026-01-27T21:02:30+00:00",
  "metadata": {}
}

Estados posibles

Estado Descripción
pending Pago creado, esperando que el cliente complete
processing Pago en proceso con el gateway
pending_3ds Esperando verificación 3D Secure
success Pago completado exitosamente
failed Pago rechazado o fallido
cancelled Pago cancelado por el cliente
refunded Pago reembolsado

API: Listar Pagos

GET /api/v1/payments

Lista las transacciones del merchant con filtros opcionales.

Query Parameters

Parámetro Tipo Descripción
status string Filtrar por estado
from datetime Fecha de inicio (ISO 8601)
to datetime Fecha de fin (ISO 8601)
per_page integer Resultados por página (default: 20, max: 100)

API: Reembolsar

POST /api/v1/payments/{payment_id}/refund

Procesa un reembolso total.

Tarjetas de Prueba

En modo sandbox (sk_test_*), usa estas tarjetas para probar:

✓ Tarjetas que aprueban

Marca Número Resultado
Visa 4111 1111 1111 1111 Aprobada
Mastercard 5555 5555 5555 4444 Aprobada
Amex 3782 822463 10005 Aprobada

✗ Tarjetas que rechazan

Número Error
4000 0000 0000 0002 Fondos insuficientes
4000 0000 0000 0069 Tarjeta expirada
4000 0000 0000 0127 CVV incorrecto
4000 0000 0000 0119 Error de procesamiento

CVV: Cualquier 3 dígitos (4 para Amex)
Fecha: Cualquier fecha futura (ej: 12/28)

Webhooks

Los webhooks notifican cambios de estado en tiempo real. Configura tu webhook_url al crear el pago.

JSON - Webhook payload
{
  "event": "payment.success",
  "payment_id": "PAY-ABC123XYZ789",
  "order_id": "ORD-1706389200",
  "status": "success",
  "amount": 29900,
  "currency": "MXN",
  "gateway": "openpay",
  "gateway_reference": "trzx_abc123",
  "timestamp": "2026-01-27T21:02:30+00:00",
  "signature": "sha256=a1b2c3d4..."
}

Eventos

Verificar firma

PHP
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_PSP_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $payload, $PSP_SECRET_KEY);

if (hash_equals($expected, $signature)) {
    // Firma válida - procesar webhook
} else {
    // Firma inválida - rechazar
    http_response_code(401);
}

Compatibilidad con Vivenu

Este PSP mantiene compatibilidad con los endpoints legacy de Vivenu para facilitar migraciones y permitir que ambos sistemas coexistan:

Endpoint Legacy (Vivenu) Nuevo Endpoint Notas
/api/pay?paymentId=X - Sigue funcionando para integraciones Vivenu existentes
/api/pay/process - Procesa pagos iniciados desde Vivenu
/api/pay/3ds-callback - Callback de 3D Secure (Openpay)
- /api/v1/payments Nueva API multi-merchant
- /api/checkout/{id} Página de checkout para pagos de la nueva API
Migración gradual Puedes usar ambas APIs simultáneamente. Los endpoints legacy usan la configuración global de Openpay, mientras que la nueva API permite credenciales por merchant.

Base URLs

URLs
# Nueva API Multi-Merchant
https://gateway-own-payment:8891/api/v1/payments

# Checkout (después de crear pago)
https://gateway-own-payment:8891/api/checkout/{payment_id}

# Legacy Vivenu (compatibilidad)
https://gateway-own-payment:8891/api/pay?paymentId={vivenu_payment_id}