ADR 0009 ya había decidido PayU LatAm como proveedor (única opción que no exige cuenta Bancolombia/Nequi) y confirmado que no existe ningún plugin real de Medusa para su API -- los paquetes que aparecen buscando "PayU" son para PayU Polonia/CEE, API completamente distinta (clientId/posId/secondKey vs. apiLogin/apiKey/merchantId/accountId). Este commit implementa esa decisión: módulo de pago custom (AbstractPaymentProvider) para PSE (transferencia bancaria), primer alcance del método de pago -- Nequi/Daviplata quedan fuera por ahora. Backend (commerce-backend): - src/modules/payu-pse/: initiatePayment arma y postea SUBMIT_TRANSACTION contra la API real de PayU LatAm; authorizePayment devuelve "pending_authorization" (PSE es async, la confirmación real llega por webhook, no en el momento de completar el carrito); getWebhookActionAndData valida la firma MD5 del webhook antes de confiar en cualquier confirmación de pago -- falla cerrado si no matchea. refundPayment/ retrievePayment tiran error explícito en vez de simular éxito: esos endpoints de PayU no quedaron verificados en vivo y hay dinero real de por medio. - No hace falta un subscriber propio para completar la orden -- el subscriber nativo de Medusa (payment-webhook + process-payment-workflow) ya hace ese trabajo con los métodos de arriba bien implementados (confirmado leyendo el código fuente instalado de @medusajs/medusa 2.18.0, no la documentación). - Correlación webhook↔sesión: Medusa inyecta su propio session_id en `data` antes de initiatePayment; se usa ese mismo valor como referenceCode de PayU, así el reference_sale que vuelve en el webhook ya es directamente el session_id de Medusa. - src/lib/payu.ts: cliente HTTP + firmas (orden y webhook, fórmulas distintas, confirmadas contra el SDK PHP oficial de PayU). - src/api/store/payments/pse-banks/route.ts: lista de bancos PSE, cacheada en memoria. - medusa-config.ts, Dockerfile, configmap/secrets.template: 7 env vars nuevas (PAYU_API_LOGIN/API_KEY/MERCHANT_ID/ACCOUNT_ID/ENV/RESPONSE_URL/ NOTIFY_URL), dummies de build agregados, secrets con placeholder "CAMBIAR". Frontend (ecommerce): - Nuevo step "payment" en components/checkout/checkout-client.tsx (reemplaza al step "review" que solo ofrecía WhatsApp): selector de banco, tipo de persona (N/J), tipo/número de documento, botón "Pagar con PSE" que crea la sesión de pago, completa el carrito y redirige al banco (navegación completa, no iframe -- así lo exige PayU). WhatsApp queda como respaldo manual si falla la iniciación del pago. - lib/headless/providers/medusa-payment.ts + 3 rutas proxy nuevas bajo app/api/cart/, mismo patrón que el resto del carrito (medusaCartFetch, ahora exportado desde medusa-cart.ts). - app/checkout/pse/return/: página de vuelta del banco -- nunca afirma éxito, la confirmación real es el webhook async. Arranca contra las credenciales de sandbox genéricas y públicas de PayU (developers.payulatam.com) mientras el usuario termina su propio registro de comercio -- swap de las 4 credenciales via secret cuando estén listas, sin cambios de código. Verificado: build real de Medusa con las env vars dummy (no solo tsc), tipos de AbstractPaymentProvider/WebhookActionResult/PaymentActions confirmados contra @medusajs/utils y @medusajs/types instalados (node_modules limpiado después), typecheck + lint + build completo del frontend, páginas nuevas renderizando sin error. Pendiente: prueba end-to-end contra el sandbox real de PayU (necesita el backend desplegado) y habilitar el provider en la región Colombia desde el Admin. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01THZFwPzrwv6VAbuwmaf5vR
35 lines
1.2 KiB
YAML
35 lines
1.2 KiB
YAML
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: commerce-config
|
|
data:
|
|
NODE_ENV: production
|
|
PORT: "9000"
|
|
|
|
STORE_CORS: https://shop.cruzcloud.net
|
|
ADMIN_CORS: https://commerce.cruzcloud.net
|
|
AUTH_CORS: https://commerce.cruzcloud.net,https://shop.cruzcloud.net
|
|
|
|
MEDUSA_BACKEND_URL: https://commerce.cruzcloud.net
|
|
STOREFRONT_URL: https://shop.cruzcloud.net
|
|
MEDUSA_WORKER_MODE: shared
|
|
DISABLE_MEDUSA_ADMIN: "false"
|
|
|
|
S3_FILE_URL: https://media.cruzcloud.net/ari-products
|
|
S3_ENDPOINT: http://minio-svc:9000
|
|
S3_REGION: us-east-1
|
|
S3_BUCKET: ari-products
|
|
|
|
# Leido por el plugin @rokmohar/medusa-plugin-meilisearch (nombre de
|
|
# env var del plugin, no del servidor Meilisearch en si -- ver
|
|
# MEILI_MASTER_KEY en secrets.template.yaml).
|
|
MEILISEARCH_HOST: http://meilisearch-svc:7700
|
|
|
|
# PayU LatAm (ADR 0009) -- solo URLs/config no sensible, credenciales
|
|
# reales (apiLogin/apiKey/merchantId/accountId) van en
|
|
# secrets.template.yaml. PAYU_ENV=sandbox hasta que haya credenciales
|
|
# de produccion reales.
|
|
PAYU_ENV: sandbox
|
|
PAYU_RESPONSE_URL: https://shop.cruzcloud.net/checkout/pse/return
|
|
PAYU_NOTIFY_URL: https://commerce.cruzcloud.net/hooks/payment/payu_pse
|