diff --git a/PAYMENTS.md b/PAYMENTS.md new file mode 100644 index 0000000..d51f8f1 --- /dev/null +++ b/PAYMENTS.md @@ -0,0 +1,257 @@ +# Sistema de Pagos con Stripe + +Este documento explica cómo configurar y usar el sistema de pagos integrado con Stripe en Wallabicher. + +## Configuración + +### 1. Crear cuenta de Stripe + +1. Visita [https://stripe.com](https://stripe.com) y crea una cuenta +2. Accede al Dashboard de Stripe +3. Obtén tus claves API desde: Developers → API keys + +### 2. Configurar variables de entorno + +Crea un archivo `.env` en `/web/backend/` con las siguientes variables: + +```bash +# Stripe Configuration +STRIPE_SECRET_KEY=sk_test_xxxxx # Tu clave secreta de Stripe +STRIPE_WEBHOOK_SECRET=whsec_xxxxx # Secret del webhook (ver paso 3) +BASE_URL=http://localhost # URL base de tu aplicación +``` + +### 3. Configurar Webhooks de Stripe + +Los webhooks son necesarios para que Stripe notifique a tu aplicación sobre eventos de pago: + +1. Ve a Developers → Webhooks en el Dashboard de Stripe +2. Haz clic en "Add endpoint" +3. URL del endpoint: `https://tu-dominio.com/api/payments/webhook` +4. Selecciona los siguientes eventos: + - `checkout.session.completed` + - `customer.subscription.updated` + - `customer.subscription.deleted` + - `invoice.payment_succeeded` + - `invoice.payment_failed` +5. Copia el "Signing secret" (whsec_xxxxx) y agrégalo a `STRIPE_WEBHOOK_SECRET` + +### 4. Configurar productos y precios en Stripe (Opcional) + +El sistema crea automáticamente los productos y precios en Stripe si no existen, pero puedes crearlos manualmente: + +**Productos:** +- Wallabicher Básico +- Wallabicher Pro +- Wallabicher Enterprise + +**Precios:** +- Cada producto debe tener precios mensual y anual +- Los `lookup_key` deben seguir el formato: `{planId}_{billingPeriod}` (ej: `basic_monthly`, `pro_yearly`) + +### 5. Actualizar Docker Compose + +Descomenta las variables de Stripe en `docker-compose.yml`: + +```yaml +environment: + - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY} + - STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET} + - BASE_URL=${BASE_URL:-http://localhost} +``` + +Luego crea un archivo `.env` en la raíz del proyecto: + +```bash +STRIPE_SECRET_KEY=sk_test_xxxxx +STRIPE_WEBHOOK_SECRET=whsec_xxxxx +BASE_URL=https://tu-dominio.com +``` + +## Flujo de registro y pago + +### 1. Registro de usuario + +Los usuarios pueden registrarse desde la landing page o directamente en `/dashboard/register`: + +1. Usuario selecciona un plan +2. Completa el formulario de registro (usuario, email, contraseña) +3. Si es plan gratuito: + - Se crea la cuenta inmediatamente + - Redirige al dashboard +4. Si es plan de pago: + - Se crea la cuenta + - Se inicia sesión automáticamente + - Redirige a Stripe Checkout + +### 2. Checkout de Stripe + +En Stripe Checkout el usuario: +- Ingresa información de tarjeta +- Confirma el pago +- Es redirigido de vuelta al dashboard + +### 3. Gestión de suscripción + +Desde `/dashboard/subscription` el usuario puede: +- Ver su plan actual y límites +- Ver uso de búsquedas +- Cambiar de plan +- Cancelar suscripción +- Reactivar suscripción cancelada +- Gestionar método de pago (portal de Stripe) + +## Endpoints API + +### Pagos + +- `POST /api/payments/create-checkout-session` - Crear sesión de checkout +- `POST /api/payments/create-portal-session` - Abrir portal de cliente +- `POST /api/payments/cancel-subscription` - Cancelar suscripción +- `POST /api/payments/reactivate-subscription` - Reactivar suscripción +- `POST /api/payments/webhook` - Webhook de Stripe (sin autenticación) + +### Usuarios + +- `POST /api/users/register` - Registro público +- `POST /api/users/login` - Iniciar sesión +- `POST /api/users/logout` - Cerrar sesión +- `GET /api/users/me` - Información del usuario actual + +### Suscripciones + +- `GET /api/subscription/plans` - Obtener planes disponibles +- `GET /api/subscription/me` - Obtener suscripción actual +- `PUT /api/subscription/me` - Actualizar suscripción + +## Límites de planes + +Los límites se aplican automáticamente mediante middleware: + +### Plan Gratuito +- 2 búsquedas simultáneas +- Solo Wallapop +- 50 notificaciones/día + +### Plan Básico (€9.99/mes) +- 5 búsquedas simultáneas +- Wallapop + Vinted +- 200 notificaciones/día + +### Plan Pro (€19.99/mes) +- 15 búsquedas simultáneas +- Todas las plataformas +- 1000 notificaciones/día + +### Plan Enterprise (€49.99/mes) +- Búsquedas ilimitadas +- Todas las plataformas +- Notificaciones ilimitadas + +## Modo de prueba vs Producción + +### Modo de prueba (Desarrollo) + +Usa claves de prueba (`sk_test_xxxxx`): +- No se procesan pagos reales +- Usa tarjetas de prueba: `4242 4242 4242 4242` +- Los webhooks requieren Stripe CLI o túnel (ngrok) + +Para probar webhooks localmente: + +```bash +stripe listen --forward-to localhost:3001/api/payments/webhook +``` + +### Modo producción + +#### 1. Obtener claves LIVE de Stripe + +1. Ve a https://dashboard.stripe.com/apikeys (modo **LIVE**) +2. Copia la clave secreta `sk_live_...` +3. **¡IMPORTANTE!** Nunca hagas commit de esta clave a git + +#### 2. Configurar webhook en Stripe Dashboard + +1. Ve a https://dashboard.stripe.com/webhooks (modo **LIVE**) +2. Click en **"Add endpoint"** +3. **Endpoint URL:** Tu dominio + la ruta del webhook + ``` + https://tudominio.com/api/payments/webhook + ``` + Ejemplos: + - `https://wallabag.midominio.com/api/payments/webhook` + - `https://api.miapp.com/api/payments/webhook` + +4. **Selecciona estos eventos:** + - `checkout.session.completed` + - `customer.subscription.updated` + - `customer.subscription.deleted` + - `invoice.payment_succeeded` + - `invoice.payment_failed` + +5. **Guarda** y copia el **Webhook signing secret** (`whsec_...`) + +#### 3. Variables de entorno en tu servidor + +**Docker Compose (VPS/servidor propio):** +```bash +# En tu servidor, edita .env +STRIPE_SECRET_KEY=sk_live_TU_CLAVE_REAL +STRIPE_WEBHOOK_SECRET=whsec_SECRET_DEL_WEBHOOK +BASE_URL=https://tudominio.com + +# Reinicia los contenedores +docker-compose restart backend +``` + +**Heroku:** +```bash +heroku config:set STRIPE_SECRET_KEY=sk_live_... +heroku config:set STRIPE_WEBHOOK_SECRET=whsec_... +heroku config:set BASE_URL=https://tu-app.herokuapp.com +``` + +**Railway/Render/Vercel:** +Añade las variables en el panel de configuración del servicio. + +#### 4. ⚠️ Requisitos obligatorios + +- **HTTPS habilitado** (Stripe requiere HTTPS en producción) +- Certificado SSL válido +- Dominio accesible públicamente + +## Seguridad + +- Las claves de Stripe NUNCA deben exponerse en el frontend +- Los webhooks verifican la firma automáticamente +- Las rutas de pago requieren autenticación (excepto webhook) +- Los administradores pueden gestionar suscripciones de todos los usuarios + +## Troubleshooting + +### Los webhooks no funcionan + +1. Verifica que `STRIPE_WEBHOOK_SECRET` esté configurado +2. Verifica que la URL del webhook en Stripe sea correcta +3. En desarrollo, usa `stripe listen` para reenviar webhooks +4. Revisa los logs en Stripe Dashboard → Developers → Webhooks + +### Los pagos no se reflejan + +1. Verifica que el webhook esté recibiendo eventos +2. Verifica logs del backend para errores +3. Verifica que los metadatos (userId, planId) se estén enviando correctamente + +### Error "Stripe no está configurado" + +- Verifica que `STRIPE_SECRET_KEY` esté en variables de entorno +- Reinicia el servidor backend después de configurar + +## Recursos + +- [Documentación de Stripe](https://stripe.com/docs) +- [Stripe Checkout](https://stripe.com/docs/payments/checkout) +- [Stripe Webhooks](https://stripe.com/docs/webhooks) +- [Stripe CLI](https://stripe.com/docs/stripe-cli) + diff --git a/docker-compose.yml b/docker-compose.yml index 972f0a4..1adab12 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -37,6 +37,9 @@ services: - MONGODB_DATABASE=wallabicher - MONGODB_USERNAME=admin - MONGODB_PASSWORD=adminpassword + - STRIPE_SECRET_KEY=sk_test_51SrpOfH73CrYqhOp2NfijzzU07ADADmwigscMVdLGzKu9zA83dsrODhfsaY1X4EFTSihhIB0lVtDQ2HpeOfMWTur00YLuuktSL + - STRIPE_WEBHOOK_SECRET=whsec_8ebec8c2aa82a791aa9f2cd68211e297a5d172aea62ebd7b771d230e3a597aa8 + - BASE_URL=https://wb.pribyte.cloud/api volumes: # Montar archivos de configuración y datos en ubicación predecible - ./config.yaml:/data/config.yaml:ro diff --git a/web/backend/services/stripe.js b/web/backend/services/stripe.js index 5bf5735..bbbc499 100644 --- a/web/backend/services/stripe.js +++ b/web/backend/services/stripe.js @@ -214,7 +214,7 @@ export function verifyWebhookSignature(payload, signature) { let webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; if (!webhookSecret) { - webhookSecret = 'whsec_8ebec8c2aa82a791aa9f2cd68211e297a5d172aea62ebd7b771d230e3a597aa8'; + webhookSecret = 'whsec_n6tTKRSG38WJQDRX8jLjZTs7kPKxbdNP'; } if (!webhookSecret) {