--- id: "ADR-003" title: "Billing Integration con Stripe" type: "ADR" status: "Accepted" priority: "P0" supersedes: "N/A" superseded_by: "N/A" version: "1.0.0" created_date: "2026-01-07" updated_date: "2026-01-10" --- # ADR-003: Billing Integration con Stripe ## Metadata | Campo | Valor | |-------|-------| | ID | ADR-003 | | Estado | Accepted | | Fecha | 2026-01-10 | | Supersede | N/A | ## Contexto Template SaaS necesita un sistema de billing para: - Planes de suscripción (mensual/anual) - Trial periods - Múltiples métodos de pago - Facturación automática - Portal de autoservicio - Webhooks para sincronización ## Opciones Consideradas ### Opción 1: Implementación Custom **Descripción:** Sistema de billing propio conectado a pasarelas de pago. **Pros:** - Control total - Sin comisiones de plataforma - Personalización completa **Contras:** - Complejidad extrema (PCI compliance) - Time-to-market largo - Mantenimiento costoso - Riesgos de seguridad ### Opción 2: Stripe ✓ **Descripción:** Plataforma de pagos completa con Billing. **Pros:** - Rápido de implementar - PCI compliance incluido - Múltiples países/monedas - Portal de cliente built-in - Webhooks robustos - Excelente documentación **Contras:** - Comisiones (~2.9% + 30¢) - Dependencia de tercero - Algunas limitaciones en personalización ### Opción 3: Paddle/Lemonsqueezy **Descripción:** Merchant of Record (MoR) completo. **Pros:** - Maneja impuestos automáticamente - Sin necesidad de entidad legal por país - Más simple que Stripe **Contras:** - Comisiones más altas (~5-8%) - Menos control - Menos features ## Decisión **Elegimos Stripe** por: 1. **Balance:** Buen equilibrio entre control y simplicidad 2. **Features:** Billing, Invoicing, Customer Portal, Tax 3. **Ecosistema:** SDKs, webhooks, testing, documentación 4. **Escalabilidad:** Crece con el negocio 5. **Confiabilidad:** Uptime excelente, soporte 24/7 ## Implementación ### Arquitectura ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Frontend │────▶│ Backend │────▶│ Stripe │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │◀───────────────────┘ │ Webhooks ┌──────▼──────┐ │ PostgreSQL │ └─────────────┘ ``` ### Modelos de Datos ```typescript // Local (sincronizado con Stripe) Subscription { id: UUID tenant_id: UUID stripe_subscription_id: string stripe_customer_id: string plan_id: UUID status: 'trialing' | 'active' | 'past_due' | 'cancelled' current_period_start: Date current_period_end: Date } Plan { id: UUID stripe_product_id: string stripe_price_id_monthly: string stripe_price_id_yearly: string name: string price_monthly: number price_yearly: number features: JSON limits: JSON } ``` ### Flujo de Suscripción ``` 1. Usuario selecciona plan 2. Backend crea Checkout Session 3. Redirect a Stripe Checkout 4. Usuario completa pago 5. Stripe envía webhook 'checkout.session.completed' 6. Backend crea/actualiza Subscription local 7. Redirect a success page ``` ### Webhooks Críticos | Evento | Acción | |--------|--------| | `checkout.session.completed` | Crear suscripción | | `customer.subscription.updated` | Actualizar estado | | `customer.subscription.deleted` | Marcar cancelada | | `invoice.paid` | Registrar pago | | `invoice.payment_failed` | Notificar, retry | ### Customer Portal Stripe Customer Portal permite: - Ver/descargar facturas - Actualizar método de pago - Cambiar plan - Cancelar suscripción ```typescript // Crear session del portal const session = await stripe.billingPortal.sessions.create({ customer: tenant.stripe_customer_id, return_url: 'https://app.example.com/billing', }); ``` ### Plan Limits Enforcement ```typescript // Verificar límite antes de acción async canAddUser(tenantId: string): Promise { const subscription = await this.getSubscription(tenantId); const plan = await this.getPlan(subscription.plan_id); const currentUsers = await this.countUsers(tenantId); return currentUsers < plan.limits.max_users; } ``` ## Consecuencias ### Positivas - Time-to-market rápido - Sin preocupaciones PCI - Billing Portal listo para usar - Webhooks confiables - Soporte multi-moneda ### Negativas - Comisiones por transacción - Dependencia de Stripe - Sincronización de datos necesaria - Algunas features requieren Stripe Tax adicional ### Testing - Stripe Test Mode para desarrollo - Webhook testing con Stripe CLI - Cards de prueba documentadas ## Referencias - [Stripe Billing Docs](https://stripe.com/docs/billing) - [Stripe Webhooks](https://stripe.com/docs/webhooks) - [Test Cards](https://stripe.com/docs/testing) - Implementación: `apps/backend/src/modules/billing/` --- **Fecha decision:** 2026-01-10 **Autores:** Claude Code (Arquitectura)