diff --git a/workloads/docs-portal/docs/decisiones/0010-pago-envio-reales-y-storefront.md b/workloads/docs-portal/docs/decisiones/0010-pago-envio-reales-y-storefront.md index e8c5c8b..d94682e 100644 --- a/workloads/docs-portal/docs/decisiones/0010-pago-envio-reales-y-storefront.md +++ b/workloads/docs-portal/docs/decisiones/0010-pago-envio-reales-y-storefront.md @@ -244,9 +244,12 @@ reubicó su contenedor según el breakpoint. ## Consecuencias - Checkout real de punta a punta (pago + envío calculado) queda - desplegado y verificado a nivel API/backend, pero **ambos proveedores - siguen en modo sandbox** — no se ha completado ni un pago real ni un - envío real todavía. Ver checklist de pruebas abajo. + desplegado y verificado con navegador real hasta la redirección al + banco de PSE (ver nota de implementación 2026-09-10 abajo), pero + **ambos proveedores siguen en modo sandbox** — no se ha completado ni + un pago real ni un envío real todavía, y el login bancario de PSE + tampoco se completó (falta credencial de prueba). Ver checklist + ampliado abajo. - La precisión de la tarifa de envío depende de cargar peso/dimensiones reales por producto — deuda de datos explícita, no de código; candidato natural a extender el importador CSV existente con columnas nuevas. @@ -262,37 +265,92 @@ reubicó su contenedor según el breakpoint. ## Checklist de pruebas reales desde el storefront (pendiente, no ejecutado en este ADR) -Todo lo de arriba se verificó a nivel API/backend con llamadas directas -o carritos de prueba armados por API — **no** todavía manejando el -storefront real como lo haría un comprador. Pendiente, con la próxima -sesión que tenga acceso a un navegador real: +Todo lo de arriba se verificó primero a nivel API/backend con llamadas +directas o carritos de prueba armados por API, sin manejar el +storefront real como lo haría un comprador. Esa parte del checklist se +cerró el 2026-09-10 (ver nota de implementación abajo) usando un +navegador real de verdad, no curl. -1. **Pago PSE completo:** agregar un producto real al carrito → checkout - → elegir PSE → seleccionar un banco del listado real (sandbox) → - confirmar que la redirección al banco ocurre (esto es justo lo que - nunca se probó — el nombre del campo de URL de `bank.create()` está - manejado a la defensiva y podría no matchear ningún candidato) → - volver a `/checkout/pse/return` → confirmar que la orden queda en - estado correcto. -2. **Envío calculado real:** en el paso de dirección del checkout, - confirmar que el precio de envío mostrado ya no es el fijo de - $15.000 sino el que devuelve EnvíoClick en vivo para esa dirección - (visible también sin completar el pago, solo llegando al paso de - shipping). -3. **Resiliencia del fallback de envío:** si es posible, forzar una - dirección o producto que haga fallar la cotización real (por ejemplo, - un DANE code inválido) y confirmar que el checkout sigue avanzando - con el precio de respaldo en vez de romperse — el comportamiento - documentado en `calculatePrice()`, nunca ejercitado con un fallo real. -4. **Banner dinámico:** confirmar en `/` que el carrusel muestra - productos reales del catálogo (no las tres imágenes viejas - hardcodeadas) y que cada slide lleva al producto correcto al hacer - clic. -5. **Buscador:** en un viewport mobile real (no solo devtools), confirmar - que el buscador ya no se ve recortado y que el autocompletado - despliega bien debajo de la fila nueva a todo el ancho. -6. **Webhook de ePayco con un pago real de sandbox:** confirmar que, - tras completar un pago PSE de prueba desde el banco sandbox, el - webhook mueve la orden a completada sin intervención manual (hoy solo - se confirmó que el endpoint responde `200` a un `POST` sintético, no - con un webhook real disparado por ePayco). +### RESUELTO (2026-09-10) — navegador real vía Docker en la NAS + +El shell donde corren los comandos de esta sesión tiene su propia red +restringida para `npm` (un proxy interno que rompe algunas descargas de +paquetes — no relacionado con la red real del lab). **Docker en la NAS +sí sale a internet real, sin ese filtro** — confirmado en vivo +(`docker pull` normal, un contenedor de Node golpeando +`registry.npmjs.org` sin problema). Se armó un harness reutilizable con +la imagen oficial `mcr.microsoft.com/playwright:v1.51.1-jammy` +(Chromium real) corrida puntualmente contra `shop.cruzcloud.net`, +guardado en `.browser-scratch/` en la raíz del lab (`checks.mjs` + +`README.md` con el comando exacto para reactivarlo — no hace falta +ningún contenedor corriendo de forma persistente, la imagen y las +dependencias ya quedan cacheadas localmente en la NAS). + +**Hallazgo no obvio:** el daemon de Docker de la NAS ve un filesystem +distinto al que ve el shell de esta sesión (que corre en su propio +sandbox, aunque monte los mismos repos git) — un volumen `-v` apuntando +a un path de `/tmp` del shell no tira error pero monta un directorio +vacío del lado del contenedor. Hay que usar un path bajo +`/media/HDD-Storage/AppData/k3d-lab-v3/lab-cruzcloud/` (montaje real +compartido) para que el contenedor vea los archivos de verdad. + +**Resultados, con capturas reales:** + +1. **Pago PSE completo — FUNCIONA.** Carrito → dirección Bogotá → + envío calculado → banco PSE (sandbox) → **la redirección real + funcionó**: el nombre de campo manejado a la defensiva en + `bank.create()`/`initiatePayment` matcheó al primer intento, y el + navegador llegó a la página real de autorización de PSE + (`registro.desarrollo.pse.com.co`, ambiente de desarrollo/sandbox + de PSE Colombia). No se completó el login bancario (requiere + credenciales de prueba específicas de PSE que no se tenían a mano) — + sigue pendiente confirmar el webhook con un pago sandbox completado + de principio a fin (ver checklist nuevo abajo). +2. **Envío calculado real — FUNCIONA.** El paso de pago mostró + `Envío $8.941` (mismo valor ya visto en la verificación por API de + la sección anterior) en vez del fijo de $15.000, para una dirección + real de Bogotá. +3. **Banner dinámico — funciona, pero destapó un bug real:** un + producto marcado `featured: true` pero **sin stock** + (`available: false`, "Toy Story 5 - Rex") salía primero en el + carrusel con botón "Comprar ahora" hacia una página donde en + realidad no se puede comprar. Corregido en el mismo commit que este + hallazgo (filtro adicional `&& product.available` en + `app/page.tsx`). +4. **Buscador mobile — funciona.** El buscador ya no se ve recortado, + y el autocompletado despliega bien debajo de la fila nueva a todo el + ancho (probado con el viewport de un iPhone 13 real, no devtools). +5. **Bug adicional encontrado, no buscado:** el sandbox real de ePayco + (`bank.getBanks()`) devuelve un primer elemento placeholder + (`bankCode: "0"`, `"A continuación seleccione su banco..."` con el + texto mal decodificado — unicode escapado literal) mezclado con los + bancos reales, mostrado como una opción más, seleccionable, en el + `