# Integración de Pagos

**Versión:** 1.0.0
**Origen:** projects/trading-platform
**Estado:** Producción
**Última actualización:** 2025-12-08

---

## Descripción

Sistema completo de pagos con integración Stripe:
- Gestión de clientes en Stripe
- Checkout sessions para pagos seguros
- Suscripciones con ciclos de facturación
- Métodos de pago (tarjetas)
- Billing portal de autoservicio
- Webhooks para eventos de Stripe
- Wallet interno para balance de usuario
- Códigos promocionales

---

## Características

| Característica | Descripción |
|----------------|-------------|
| Stripe Checkout | Hosted checkout pages |
| Suscripciones | Monthly/yearly con trial |
| Payment Intents | One-time payments |
| Billing Portal | Self-service portal |
| Webhooks | Eventos en tiempo real |
| Wallet | Balance interno |
| Promo codes | Descuentos y cupones |
| Invoices | Facturas automáticas |
| Refunds | Reembolsos parciales/totales |

---

## Stack Tecnológico

```yaml
backend:
  framework: NestJS / Express
  payment_processor: Stripe
  database: PostgreSQL

packages:
  - "stripe"
```

---

## Dependencias NPM

```json
{
  "stripe": "^14.x"
}
```

---

## Tablas Requeridas

| Tabla | Propósito |
|-------|-----------|
| financial.stripe_customers | Relación user-customer Stripe |
| financial.subscription_plans | Planes disponibles |
| financial.subscriptions | Suscripciones activas |
| financial.payments | Historial de pagos |
| financial.invoices | Facturas |
| financial.wallets | Balance del usuario |
| financial.wallet_transactions | Movimientos del wallet |
| financial.promo_codes | Códigos promocionales |

---

## Estructura del Módulo

```
payments/
├── services/
│   ├── stripe.service.ts        # Integración con Stripe API
│   ├── subscription.service.ts  # Gestión de suscripciones
│   └── wallet.service.ts        # Wallet interno
├── controllers/
│   └── payments.controller.ts   # Endpoints REST
├── webhooks/
│   └── stripe.webhook.ts        # Handler de webhooks
├── types/
│   └── payments.types.ts        # Tipos e interfaces
└── dto/
    ├── create-checkout.dto.ts
    └── subscription.dto.ts
```

---

## Modelos de Datos

### StripeCustomer

```typescript
interface StripeCustomer {
  id: string;
  userId: string;
  stripeCustomerId: string;         // cus_xxx
  email?: string;
  defaultPaymentMethodId?: string;  // pm_xxx
  metadata?: Record<string, any>;
  createdAt: Date;
  updatedAt: Date;
}
```

### SubscriptionPlan

```typescript
interface SubscriptionPlan {
  id: string;
  name: string;                     // "Pro Plan"
  slug: string;                     // "pro"
  description?: string;
  priceMonthly: number;             // 29.99
  priceYearly?: number;             // 299.99
  currency: string;                 // "usd"
  stripePriceIdMonthly?: string;    // price_xxx
  stripePriceIdYearly?: string;     // price_xxx
  stripeProductId?: string;         // prod_xxx
  features: PlanFeature[];
  isActive: boolean;
  sortOrder: number;
}
```

### Subscription

```typescript
interface Subscription {
  id: string;
  userId: string;
  planId: string;
  stripeSubscriptionId?: string;    // sub_xxx
  stripeCustomerId?: string;        // cus_xxx
  status: 'trialing' | 'active' | 'past_due' | 'cancelled' | 'unpaid';
  billingCycle: 'monthly' | 'yearly';
  currentPeriodStart?: Date;
  currentPeriodEnd?: Date;
  trialStart?: Date;
  trialEnd?: Date;
  cancelAtPeriodEnd: boolean;
  cancelledAt?: Date;
  cancellationReason?: string;
  currentPrice?: number;
  currency: string;
}
```

