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
58 lines
1.9 KiB
YAML
58 lines
1.9 KiB
YAML
# NO agregar este archivo al kustomization ni subir valores reales a Gitea.
|
|
# Utiliza scripts/create-commerce-secrets.sh o reemplázalo por Sealed Secrets.
|
|
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: commerce-secrets
|
|
type: Opaque
|
|
stringData:
|
|
POSTGRES_USER: medusa
|
|
POSTGRES_PASSWORD: CAMBIAR
|
|
POSTGRES_DB: medusa
|
|
DATABASE_URL: postgresql://medusa:CAMBIAR@postgres-svc:5432/medusa
|
|
|
|
REDIS_PASSWORD: CAMBIAR
|
|
REDIS_URL: redis://:CAMBIAR@redis-svc:6379
|
|
|
|
MINIO_ROOT_USER: ari-minio
|
|
MINIO_ROOT_PASSWORD: CAMBIAR
|
|
S3_ACCESS_KEY_ID: ari-minio
|
|
S3_SECRET_ACCESS_KEY: CAMBIAR
|
|
|
|
JWT_SECRET: CAMBIAR
|
|
COOKIE_SECRET: CAMBIAR
|
|
|
|
# Master key del servidor Meilisearch (StatefulSet commerce-meilisearch,
|
|
# env MEILI_MASTER_KEY del propio contenedor getmeili/meilisearch) Y
|
|
# credencial que usa el plugin de Medusa para autenticarse contra el
|
|
# -- MISMO valor, dos nombres de secret porque cada lado (servidor vs.
|
|
# plugin cliente) usa su propia convencion de nombre de env var.
|
|
MEILI_MASTER_KEY: CAMBIAR
|
|
MEILISEARCH_API_KEY: CAMBIAR
|
|
|
|
# Debe ser el MISMO valor que REVALIDATE_SECRET en el Secret
|
|
# commerce-storefront: el subscriber de Medusa lo envía como header
|
|
# x-revalidate-secret al invocar POST /api/revalidate en el storefront.
|
|
REVALIDATE_SECRET: CAMBIAR
|
|
|
|
# PayU LatAm (ADR 0009) -- credenciales del comercio. Mientras no exista
|
|
# cuenta real, usar las de sandbox genéricas y públicas de PayU
|
|
# (developers.payulatam.com/latam/en/docs/getting-started/test-your-solution.html),
|
|
# nunca hardcodeadas acá.
|
|
PAYU_API_LOGIN: CAMBIAR
|
|
PAYU_API_KEY: CAMBIAR
|
|
PAYU_MERCHANT_ID: CAMBIAR
|
|
PAYU_ACCOUNT_ID: CAMBIAR
|
|
---
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: commerce-storefront
|
|
type: Opaque
|
|
stringData:
|
|
MEDUSA_PUBLISHABLE_KEY: pk_CAMBIAR_DESPUES_DE_CREARLA_EN_MEDUSA
|
|
|
|
# Mismo valor que REVALIDATE_SECRET en commerce-secrets.
|
|
REVALIDATE_SECRET: CAMBIAR
|