Delete CRYPTO_WATCHER_FLOW.md

This commit is contained in:
Russell Ballestrini 2025-10-01 00:40:29 +00:00
parent 29baa1bb73
commit 86fdab0f3a

View file

@ -1,345 +0,0 @@
# Crypto Watcher Mechanism - Complete Flow Documentation
This document describes the complete flow of the crypto payment watcher system, including all paths for payment processing, duplicate detection, and refund handling.
```mermaid
flowchart TD
A[Crypto Watcher Starts] --> B[Load Active Crypto Processors]
B --> C[For Each Processor: Scan Wallet]
C --> D{New Transactions Found?}
D -->|No| E[Sleep 20 seconds]
D -->|Yes| F[Process Each Transaction]
F --> G[Match Transaction to Payment by Subaddress]
G --> H{Payment Found?}
H -->|No| I[Log: No matching payment]
H -->|Yes| J[Call process_payment]
J --> K{Payment Status?}
K -->|PENDING| L[First Payment Path]
K -->|RECEIVED/CONFIRMED| M[Duplicate Detection Path]
K -->|DOUBLEPAY_REFUND| N[Refund Processing Path]
subgraph FirstPayment [First Payment Path]
L1[Add transaction amount]
L2[Update tx_hashes with txid]
L3[Update confirmations]
L4{Amount >= Expected AND Confirmations >= Required?}
L5[Status = CONFIRMED]
L6[Status = RECEIVED]
L7[Finalize Invoice - Unlock Products]
L8[Continue Monitoring]
L1 --> L2
L2 --> L3
L3 --> L4
L4 -->|Yes| L5
L4 -->|No| L6
L5 --> L7
L6 --> L8
L7 --> L8
end
subgraph DuplicateDetection [Duplicate Detection Path]
M1{received_amount > 0 AND new_txids?}
M2[DUPLICATE PAYMENT DETECTED]
M3[Create Duplicate Payment Records]
M4[Set status = STATUS_DOUBLEPAY_REFUND]
M5[Store tx_hashes with duplicate txid]
M6[Update original payment confirmations only]
M7[Scanner will process refunds]
M1 -->|Yes| M2
M2 --> M3
M3 --> M4
M4 --> M5
M5 --> M6
M6 --> M7
end
subgraph RefundProcessing [Refund Processing Path]
N1{PaymentRescue available?}
N2[Status = STATUS_NO_REFUND]
N3[Calculate refund amount with 9% fee]
N4[Execute refund transaction]
N5{Refund successful?}
N6[Store refund_tx_hash]
N7[Log refund failure]
N8[Monitor refund confirmations]
N9[Status remains DOUBLEPAY_REFUND]
N10{Refund confirmed?}
N11[Status = STATUS_DOUBLEPAY_REFUND_COMPLETE]
N12[Continue monitoring]
N1 -->|No| N2
N1 -->|Yes| N3
N3 --> N4
N4 --> N5
N5 -->|Yes| N6
N5 -->|No| N7
N6 --> N8
N7 --> N9
N8 --> N10
N10 -->|Yes| N11
N10 -->|No| N12
end
L --> FirstPayment
M --> DuplicateDetection
N --> RefundProcessing
M1 -->|No| L1
E --> C
L8 --> E
M7 --> E
N2 --> E
N9 --> E
N11 --> E
N12 --> E
I --> E
```
## Complete Payment Status State Machine
```mermaid
stateDiagram-v2
[*] --> PENDING : Payment created
%% Normal payment flow
PENDING --> RECEIVED : First transaction received
RECEIVED --> CONFIRMED : Sufficient confirmations + exact payment
RECEIVED --> CONFIRMED_OVERPAID : Sufficient confirmations + overpayment
%% Terminal success states
CONFIRMED --> [*] : Products unlocked
CONFIRMED_OVERPAID --> CONFIRMED_OVERPAID_REFUNDED : Excess refunded
CONFIRMED_OVERPAID_REFUNDED --> [*] : Refund confirmed
%% Expiration flow
PENDING --> EXPIRED : Quote expires (no payment)
RECEIVED --> EXPIRED : Quote expires (partial payment)
EXPIRED --> EXPIRED_REFUNDED : Late payment arrives + refund sent
EXPIRED_REFUNDED --> EXPIRED_REFUNDED_COMPLETE : Refund confirmed
EXPIRED_REFUNDED_COMPLETE --> [*]
EXPIRED --> [*] : No late payment
%% Underpayment flow
RECEIVED --> UNDERPAID_REFUNDED : Quote expires + insufficient funds
UNDERPAID_REFUNDED --> UNDERPAID_REFUNDED_COMPLETE : Refund confirmed
UNDERPAID_REFUNDED_COMPLETE --> [*]
%% Duplicate payment flow
CONFIRMED --> DOUBLEPAY_REFUND : Duplicate payment detected
CONFIRMED_OVERPAID --> DOUBLEPAY_REFUND : Duplicate payment detected
RECEIVED --> DOUBLEPAY_REFUND : Duplicate payment detected
DOUBLEPAY_REFUND --> DOUBLEPAY_REFUND_COMPLETE : Refund confirmed
DOUBLEPAY_REFUND_COMPLETE --> [*]
%% Out of stock flow
PENDING --> OUT_OF_STOCK_REFUNDED : Product out of stock + payment received
RECEIVED --> OUT_OF_STOCK_REFUNDED : Product out of stock
CONFIRMED --> OUT_OF_STOCK_REFUNDED : Product out of stock after payment
OUT_OF_STOCK_REFUNDED --> OUT_OF_STOCK_REFUNDED_COMPLETE : Refund confirmed
OUT_OF_STOCK_REFUNDED_COMPLETE --> [*]
%% No refund scenarios
EXPIRED --> NO_REFUND : No refund address configured
UNDERPAID_REFUNDED --> NO_REFUND : Refund failed
DOUBLEPAY_REFUND --> NO_REFUND : Refund failed
OUT_OF_STOCK_REFUNDED --> NO_REFUND : Refund failed
NO_REFUND --> NO_REFUND_COMPLETE : Manual resolution
NO_REFUND_COMPLETE --> [*]
%% Cancellation flow
PENDING --> CANCELLED : Payment cancelled by user/system
RECEIVED --> CANCELLED : Payment cancelled with refund
CANCELLED --> [*]
%% Status groupings for processing
state "Active Statuses (Monitored)" as ActiveGroup {
PENDING
RECEIVED
CONFIRMED
CONFIRMED_OVERPAID
NO_REFUND
}
state "Refund Pending (Confirmation Monitoring)" as RefundGroup {
EXPIRED_REFUNDED
UNDERPAID_REFUNDED
OUT_OF_STOCK_REFUNDED
DOUBLEPAY_REFUND
}
state "Terminal Statuses (No Processing)" as TerminalGroup {
EXPIRED
EXPIRED_REFUNDED_COMPLETE
UNDERPAID_REFUNDED_COMPLETE
CONFIRMED_OVERPAID_REFUNDED
CANCELLED
OUT_OF_STOCK_REFUNDED_COMPLETE
NO_REFUND_COMPLETE
DOUBLEPAY_REFUND_COMPLETE
}
```
## Status Categories and Processing Rules
### Active Statuses (Actively Monitored)
- **PENDING**: Waiting for first payment
- **RECEIVED**: Has funds, waiting for confirmations
- **CONFIRMED**: Payment complete, products unlocked
- **CONFIRMED_OVERPAID**: Overpaid, products unlocked, excess pending refund
- **NO_REFUND**: Failed refund scenarios, manual intervention needed
### Refund Pending (Confirmation Monitoring)
- **EXPIRED_REFUNDED**: Late payment refunded with 9% fee
- **UNDERPAID_REFUNDED**: Partial payment refunded with 9% fee
- **OUT_OF_STOCK_REFUNDED**: Out of stock, full refund (no fee)
- **DOUBLEPAY_REFUND**: Duplicate payment refunded with 9% fee
### Terminal Statuses (No Further Processing)
- **EXPIRED**: Quote expired, no payment received
- **EXPIRED_REFUNDED_COMPLETE**: Late payment refund confirmed
- **UNDERPAID_REFUNDED_COMPLETE**: Partial payment refund confirmed
- **CONFIRMED_OVERPAID_REFUNDED**: Overpayment excess refund confirmed
- **CANCELLED**: Payment cancelled by user/system
- **OUT_OF_STOCK_REFUNDED_COMPLETE**: Out of stock refund confirmed
- **NO_REFUND_COMPLETE**: Manual resolution complete
- **DOUBLEPAY_REFUND_COMPLETE**: Duplicate payment refund confirmed
## Key Functions and Their Responsibilities
### Main Processing Loop
- **`crypto_watcher_main()`**: Entry point, coordinates scanning and processing
- **`process_payment()`**: Core payment processing logic
- **`scan_wallet_for_double_or_late_payments()`**: Scanner for missed/duplicate transactions
### Duplicate Detection
- **`_create_duplicate_payment()`**: Creates separate records for duplicate transactions
- **`_should_process_late_payment()`**: Determines if a transaction should be processed
### Payment Processing Paths
#### 1. Normal Payment Path
```python
# New payment to fresh address
status: PENDING → RECEIVED → CONFIRMED
actions:
- Add amount to received_amount
- Update tx_hashes with transaction IDs
- Update confirmation count
- Finalize invoice when confirmed
```
#### 2. Duplicate Payment Path (Main Loop)
```python
# Additional payment to already-paid address
if (received_amount > 0 AND new_txids AND status != PENDING):
# Create separate duplicate records
for txid in new_txids:
duplicate = _create_duplicate_payment(original, tx, coin_type)
duplicate.status = STATUS_DOUBLEPAY_REFUND
duplicate.tx_hashes = json.dumps([txid])
# Update original payment confirmations only (no new amounts)
original.confirmations = calculate_from_legitimate_txs_only()
```
#### 3. Scanner Duplicate Processing
```python
# Scanner finds duplicate transactions
for tx in wallet_transfers:
payment = find_by_subaddress(tx)
if payment.received_amount > 0: # Duplicate
existing = find_duplicate_by_txid(tx.txid)
if not existing:
duplicate = _create_duplicate_payment(payment, tx, coin_type)
else:
duplicate = existing
# Process refund
process_payment(request, duplicate, [tx], client=refund_client)
```
#### 4. Refund Processing Path
```python
# For payments with STATUS_DOUBLEPAY_REFUND
if payment.status == STATUS_DOUBLEPAY_REFUND:
if payment_rescue and payment.refund_address:
refund_amount = received_amount * 0.91 # 9% fee
result = payment_rescue.execute_refund(payment, refund_amount)
if result.success:
payment.refund_tx_hash = result.tx_hash
# Monitor for refund confirmation
else:
# Log failure, retry later
else:
payment.status = STATUS_NO_REFUND
```
## Infinite Duplicate Support
The system now supports unlimited duplicate payments to the same address:
1. **Payment #1**: Normal processing → CONFIRMED
2. **Payment #2**: Main loop creates duplicate record #1 → Scanner processes refund #1
3. **Payment #3**: Main loop creates duplicate record #2 → Scanner processes refund #2
4. **Payment #4**: Main loop creates duplicate record #3 → Scanner processes refund #3
5. **etc...**
Each duplicate gets:
- Its own `CryptoPayment` record with unique ID
- Status: `STATUS_DOUBLEPAY_REFUND`
- Individual refund processing
- Separate entry in crypto payments history
## Error Handling and Edge Cases
### Double Refund Prevention
- Scanner checks for existing duplicate records by transaction ID
- Only one duplicate record created per transaction
- Refund only processed once per duplicate
### Confirmation Handling for Duplicates
- Original payment confirmations calculated from legitimate transactions only
- Duplicate transactions don't affect original payment confirmation count
- Original payment can move RECEIVED → CONFIRMED despite having duplicates
### Missing Transaction Scenarios
- Scanner catches transactions missed by main loop
- Late payments to expired quotes handled separately
- Blockchain reorganizations handled through re-scanning
## Database Schema Impact
### CryptoPayment Table Fields Used
- `id`: Unique payment identifier
- `status`: Payment status (see status flow above)
- `received_amount`: Amount received for this specific payment
- `tx_hashes`: JSON array of transaction IDs
- `refund_tx_hash`: Transaction ID of refund (for duplicates)
- `refund_address`: Where to send refund
- `subaddress_index`: Unique address identifier
### Query Patterns
```sql
-- Find payment by subaddress
SELECT * FROM mps_crypto_payment
WHERE coin_type = ? AND account_index = ? AND subaddress_index = ?
-- Find duplicate by transaction ID
SELECT * FROM mps_crypto_payment
WHERE status = 'doublepay-refund'
AND tx_hashes LIKE '%"transaction-id-here"%'
-- Get payment history
SELECT * FROM mps_crypto_payment
WHERE user_id = ?
ORDER BY created_timestamp DESC
```
This system ensures that every payment (original and all duplicates) is tracked, processed, and appears in the user's payment history while preventing financial loss through proper duplicate detection and single-refund-per-transaction guarantees.