### Wallet

```typescript
interface Wallet {
  id: string;
  userId: string;
  currency: string;
  balance: number;
  availableBalance: number;
  pendingBalance: number;
  isActive: boolean;
  dailyWithdrawalLimit: number;
  monthlyWithdrawalLimit: number;
}
```

---

## Flujo de Pago con Stripe Checkout

```
1. Usuario selecciona plan
       │
       ▼
2. Backend crea Checkout Session
   - Obtiene/crea customer en Stripe
   - Configura line_items con price_id
   - Define success_url y cancel_url
       │
       ▼
3. Redirect a Stripe Checkout
       │
       ▼
4. Usuario completa pago
       │
       ▼
5. Stripe envía webhook
   - checkout.session.completed
   - invoice.paid
       │
       ▼
6. Backend procesa webhook
   - Crea/actualiza suscripción
   - Registra pago
   - Activa features del plan
```

---

## Uso Rápido

### 1. Crear cliente en Stripe

```typescript
const customer = await stripeService.getOrCreateCustomer(
  userId,
  userEmail
);
// { stripeCustomerId: 'cus_xxx', ... }
```

### 2. Crear checkout session

```typescript
const session = await stripeService.createCheckoutSession({
  userId: 'user-uuid',
  planId: 'plan-uuid',
  billingCycle: 'monthly',
  successUrl: 'https://app.com/success?session_id={CHECKOUT_SESSION_ID}',
  cancelUrl: 'https://app.com/pricing',
  promoCode: 'SUMMER20', // opcional
});

// Redirect usuario a session.url
```

### 3. Verificar suscripción

```typescript
const subscription = await subscriptionService.getSubscriptionByUserId(userId);

if (subscription?.status === 'active') {
  // Usuario tiene suscripción activa
  const hasFeature = subscription.plan.apiAccess;
}
```

### 4. Billing Portal (autoservicio)

```typescript
const portal = await stripeService.createBillingPortalSession(
  userId,
  'https://app.com/dashboard'
);

// Redirect a portal.url
// Usuario puede: actualizar tarjeta, ver facturas, cancelar
```

### 5. Cancelar suscripción

```typescript
// Al final del período
await subscriptionService.cancelSubscription(userId, false, 'User requested');

// Inmediatamente
await subscriptionService.cancelSubscription(userId, true);
```

### 6. Cambiar de plan

```typescript
await subscriptionService.changePlan(userId, newPlanId, 'yearly');
```

---

## Webhook Handler

```typescript
// POST /webhooks/stripe
async handleStripeWebhook(req: Request) {
  const signature = req.headers['stripe-signature'];
  const event = stripe.webhooks.constructEvent(
    req.body,
    signature,
    process.env.STRIPE_WEBHOOK_SECRET
  );

  switch (event.type) {
    case 'checkout.session.completed':
      await this.handleCheckoutCompleted(event.data.object);
      break;

    case 'invoice.paid':
      await this.handleInvoicePaid(event.data.object);
      break;

    case 'invoice.payment_failed':
      await this.handlePaymentFailed(event.data.object);
      break;

    case 'customer.subscription.updated':
      await this.handleSubscriptionUpdated(event.data.object);
      break;

    case 'customer.subscription.deleted':
      await this.handleSubscriptionDeleted(event.data.object);
      break;
  }

  return { received: true };
}

private async handleCheckoutCompleted(session: Stripe.Checkout.Session) {
  const { userId, planId, billingCycle } = session.metadata!;

  // Crear suscripción local
  await db.query(`
    INSERT INTO financial.subscriptions (
      user_id, plan_id, stripe_subscription_id, stripe_customer_id,
      status, billing_cycle, current_period_start, current_period_end
    ) VALUES ($1, $2, $3, $4, 'active', $5, $6, $7)
  `, [userId, planId, session.subscription, session.customer, billingCycle, ...]);
}
```

---

