- FASE-0: Diagnostic audit of 500+ files, 33 findings cataloged (7P0/8P1/12P2/6P3) - FASE-1: Resolved 7 P0 critical conflicts (ports, paths, dedup OQI-010/ADR-002, orphan schemas) - FASE-2: Resolved 8 P1 issues (traces, README/CLAUDE.md, DEPENDENCY-GRAPH v2.0, DDL drift, stack versions, DoR/DoD) - FASE-3: Resolved 12 P2 issues (archived tasks indexed, RNFs created, OQI-010 US/RF/ET, AGENTS v2.0) - FASE-4: Purged 3 obsolete docs to _archive/, fixed MODELO-NEGOCIO.md broken ref - FASE-5: Cross-layer validation (DDL→OQI 66%, OQI→BE 72%, BE→FE 78%, Inventories 95%) - FASE-6: INFORME-FINAL, SA-INDEX (18 subagents), METADATA COMPLETED 27/33 findings resolved (82%), 6 P3 deferred to backlog. 18 new files created, 40+ modified, 4 archived. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7.0 KiB
7.0 KiB
| id | title | type | project | version | updated_date |
|---|---|---|---|---|---|
| README | Sistema de Pagos con Stripe | Documentation | trading-platform | 1.0.0 | 2026-02-06 |
OQI-005: Sistema de Pagos con Stripe
Estado: ✅ Implementado
Fecha: 2025-12-05
Modulo: apps/backend/src/modules/payments
Descripcion
Sistema completo de pagos integrado con Stripe para:
- Pagos unicos (compra de cursos)
- Suscripciones mensuales (planes Basic, Pro, Premium)
- Webhooks para eventos de pago
- Historial de transacciones
Arquitectura
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Frontend │────▶│ NestJS API │────▶│ Stripe │
│ (React) │ │ /payments/* │ │ API │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ PostgreSQL │
│ billing schema │
└─────────────────┘
Endpoints
| Metodo | Ruta | Descripcion | Auth |
|---|---|---|---|
| POST | /payments/create-payment-intent |
Crear pago directo | JWT |
| POST | /payments/create-checkout-session |
Checkout hosted | JWT |
| POST | /payments/subscriptions |
Crear suscripcion | JWT |
| GET | /payments/subscriptions/current |
Suscripcion actual | JWT |
| DELETE | /payments/subscriptions/:id |
Cancelar suscripcion | JWT |
| GET | /payments/history |
Historial de pagos | JWT |
| POST | /payments/webhook |
Webhook Stripe | - |
Entidades
Payment
@Entity({ name: 'payments', schema: 'billing' })
class Payment {
id: string; // UUID
userId: string; // FK a users
type: PaymentType; // course_purchase | subscription | one_time
status: PaymentStatus; // pending | processing | succeeded | failed | cancelled | refunded
amount: number; // Monto en USD
currency: string; // USD
stripePaymentIntentId: string;
stripeCustomerId: string;
courseId?: string; // Si es compra de curso
subscriptionId?: string; // Si es pago de suscripcion
description?: string;
metadata?: object;
failureReason?: string;
refundedAt?: Date;
createdAt: Date;
updatedAt: Date;
}
Subscription
@Entity({ name: 'subscriptions', schema: 'billing' })
class Subscription {
id: string; // UUID
userId: string; // FK a users
plan: SubscriptionPlan; // basic | pro | premium
status: SubscriptionStatus; // active | past_due | cancelled | incomplete | trialing | unpaid
stripeSubscriptionId: string;
stripeCustomerId: string;
stripePriceId: string;
price: number; // Precio mensual
currency: string; // USD
billingInterval: string; // month | year
currentPeriodStart: Date;
currentPeriodEnd: Date;
trialEnd?: Date;
cancelledAt?: Date;
cancelAtPeriodEnd: boolean;
metadata?: object;
createdAt: Date;
updatedAt: Date;
}
Planes de Suscripcion
| Plan | Precio | Price ID | Caracteristicas |
|---|---|---|---|
| Basic | $19/mes | price_1Sb3k64dPtEGmLmpeAdxvmIu |
Predicciones basicas, cursos intro |
| Pro | $49/mes | price_1Sb3k64dPtEGmLmpm5n5bbJH |
Predicciones avanzadas, todos los cursos |
| Premium | $99/mes | price_1Sb3k74dPtEGmLmpHfLpUkvQ |
Todo + soporte prioritario |
Flujo de Pago
Pago Unico (Payment Intent)
1. Frontend solicita crear payment intent
2. Backend crea PaymentIntent en Stripe
3. Backend guarda registro en BD (status: pending)
4. Frontend recibe clientSecret
5. Frontend muestra formulario de tarjeta (Stripe Elements)
6. Usuario completa pago
7. Stripe envia webhook (payment_intent.succeeded)
8. Backend actualiza status a succeeded
9. Backend otorga acceso al recurso
Suscripcion
1. Frontend solicita crear suscripcion
2. Backend obtiene/crea Customer en Stripe
3. Backend adjunta metodo de pago
4. Backend crea Subscription en Stripe
5. Backend guarda registro en BD
6. Stripe cobra automaticamente cada mes
7. Webhooks actualizan estado
Configuracion
Variables de Entorno
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
FRONTEND_URL=http://localhost:5173
Webhook Events
| Evento | Accion |
|---|---|
payment_intent.succeeded |
Actualizar pago a succeeded, otorgar acceso |
payment_intent.payment_failed |
Actualizar pago a failed |
customer.subscription.updated |
Sincronizar estado de suscripcion |
customer.subscription.deleted |
Marcar suscripcion como cancelled |
Ejemplo de Uso
Crear Payment Intent
curl -X POST http://localhost:3000/payments/create-payment-intent \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 2900,
"currency": "usd",
"type": "course_purchase",
"courseId": "uuid-del-curso",
"description": "Curso de Trading Basico"
}'
Respuesta:
{
"clientSecret": "pi_xxx_secret_xxx",
"paymentIntentId": "pi_xxx",
"amount": 2900,
"currency": "usd"
}
Crear Suscripcion
curl -X POST http://localhost:3000/payments/subscriptions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"plan": "pro",
"paymentMethodId": "pm_xxx"
}'
Modo Mock
Cuando STRIPE_SECRET_KEY no esta configurado, el sistema funciona en modo mock:
- Retorna payment intents simulados
- Las suscripciones se crean localmente
- Util para desarrollo sin cuenta Stripe
Archivos
apps/backend/src/modules/payments/
├── dto/
│ ├── payment.dto.ts
│ └── subscription.dto.ts
├── entities/
│ ├── payment.entity.ts
│ └── subscription.entity.ts
├── payments.controller.ts
├── payments.service.ts
└── payments.module.ts
Seguridad
- Todos los endpoints requieren JWT (excepto webhook)
- Webhook valida firma de Stripe
- Claves secretas en variables de entorno
- Nunca exponer
sk_test_*en frontend
Schemas DDL Asignados
Este modulo es owner del siguiente schema DDL:
| Schema | Tablas | Descripcion |
|---|---|---|
| financial | 11 | wallets, wallet_transactions, payment_methods, payments, invoices, subscriptions, subscription_plans, refunds, commissions, commission_payouts, price_alerts |
Total tablas: 11 Nota DDL drift: Documentacion previa listaba ~5 tablas. Las tablas no documentadas son: subscription_plans, refunds, commissions, commission_payouts, price_alerts, wallet_transactions. Actualizado por TASK-2026-02-06 F2.6.
Documentacion generada: 2025-12-05