trading-platform/docs/02-definicion-modulos/OQI-005-payments-stripe
Adrian Flores Cortes 3d8bf17b72 docs(payments): Add Developer Guidelines (ST4.2.5)
Comprehensive developer guidelines for payment system development.

New Files:
- docs/.../OQI-005-payments-stripe/DEVELOPER-GUIDELINES.md (900+ lines)
  - Complete reference for payment development
  - PCI-DSS compliance rules (DO's and DON'Ts)
  - Backend development guidelines
  - Frontend development guidelines
  - Testing guidelines (unit + E2E)
  - Common pitfalls and how to avoid them
  - Code review checklist
  - Deployment checklist
  - Troubleshooting guide
  - Examples and templates

Sections:
1. Overview - Architecture summary, tech stack, compliance level
2. PCI-DSS Compliance Rules - What's allowed vs prohibited
3. Backend Development - File structure, endpoints, webhooks, database
4. Frontend Development - Stripe Elements, checkout flow, error handling
5. Testing Guidelines - Unit tests, E2E tests, component tests
6. Common Pitfalls - 5 common mistakes and how to avoid them
7. Code Review Checklist - Security, quality, Stripe integration
8. Deployment Checklist - Environment, security, testing, monitoring
9. Troubleshooting - Common issues and solutions
10. Examples & Templates - Complete flow examples

Key Guidelines:
 DO's:
  - Use Payment Intents (server-side processing)
  - Use Stripe Elements (client-side tokenization)
  - Verify webhook signatures
  - Store only tokens/IDs (pm_xxx, pi_xxx)
  - Use HTTPS everywhere
  - Log payment events (without sensitive data)
  - Write E2E tests for PCI-DSS compliance

 DON'Ts:
  - Accept card data in backend
  - Store PAN, CVV, or expiry in database
  - Create native card inputs
  - Store card data in React state
  - Skip webhook signature verification
  - Use HTTP (only HTTPS)
  - Log sensitive data

PCI-DSS Compliance:
 ALLOWED:
  - Store last 4 digits
  - Store card brand
  - Store Stripe tokens (pm_xxx, pi_xxx, cus_xxx)
  - Store customer name

 PROHIBITED:
  - Store full PAN (card number)
  - Store CVV/CVC
  - Store expiry date
  - Store PIN

Common Pitfalls:
1. Accepting card data in backend → Block sensitive fields
2. Storing full PAN in database → Use tokens only
3. Native card inputs → Use Stripe CardElement
4. Not verifying webhook signatures → Use constructEvent
5. Logging sensitive data → Filter sensitive fields

Code Examples:
- Wallet deposit flow (complete end-to-end)
- Subscription checkout (Stripe hosted)
- Payment Intent creation (backend)
- Stripe Elements integration (frontend)
- Webhook signature verification
- Database schema (safe vs prohibited)

Testing Examples:
- Unit tests (Stripe service mocked)
- E2E tests (PCI-DSS compliance)
- Component tests (CardElement rendering)
- Integration tests (webhook handling)

Deployment Checklist:
- Environment variables configured
- Stripe webhooks set up
- SSL/TLS enabled
- Security headers configured
- Rate limiting enabled
- All tests passing (45+ PCI-DSS tests)
- Monitoring and alerts configured

Target Audience:
- Backend developers (Express.js, TypeScript)
- Frontend developers (React, Stripe.js)
- DevOps engineers (deployment, monitoring)
- Code reviewers (security validation)
- New team members (onboarding)

Status: BLOCKER-002 (ST4.2) - Developer guidelines complete
Task: #5 ST4.2.5 - Actualizar developer guidelines pagos

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 22:03:47 -06:00
..
especificaciones feat(payments): Add PCI-DSS architecture documentation (ST4.2.2) 2026-01-26 19:53:08 -06:00
historias-usuario feat(ml): Complete FASE 11 - BTCUSD update and comprehensive documentation alignment 2026-01-07 09:31:29 -06:00
implementacion [OQI-005] docs: Complete CAPVED documentation and module updates 2026-01-26 10:02:20 -06:00
requerimientos feat(ml): Complete FASE 11 - BTCUSD update and comprehensive documentation alignment 2026-01-07 09:31:29 -06:00
security docs(payments): Add PCI-DSS SAQ-A Security Audit (ST4.2.4) 2026-01-26 22:00:57 -06:00
_MAP.md feat: Major platform documentation and architecture updates 2026-01-07 05:33:35 -06:00
DEVELOPER-GUIDELINES.md docs(payments): Add Developer Guidelines (ST4.2.5) 2026-01-26 22:03:47 -06:00
README.md feat: Major platform documentation and architecture updates 2026-01-07 05:33:35 -06:00

id title type project version updated_date
README Sistema de Pagos con Stripe Documentation trading-platform 1.0.0 2026-01-04

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

Documentacion generada: 2025-12-05