@startuml uml-state-pago !include _style.iuml title 2. State machine — Pago (estatus_pago + raw_status Stripe) [*] --> pendiente : crear(orden, monto)\n/ POST /payments/intent state pendiente { pendiente : raw_status = "requires_payment_method" pendiente : / "requires_confirmation" / "requires_action" pendiente : payment_intent_id = pi_... } state procesado { procesado : raw_status = "succeeded" procesado : metodo = "tarjeta" (mapeado de Stripe) procesado : referencia_pasarela = "Visa **** 4242" procesado : webhook_received_at IS NOT NULL } state fallido { fallido : raw_status = "requires_payment_method" fallido : / "canceled" } state reembolsado { reembolsado : Reembolso ACH ejecutado reembolsado : webhook charge.refunded recibido } pendiente --> procesado : webhook payment_intent.succeeded\n[firma valida + idempotente] pendiente --> fallido : webhook payment_intent.payment_failed\n/ raw_status = "requires_payment_method" pendiente --> fallido : webhook payment_intent.canceled\n/ raw_status = "canceled" fallido --> pendiente : reintentar() / cliente reabre PaymentSheet\n(reusa intent si client_secret valido,\nsino crea nuevo) fallido --> [*] : abandonar() procesado --> reembolsado : webhook charge.refunded\n[reembolso SoD aprobado y ejecutado] reembolsado --> [*] procesado --> [*] note right of pendiente Estado inicial al crear el registro tras POST /api/v1/mobile/payments/intent (apps/web/src/lib/payments/intent.ts:124-131). raw_status mapea uno-a-uno con Stripe. end note note right of procesado Habilita liquidacion al prestador via cortes_pago + emision de factura CFDI (cuando se implemente Phase 5). Webhook stripe es la fuente de verdad (apps/web/src/lib/payments/webhook.ts:76-112). end note note left of reembolsado Solo accesible via workflow de reembolsos (ver state machine 3 + SoD). Webhook charge.refunded reconcilia el estatus tras la operacion ACH del banco. end note footer Fuente: ENUM estatus_pago 00.sql:54 | tabla pagos 00.sql:444 + migrations/007_pagos_facturas_extensions.sql (payment_intent_id, raw_status, webhook_received_at) | apps/web/src/lib/payments/{intent,webhook,mappers}.ts @enduml