Saltar a contenido

RF-002 — Descuento automático por medio de pago

Estado En desarrollo (rama hquintero)
Tipo Middleware de API + hooks de workflow
Ubicación src/api/middlewares.ts · src/workflows/hooks/
Depende de RF-001 · módulos Promotion, Cart y Payment

Requisito

Aplicar un descuento comercial cuando el cliente elige transferencia bancaria como medio de pago, sin exigirle ingresar código alguno; retirarlo automáticamente al cambiar de medio de pago o al retroceder en el checkout; e impedir que el mismo código se aplique en forma manual sobre un carrito que no tenga sesión de transferencia activa.

Solución adoptada

Vincular una promoción existente de Medusa —identificada por su código— al provider_id de la sesión de pago, interviniendo en los tres momentos en que esa relación puede romperse.

# Punto de intervención Disparador Acción
1 Middleware sobre POST /store/payment-collections/:id/payment-sessions Creación o cambio de sesión de pago Aplicar la promoción si el provider es bank_transfer; retirarla si es cualquier otro
2 Hook validate de updateCartPromotionsWorkflow Aplicación manual del código Rechazar con INVALID_DATA si el carrito no tiene sesión de transferencia
3 Hook validate de refreshPaymentCollectionForCartWorkflow Refresco del carrito al retroceder de paso Retirar la promoción si ya no existe sesión de transferencia
flowchart TD
    A[Cliente selecciona medio de pago] --> B{provider_id}
    B -->|bank_transfer| C[Aplicar promoción<br/>updateCartPromotions · ADD]
    B -->|otro| D[Retirar promoción<br/>updateCartPromotions · REPLACE]
    E[Cliente ingresa el código a mano] --> F{¿Existe sesión<br/>de transferencia?}
    F -->|sí| C
    F -->|no| G[Rechazar con mensaje explicativo]
    H[Cliente retrocede en el checkout] --> I{¿Persiste la sesión<br/>de transferencia?}
    I -->|no| D
    I -->|sí| J[Mantener promoción]

Reglas de negocio

  • Reconocer el provider tanto por su identificador propio (bank_transfer) como por el identificador compuesto que genera Medusa (pp_bank_transfer_bank_transfer).
  • Retirar la promoción por reemplazo del conjunto de códigos, preservando las demás promociones aplicadas al carrito.
  • Aplicar la validación únicamente al código configurado; el resto de las promociones opera sin restricción por medio de pago.
  • Resolver la promoción antes de responder al storefront, para que los totales devueltos ya incluyan el descuento.
  • Registrar los errores de gestión de la promoción sin interrumpir la respuesta al cliente.

Configuración

Variable Efecto
BANK_TRANSFER_PROMO_CODE Código de la promoción a aplicar. Sin definir, desactiva por completo el middleware y ambos hooks

La promoción y su importe se administran desde el dashboard: el desarrollo propio resuelve cuándo aplicarla, no cuánto descuenta.

Criterios de aceptación

# Criterio
1 Reflejar el descuento en los totales al seleccionar transferencia, sin intervención del cliente
2 Retirar el descuento al cambiar a otro medio de pago dentro del mismo carrito
3 Rechazar el ingreso manual del código sin sesión de transferencia, con mensaje en castellano
4 Mantener las demás promociones del carrito tras aplicar o retirar la de transferencia
5 Operar el checkout sin descuento y sin error cuando la variable no está definida

Limitaciones conocidas

  • Acoplar la lógica a un único código de promoción: no admite descuentos por medio de pago múltiples ni por provider distinto de transferencia.
  • Depender de la interceptación de res.json en el middleware, lo que suma la latencia del workflow de promociones a la respuesta de creación de la sesión de pago.