workspace-v1/shared/libs/payments/README.md
rckrdmrd 66161b1566 feat: Workspace-v1 complete migration with NEXUS v3.4
Sistema NEXUS v3.4 migrado con:

Estructura principal:
- core/orchestration: Sistema SIMCO + CAPVED (27 directivas, 28 perfiles)
- core/catalog: Catalogo de funcionalidades reutilizables
- shared/knowledge-base: Base de conocimiento compartida
- devtools/scripts: Herramientas de desarrollo
- control-plane/registries: Control de servicios y CI/CD
- orchestration/: Configuracion de orquestacion de agentes

Proyectos incluidos (11):
- gamilit (submodule -> GitHub)
- trading-platform (OrbiquanTIA)
- erp-suite con 5 verticales:
  - erp-core, construccion, vidrio-templado
  - mecanicas-diesel, retail, clinicas
- betting-analytics
- inmobiliaria-analytics
- platform_marketing_content
- pos-micro, erp-basico

Configuracion:
- .gitignore completo para Node.js/Python/Docker
- gamilit como submodule (git@github.com:rckrdmrd/gamilit-workspace.git)
- Sistema de puertos estandarizado (3005-3199)

Generated with NEXUS v3.4 Migration System
EPIC-010: Configuracion Git y Repositorios
2026-01-04 03:37:42 -06:00

469 lines
10 KiB
Markdown

# 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