E-commerce: cómo diseñar devoluciones parciales sin desordenar pedidos y pagos
Un cliente compra una mochila y una chaqueta en el mismo pedido, pero decide devolver únicamente la chaqueta. La tienda recibe el producto, debe ajustar el inventario, devolver solo el importe correspondiente y conservar la mochila como parte válida de la compra. Si el sistema trata la devolución como una operación binaria sobre todo el pedido, es fácil terminar con estados contradictorios: un pedido marcado como cancelado, un reembolso duplicado o un inventario que no refleja lo ocurrido.
Diseñar bien una devolución parcial requiere separar varias realidades que suelen confundirse: el movimiento físico del producto, el reembolso del dinero, el ajuste de inventario y el estado general del pedido. En este artículo veremos cómo modelarlas, qué invariantes conviene proteger, cómo tratar eventos tardíos y qué pruebas ayudan a detectar errores antes de que lleguen a producción.
Una devolución parcial no es una sola operación
Un pedido puede contener varios productos y cada uno puede atravesar un ciclo diferente. Por eso, la devolución parcial debería modelarse como una operación relacionada con una o más líneas del pedido, no como un cambio directo del estado global.
Supongamos el siguiente pedido:
- Una mochila: cantidad 1, precio de 80 €.
- Una chaqueta: cantidad 1, precio de 120 €.
- Total del pedido: 200 €.
Si el cliente devuelve la chaqueta, al menos cuatro hechos deben registrarse por separado:
- Devolución física: la tienda recibe la chaqueta y decide si es aceptada, rechazada o queda pendiente de inspección.
- Reembolso: se solicita o confirma la devolución de 120 €, según las reglas comerciales y financieras aplicables.
- Ajuste de inventario: la unidad puede volver al stock disponible, quedar en cuarentena o clasificarse como dañada.
- Estado del pedido: el pedido continúa parcialmente completado, aunque una de sus líneas haya sido devuelta.
Estos hechos pueden ocurrir en momentos distintos. La mercancía puede llegar antes de que un proveedor de pagos confirme el reembolso. El reembolso puede confirmarse mientras el producto aún está pendiente de inspección. Incluso puede existir una devolución autorizada que nunca llegue físicamente al almacén.
La arquitectura debe representar esa realidad en lugar de asumir que una única actualización resuelve todos los aspectos.
El modelo de datos debe conservar la correspondencia entre líneas, dinero e inventario
El error más frecuente consiste en guardar información suficiente para el pedido completo, pero no para cada línea. Un campo como refundedAmount puede indicar cuánto dinero se devolvió, pero no necesariamente qué producto originó ese importe ni qué ocurrió con su inventario.
Una estructura más segura relaciona cada devolución con líneas concretas del pedido. De forma conceptual, podría incluir:
- Identificador de la devolución.
- Identificador del pedido.
- Una o varias líneas afectadas.
- Cantidad devuelta por línea.
- Motivo y condición del producto.
- Estado logístico de la devolución.
- Estado financiero del reembolso.
- Referencia del movimiento de inventario.
- Clave de idempotencia y referencias externas disponibles.
En un pedido con una sola unidad por producto, devolver la chaqueta implica asociar la devolución a la línea de la chaqueta. En pedidos con varias unidades, la cantidad también es relevante: devolver una de tres unidades no debe marcar como devuelta toda la línea.
Invariantes que conviene proteger
Los invariantes son reglas que deben mantenerse verdaderas aunque existan reintentos, errores de red o eventos recibidos fuera de orden. Algunos ejemplos son:
- La cantidad devuelta de una línea no puede superar la cantidad comprada, salvo que exista una corrección explícita y auditada.
- El importe reembolsado para una línea no puede superar el importe autorizado, considerando las reglas de descuentos, impuestos y gastos aplicables.
- Una misma unidad física no debe reincorporarse dos veces al inventario.
- Un reembolso confirmado no debe generar un segundo reembolso por procesar nuevamente el mismo evento.
- El estado global del pedido debe derivarse de sus líneas y de las operaciones relacionadas, no sobrescribirse arbitrariamente.
- Cada transición relevante debe ser trazable mediante un identificador y un registro de auditoría.
Estas reglas deben validarse en la aplicación y, cuando sea viable, reforzarse con restricciones de base de datos, claves únicas y transacciones. No conviene confiar únicamente en que la interfaz de administración impedirá las combinaciones incorrectas.
Separar los estados de la devolución, el reembolso y el pedido
Un único estado para todo el proceso suele resultar insuficiente. Una alternativa es manejar máquinas de estado relacionadas, pero independientes.
Estado de la devolución física
- Solicitada: el cliente inició el proceso.
- Autorizada: la tienda aceptó recibir el producto bajo ciertas condiciones.
- En tránsito: el producto fue entregado al operador logístico o se registró un envío.
- Recibida: el almacén confirmó la llegada.
- Inspeccionada: se determinó su condición y el tratamiento aplicable.
- Completada: las acciones físicas y administrativas asociadas finalizaron.
- Rechazada o cancelada: la devolución no fue aceptada o no continuó.
Estado del reembolso
- No solicitado: todavía no se pidió devolver el dinero.
- Pendiente: la solicitud está preparada o enviada, pero no hay confirmación final.
- Confirmado: existe una confirmación válida del reembolso.
- Fallido: la operación no se completó y requiere revisión o reintento controlado.
- Revertido o ajustado: se produjo una corrección posterior que debe quedar auditada.
Estado de la línea y del pedido
Cada línea puede estar en estados como enviada, entregada, parcialmente devuelta, devuelta o cancelada. El pedido, en cambio, puede permanecer como parcialmente completado mientras la mochila sigue siendo válida y la chaqueta está en proceso de devolución.
Por ejemplo, el pedido podría evolucionar así:
- Pedido confirmado: ambas líneas están activas.
- Pedido enviado: ambas líneas fueron despachadas.
- Devolución parcial en curso: la chaqueta tiene una devolución abierta; la mochila no cambia.
- Pedido parcialmente devuelto: el reembolso de la chaqueta fue confirmado.
Los nombres concretos dependen del negocio. Lo importante es evitar que “pedido cancelado”, “producto devuelto” y “dinero reembolsado” se utilicen como sinónimos.
Idempotencia: cómo evitar duplicados en reintentos y eventos repetidos
En una integración distribuida, una misma solicitud puede procesarse más de una vez. Puede ocurrir porque el cliente reintenta, porque un worker vuelve a ejecutar un mensaje o porque un sistema externo entrega nuevamente una notificación.
La idempotencia significa que procesar dos veces la misma operación produce el mismo resultado de negocio que procesarla una sola vez. Para aplicarla a devoluciones parciales, conviene:
- Asignar una clave de idempotencia a la solicitud de devolución o reembolso.
- Guardar identificadores externos y evitar crear una nueva operación si ya existe una coincidencia válida.
- Registrar qué transición ya fue aplicada a cada devolución.
- Proteger la creación de movimientos de inventario con una clave única.
- Hacer que los consumidores de eventos puedan recibir el mismo evento sin duplicar efectos.
También es importante distinguir entre “la petición fue recibida” y “el reembolso fue confirmado”. Si una API externa responde que la solicitud fue aceptada, eso no necesariamente equivale a que el dinero ya esté disponible para el cliente. El modelo interno debe conservar esa diferencia.
Eventos tardíos, fuera de orden y conciliación
Las integraciones de pagos, logística e inventario pueden producir eventos con retraso o en un orden diferente al esperado. Por ejemplo, el sistema puede recibir primero una confirmación financiera y después el registro de recepción en almacén.
Por esa razón, un evento no debería cambiar ciegamente el estado completo del pedido. Cada consumidor debe actualizar únicamente la parte que conoce y validar si la transición es compatible con el estado actual.
Una estrategia práctica combina varios mecanismos:
- Persistencia de eventos recibidos: guardar el identificador del evento, su origen y cuándo fue procesado.
- Transiciones explícitas: rechazar o poner en revisión los cambios imposibles, en lugar de sobrescribir datos.
- Cola de excepciones: separar los casos que requieren intervención operativa.
- Reconciliación periódica: comparar el estado interno con los registros disponibles de pagos, almacén y logística.
- Auditoría: conservar quién o qué proceso cambió cada estado y por qué.
La conciliación no debe limitarse a comprobar que los totales coinciden. También debería detectar diferencias entre las líneas afectadas, los importes, las cantidades y las referencias externas. Un pedido puede tener el importe total correcto y, aun así, haber aplicado el reembolso a la línea equivocada.
Atención al cliente y operación: convertir los estados técnicos en respuestas claras
Una devolución parcial suele generar consultas como “¿por qué recibí solo una parte del dinero?” o “¿por qué el pedido todavía aparece como entregado?”. La respuesta depende de los estados internos y de la política comercial, pero el sistema debe ofrecer una vista comprensible para los equipos de atención al cliente.
La pantalla operativa debería mostrar, como mínimo:
- Qué productos y cantidades están incluidos en la devolución.
- Cuándo se solicitó y cuándo se recibió el producto.
- Resultado de la inspección, si aplica.
- Importe solicitado y confirmado del reembolso.
- Estado del inventario asociado.
- Errores pendientes y próxima acción recomendada.
- Historial de cambios con fechas y referencias.
Esto evita que una persona de soporte tenga que inferir el estado real a partir de varios sistemas o repetir manualmente un reembolso que solo está pendiente de confirmación.
También conviene definir qué ocurre cuando hay diferencias: el producto llega incompleto, se devuelve una cantidad superior, el artículo está dañado o el importe esperado no coincide con el cálculo. Esos casos deben tener estados de revisión, no resolverse mediante ediciones directas sin trazabilidad.
Pruebas para validar una devolución parcial
Las pruebas deben cubrir tanto el flujo normal como las combinaciones que pueden romper la correspondencia entre pedido, inventario y dinero.
Casos funcionales
- Devolver una de dos líneas y confirmar que la otra permanece activa.
- Devolver parcialmente una línea con varias unidades.
- Reembolsar el importe correcto cuando existen descuentos, impuestos o gastos según las reglas del negocio.
- Registrar una devolución física sin confirmar todavía el reembolso.
- Confirmar un reembolso sin modificar dos veces el inventario.
- Rechazar una devolución y conservar el historial de la decisión.
Casos de idempotencia y consistencia
- Procesar dos veces la misma solicitud de reembolso.
- Recibir dos veces el mismo evento de confirmación.
- Recibir los eventos de reembolso y recepción en orden inverso.
- Reintentar una operación después de un timeout, cuando el resultado externo es desconocido.
- Intentar devolver más unidades de las compradas.
- Intentar aplicar un segundo movimiento de inventario a la misma unidad.
Pruebas operativas
Además de pruebas unitarias y de integración, conviene validar la conciliación mediante datos representativos y revisar si los equipos pueden resolver una incidencia sin modificar directamente la base de datos. Los logs, métricas y trazas deberían permitir seguir una devolución desde la solicitud inicial hasta el inventario y el reembolso, usando un identificador común.
Conclusión: una devolución parcial exige varios estados coordinados
El aprendizaje principal es que una devolución parcial no debe reducirse a cambiar el estado de un pedido ni a restar un importe del total. El sistema debe conservar la relación entre las líneas afectadas, el movimiento físico, el inventario y el dinero, incluso cuando existan reintentos, eventos tardíos o excepciones operativas.
La decisión más importante es definir un modelo de estados y unas invariantes antes de conectar servicios externos. Después, la implementación puede apoyarse en APIs, colas o eventos, pero ninguna herramienta sustituye un modelo de negocio preciso y auditable.
Revisa si tu tienda puede registrar una devolución parcial sin perder la correspondencia entre inventario, pedido y dinero. Si el flujo actual depende de cambios manuales o de un único estado global, puede ser un buen momento para evaluar su modelo de datos, sus pruebas y sus mecanismos de conciliación.
