Fix crypto payment state machine logic and naming consistency

Major fixes:
1. Remove invalid received→expired transition
   - Payments that reach 'received' state cannot expire
   - Only pending payments can expire
   - Updated VALID_TRANSITIONS and tests accordingly

2. Rename STATUS_DOUBLEPAY_REFUND to STATUS_DOUBLEPAY_REFUNDED
   - Maintains consistency with all other past-tense status names
   - Updated all references across codebase and tests

3. Add INITIAL_WAITING_STATUSES semantic group
   - Groups states that are entry points: pending, latepay_refunded, doublepay_refunded
   - These states don't transition from 'received' - they represent initial states
   - Added is_initial_waiting_state() helper method

4. Update semantic groups
   - Removed latepay_refunded and doublepay_refunded from FAILED_PAYMENT_STATUSES
   - These are now in INITIAL_WAITING_STATUSES as they represent entry points

5. Fix mermaid diagram label
   - confirmed_overpay_not_refunded now correctly labeled as "Terminal Success (Not Refunded)"
   - Remove invalid received→expired transition from documentation

This improves the logical consistency of the state machine and aligns
the naming conventions across all status constants.
This commit is contained in:
Russell Ballestrini 2025-09-30 14:34:11 -04:00
parent 7625563f6a
commit c7caae8d4a
10 changed files with 106 additions and 89 deletions

View file

@ -16,9 +16,8 @@ stateDiagram-v2
%% From received state - multiple possible outcomes
received --> confirmed : Sufficient payment + confirmations
received --> confirmed_overpay : Overpayment detected
received --> expired : Payment timeout
received --> underpaid_refunded : Underpayment detected
received --> doublepay_refund : Duplicate payment detected
received --> doublepay_refunded : Duplicate payment detected
received --> out_of_stock_refunded : Product unavailable
%% Successful payment paths
@ -29,7 +28,7 @@ stateDiagram-v2
confirmed_overpay_refunded --> confirmed_overpay_refunded_complete : Refund confirmed
confirmed_overpay_refunded --> confirmed_overpay_not_refunded : No refund wallet configured
confirmed_overpay_refunded_complete --> [*] : ✓ Terminal Success
confirmed_overpay_not_refunded --> [*] : ✓ Terminal (Not Refunded)
confirmed_overpay_not_refunded --> [*] : ✓ Terminal Success (Not Refunded)
%% Expired payment handling (terminal - late payments create new objects)
expired --> [*] : ✓ Terminal (Expired)
@ -51,9 +50,9 @@ stateDiagram-v2
out_of_stock_not_refunded --> [*] : ✓ Terminal (Not Refunded)
%% Double payment refund flow
doublepay_refund --> doublepay_refund_complete : Refund confirmed
doublepay_refund --> doublepay_not_refunded : No refund wallet configured
doublepay_refund_complete --> [*] : ✓ Terminal Success
doublepay_refunded --> doublepay_refunded_complete : Refund confirmed
doublepay_refunded --> doublepay_not_refunded : No refund wallet configured
doublepay_refunded_complete --> [*] : ✓ Terminal Success
doublepay_not_refunded --> [*] : ✓ Terminal (Not Refunded)
@ -66,8 +65,8 @@ stateDiagram-v2
classDef terminalState fill:#f8d7da,stroke:#721c24,color:#721c24
classDef processingState fill:#cce5ff,stroke:#004085,color:#004085
class confirmed,confirmed_overpay_refunded_complete,latepay_refunded_complete,underpaid_refunded_complete,out_of_stock_refunded_complete,doublepay_refund_complete successState
class confirmed_overpay_refunded,latepay_refunded,underpaid_refunded,out_of_stock_refunded,doublepay_refund refundState
class confirmed,confirmed_overpay_refunded_complete,latepay_refunded_complete,underpaid_refunded_complete,out_of_stock_refunded_complete,doublepay_refunded_complete successState
class confirmed_overpay_refunded,latepay_refunded,underpaid_refunded,out_of_stock_refunded,doublepay_refunded refundState
class cancelled terminalState
class confirmed_overpay_not_refunded,latepay_not_refunded,underpaid_not_refunded,out_of_stock_not_refunded,doublepay_not_refunded successState
class pending,received,confirmed_overpay,expired processingState