PayU LatAm (integrado en el commit anterior) resultó inviable: Rapyd compró ese negocio completo en LatAm/África en 2023, y el registro real del usuario quedó en la plataforma de Rapyd (board.rapyd.net, credenciales access_key/secret_key incompatibles con el módulo ya construido, API completamente distinta). Se evaluó reconstruir contra Rapyd, pero el usuario comparó costos para su volumen real (~8 ventas/mes) y encontró que ePayco cobra menos en PSE. Se investigó ePayco en vivo: es 100% de Davivienda desde 2024, acepta liquidación a cualquier banco colombiano (no exige Bancolombia/Nequi como Wompi) y da tarifa preferencial a cuentas Davivienda -- el usuario ya tiene una. Mejor encaje de negocio y más barato que PayU/Rapyd. Confirmado como elección definitiva. - src/modules/epayco-pse/ reemplaza a src/modules/payu-pse/: mismo contrato AbstractPaymentProvider (initiatePayment/authorizePayment "pending_authorization"/getWebhookActionAndData con firma SHA256 verificada), pero envuelve el SDK oficial `epayco-sdk-node` en vez de llamar la API cruda -- leyendo el código fuente del SDK (no la documentación pública, que resultó desactualizada en más de un campo) se confirmó que el protocolo real de ePayco para PSE es bastante más particular de lo que sugieren los ejemplos: cada campo del payload se cifra con AES usando la private key del comercio, más un login previo que da un bearer token que también viaja en la misma request. Reimplementar esto a mano tenía mucho más riesgo de error que delegar en el SDK mantenido por el propio proveedor. - Corregido en el camino: el método real para listar bancos es `bank.getBanks()`, no `pseBank()` (así aparecía en un resumen de búsqueda, pero no existe en el SDK real -- confirmado leyendo node_modules/epayco-sdk-node/lib/resources/bank.js directamente). El campo real para la URL de confirmación es `method_confirmation` (con guión bajo en medio), no `metodoconfirmacion` como mostraba la documentación pública -- confirmado contra tests/bank.js del propio paquete. - retrievePayment sí se implementó esta vez (endpoint de validación de ePayco documentado); refundPayment sigue sin implementar -- ese endpoint no quedó verificado en vivo, tira error explícito en vez de fingir éxito. - Frontend: el step de pago recupera el selector de banco + tipo de persona + documento (a diferencia del diseño que se había planeado para Rapyd, donde esos datos se recolectaban en la página del propio Rapyd/SafetyPay) -- ePayco sí necesita esos campos de nuestro lado, como PayU. - Dos puntos quedan sin verificar contra un sandbox real (anotados en el código con qué hacer si fallan): el nombre exacto del campo con la URL del banco en la respuesta de bank.create() (initiatePayment tira un error con el payload completo si no matchea ningún candidato probado), y si p_cust_id_cliente/p_key del webhook son iguales a las API keys o valores aparte del dashboard de ePayco. Verificado: build real de Medusa con las 7 env vars EPAYCO_* dummy, smoke test del wrapper del SDK cargando y la verificación de firma dando el resultado esperado contra un caso conocido, typecheck+lint+ build completo del frontend. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01THZFwPzrwv6VAbuwmaf5vR
117 lines
4.0 KiB
Docker
117 lines
4.0 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
|
|
#############################################################
|
|
# Builder
|
|
#############################################################
|
|
FROM node:22.18.0-bookworm-slim AS builder
|
|
|
|
WORKDIR /app
|
|
|
|
ENV CI=true \
|
|
NODE_ENV=development \
|
|
NPM_CONFIG_UPDATE_NOTIFIER=false \
|
|
DATABASE_URL=postgres://medusa:[email protected]:5432/medusa \
|
|
REDIS_URL=redis://127.0.0.1:6379 \
|
|
STORE_CORS=http://localhost:8000 \
|
|
ADMIN_CORS=http://localhost:7001 \
|
|
AUTH_CORS=http://localhost:7001 \
|
|
JWT_SECRET=build-only-jwt-secret \
|
|
COOKIE_SECRET=build-only-cookie-secret \
|
|
S3_FILE_URL=http://localhost:9000/ari-shopping \
|
|
S3_ACCESS_KEY_ID=build-access-key \
|
|
S3_SECRET_ACCESS_KEY=build-secret-key \
|
|
S3_BUCKET=ari-shopping \
|
|
S3_ENDPOINT=http://127.0.0.1:9000 \
|
|
MEILISEARCH_HOST=http://127.0.0.1:7700 \
|
|
MEILISEARCH_API_KEY=build-only-meili-key \
|
|
GOOGLE_CLIENT_ID=build-only-google-client-id \
|
|
GOOGLE_CLIENT_SECRET=build-only-google-client-secret \
|
|
GOOGLE_CALLBACK_URL=http://localhost:9000/auth/customer/google/callback \
|
|
EPAYCO_PUBLIC_KEY=build-only-epayco-public \
|
|
EPAYCO_PRIVATE_KEY=build-only-epayco-private \
|
|
EPAYCO_P_CUST_ID_CLIENTE=build-only-epayco-pcust \
|
|
EPAYCO_P_KEY=build-only-epayco-pkey \
|
|
EPAYCO_ENV=sandbox \
|
|
EPAYCO_RESPONSE_URL=http://localhost:8000/checkout/pse/return \
|
|
EPAYCO_NOTIFY_URL=http://localhost:9000/hooks/payment/epayco_pse
|
|
|
|
COPY package.json package-lock.json .npmrc ./
|
|
|
|
RUN --mount=type=cache,id=medusa-npm-cache,target=/root/.npm \
|
|
npm ci \
|
|
--legacy-peer-deps \
|
|
--prefer-offline \
|
|
--no-audit \
|
|
--no-fund
|
|
|
|
COPY tsconfig.json ./
|
|
COPY medusa-config.ts ./
|
|
COPY src ./src
|
|
|
|
RUN npm run build
|
|
|
|
#
|
|
# Elimina todas las dependencias de desarrollo
|
|
#
|
|
RUN npm prune --omit=dev
|
|
|
|
#
|
|
# Limpia cache de npm
|
|
#
|
|
RUN npm cache clean --force
|
|
|
|
#############################################################
|
|
# Runtime
|
|
#############################################################
|
|
FROM node:22.18.0-bookworm-slim
|
|
|
|
WORKDIR /app
|
|
|
|
ENV NODE_ENV=production \
|
|
PORT=9000 \
|
|
NPM_CONFIG_UPDATE_NOTIFIER=false
|
|
|
|
#
|
|
# libgnutls30 en la base node:22.18.0-bookworm-slim trae dos CVE
|
|
# CRITICAL con fix ya publicado por Debian (CVE-2026-33845,
|
|
# CVE-2026-42010) -- detectado por el gate de Trivy imagen del
|
|
# pipeline (run 138). Solo se actualiza este paquete puntual, no toda
|
|
# la imagen, para minimizar el diff de superficie de la base.
|
|
RUN apt-get update \
|
|
&& apt-get upgrade -y libgnutls30 \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# El CLI global de npm que trae la imagen base node:*-slim arrastra su
|
|
# propia copia vendorizada de `tar` con un CVE CRITICAL
|
|
# (CVE-2026-59873, detectado por Trivy en
|
|
# usr/local/lib/node_modules/npm/node_modules/tar). Se elimina npm
|
|
# entero -- no alcanza con borrar solo el tar vendorizado: el propio
|
|
# `npx` depende de ese tar internamente (pacote/arborist) incluso para
|
|
# ejecutar un binario ya instalado localmente, así que queda roto igual
|
|
# si el paquete tar desaparece pero npm sigue ahí (confirmado
|
|
# probando "npx medusa --version" contra la imagen: falla con
|
|
# "Cannot find module 'tar'").
|
|
#
|
|
# OJO con este cambio: el init container "migrations" de
|
|
# workloads/ecommerce/commerce/medusa.yaml corría "npx medusa
|
|
# db:migrate" contra esta misma imagen -- un primer intento de este
|
|
# fix borraba npm sin ajustar ese comando y rompió el init container
|
|
# en producción ("npx: executable file not found in $PATH",
|
|
# medusa-deploy atascado en Init:CrashLoopBackOff, detectado revisando
|
|
# el estado real del cluster después del deploy). El fix completo
|
|
# incluye cambiar ese comando a invocar el CLI directo con `node`, sin
|
|
# pasar por npm/npx -- mismo patrón que ya usa el CMD de este
|
|
# Dockerfile más abajo.
|
|
RUN rm -rf /usr/local/lib/node_modules/npm
|
|
|
|
#
|
|
# Solo lo necesario para ejecutar Medusa
|
|
#
|
|
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
|
|
COPY --from=builder --chown=node:node /app/.medusa/server ./
|
|
|
|
USER node
|
|
|
|
EXPOSE 9000
|
|
|
|
CMD ["node","node_modules/@medusajs/cli/dist/index.js","start"] |