📋 Introducción
API REST para procesar pagos de tickets de autobús mediante ePayco. Implementa estándares bancarios de seguridad.
Características
- ✅ Cifrado AES-256-GCM
- ✅ Autenticación API Key + HMAC
- ✅ Rate Limiting Anti-DDoS
- ✅ Protección SQL Injection/XSS
- ✅ Webhooks para notificaciones
- ✅ Auditoría completa
URLs Base
| Entorno | URL |
|---|---|
| Producción | https://api.transportessuroeste.com |
| Sandbox | https://sandbox.transportessuroeste.com |
🔐 Autenticación
Incluir estos headers en cada petición:
| Header | Descripción | Requerido |
|---|---|---|
X-API-Key | API Key proporcionada | ✅ Sí |
X-Timestamp | Unix timestamp actual | ⚠️ Recomendado |
X-Signature | Firma HMAC-SHA512 | ⚠️ Recomendado |
Generar Firma
// PHP
$dataToSign = "{$method}\n{$uri}\n{$timestamp}\n{$body}";
$signature = hash_hmac('sha512', $dataToSign, $apiSecret);
📡 Endpoints
POST
/api/v1/payments - Crear transacción
// Request
{
"ticket_reference": "TK-2024-001234",
"amount": 45000,
"description": "Ticket Medellín-Bogotá | Asiento 12A",
"payer_email": "cliente@email.com",
"payer_name": "Juan Pérez",
"payer_document_type": "CC",
"payer_document": "1234567890",
"extra_data": { "route": "MDE-BOG", "seat": "12A" }
}
// Response 201
{
"success": true,
"data": {
"transaction_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"internal_reference": "TS20241215A1B2C3D4",
"status": "pending",
"payment_url": "https://api.../payment/f47ac10b..."
}
}
Parámetros
| Campo | Tipo | Descripción |
|---|---|---|
| ticket_reference | string | Referencia única del ticket (máx 100) |
| amount | integer | Monto en COP (sin decimales) |
| payer_email | string | Email del pagador |
| payer_name | string | Nombre completo |
| payer_document_type | string | CC, CE, NIT, PP, TI |
| payer_document | string | Número de documento |
GET
/api/v1/payments/{uuid} - Consultar transacción
GET
/api/v1/payments/ticket/{reference} - Consultar por ticket
GET
/api/v1/health - Health check (sin auth)
🔗 Guía de Integración
Ejemplo Completo PHP
<?php
$apiUrl = 'https://api.transportessuroeste.com';
$apiKey = 'ts_live_xxxxxxxx';
$apiSecret = 'your_secret';
function createPayment($ticket) {
global $apiUrl, $apiKey, $apiSecret;
$body = json_encode([
'ticket_reference' => $ticket['id'],
'amount' => $ticket['price'],
'description' => "Ticket {$ticket['route']}",
'payer_email' => $ticket['email'],
'payer_name' => $ticket['name'],
'payer_document_type' => 'CC',
'payer_document' => $ticket['document']
]);
$timestamp = time();
$signature = hash_hmac('sha512', "POST\n/api/v1/payments\n{$timestamp}\n{$body}", $apiSecret);
$ch = curl_init($apiUrl . '/api/v1/payments');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-API-Key: ' . $apiKey,
'X-Timestamp: ' . $timestamp,
'X-Signature: ' . $signature
]
]);
return json_decode(curl_exec($ch), true);
}
// Uso
$result = createPayment([
'id' => 'TK-001', 'price' => 45000, 'route' => 'MDE-BOG',
'email' => 'cliente@mail.com', 'name' => 'Juan', 'document' => '123456'
]);
header('Location: ' . $result['data']['payment_url']);
Webhook de Notificación
<?php // webhook.php
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
if (!hash_equals(hash_hmac('sha512', $payload, $webhookSecret), $signature)) {
http_response_code(401); exit;
}
$data = json_decode($payload, true);
if ($data['status'] === 'approved') {
markTicketAsPaid($data['ticket_reference']);
}
http_response_code(200);
🛡️ Seguridad
Estándares: PCI-DSS, ISO 27001, OWASP Top 10
| Amenaza | Protección |
|---|---|
| SQL Injection | Prepared Statements PDO |
| XSS | Sanitización + CSP Headers |
| DDoS | Rate Limit 100 req/min + Bloqueo automático |
| MITM | TLS 1.3 + HSTS |
| Data Breach | AES-256-GCM para datos sensibles |
⚠️ Códigos de Error
| Código | Tipo | Descripción |
|---|---|---|
| 400 | Bad Request | Petición malformada |
| 401 | Unauthorized | API Key inválida |
| 403 | Forbidden | IP no autorizada |
| 404 | Not Found | Recurso no encontrado |
| 422 | Validation Error | Datos inválidos |
| 429 | Rate Limited | Límite excedido |
| 500 | Server Error | Error interno |
🗄️ Base de Datos
Tablas Principales
- api_clients - Clientes autorizados
- transactions - Transacciones de pago
- transaction_status_history - Historial de estados
- audit_trail - Auditoría del sistema
- security_events - Eventos de seguridad
- rate_limit_tracking - Control anti-DDoS
- webhook_deliveries - Entregas de webhooks
Ver archivo sql/database.sql para el esquema completo.
⚙️ Instalación
Requisitos
- PHP 8.1+ con extensiones: pdo_mysql, openssl, mbstring, curl, json
- MySQL 8.0+ o MariaDB 10.5+
- Composer 2.0+
- Apache 2.4+ o Nginx 1.18+
Pasos de Instalación
# 1. Instalar PHP y extensiones (Ubuntu)
sudo apt install php8.1 php8.1-mysql php8.1-curl php8.1-mbstring php8.1-xml
# 2. Instalar Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
# 3. Clonar e instalar
cd /var/www
git clone [repo] payment-gateway && cd payment-gateway
composer install --no-dev
# 4. Configurar
cp config/.env.example config/.env
nano config/.env # Editar credenciales ePayco
# 5. Base de datos
mysql -u root -p < sql/database.sql
# 6. Permisos
chmod 755 logs && chmod 644 config/.env
# 7. Probar
php -S localhost:8000 -t public
⚠️ Producción: Usar HTTPS, credenciales reales de ePayco, claves únicas de cifrado, backups automáticos.