diff --git a/workloads/docs-portal/docs/decisiones/0009-checkout-real.md b/workloads/docs-portal/docs/decisiones/0009-checkout-real.md index ada1c55..f8449c9 100644 --- a/workloads/docs-portal/docs/decisiones/0009-checkout-real.md +++ b/workloads/docs-portal/docs/decisiones/0009-checkout-real.md @@ -126,28 +126,29 @@ Verificado contra fuentes reales el mismo día (no memoria): los métodos que se pidieron (PSE + Nequi "y demás bancos") sin que la cuenta bancaria propia del comercio sea Bancolombia. -**Decisión:** PayU, vía el plugin comunitario `@tax1driver/medusa-payu` -(compatibilidad declarada con Medusa 2.4.0+, cubre nuestra versión -2.18.0). Wompi queda descartado por el requisito de registro -Bancolombia/Nequi, no por limitación técnica del plugin en sí. +**Decisión:** PayU como proveedor de pago (negocio) se mantiene. La vía +técnica cambió el 2026-08-29 — ver nota de implementación al final de +este documento: ningún plugin comunitario de Medusa sirve para PayU +LatAm, hace falta un módulo de pago custom. Wompi queda descartado por +el requisito de registro Bancolombia/Nequi, no por limitación técnica. **Pendiente antes de implementar (no resoluble en este ADR):** - Registro real de comercio en PayU (persona natural o jurídica — jurídica pide NIT, representante legal y estados financieros - básicos) y credenciales reales (API keys, merchant ID, webhook - config) — nunca generadas ni asumidas por mí. -- Verificar el código fuente real de `@tax1driver/medusa-payu` en el - tag exacto a instalar antes de confiar en su documentación, misma - disciplina que ya destapó desviaciones reales en el plugin de - Meilisearch (ADR 0006). + básicos) y credenciales reales (`apiLogin`, `apiKey`, `merchantId`, + `accountId` — terminología real de la API de PayU LatAm, ver nota de + implementación) — nunca generadas ni asumidas por mí. +- Escribir el módulo de pago custom para PayU LatAm (no instalar un + plugin — no existe ninguno real para esta API, ver nota de + implementación). ## 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`) — **elegido** | Compatibilidad declarada explícitamente con Medusa 2.4.0+ (cubre 2.18.0); solo exige cuenta bancaria colombiana a nombre del comercio, sin banco específico (encaja con Davivienda/Lulo Bank/Banco de Bogotá); soporta PSE + Nequi + Daviplata para el cliente sin importar el banco del comercio | 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 | +| **PayU** — **elegido** (proveedor de negocio; integración técnica ahora es custom, ver nota de implementación) | Solo exige cuenta bancaria colombiana a nombre del comercio, sin banco específico (encaja con Davivienda/Lulo Bank/Banco de Bogotá); soporta PSE + Nequi + Daviplata para el cliente sin importar el banco del comercio | Ningún plugin de Medusa real sirve para su API LatAm (`apiLogin`/`apiKey`/`accountId`) — los dos paquetes que parecían encajar por nombre son en realidad para PayU Polonia/CEE (`clientId`/`posId`/`secondKey`), uno de ellos archivado; requiere módulo de pago custom | | **Wompi** (`medusa-payment-wompi-col`) | Liquidación directa en COP vía Bancolombia | Exige cuenta Bancolombia o, como mínimo, Nequi solo para **registrarse** como comercio — ninguno de los bancos disponibles (Davivienda/Lulo Bank/Banco de Bogotá) califica sin abrir una cuenta nueva; además, sin versión de Medusa documentada ni actividad reciente visible en el plugin | | **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 | @@ -156,17 +157,14 @@ Bancolombia/Nequi, no por limitación técnica del plugin en sí. - 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. -- Al ser `@tax1driver/medusa-payu` un plugin comunitario (no de - primera clase como Stripe), 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 - ni asumir que "compatibilidad declarada" significa "verificado en - este proyecto". -- Los webhooks de pago (registrados por el plugin en - `/hooks/payment/payu`) 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`. +- El pago de PayU se implementa como módulo custom (`AbstractPaymentProvider` + de Medusa) contra la API real de PayU LatAm, no como instalación de + un plugin de terceros — más superficie propia para mantener, mismo + patrón de esfuerzo que ya se identificó para EnvíoClick en §2. +- Los webhooks de pago (a definir en el módulo custom, apuntando a la + URL de notificación real de PayU LatAm) 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`. - Se acepta como deuda: si en el futuro se abre una cuenta Bancolombia o Nequi, Wompi (liquidación más directa en COP) vuelve a ser una opción válida a reevaluar — no se descarta por limitación técnica, @@ -174,3 +172,56 @@ Bancolombia/Nequi, no por limitación técnica del plugin en sí. - Revertir esta decisión 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. + +## Nota de implementación (2026-08-29): shipping options creadas + +Bloqueador de §1 resuelto en producción, verificado extremo a extremo +contra el Store API real (no solo creado en Admin): + +- Stock location "Bodega principal ARI Shopping" (`sloc_01M15G3D1336V8WQW3VZQRP6AN`). +- Fulfillment set + zona de servicio "Colombia" (`geo_zone` tipo país, `co`). +- Provider `manual_manual` habilitado en la ubicación. +- Shipping option "Envío nacional estándar", tarifa fija $15.000 COP + (placeholder de negocio dentro del rango real de mercado + $12.000–$18.000 que dio el usuario, no un cálculo por peso/volumen — + eso es justamente lo que EnvíoClick resolvería más adelante), + vinculada al Default Shipping Profile y a la región Colombia/COP. +- **Paso no documentado en ningún lado y que rompía todo en silencio:** + la stock location tiene que estar vinculada al Sales Channel + (`/admin/stock-locations/{id}/sales-channels`) para que el Store API + devuelva la shipping option — sin esto, `GET /store/shipping-options` + devolvía `[]` vacío pese a que el fulfillment set, la zona de + servicio y el provider ya estaban bien configurados. Confirmado con + un carrito de prueba real (dirección `co` + `cart_id`) antes y + después del vínculo. + +## Nota de implementación 2 (2026-08-29): corrección — no existe plugin real para PayU LatAm + +Antes de instalar nada se verificó el código/README real de los dos +únicos paquetes de Medusa que aparecen buscando "PayU" — misma +disciplina que ya aplicó ADR 0006 al plugin de Meilisearch, esta vez +con un resultado distinto: **ninguno de los dos sirve.** + +- `@tax1driver/medusa-payu`: opciones de configuración `clientId`, + `clientSecret`, `merchantPosId`, `secondKey` — terminología exacta + de la API de **PayU Polonia/CEE** (OAuth + `posId`), no de PayU + LatAm. +- `medusa-plugin-payu` (`rigby-sh/medusa-plugin-payu`): mismo problema + (`clientId`, `posId`, sandbox en `secure.snd.payu.com`, dominio de + PayU Europa) y además **archivado desde 2025-03-21** — sin + mantenimiento. +- La API real que se necesita, PayU LatAm + (`developers.payulatam.com`, la que cubre Colombia junto con + Argentina/Brasil/Chile/México/Panamá/Perú), autentica con + `apiLogin`/`apiKey` en el objeto merchant y `accountId` en el + objeto order — un modelo de autenticación distinto, no solo nombres + de campo distintos. + +"PayU" es una marca compartida por dos productos/API históricamente +separados (LatAm vs. Europa/CEE); un paquete que dice "PayU" a secas +sin especificar LatAm es, con alta probabilidad, para el producto +europeo. **Consecuencia:** la integración de pago se implementa como +módulo custom de Medusa (`AbstractPaymentProvider`) contra +`developers.payulatam.com` directamente — mismo tipo de esfuerzo que +ya se había anticipado para EnvíoClick en §2, no una instalación de +plugin como asumía la decisión original de este ADR.