## Variables de Entorno

```env
# Stripe
STRIPE_SECRET_KEY=sk_live_xxx          # o sk_test_xxx
STRIPE_PUBLISHABLE_KEY=pk_live_xxx     # para frontend
STRIPE_WEBHOOK_SECRET=whsec_xxx

# URLs
FRONTEND_URL=https://app.example.com
STRIPE_SUCCESS_URL=${FRONTEND_URL}/success
STRIPE_CANCEL_URL=${FRONTEND_URL}/pricing
```

---

## Endpoints Principales

| Método | Ruta | Descripción |
|--------|------|-------------|
| GET | /plans | Listar planes disponibles |
| GET | /plans/:id | Obtener plan por ID |
| GET | /subscription | Obtener suscripción del usuario |
| POST | /checkout/subscription | Crear checkout para suscripción |
| POST | /checkout/course | Crear checkout para curso |
| GET | /billing-portal | Obtener URL del billing portal |
| POST | /subscription/cancel | Cancelar suscripción |
| POST | /subscription/resume | Reactivar suscripción |
| POST | /subscription/change-plan | Cambiar de plan |
| GET | /invoices | Listar facturas del usuario |
| GET | /payment-methods | Listar métodos de pago |
| POST | /payment-methods | Agregar método de pago |
| DELETE | /payment-methods/:id | Eliminar método de pago |
| POST | /webhooks/stripe | Webhook handler |

---

## Configuración en Stripe Dashboard

### 1. Productos y Precios

```
Producto: Pro Plan (prod_xxx)
├── Precio mensual: $29.99/month (price_monthly_xxx)
└── Precio anual: $299.99/year (price_yearly_xxx)
```

### 2. Webhook Endpoints

```
Endpoint: https://api.example.com/webhooks/stripe
Events:
- checkout.session.completed
- invoice.paid
- invoice.payment_failed
- customer.subscription.updated
- customer.subscription.deleted
- customer.subscription.created
```

### 3. Customer Portal

Configurar en Settings > Billing > Customer portal:
- Allow customers to update payment methods
- Allow customers to view invoice history
- Allow customers to cancel subscriptions

---

## Wallet (Balance Interno)

### Depositar fondos

```typescript
await walletService.deposit({
  userId: 'user-uuid',
  amount: 100.00,
  currency: 'usd',
  description: 'Initial deposit',
});
```

### Usar balance para pago

```typescript
const canPay = await walletService.canAfford(userId, 50.00);
if (canPay) {
  await walletService.debit(userId, 50.00, 'Course purchase');
}
```

### Reembolso al wallet

```typescript
await walletService.credit(userId, 25.00, 'Partial refund');
```

---

## Códigos Promocionales

```typescript
// Validar código
const result = await promoService.validateCode('SUMMER20', {
  userId,
  planId,
  amount: 29.99,
});

if (result.valid) {
  // Aplicar descuento
  const finalPrice = 29.99 - result.discountAmount;
}
```

---

## Adaptaciones Necesarias

1. **Productos en Stripe**: Crear productos y precios en dashboard
2. **Webhook URL**: Configurar endpoint público
3. **Planes**: Ajustar features según tu modelo de negocio
4. **Moneda**: Configurar currency (usd, eur, mxn, etc.)
5. **Trial**: Configurar período de prueba si aplica
6. **Tax**: Configurar impuestos si aplica (Stripe Tax)

---

## Referencias

- [Stripe API Reference](https://stripe.com/docs/api)
- [Stripe Checkout](https://stripe.com/docs/payments/checkout)
- [Stripe Subscriptions](https://stripe.com/docs/billing/subscriptions)
- [Stripe Webhooks](https://stripe.com/docs/webhooks)
- [Stripe Customer Portal](https://stripe.com/docs/billing/subscriptions/customer-portal)

---

**Mantenido por:** Sistema NEXUS
**Proyecto origen:** Trading Platform
