diff --git a/workloads/docs-portal/docs/decisiones/0009-checkout-real.md b/workloads/docs-portal/docs/decisiones/0009-checkout-real.md new file mode 100644 index 0000000..2f682f7 --- /dev/null +++ b/workloads/docs-portal/docs/decisiones/0009-checkout-real.md @@ -0,0 +1,141 @@ +# ADR 0009 — Checkout real (pago en línea + envíos) para ARI Shopping + +**Estado:** propuesta — pendiente de decisión de negocio (§3) antes de +implementar +**Fecha:** 2026-08-28 + +## Contexto + +El carrito hoy no completa una transacción real: arma el pedido en el +cliente y lo cierra con un botón "Continuar por WhatsApp" +(`components/layout/navbar.tsx`, `mobile-add-to-cart.tsx`) — un +placeholder intencional, no un bug. El diálogo de cuenta ya lo admite +explícitamente ("El inicio de sesión quedará conectado al backend +headless. Mientras tanto..."). Ni checkout ni auth de clientes tienen +ADR previo ni intento de implementación en el historial de git de +ningún repo del lab — este es terreno nuevo. + +Investigación previa a este ADR (2026-08-28, confirmado contra código +real y documentación oficial vigente, no memoria de entrenamiento — +misma disciplina que ADR 0006): + +- **Pagos:** `commerce-backend/medusa-config.ts` no registra ningún + provider de pago — el único módulo configurado hoy es + `@medusajs/medusa/file` (storage S3). +- **Envíos:** existe una sola región ("Colombia", COP), creada a mano + vía Admin API durante el incidente de precios de agosto + (`incidente-medusa-precios-region-id-2026-08.md`), no vía ningún + script de seed — no existe ningún script de seed en el repo. **No + hay ninguna shipping option configurada en ningún lado.** Sin esto + el checkout no puede completarse aunque el pago ya funcione — es un + prerequisito invisible, independiente del proveedor de pago elegido. +- **Auth:** cero código de cliente/login en todo el storefront (grep + sobre `lib/`, `app/`, `components/` sin resultados para + `customer`/`login`/`useAuth`/`/store/customers`). El módulo de + auth/customer de Medusa viene incluido en el core — falta + enteramente el lado del storefront, no el backend. **Medusa soporta + checkout como invitado**, así que auth no bloquea checkout y puede + secuenciarse por separado — fuera de alcance de este ADR. + +## 1. Flujo de checkout real en Medusa v2 (Store API) + +Confirmado contra `docs.medusajs.com` (2026-08-28): el flujo son 7 +pasos encadenados — crear carrito → agregar items → dirección de envío +→ **seleccionar método de envío** (`POST` a la ruta de shipping method +del carrito, requiere que ya exista al menos una shipping option) → +payment collection → payment session → completar orden. Ningún paso +es opcional; el paso de método de envío es exactamente el que hoy no +tiene ninguna shipping option que ofrecer. + +## 2. Estado real de soporte de pago en Medusa 2.18.0 + +- **Stripe es de primera clase** (`@medusajs/medusa/payment-stripe`, + incluido en el core, no un plugin de terceros — a diferencia de la + situación de Meilisearch en ADR 0006). Configuración mínima + verificada: + + ```ts + { + resolve: "@medusajs/medusa/payment", + options: { + providers: [{ + resolve: "@medusajs/medusa/payment-stripe", + id: "stripe", + options: { apiKey: process.env.STRIPE_API_KEY }, + }], + }, + } + ``` + + Env vars: `STRIPE_API_KEY` (siempre) y `STRIPE_WEBHOOK_SECRET` + (obligatorio en producción). Tras configurar, hay que habilitar el + provider **en la región** desde el Admin — un paso manual aparte, + igual que ya pasó con la región misma. + +- **Bloqueador real de negocio, no técnico: Stripe no acepta cuentas + de comercio registradas en Colombia.** Confirmado contra + `stripe.com/global` (2026-08-28) — Brasil y México sí están en la + lista de países soportados para abrir cuenta, Colombia no aparece. + La única vía sería registrar una entidad de negocio en un país + soportado, fuera de alcance realista para este lab. Esto invalida a + Stripe como opción pese a ser la integración técnicamente más + simple y mejor documentada. +- **Alternativas con presencia real en Colombia y algún plugin de + Medusa existente:** + - **PayU** (`@tax1driver/medusa-payu`): el propio repo declara + compatibilidad explícita con Medusa `v2.4.0+` — cubre nuestra + versión (2.18.0). Webhook auto-registrado en `/hooks/payment/payu`. + - **Wompi** (`medusa-payment-wompi-col`, respaldado por Bancolombia, + liquidación directa en COP): revisé el repo directamente + (2026-08-28) y **no documenta contra qué versión de Medusa se + probó, ni tiene releases/actividad reciente visible** — mayor + riesgo de compatibilidad no verificada que PayU, aunque el + encaje de negocio (banco local, moneda nativa) sea el más + directo. Antes de elegirlo habría que repetir el nivel de + verificación que ADR 0006 le hizo al plugin de Meilisearch: leer + el código fuente real, no confiar en el README. +- **Riesgo de red ya conocido, no nuevo:** cualquier webhook de pago + entra por la misma cadena Cloudflare → NPM → Traefik que ya causó + un incidente real con otro servicio + (`incidente-cloudflared-504-quic-2026-08.md`). Validar la entrega de + webhooks en vivo antes de confiar en el flujo, no asumir que + "funciona igual que todo lo demás". + +## 3. Decisión pendiente — requiere input del usuario, no se puede resolver en este ADR + +Este ADR **no elige proveedor de pago** porque la elección real +depende de datos de negocio que no están en el código ni son míos +para decidir: + +- ¿Ya existe una cuenta bancaria/comercial en Colombia con la que + abrir Wompi (Bancolombia) o PayU directamente? +- ¿Preferencia por comisión, tiempo de liquidación, o soporte en + español de cada uno? +- Credenciales reales (API keys, webhook secrets) — nunca generadas + ni asumidas por mí. + +## Opciones consideradas + +| Opción | A favor | En contra | +|---|---|---| +| **Stripe** | Integración core de Medusa, mejor documentada, configuración mínima | No acepta comercios registrados en Colombia — bloqueador de negocio, no técnico | +| **PayU** (`@tax1driver/medusa-payu`) | Compatibilidad declarada explícitamente con Medusa 2.4.0+ (cubre 2.18.0); presencia real en Colombia | Plugin comunitario, no de primera clase; requiere la misma verificación de código fuente que ya se le hizo al plugin de Meilisearch antes de confiar en él | +| **Wompi** (`medusa-payment-wompi-col`) | Liquidación directa en COP vía Bancolombia, el encaje de negocio más directo para un comercio colombiano | Sin versión de Medusa documentada ni actividad reciente visible — mayor riesgo de compatibilidad no verificada que PayU | +| **Seguir con WhatsApp** (no pago en línea) | Cero riesgo nuevo, cero dependencia externa | No resuelve el objetivo real (transacción completa sin intervención manual); no es checkout, es lo que ya existe hoy | + +## Consecuencias (si se procede, una vez elegido el proveedor) + +- Las shipping options son un prerequisito independiente del proveedor + y deben configurarse primero — sin ellas ningún flujo de checkout + completa, sea cual sea el pago. +- Cualquier plugin comunitario (PayU o Wompi) exige la misma + disciplina de verificación que ya destapó desviaciones reales en el + plugin de Meilisearch (ADR 0006, nota de implementación): leer el + código fuente en el tag exacto que se va a instalar, no el README + genérico. +- Los webhooks de pago deben validarse en vivo contra la cadena de red + real del lab antes de confiar en el flujo, dado el precedente de + `incidente-cloudflared-504-quic-2026-08.md`. +- Revertir esta decisión (una vez implementada) implica deshabilitar + el provider en la región y volver al botón de WhatsApp — el carrito + y el catálogo no cambian de forma, solo el paso final. diff --git a/workloads/docs-portal/mkdocs.yml b/workloads/docs-portal/mkdocs.yml index 1048e4f..ab04a7d 100644 --- a/workloads/docs-portal/mkdocs.yml +++ b/workloads/docs-portal/mkdocs.yml @@ -96,6 +96,7 @@ nav: - "0006 · Motor de búsqueda y facetas": decisiones/0006-motor-busqueda-facetas.md - "0007 · Identidad visual propia": decisiones/0007-identidad-visual-propia.md - "0008 · Identidad Navy & Coral": decisiones/0008-identidad-navy-coral.md + - "0009 · Checkout real": decisiones/0009-checkout-real.md - Plantilla ADR: decisiones/plantilla-adr.md - Playbooks: - Crashloop Medusa: playbooks/incidente-crashloop-medusa.md