Documento histórico
Este documento se conserva solo para trazabilidad. Consulte el índice maestro para la fuente vigente.
Documento histórico — no usar como fuente de decisiones actuales
Reemplazado por la versión canónica del 2026-07-11. Conservar solo como trazabilidad histórica.
CU-008: Pagar y despachar envío¶
Caso de uso detallado para el pago de una cotización de envío (o consolidación) y el despacho por parte del operador.
Metadatos¶
| Campo | Valor |
|---|---|
| ID | CU-008 |
| Nombre | Pagar y despachar envío |
| Actor primario | Usuario Final (pago) + Operador (despacho) |
| Módulo | Paquetes y envíos |
| Prioridad | Alta (MVP) |
| Frecuencia esperada | Media |
| Trazabilidad SRS | RF-026, RF-027, RF-028, RF-029 |
Descripción¶
Una vez creada la consolidación y generada la cotización, el usuario la paga (o registra el pago) y el operador la despacha hacia Cuba. El sistema notifica los cambios de estado al usuario y este puede hacer tracking.
Precondiciones¶
- Existe un
Quotevigente (no expirado, ≤ 7 días). - El usuario tiene KYC aprobado.
- Hay una
Consolidationo unShipmentindividual en estadocotizadaopendiente_pago.
Postcondiciones¶
Éxito:
- El Quote se marca como aceptada y se crea un Payment con status = completado.
- El Shipment pasa a pagado y luego en_preparacion.
- Cuando el operador marca despachado_desde_almacen, se asigna master_guide y carrier.
- Se notifica al usuario en cada cambio de estado.
Flujo principal¶
Parte A: Pago (Usuario)¶
- El usuario accede a la pantalla Cotización y Pago desde:
- La confirmación de consolidación
- El detalle del envío en estado
cotizada - La sección "Requiere tu atención" (si hay un pago pendiente)
- El sistema muestra la pantalla con:
- Resumen de la cotización (paquetes, vía, peso, servicios, costo total)
- Fecha de expiración de la cotización
- Métodos de pago disponibles (en MVP: registro manual; en Fase 2: Stripe vía Stripe Checkout)
- Desglose detallado de cargos
- El usuario revisa y toca Pagar ahora (si Stripe está habilitado) o Confirmar pago manual (MVP).
- Pago manual (MVP):
- El sistema muestra instrucciones: "Realiza el pago por {Zelle/Wise/etc.} a {datos}. Sube el comprobante."
- El usuario sube el comprobante (opcional).
- El usuario confirma: "He realizado el pago."
- El operador validará el comprobante en el backoffice.
- Pago online (Fase 2, con Stripe):
- El sistema crea una Stripe Checkout Session con el monto, moneda y metadata del envío.
- Redirige al usuario al formulario seguro de Stripe.
- El usuario completa el pago con tarjeta (o método habilitado por Stripe).
- Stripe notifica vía webhook al backend (
payment_intent.succeeded/checkout.session.completed). - El sistema valida la firma del webhook y actualiza el estado del pago.
- El sistema crea el
Paymentconstatus = completado(manual) opendiente(online, hasta confirmar). - El sistema actualiza:
Quote.status = aceptadaShipment.status = pagado(luegoen_preparacioncuando el operador prepara)Consolidation.status = pagada(luegoen_preparacion)PhysicalPackage.status = listo_para_consolidar(uno por uno)- Se genera una
Invoicecon el desglose completo. - Se envía notificación push al usuario: "Pago confirmado. Tu envío está en preparación."
Parte B: Despacho (Operador)¶
- El operador accede al backoffice, va a la cola Consolidaciones por preparar.
- Selecciona la consolidación pagada.
- Verifica los paquetes (uno por uno, escaneando).
- Empaqueta y sella.
- Asigna
master_guide(número de guía de la agencia) ycarrier(transportista). - Toca Marcar como despachado.
- El sistema:
- Cambia
Shipment.status = despachado_desde_almacen - Cambia
Consolidation.status = despachada - Cambia cada
PhysicalPackage.status = en_transito(odespachado) - Crea un
package_eventpor cada paquete - Registra
shipped_at
- Cambia
- El sistema entrega el envío a la agencia aliada (intermediario digital). La agencia es quien realiza el transporte internacional; IslaBox no transporta.
- El sistema envía push al usuario: "Tu envío ha sido despachado. Guía: {master_guide}."
Parte C: Tracking (Sistema)¶
- El sistema actualiza el estado del envío. La agencia aliada expone una API/webhook que notifica los cambios. Adicionalmente, el operador puede actualizar manualmente como respaldo:
en_transito_a_cuba→ agencia (API) o operadoren_aduana→ agencia (API) o operadorliberado_de_aduana→ agencia (API) o operadoren_reparto→ agencia (API) o operadorentregado→ agencia (API) o operador
- Cada cambio genera un
shipment_eventcon timestamp y descripción. - Cada cambio genera push al usuario.
- Cuando llega a
entregado, se muestra en el dashboard como "Entregados" y se quita de "Requiere tu atención".
Flujos alternativos¶
FA-1: Cotización expirada¶
- Si pasaron más de 7 días desde la cotización:
- Al intentar pagar, el sistema muestra: "La cotización expiró. Se recalculará el costo."
- Recalcula con el peso y vía actuales.
- Genera nueva cotización con nuevos 7 días de vigencia.
FA-2: Pago rechazado (online)¶
- Si Stripe rechaza el pago:
- El sistema muestra "Pago rechazado. Intenta con otro método."
- El
Paymentqueda enstatus = fallido. - El
Shipmentsigue enpendiente_pago.
FA-3: Comprobante manual rechazado¶
- En MVP, si el operador valida el comprobante y no coincide con el pago real:
- El operador marca el pago como
rechazadoen el backoffice. - El
Shipmentvuelve apendiente_pago. - Se notifica al usuario por push y email.
FA-4: Cancelación después del pago¶
- Si el usuario quiere cancelar después de pagar pero antes del despacho:
- Si el operador aún no marcó como despachado, se puede cancelar y reembolsar.
- El sistema crea un
Paymentinverso (reembolso). - El estado del envío pasa a
cancelado.
FA-5: Operador detecta problema antes de despachar¶
- Si el operador detecta un problema (ej. daño en el paquete, discrepancia con la prealerta):
- Cambia el
PhysicalPackage.status = incidenciacon motivo. - La consolidación queda en
en_preparacionhasta resolución. - Notifica al usuario.
FA-6: Incidencia en tránsito¶
- Si la agencia aliada reporta un problema (paquete dañado, retenido en aduana, etc.):
- El operador actualiza el
Shipment.status = incidenciacon motivo. - Se notifica al usuario.
- La incidencia aparece en "Requiere tu atención".
Excepciones¶
| Excepción | Causa | Manejo |
|---|---|---|
QUOTE_EXPIRED |
Más de 7 días | Recalcular |
PAYMENT_FAILED |
Stripe rechazó el pago (tarjeta declinada, fondos insuficientes, etc.) | Mensaje + reintentar con otro método |
KYC_NOT_APPROVED |
Sin KYC | Bloqueo |
INSUFFICIENT_AMOUNT |
Pago parcial (no debe pasar) | Mensaje |
STRIPE_UNAVAILABLE |
API de Stripe caída o con timeout | Ofrecer registro manual de pago |
ALREADY_SHIPPED |
Operador intenta despachar 2 veces | Mensaje |
INVALID_MASTER_GUIDE |
Formato inválido | Mensaje |
Reglas de negocio aplicables¶
- RN-21 (Cotización): vigencia 7 días. Ver modulos/servicios-cargos.md.
- RN-22 (KYC bloquea pago): sin KYC aprobado no se puede pagar. Ver kyc.md.
- RN-23 (Master guide única): asignada por la agencia al despachar. Ver integraciones.md.
- RN-24 (Pago): en MVP es manual (registro por operador con comprobante); en Fase 2 es vía Stripe (Stripe Checkout + Webhook firmado). Ver integraciones.md.
Criterios de aceptación¶
- Un usuario con KYC aprobado puede pagar una cotización vigente.
- La cotización expirada se detecta y se recalcula.
- El pago crea un
Paymentcon desglose correcto. - La factura incluye todos los cargos por separado.
- El operador puede despachar solo consolidaciones pagadas.
- El
master_guidese valida (alfanumérico, 8+ caracteres). - El usuario recibe push en cada cambio de estado.
- La transición
despachado_desde_almacenes la última que puede hacer el operador (luego se alimenta manualmente desde la agencia hastaentregadoen MVP). - Un envío en
incidenciase muestra en "Requiere tu atención".
Diagrama de actividad¶
flowchart TD
A["Cotización pendiente"] --> B{"¿Vigente?"}
B -- No --> C["Recalcular"]
C --> A
B -- Sí --> D["Usuario revisa y paga"]
D --> E{"¿Pago confirmado?"}
E -- No --> F["Pago fallido"]
F --> D
E -- Sí --> G["Crea Payment + Invoice"]
G --> H["Shipment → pagado"]
H --> I["Operador prepara"]
I --> J["Operador despacha"]
J --> K["Asigna master_guide"]
K --> L["Shipment → despachado"]
L --> M["Push al usuario"]
M --> N["Tracking por estado"]
N --> O{"¿Entregado?"}
O -- No --> P["Continúa transit"]
O -- Sí --> Q["Push de entrega"]
Diagrama de estados (envío)¶
stateDiagram-v2
[*] --> borrador
borrador --> pendiente_kyc: sin KYC
borrador --> pendiente_destinatario: sin destinatario
borrador --> pendiente_cotizacion
pendiente_kyc --> pendiente_cotizacion: KYC aprobado
pendiente_destinatario --> pendiente_cotizacion
pendiente_cotizacion --> cotizado
cotizado --> pendiente_pago
pendiente_pago --> pagado: pagar
pendiente_pago --> cancelado: cancelar / expirar
pagado --> en_preparacion: operador prepara
en_preparacion --> despachado_desde_almacen: despachar
despachado_desde_almacen --> en_transito_a_cuba
en_transito_a_cuba --> en_aduana
en_aduana --> liberado_de_aduana
liberado_de_aduana --> en_reparto
en_reparto --> entregado
entregado --> [*]
en_aduana --> incidencia
en_transito_a_cuba --> incidencia
en_reparto --> incidencia
incidencia --> en_reparto: resolver
incidencia --> entregado: resolver
incidencia --> cancelado
Pruebas asociadas¶
- PT-100: Pago manual de cotización vigente
- PT-101: Intento de pago con cotización expirada
- PT-102: Pago con KYC no aprobado (debe fallar)
- PT-103: Operador despacha consolidación pagada
- PT-104: Intento de despacho sin pago (debe fallar)
- PT-105: Validación de master_guide
- PT-106: Cambio de estado en tránsito (operador)
- PT-107: Notificación push en cada cambio
- PT-108: Generación de invoice con desglose
- PT-109: Cancelación post-pago (con reembolso)
- PT-110: Incidencia en tránsito
- PT-111: Re-cotización tras cambios