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
- Multi-merchant: Cada comercio usa sus propias credenciales
- Multi-gateway: Soporte para Openpay y Stripe
- 3D Secure: Manejo automático de autenticación 3DS
- Stateless: Sin sesiones ni CSRF para máxima compatibilidad
- API REST: Integración sencilla via JSON
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.
/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) |
X-API-Key: sk_test_demo_merchant_secret_key_67890
Inicio Rápido
Integra pagos en tu aplicación en 3 pasos:
POST /api/v1/payments con datos del pedido
Recibes:
checkout_url
Rediriges al cliente a
checkout_urlCliente completa pago en página segura del PSP
Redirige a tu
success_url o cancel_urlWebhook 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:
┌──────────┐ ┌──────────────┐ ┌─────────┐ ┌─────────────┐
│ 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)
Crea una nueva transacción y obtiene la URL de checkout. Esta llamada debe hacerse desde tu backend.
Ejemplo en 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
{
"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.
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:
https://mitienda.com/success.php?payment_id=PAY-ABC123&order_id=ORD-123&status=success
<?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
Crea una nueva transacción de pago.
Ver Paso 1: Crear Pago para detalles completos.
API: Consultar Pago
Obtiene el estado actual de una transacción.
Response
{
"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
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
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.
{
"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
payment.success- Pago completadopayment.failed- Pago rechazadopayment.refunded- Reembolso procesadopayment.expired- Sesión expirada
Verificar firma
$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 |
Base 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}