/home/suroeste/public_html/payments.transportessuroeste.com/docs
Edit: /home/suroeste/public_html/payments.transportessuroeste.com/docs/DOCUMENTACION_FUNCIONAL.md (34232B)
# Transportes Suroeste - Documentacion Funcional
## 1. Informacion General
| Campo | Valor |
|-------|-------|
| **Sistema** | Transportes Suroeste - API Pasarela de Pagos |
| **Version** | 1.0.0 |
| **Ultima actualizacion** | 2026-02-02 |
| **Licencia** | Propietaria |
| **Estandares** | PCI-DSS, ISO 27001, OWASP Top 10 |
### Stack Tecnologico
| Componente | Tecnologia | Version |
|-----------|-----------|---------|
| Lenguaje | PHP | 8.1+ |
| Base de datos | MySQL / MariaDB | 8.0+ / 10.5+ |
| Servidor web | Nginx | 1.25 |
| Contenedores | Docker + Docker Compose | 24+ |
| Pasarela de pagos | ePayco Smart Checkout v2 | SDK 1.9+ |
| Cifrado | AES-256-GCM + HMAC-SHA512 | OpenSSL |
| Cache / Rate Limiting / Sesiones | Redis | 7 |
---
## 2. Arquitectura del Sistema
### 2.1 Diagrama de Componentes
```mermaid
graph TB
subgraph "Cliente Externo"
A[Sistema de Tickets]
B[Navegador del Pagador]
end
subgraph "Capa de Red"
C[Nginx Reverse Proxy
Rate Limiting + Security Headers]
end
subgraph "Capa de Aplicacion"
D[PHP-FPM]
subgraph "Middleware Pipeline"
E[SecurityMiddleware]
F[RateLimiter]
G[AuthMiddleware]
end
subgraph "Core"
H[Router]
I[ApiController]
end
subgraph "Servicios"
J[PaymentService]
K[EncryptionService]
L[LogService]
R[ClientDatabaseService]
end
M[Validator]
end
subgraph "Capa de Datos"
N[(MySQL
12 tablas)]
O[(Redis
Cache)]
end
subgraph "Servicios Externos"
P[ePayco API
Smart Checkout v2]
Q[Banco]
end
A -->|API REST| C
B -->|HTTPS| C
C --> D
D --> E --> F --> G --> H --> I
I --> J
I --> M
J --> K
J --> L
J --> N
J --> P
J --> R
P --> Q
R --> S[(BD Cliente
reservas_clientes)]
L --> N
F --> N
```
### 2.2 Estructura de Directorios
```
transportes-suroeste/
├── config/ # Configuracion de la aplicacion
│ ├── .env # Variables de entorno (no versionado)
│ ├── .env.example # Template de variables
│ └── config.php # Configuracion principal PHP
├── docker/ # Configuracion Docker
│ ├── nginx/ # Nginx reverse proxy
│ │ ├── nginx.conf # Configuracion global
│ │ └── sites/default.conf # Configuracion del sitio
│ ├── php/ # PHP-FPM
│ │ ├── Dockerfile # Imagen PHP multi-stage
│ │ ├── php.ini # Configuracion PHP produccion
│ │ └── php-fpm.conf # Pool configuration
│ └── mysql/
│ └── my.cnf # Configuracion MySQL
├── public/ # Document root (accesible via web)
│ ├── index.php # Front controller / API entry point
│ ├── assets/css/ # Estilos para paginas de pago
│ └── payment/ # Paginas de checkout y respuesta
│ ├── checkout.php # Pagina de pago ePayco
│ └── response.php # Pagina de resultado
├── src/ # Codigo fuente PSR-4
│ ├── Controllers/ # Controladores de la API
│ ├── Models/ # Capa de acceso a datos
│ ├── Services/ # Logica de negocio
│ ├── Middleware/ # Pipeline de seguridad
│ ├── Validators/ # Validacion de entrada
│ ├── Exceptions/ # Excepciones personalizadas
│ └── Utils/ # Router, JsonResponse
├── sql/ # Scripts de base de datos
│ └── database.sql # Esquema completo (12 tablas)
├── docs/ # Documentacion
├── logs/ # Logs de aplicacion
├── scripts/ # Scripts de operaciones
├── vendor/ # Dependencias (Composer)
├── docker-compose.yml # Configuracion base Docker
├── docker-compose.override.yml # Overrides desarrollo
├── docker-compose.prod.yml # Overrides produccion
├── Makefile # Comandos rapidos
└── .env.example # Template variables Docker
```
### 2.3 Flujo de Datos
```mermaid
sequenceDiagram
participant ST as Sistema Tickets
participant API as API Gateway
participant EP as ePayco
participant BD as MySQL
participant WH as Webhook
ST->>API: POST /api/v1/payments
Note over API: Validar API Key + HMAC
Note over API: Sanitizar + Validar datos
Note over API: Cifrar datos sensibles (AES-256-GCM)
API->>EP: Login Apify (Basic Auth)
EP-->>API: Bearer Token
API->>EP: Crear sesion Smart Checkout
EP-->>API: sessionId
API->>BD: INSERT transactions (status=pending)
API-->>ST: {transaction_uuid, payment_url}
Note over ST: Usuario redirigido a payment_url
ST->>API: GET /payment/checkout?sessionId=xxx
Note over API: Renderizar pagina con ePayco JS SDK
API->>EP: checkout.open() (iframe)
Note over EP: Proceso de pago (tarjeta/PSE/etc)
EP->>API: POST /api/v1/webhook/epayco
Note over API: Validar firma SHA256
Note over API: Validar IP origen
API->>BD: UPDATE transactions SET status=approved
API->>BD: INSERT transaction_status_history
API->>WH: POST webhook_url del cliente
API-->>EP: HTTP 200 OK
```
---
## 3. Modulos Funcionales
### 3.1 Modulo de Pagos (PaymentService)
**Descripcion**: Gestiona el ciclo de vida completo de transacciones de pago de tickets de autobus via ePayco Smart Checkout v2.
**Casos de Uso**:
| UC | Descripcion | Actor |
|----|-------------|-------|
| UC1 | Crear Transaccion de Pago | Sistema de Tickets |
| UC2 | Consultar Estado por UUID | Sistema de Tickets |
| UC3 | Consultar Estado por Ticket | Sistema de Tickets |
| UC4 | Recibir Webhook ePayco | ePayco |
| UC5 | Health Check | Cualquiera |
| UC6 | Obtener Bancos PSE | Sistema de Tickets |
**Vistas involucradas**:
- `public/payment/checkout.php` - Pagina de checkout con ePayco Smart Checkout v2
- `public/payment/response.php` - Pagina de resultado del pago
**Reglas de Negocio**:
1. Monto minimo: $1,000 COP (10 COP en centavos segun config)
2. Monto maximo: $10,000,000 COP
3. Moneda: COP (pesos colombianos)
4. Timeout de transaccion: 300 segundos (5 minutos)
5. Tipos de documento aceptados: CC, CE, NIT, PP, TI
6. Email del pagador es obligatorio
7. Datos sensibles (email, documento, nombre) se cifran con AES-256-GCM antes de almacenarse
**Validaciones**:
- `ticket_reference`: requerido, max 100 caracteres
- `amount`: requerido, numerico, entre min y max
- `description`: requerido, max 500 caracteres
- `payer_email`: requerido, email valido
- `payer_name`: requerido
- `payer_document`: requerido
- `payer_document_type`: requerido, enum(CC,CE,NIT,PP,TI)
- `payer_phone`: opcional, entre 7 y 15 digitos
### 3.2 Modulo de Autenticacion (AuthMiddleware)
**Descripcion**: Valida credenciales API Key + HMAC-SHA512 para endpoints protegidos.
**Flujo de autenticacion**:
```mermaid
flowchart TD
A[Request entrante] --> B{API Key presente?}
B -->|No| C[401 API Key requerida]
B -->|Si| D{Timestamp valido?}
D -->|No| E[401 Timestamp invalido]
D -->|Si| F{API Key existe en BD?}
F -->|No| G[401 Credenciales invalidas]
F -->|Si| H{IP en whitelist?}
H -->|No| I[403 IP no autorizada]
H -->|Si| J{Firma HMAC valida?}
J -->|No| K[401 Firma invalida]
J -->|Si| L[Autenticado OK]
```
**Reglas**:
- API Key se envia via header `X-API-Key`
- Timestamp via `X-Timestamp` (max 5 minutos de diferencia)
- Firma HMAC-SHA512 via `X-Signature`
- Formula firma: `HMAC-SHA512("{METHOD}\n{URI}\n{TIMESTAMP}\n{BODY}", api_secret)`
- Timestamp y firma son recomendados pero no estrictamente requeridos (backward compatibility)
### 3.3 Modulo de Rate Limiting (RateLimiter)
**Descripcion**: Proteccion Anti-DDoS basada en IP con ventanas deslizantes.
**Backend de almacenamiento**:
- **Primario**: Redis (operaciones atomicas INCR con TTL, ~0.1ms por operacion)
- **Fallback**: MySQL (si Redis no esta disponible, usa tabla `rate_limit_tracking`)
- La deteccion es automatica al inicializar el middleware
**Configuracion por defecto**:
- 100 peticiones por ventana
- Ventana de 60 segundos
- Ban de 3600 segundos (1 hora) al exceder limite
**Flujo**:
```mermaid
flowchart TD
A[Request] --> B{IP bloqueada?}
B -->|Si| C[429 Too Many Requests]
B -->|No| D[Incrementar contador]
D --> E{Excede limite?}
E -->|No| F[Continuar request]
E -->|Si| G[Bloquear IP]
G --> C
```
### 3.4 Modulo de Seguridad (SecurityMiddleware)
**Descripcion**: Aplica headers de seguridad, detecta patrones de ataque (SQLi, XSS, path traversal), y bloquea bots maliciosos.
**Protecciones**:
1. Security Headers (X-Frame-Options, CSP, HSTS, etc.)
2. Deteccion de SQL Injection (patron regex)
3. Deteccion de XSS (script tags, event handlers)
4. Deteccion de bots maliciosos (sqlmap, nikto, nmap, etc.)
5. Proteccion Path Traversal
6. Validacion Content-Type para POST/PUT
7. Limite de tamanio de payload (1MB)
### 3.5 Modulo de Cifrado (EncryptionService)
**Descripcion**: Cifrado/descifrado de datos sensibles con estandares bancarios.
**Algoritmos**:
- Cifrado simetrico: AES-256-GCM (autenticado)
- Integridad adicional: HMAC-SHA512
- Hash de contrasenas: Argon2id
- UUIDs: CSPRNG (random_bytes)
**Formato de dato cifrado**:
```
base64(HMAC-SHA512(64 bytes) + IV(12 bytes) + GCM-TAG(16 bytes) + CIPHERTEXT)
```
### 3.6 Modulo de Logging (LogService)
**Descripcion**: Sistema de logging multi-canal con niveles.
**Canales**:
| Canal | Archivo | Contenido |
|-------|---------|-----------|
| transactions | transactions.log | Operaciones de pago |
| security | security.log | Eventos de seguridad |
| audit | audit.log | Auditoria de compliance |
| errors | errors.log | Errores del sistema |
| access | access.log | Acceso HTTP a la API |
**Niveles**: DEBUG (100), INFO (200), WARNING (300), ERROR (400), CRITICAL (500)
---
## 4. Modelo de Datos
### 4.1 Diagrama Entidad-Relacion
```mermaid
erDiagram
api_clients ||--o{ transactions : "1:N"
api_clients ||--o{ security_events : "1:N"
api_clients ||--o{ webhook_deliveries : "1:N"
api_clients ||--o{ daily_reconciliation : "1:N"
transactions ||--o{ transaction_status_history : "1:N"
transactions ||--o{ transaction_logs : "1:N"
transactions ||--o{ webhook_deliveries : "1:N"
transactions ||--o{ refunds : "1:N"
api_clients {
bigint id PK
char client_uuid UK
varchar client_name
varchar api_key UK
varchar api_secret_hash
varchar webhook_url
varchar webhook_secret
text allowed_ips
int rate_limit
tinyint is_active
varchar environment
datetime created_at
datetime updated_at
datetime last_access_at
}
transactions {
bigint id PK
char transaction_uuid UK
bigint client_id FK
varchar ticket_reference
varchar internal_reference UK
varchar epayco_ref
varchar epayco_transaction_id
decimal amount
char currency
decimal tax
decimal tax_base
varchar status
varchar status_code
varchar status_message
varchar payment_method
varchar payer_email
varchar payer_document_type
varchar payer_document
varchar payer_name
varchar description
varchar ip_address
varchar request_signature
text extra_data
datetime created_at
datetime processed_at
datetime expires_at
}
transaction_status_history {
bigint id PK
bigint transaction_id FK
varchar previous_status
varchar new_status
varchar status_code
varchar status_message
varchar changed_by
datetime created_at
}
transaction_logs {
bigint id PK
bigint transaction_id FK
char log_uuid UK
varchar log_type
varchar action
varchar endpoint
int http_status
text request_body
text response_body
int response_time_ms
datetime created_at
}
audit_trail {
bigint id PK
char audit_uuid UK
varchar entity_type
varchar entity_id
varchar action
varchar actor_type
varchar actor_ip
text old_values
text new_values
varchar risk_level
tinyint is_suspicious
datetime created_at
}
security_events {
bigint id PK
char event_uuid UK
varchar event_type
varchar severity
varchar source_ip
bigint client_id FK
text description
tinyint blocked
tinyint resolved
datetime created_at
}
rate_limit_tracking {
bigint id PK
varchar identifier
varchar identifier_type
varchar endpoint
int request_count
datetime window_start
datetime window_end
tinyint is_blocked
}
blocked_ips {
bigint id PK
varchar ip_address UK
varchar reason
tinyint is_permanent
datetime expires_at
}
webhook_deliveries {
bigint id PK
char delivery_uuid UK
bigint transaction_id FK
bigint client_id FK
varchar webhook_url
text payload
varchar signature
int http_status
tinyint attempt_number
varchar status
datetime delivered_at
}
refunds {
bigint id PK
char refund_uuid UK
bigint transaction_id FK
decimal amount
varchar reason
varchar status
varchar requested_by
datetime processed_at
}
daily_reconciliation {
bigint id PK
date reconciliation_date
bigint client_id FK
int total_transactions
int approved_count
decimal total_amount
decimal approved_amount
decimal net_amount
varchar status
}
system_config {
int id PK
varchar config_key UK
text config_value
varchar config_type
tinyint is_encrypted
}
```
### 4.2 Descripcion de Tablas
| Tabla | Registros esperados | Proposito |
|-------|-------------------|-----------|
| `api_clients` | Bajo (<100) | Clientes autorizados del API |
| `transactions` | Alto (miles/dia) | Transacciones de pago |
| `transaction_status_history` | Alto | Auditoria de cambios de estado |
| `transaction_logs` | Alto | Logs detallados de operaciones |
| `audit_trail` | Alto | Compliance bancario |
| `security_events` | Medio | Intentos de ataque, eventos de seguridad |
| `rate_limit_tracking` | Alto (rotativo) | Contadores de rate limiting |
| `blocked_ips` | Bajo | IPs baneadas |
| `webhook_deliveries` | Alto | Registro de webhooks enviados |
| `refunds` | Bajo | Reembolsos procesados |
| `daily_reconciliation` | Bajo (1/dia) | Conciliacion financiera |
| `system_config` | Bajo (<50) | Configuracion dinamica |
### 4.3 Estados de Transaccion
```mermaid
stateDiagram-v2
[*] --> pending: Crear pago
pending --> processing: Usuario inicia pago
pending --> expired: Timeout (5 min)
pending --> cancelled: Cancelado
processing --> approved: Pago exitoso
processing --> rejected: Pago rechazado
processing --> failed: Error en pago
approved --> refunded: Reembolso
approved --> [*]
rejected --> [*]
failed --> [*]
expired --> [*]
cancelled --> [*]
refunded --> [*]
```
---
## 5. API / Endpoints
### 5.1 Listado de Rutas
| Metodo | Endpoint | Auth | Descripcion |
|--------|----------|------|-------------|
| `POST` | `/api/v1/payments` | Si | Crear transaccion de pago |
| `GET` | `/api/v1/payments/{uuid}` | Si | Consultar por UUID |
| `GET` | `/api/v1/payments/ticket/{ref}` | Si | Consultar por referencia ticket |
| `GET` | `/api/v1/banks/pse` | No | Listar bancos PSE |
| `POST` | `/api/v1/webhook/epayco` | No | Webhook ePayco |
| `GET` | `/api/v1/callback` | No | Callback ePayco (GET) |
| `POST` | `/api/v1/callback` | No | Callback ePayco (POST) |
| `GET` | `/api/v1/health` | No | Health check |
### 5.2 POST /api/v1/payments
**Request**:
```json
{
"ticket_reference": "TK-2024-001234",
"amount": 45000,
"description": "Ticket Medellin-Bogota | Asiento 12A",
"payer_email": "cliente@email.com",
"payer_name": "Juan Perez",
"payer_document_type": "CC",
"payer_document": "1234567890",
"payer_phone": "3001234567",
"extra_data": {
"route": "MDE-BOG",
"seat": "12A"
}
}
```
**Headers requeridos**:
```
Content-Type: application/json
X-API-Key: ts_xxxxxxxxxxxx
X-Timestamp: 1704067200
X-Signature: hmac_sha512_signature
```
**Response 201**:
```json
{
"success": true,
"message": "Transaccion creada exitosamente",
"data": {
"transaction_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"internal_reference": "TS20241215A1B2C3D4",
"ticket_reference": "TK-2024-001234",
"amount": 45000,
"currency": "COP",
"status": "pending",
"payment_url": "https://api.../payment/checkout?sessionId=xxx&uuid=xxx",
"session_id": "abc123def456...",
"expires_at": "2024-12-15 10:05:00",
"created_at": "2024-12-15 10:00:00"
},
"meta": {
"timestamp": "2024-12-15T10:00:00.000000-05:00",
"request_id": "a1b2c3d4e5f6"
}
}
```
### 5.3 GET /api/v1/payments/{uuid}
**Response 200**:
```json
{
"success": true,
"message": "OK",
"data": {
"transaction_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"internal_reference": "TS20241215A1B2C3D4",
"ticket_reference": "TK-2024-001234",
"amount": 45000,
"currency": "COP",
"status": "approved",
"status_code": "1",
"status_message": "Aprobada",
"payment_method": "visa",
"epayco_ref": "12345678",
"created_at": "2024-12-15 10:00:00",
"processed_at": "2024-12-15 10:02:30"
}
}
```
### 5.4 GET /api/v1/health
**Response 200** (sin autenticacion):
```json
{
"success": true,
"data": {
"status": "healthy",
"service": "Transportes Suroeste - Payment Gateway",
"version": "1.0.0",
"timestamp": "2024-12-15 10:00:00",
"environment": "production"
}
}
```
### 5.5 Codigos de Error
| HTTP | Tipo | Descripcion |
|------|------|-------------|
| 400 | bad_request | Peticion malformada o datos invalidos |
| 401 | unauthorized | API Key invalida o firma incorrecta |
| 403 | forbidden | IP no autorizada o solicitud bloqueada |
| 404 | not_found | Recurso no encontrado |
| 405 | method_not_allowed | Metodo HTTP no soportado |
| 413 | payload_too_large | Body excede 1MB |
| 415 | unsupported_media_type | Content-Type no es application/json |
| 422 | validation_error | Datos no pasan validacion |
| 429 | rate_limit_exceeded | Limite de peticiones excedido |
| 500 | internal_error | Error interno del servidor |
**Formato de error**:
```json
{
"success": false,
"message": "Descripcion del error",
"error": {
"code": 422,
"type": "validation_error",
"details": {
"payer_email": "Email invalido",
"amount": "Monto minimo: $10"
}
},
"meta": {
"timestamp": "...",
"request_id": "..."
}
}
```
---
## 6. Roles y Permisos
### 6.1 Tipos de Actor
| Actor | Descripcion | Autenticacion |
|-------|-------------|---------------|
| Sistema de Tickets | Aplicacion externa que vende boletos | API Key + HMAC |
| ePayco | Proveedor de pagos (webhooks) | Firma SHA256 + Validacion IP |
| Admin Sistema | Administrador (acceso directo BD) | Credenciales MySQL |
| Pagador | Usuario final (navegador) | Ninguna (paginas publicas) |
### 6.2 Matriz de Permisos
| Recurso | Sistema Tickets | ePayco | Pagador | Admin |
|---------|:---------------:|:------:|:-------:|:-----:|
| POST /payments | SI | - | - | SI |
| GET /payments/{uuid} | SI | - | - | SI |
| GET /payments/ticket/{ref} | SI | - | - | SI |
| POST /webhook/epayco | - | SI | - | - |
| GET /callback | - | SI | - | - |
| GET /health | SI | - | SI | SI |
| GET /banks/pse | SI | - | - | SI |
| /payment/checkout | - | - | SI | - |
| /payment/response | - | - | SI | - |
| Base de datos directa | - | - | - | SI |
---
## 7. Procesos de Negocio
### 7.1 Proceso de Pago Completo
```mermaid
flowchart TD
A[Sistema Tickets
solicita crear pago] --> B[API valida
credenciales]
B --> C{Autenticado?}
C -->|No| D[Error 401/403]
C -->|Si| E[Validar datos
del pago]
E --> F{Datos validos?}
F -->|No| G[Error 422]
F -->|Si| H[Cifrar datos
sensibles]
H --> I[Crear sesion
ePayco Apify]
I --> J{Sesion creada?}
J -->|No| K[Error 500]
J -->|Si| L[Guardar transaccion
en BD status=pending]
L --> M[Retornar payment_url
al Sistema Tickets]
M --> N[Usuario redirigido
a checkout page]
N --> O[ePayco Smart
Checkout v2]
O --> P{Pago exitoso?}
P -->|Si| Q[ePayco envia
webhook a API]
P -->|No| R[ePayco envia
webhook rechazo]
Q --> S[API valida firma
y actualiza BD]
R --> S
S --> T[API envia webhook
al Sistema Tickets]
T --> U[Sistema Tickets
actualiza ticket]
```
### 7.2 Proceso de Validacion de Webhook ePayco
```mermaid
flowchart TD
A[Webhook ePayco
recibido] --> B{Metodo
GET o POST?}
B -->|Otro| C[Error 405]
B -->|OK| D{Datos
no vacios?}
D -->|No| E[Error 400]
D -->|Si| F{Campos requeridos
presentes?}
F -->|No| G[Error 400
campos faltantes]
F -->|Si| H{IP de ePayco
valida? prod only}
H -->|No| I[Error 403
IP no autorizada]
H -->|Si| J{Firma SHA256
valida?}
J -->|No| K[Error 403
Firma invalida]
J -->|Si| L[Sanitizar datos
lista blanca]
L --> M[Procesar callback
actualizar BD]
M --> N[Enviar webhook
al cliente]
```
---
## 7.3 Proceso de Actualizacion de BD del Cliente y Redireccion Post-Pago
**Descripcion**: Cuando una transaccion finaliza (ePayco envia el webhook/callback), el sistema
automaticamente conecta a la base de datos externa del cliente para actualizar el estado del pago
y redirige al usuario a una URL configurable.
### Flujo
```mermaid
sequenceDiagram
participant EP as ePayco
participant API as Payment Gateway
participant BD as BD Pasarela
participant BDC as BD Cliente
participant USR as Navegador Usuario
participant SYS as Sistema Cliente
EP->>API: POST /api/v1/webhook/epayco
Note over API: Validar firma, IP, campos
API->>BD: UPDATE transactions SET status=approved
API->>BDC: UPDATE reservas_clientes SET estadopago='approved' WHERE idreserva_cliente='ticket_ref'
API->>API: Enviar webhook al cliente
EP->>USR: Redirigir a /payment/response
USR->>API: GET /payment/response?tx=uuid
Note over API: Consultar estado de transaccion
API->>USR: HTTP 302 Redirect
USR->>SYS: GET CLIENT_REDIRECT_URL?Ref_cobro=ticket_reference
```
### Componentes Involucrados
| Componente | Archivo | Funcion |
|-----------|---------|---------|
| ClientDatabaseService | `src/Services/ClientDatabaseService.php` | Conexion y update en BD del cliente |
| PaymentService | `src/Services/PaymentService.php` | Invoca updateClientPaymentStatus() tras el callback |
| Response Page | `public/payment/response.php` | Redirige al usuario con Ref_cobro |
### Configuracion Requerida (.env)
| Variable | Requerida | Ejemplo | Descripcion |
|----------|:---------:|---------|-------------|
| `CLIENT_DB_HOST` | Si | localhost | Host de la BD del cliente |
| `CLIENT_DB_PORT` | No | 3306 | Puerto de la BD del cliente |
| `CLIENT_DB_NAME` | Si | nombre_bd_cliente | Nombre de la base de datos del cliente |
| `CLIENT_DB_USER` | Si | usuario_bd_cliente | Usuario de la BD del cliente |
| `CLIENT_DB_PASS` | Si | password | Contrasena de la BD del cliente |
| `CLIENT_REDIRECT_URL` | Si | https://gorbus.transportessuroeste.com/form_genera_tiquetes | URL de redireccion post-pago |
### Tabla del Cliente: reservas_clientes
| Campo | Tipo | Descripcion |
|-------|------|-------------|
| `idreserva_cliente` | VARCHAR | ID de la reserva (corresponde a `ticket_reference` de la API) |
| `estadopago` | VARCHAR | Estado del pago actualizado por el gateway (approved, rejected, pending, failed, cancelled) |
### Redireccion Post-Pago
Cuando el usuario es redirigido a la pagina de respuesta (`/payment/response`) y la transaccion
tiene un estado definitivo (approved, rejected, failed, cancelled), el sistema redirige automaticamente
al usuario a la URL configurada en `CLIENT_REDIRECT_URL` enviando el `ticket_reference` como
parametro GET `Ref_cobro`.
**Ejemplo de redireccion**:
```
https://gorbus.transportessuroeste.com/form_genera_tiquetes?Ref_cobro=TK-2024-001234
```
**Nota**: Si la transaccion esta en estado `pending`, NO se redirige. La pagina se recarga
automaticamente cada 10 segundos hasta que ePayco confirme el estado final.
### Valores de estadopago
| Valor | Descripcion |
|-------|-------------|
| `approved` | Pago aprobado exitosamente |
| `rejected` | Pago rechazado por el banco/entidad |
| `pending` | Pago en proceso de verificacion |
| `failed` | Error en el procesamiento del pago |
| `cancelled` | Pago cancelado por el usuario |
---
## 8. Guia de Instalacion
### 8.1 Requisitos Previos
- Docker Engine 24+ y Docker Compose v2
- Git
- 2 GB RAM minimo
- 10 GB disco libre
### 8.2 Instalacion con Docker
```bash
# 1. Clonar repositorio
git clone
transportes-suroeste
cd transportes-suroeste
# 2. Configurar variables de entorno
cp .env.example .env
# Editar .env con credenciales reales
# 3. Iniciar servicios
make setup
make up
# 4. Verificar
make health
# Respuesta esperada: {"success":true,"data":{"status":"healthy",...}}
```
### 8.3 Instalacion con Docker (manual)
```bash
# Iniciar en desarrollo
docker compose up -d
# Iniciar en produccion
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```
### 8.4 Variables de Entorno
| Variable | Requerida | Default | Descripcion |
|----------|:---------:|---------|-------------|
| `APP_ENV` | No | production | Entorno: development, staging, production |
| `APP_URL` | No | https://api... | URL base de la aplicacion |
| `DB_NAME` | No | transportes_suroeste_payments | Nombre de la BD |
| `DB_USER` | No | ts_app | Usuario de BD |
| `DB_PASS` | **Si** | - | Contrasena de BD |
| `MYSQL_ROOT_PASSWORD` | **Si** | - | Contrasena root MySQL |
| `EPAYCO_PUBLIC_KEY` | **Si** | - | Llave publica ePayco |
| `EPAYCO_PRIVATE_KEY` | **Si** | - | Llave privada ePayco |
| `EPAYCO_P_KEY` | **Si** | - | P_KEY ePayco |
| `EPAYCO_TEST_MODE` | No | false | Modo sandbox |
| `ENCRYPTION_KEY` | **Si** | - | Llave cifrado AES-256 (64 hex chars) |
| `JWT_SECRET` | **Si** | - | Secret JWT (64 hex chars) |
| `REDIS_HOST` | No | redis | Host de Redis |
| `REDIS_PORT` | No | 6379 | Puerto de Redis |
| `REDIS_PASSWORD` | No | (vacio) | Contrasena Redis |
| `REDIS_DATABASE` | No | 0 | DB number (0-15) |
| `RATE_LIMIT_REQUESTS` | No | 100 | Peticiones por ventana |
| `RATE_LIMIT_WINDOW` | No | 60 | Ventana en segundos |
| `NGINX_PORT` | No | 80/8080 | Puerto HTTP |
| `CLIENT_DB_HOST` | No | localhost | Host BD del cliente |
| `CLIENT_DB_PORT` | No | 3306 | Puerto BD del cliente |
| `CLIENT_DB_NAME` | **Si** | - | Nombre BD del cliente (reservas_clientes) |
| `CLIENT_DB_USER` | **Si** | - | Usuario BD del cliente |
| `CLIENT_DB_PASS` | **Si** | - | Contrasena BD del cliente |
| `CLIENT_REDIRECT_URL` | **Si** | https://gorbus.../ | URL redireccion post-pago |
### 8.5 Configuracion Inicial Post-Instalacion
1. La base de datos se inicializa automaticamente al primer `docker compose up` usando `sql/database.sql`
2. Crear un cliente API en la tabla `api_clients`:
```sql
INSERT INTO api_clients (
client_uuid, client_name, api_key, api_secret_hash,
webhook_url, webhook_secret, is_active, environment
) VALUES (
UUID(), 'Mi Sistema de Tickets',
'ts_mi_api_key_generada',
'$argon2id$...hash_del_secret...',
'https://mi-sistema.com/webhook',
'mi_webhook_secret',
1, 'production'
);
```
Se puede generar credenciales con:
```php
php -r "
require 'vendor/autoload.php';
require 'config/config.php';
$creds = \TransportesSuroeste\Middleware\AuthMiddleware::generateCredentials();
print_r(\$creds);
"
```
---
## 9. Guia de Uso
### 9.1 Flujo de Pago para Integradores
1. **Crear pago**: `POST /api/v1/payments` con datos del ticket
2. **Redirigir usuario**: Enviar al `payment_url` retornado
3. **Esperar webhook**: Configurar endpoint para recibir notificacion
4. **Consultar estado**: `GET /api/v1/payments/{uuid}` para verificar
### 9.2 Pagina de Checkout
La pagina de checkout (`/payment/checkout`) muestra:
- Informacion del ticket (referencia, monto)
- Boton "Pagar Ahora" que abre el modal de ePayco
- Badge de seguridad (SSL 256-bit)
- Logo de ePayco
### 9.3 Pagina de Respuesta
La pagina de respuesta (`/payment/response`) muestra:
- Estado del pago (exitoso, pendiente, rechazado, fallido)
- Monto pagado
- Referencia de transaccion
- Referencia ePayco
- Metodo de pago utilizado
- Botones de accion (volver al inicio, reintentar)
Si el pago esta pendiente, la pagina se recarga automaticamente cada 10 segundos.
### 9.4 Ejemplo de Integracion (PHP)
```php
'TK-001',
'amount' => 45000,
'description' => 'Ticket Medellin-Bogota',
'payer_email' => 'cliente@mail.com',
'payer_name' => 'Juan Perez',
'payer_document_type' => 'CC',
'payer_document' => '1234567890'
]);
$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}"
]
]);
$response = json_decode(curl_exec($ch), true);
// Redirigir al usuario a $response['data']['payment_url']
```
---
## 10. Mantenimiento
### 10.1 Backups
```bash
# Backup manual
make backup
# Backup automatizado (cron, 2 AM diario)
0 2 * * * /path/to/scripts/backup.sh >> /var/log/ts-backup.log 2>&1
```
Los backups se almacenan en `backups/` con formato `db_name_YYYYMMDD_HHMMSS.sql.gz`.
Retencion por defecto: 30 dias.
### 10.2 Logs
| Comando | Descripcion |
|---------|-------------|
| `make logs` | Ver todos los logs en tiempo real |
| `make logs-php` | Solo logs PHP-FPM |
| `make logs-nginx` | Solo logs Nginx |
| `make logs-app` | Logs de aplicacion |
| `make clean-logs` | Limpiar logs |
**Archivos de log de la aplicacion** (en `/var/www/html/logs/`):
- `app.log` - Log general
- `transactions.log` - Transacciones de pago
- `security.log` - Eventos de seguridad
- `audit.log` - Auditoria compliance
- `errors.log` - Errores del sistema
- `access.log` - Acceso HTTP
### 10.3 Monitoreo
```bash
# Estado de contenedores
make status
# Health check
make health
# Verificar MySQL
make shell-mysql
# > SHOW PROCESSLIST;
# > SELECT COUNT(*) FROM transactions WHERE status='pending' AND created_at < NOW() - INTERVAL 1 HOUR;
```
### 10.4 Troubleshooting
| Problema | Solucion |
|----------|---------|
| API retorna 502 | Verificar que PHP-FPM este corriendo: `make logs-php` |
| Error de BD | Verificar MySQL: `make logs-mysql`, `make shell-mysql` |
| Rate limit excedido | Limpiar tabla `rate_limit_tracking` y `blocked_ips` |
| Webhook no llega | Verificar tabla `webhook_deliveries`, logs de transaccion |
| Error ePayco | Verificar credenciales en `.env`, verificar modo test |
| Paginas en blanco | Verificar `logs/php_errors.log`, `logs/errors.log` |
| Permisos de logs | `make shell` y verificar permisos de `/var/www/html/logs/` |
### 10.5 Eventos Programados (MySQL)
| Evento | Frecuencia | Funcion |
|--------|------------|---------|
| `evt_cleanup_rate_limits` | Cada hora | Limpia rate limits expirados |
| `evt_daily_reconciliation` | 2:00 AM diario | Genera conciliacion diaria |
### 10.6 Actualizacion
```bash
# 1. Backup
make backup
# 2. Pull cambios
git pull origin main
# 3. Rebuild y deploy
make rebuild
# 4. Verificar
make health
```