Backend FastAPI reutilizable para integración con Transbank Webpay Plus. Incluye persistencia de transacciones con SQLAlchemy, validación con Pydantic, rate limiting y headers de seguridad.
- FastAPI con documentación automática (Swagger/OpenAPI)
- Transbank SDK (Webpay Plus)
- SQLAlchemy 2.0 para persistencia de transacciones
- Pydantic v2 para validación de entrada/salida
- Rate Limiting con SlowAPI
- CORS configurable
- Headers de seguridad (HSTS, X-Frame-Options, etc.)
- Variables de entorno con pydantic-settings
pip install apofis-webpay-backend# Para PostgreSQL
pip install apofis-webpay-backend[postgres]
# Para MySQL
pip install apofis-webpay-backend[mysql]
# Para desarrollo
pip install apofis-webpay-backend[dev]Copia .env.example a .env y configura:
# Transbank Webpay
COMMERCE_CODE=597055555532
API_KEY=579B532A7440BB0C9079DED94D31EA1615BACEB56610332264630D42D0A36B1C
ENVIRONMENT=integration
# Base de datos
DATABASE_URL=sqlite:///./webpay_transactions.db
# CORS
CORS_ORIGINS=["http://localhost:3000","http://localhost:5173"]
# Rate Limiting
RATE_LIMIT=10/minute
# Servidor
APP_HOST=0.0.0.0
APP_PORT=8000
DEBUG=true| Variable | Descripción | Default |
|---|---|---|
COMMERCE_CODE |
Código de comercio Transbank | Código de integración |
API_KEY |
API Key de Transbank | Key de integración |
ENVIRONMENT |
integration o production |
integration |
DATABASE_URL |
URL de conexión a base de datos | SQLite local |
CORS_ORIGINS |
Lista de orígenes permitidos (JSON array) | localhost:3000/5173 |
RATE_LIMIT |
Límite de requests (ej: 10/minute) |
10/minute |
DEBUG |
Habilitar docs Swagger | false |
Producción: Cambia
ENVIRONMENT=production, usa credenciales reales de Transbank, configura PostgreSQL y desactivaDEBUG.
# Copiar configuración
cp .env.example .env
# Ejecutar servidor
uvicorn apofis_webpay_backend.main:app --host 0.0.0.0 --port 8000 --reloadfrom fastapi import FastAPI
from apofis_webpay_backend.routes import router
from apofis_webpay_backend.database import init_db
app = FastAPI()
@app.on_event("startup")
async def startup():
init_db()
# Montar rutas bajo un prefijo
app.include_router(router, prefix="/api/webpay")from apofis_webpay_backend.main import create_app
app = create_app()
# uvicorn mi_app:app --host 0.0.0.0 --port 8000Crea una transacción en Webpay y retorna token + URL para redirección.
Request:
{
"buy_order": "orden-12345",
"session_id": "sesion-abc",
"amount": 15000,
"return_url": "https://tu-app.com/checkout/result"
}Response (200):
{
"token": "01ab23cd45ef...",
"url": "https://webpay3gint.transbank.cl/webpayserver/initTransaction"
}Confirma una transacción con Transbank y actualiza el estado en BD.
Request:
{
"token": "01ab23cd45ef..."
}Response (200):
{
"status": "AUTHORIZED",
"amount": 15000,
"authorization_code": "1234",
"buy_order": "orden-12345",
"session_id": "sesion-abc",
"card_number": "6623",
"transaction_date": "2026-04-17T10:30:00",
"payment_type": "VN",
"installments_number": 0,
"vci": "TSY"
}Health check del servicio.
Response:
{
"status": "ok",
"environment": "integration"
}apofis_webpay_backend/
├── __init__.py # Package init
├── config.py # Settings (pydantic-settings)
├── database.py # SQLAlchemy engine, session, init_db
├── models.py # Modelo Transaction (SQLAlchemy)
├── schemas.py # Schemas Pydantic (request/response)
├── controllers.py # Lógica de negocio (create/confirm)
├── routes.py # Endpoints FastAPI
└── main.py # App factory, middleware, CORS
Request → routes.py (Vista/Router)
↓
controllers.py (Controlador/Servicio)
↓
models.py (Modelo) + Transbank SDK
↓
schemas.py (Serialización)
↓
Response
El frontend (@apofis/webpay-ui) y este backend trabajan juntos así:
1. Usuario presiona "Pagar con Webpay"
└─▶ Frontend POST /create-transaction { buy_order, session_id, amount, return_url }
2. Backend crea transacción en Transbank
└─▶ Retorna { token, url }
3. Frontend redirige al usuario
└─▶ window.location.href = url + "?token_ws=" + token
4. Usuario paga en portal Webpay
└─▶ Webpay redirige a return_url?token_ws=...
5. Frontend detecta token_ws en URL
└─▶ POST /confirm-transaction { token: token_ws }
6. Backend confirma con Transbank y actualiza BD
└─▶ Retorna { status, amount, authorization_code, ... }
7. Frontend muestra resultado al usuario
Backend (este paquete):
uvicorn apofis_webpay_backend.main:app --port 8000Frontend (React):
import { WebpayComponent } from "@apofis/webpay-ui";
<WebpayComponent
apiUrl="http://localhost:8000"
buyOrder="ord-001"
sessionId="sess-001"
amount={25000}
returnUrl="http://localhost:3000/checkout"
onSuccess={(data) => console.log("Pagado:", data)}
/>- Nunca hardcodear
COMMERCE_CODEniAPI_KEYen el código. - Usar
.envpara desarrollo y variables de entorno del sistema en producción. - El archivo
.envno debe subirse al repositorio (agregar a.gitignore).
- Configurado por defecto a
10/minutepor IP. - Previene abuso y cumple con buenas prácticas de Webpay.
- Ajustar según volumen esperado de transacciones.
- Solo permite orígenes explícitamente configurados.
- En producción, configurar únicamente el dominio del frontend.
- Obligatorio en producción para Webpay.
- Configurar en el reverse proxy (nginx, Caddy) o load balancer.
- El middleware agrega header
Strict-Transport-Securityautomáticamente.
El middleware agrega automáticamente:
X-Content-Type-Options: nosniffX-Frame-Options: DENYX-XSS-Protection: 1; mode=blockStrict-Transport-Security: max-age=31536000; includeSubDomainsReferrer-Policy: strict-origin-when-cross-origin
- Todas las transacciones se registran con
logging. - Los tokens se truncan en los logs por seguridad.
- En producción, enviar logs a un servicio centralizado (CloudWatch, Datadog, etc.).
- SQLite para desarrollo, PostgreSQL/MySQL para producción.
- Las transacciones se persisten con timestamps automáticos.
- Índices en
buy_order,session_idytokenpara consultas eficientes.
# Clonar y crear entorno virtual
python -m venv .venv
source .venv/bin/activate # Linux/Mac
.venv\Scripts\activate # Windows
# Instalar en modo desarrollo
pip install -e ".[dev]"
# Ejecutar tests
pytest
# Ejecutar servidor con hot reload
uvicorn apofis_webpay_backend.main:app --reloadMIT © APOFIS