- Remove pooled_sweep logic from both Monero and Dogecoin sweep functions - Each payment now swept individually for better accounting and audit trail - Insufficient balance now returns False to retry later instead of fake pooled_sweep - Update all tests to expect new behavior (False for insufficient balance) - Update documentation to reflect 1:1 payment-to-sweep mapping - Add link to refund address configuration in crypto checkout template - All crypto watcher tests now passing with new individual sweep logic
313 lines
No EOL
12 KiB
ReStructuredText
313 lines
No EOL
12 KiB
ReStructuredText
Cryptocurrency Payment Problems and Solutions
|
|
=============================================
|
|
|
|
This document outlines the various failure modes in cryptocurrency payment processing and proposed solutions for each.
|
|
|
|
Transaction Failure Scenarios
|
|
-----------------------------
|
|
|
|
1. Underpayment
|
|
~~~~~~~~~~~~~~~
|
|
**Problem**: Customer sends less than the required amount (e.g., $9.50 instead of $10)
|
|
|
|
**Current Behavior**:
|
|
- Order not fulfilled (remains 'pending' status)
|
|
- Automatic refund minus 9% restocking fee (if refund address configured) (✓ RESOLVED)
|
|
- Remaining funds auto-swept to cold wallet after refund (✓ RESOLVED)
|
|
|
|
**Implemented Solutions**:
|
|
- ✓ PaymentRescue.handle_underpayment() processes partial payments
|
|
- ✓ Automatic refund minus 9% restocking fee (covers network costs)
|
|
- ✓ Auto-sweep ensures partial payments don't accumulate in hot wallet
|
|
- ✓ Minimal reserve (0.001 XMR) maintained for operations
|
|
|
|
**Remaining Solutions Needed**:
|
|
- **WANT**: Implement configurable underpayment tolerance (e.g., accept if within 1%)
|
|
- **WANT**: Add manual order completion option in shop admin panel
|
|
- **WANT**: Track all payment attempts for accounting/recovery
|
|
- Allow grace period for customer to send remaining amount
|
|
|
|
2. Overpayment
|
|
~~~~~~~~~~~~~~
|
|
**Problem**: Customer sends more than required amount (e.g., $12 instead of $10)
|
|
|
|
**Current Behavior**:
|
|
- If payment >= expected, order completes
|
|
- Automatic refund of excess minus 9% restocking fee (if refund address configured) (✓ RESOLVED)
|
|
- Remaining funds auto-swept to cold wallet after refund (✓ RESOLVED)
|
|
|
|
**Implemented Solutions**:
|
|
- ✓ Optional "refund address" field at checkout (stored in crypto_payment.refund_address)
|
|
- ✓ Automatic overpayment refunds minus 9% restocking fee (prevents abuse)
|
|
- ✓ 5% overpayment tolerance before triggering refund
|
|
- ✓ Auto-sweep prevents excess funds from accumulating in hot wallet
|
|
- ✓ PaymentRescue class handles all refund logic
|
|
|
|
**Remaining Solutions Needed**:
|
|
- Credit overpayment to customer's account for future purchases (alternative to refund)
|
|
- Allow shop to set custom overpayment handling policy
|
|
- Track overpayments separately for accounting
|
|
|
|
3. Payment After Quote Expiry
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
**Problem**: Customer sends correct amount after 15-minute pricing window
|
|
|
|
**Current Behavior**:
|
|
- Quote marked as 'expired' after time window
|
|
- Automatic refund minus 9% restocking fee (if refund address configured) (✓ RESOLVED)
|
|
- NO grace period - strict expiry enforced as shown in template (✓ RESOLVED)
|
|
- Remaining funds auto-swept to cold wallet after refund (✓ RESOLVED)
|
|
|
|
**Implemented Solutions**:
|
|
- ✓ PaymentRescue.handle_expired_payment() processes late payments
|
|
- ✓ Automatic refund minus 9% restocking fee
|
|
- ✓ 15-minute quote window configurable via monero.quote_expiry_seconds
|
|
- ✓ Clear warning in checkout UI about strict expiry time
|
|
- ✓ Auto-sweep ensures expired payment funds don't accumulate
|
|
|
|
**Remaining Solutions Needed**:
|
|
- **WANT**: Send email notification to customer about expired payment
|
|
- **WANT**: Allow manual order completion by shop owner (override)
|
|
- **WANT**: Track expired payments for analytics
|
|
|
|
4. Wrong Address
|
|
~~~~~~~~~~~~~~~~
|
|
**Problem**: Customer sends to incorrect address (typo or old address)
|
|
|
|
**Current Behavior**:
|
|
- Funds permanently lost (if invalid address)
|
|
- Funds go to wrong recipient (if valid but wrong address)
|
|
|
|
**Solutions**:
|
|
- Display address as QR code to reduce typing errors
|
|
- Implement address verification/checksum display
|
|
- Warn users that addresses are single-use
|
|
- Add copy-to-clipboard functionality
|
|
- Use payment URIs with amount included
|
|
|
|
5. Double Payment
|
|
~~~~~~~~~~~~~~~~~
|
|
**Problem**: Customer accidentally pays twice for same order
|
|
|
|
**Current Behavior**:
|
|
- First payment completes order
|
|
- Second payment automatically swept to shop's cold wallet (✓ RESOLVED)
|
|
|
|
**Implemented Solutions**:
|
|
- ✓ Refund address collected at checkout for potential refunds
|
|
- ✓ Auto-sweep prevents duplicate payments from accumulating
|
|
|
|
**Remaining Solutions Needed**:
|
|
- Detect and flag duplicate payments within time window
|
|
- Auto-refund second payment if refund address known
|
|
- **WANT**: Email notification about duplicate payment
|
|
- Add "payment already received" status check
|
|
|
|
6. Network/Mempool Congestion
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
**Problem**: Transaction stuck in mempool, confirmations delayed
|
|
|
|
**Current Behavior**:
|
|
- Order remains pending
|
|
- May arrive after quote expiry
|
|
|
|
**Solutions**:
|
|
- Implement 0-conf acceptance for trusted customers
|
|
- Dynamic confirmation requirements based on network conditions
|
|
- Accept transaction once seen in mempool for small amounts
|
|
- Email updates about confirmation progress
|
|
- Allow RBF (Replace-By-Fee) for stuck transactions
|
|
|
|
7. Insufficient Confirmations
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
**Problem**: Payment received but not enough confirmations before timeout
|
|
|
|
**Current Behavior**:
|
|
- System uses risk-based confirmation requirements (✓ RESOLVED)
|
|
- Order waits for required confirmations based on amount/product type
|
|
|
|
**Implemented Solutions**:
|
|
- ✓ Risk-based confirmation requirements (petty/mid/high tiers)
|
|
- ✓ Fewer confirmations for digital goods (2/10/20 defaults)
|
|
- ✓ Physical products always use maximum confirmations
|
|
- ✓ Per-shop configurable risk thresholds
|
|
|
|
**Remaining Solutions Needed**:
|
|
- Implement confirmation timeout extension
|
|
- Progressive order fulfillment (partial access)
|
|
- Customer notification of confirmation progress
|
|
|
|
8. Exchange Rate Fluctuation
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
**Problem**: Crypto value changes significantly during payment window
|
|
|
|
**Current Behavior**:
|
|
- Customer may pay correct crypto amount but USD value differs
|
|
- Treated as under/overpayment
|
|
|
|
**Solutions**:
|
|
- Implement rate-lock tolerance (e.g., ±5%)
|
|
- Use shorter quote windows during volatile periods
|
|
- Offer "pay extra" option if rate moves against customer
|
|
- Multiple rate sources for better accuracy
|
|
- Allow payment in stablecoins
|
|
|
|
9. Invalid Cold Wallet Configuration
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
**Problem**: Shop owner enters invalid sweep destination address
|
|
|
|
**Current Behavior**:
|
|
- Sweep operation fails but order still completes
|
|
- Failed sweeps are logged but don't block fulfillment
|
|
|
|
**Implemented Solutions**:
|
|
- ✓ Auto-sweep maintains minimal reserve (0.001 XMR) to prevent total accumulation
|
|
- ✓ All sweep attempts are logged for debugging
|
|
- ✓ Failed sweeps don't block order completion
|
|
|
|
**Remaining Solutions Needed**:
|
|
- **NEED**: Validate cold wallet address format on entry
|
|
- **NEED**: Alert shop owner of failed sweeps via email/admin panel
|
|
- **NEED**: Implement sweep retry logic with exponential backoff
|
|
- **WANT**: Test sweep with minimal amount on configuration
|
|
|
|
10. RPC Node Failure
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
**Problem**: Cannot communicate with blockchain node
|
|
|
|
**Current Behavior**:
|
|
- Cannot detect incoming payments
|
|
- Cannot create new addresses
|
|
- Cannot perform sweeps
|
|
|
|
**Remaining Solutions Needed**:
|
|
- **NEED**: Configure multiple backup nodes
|
|
- **NEED**: Automatic failover to backup nodes
|
|
- **WANT**: Node health monitoring dashboard
|
|
- Cache recent blockchain data
|
|
- Manual payment verification fallback
|
|
|
|
11. Blockchain Reorganization
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
**Problem**: Confirmed transaction gets reversed in chain reorg
|
|
|
|
**Current Behavior**:
|
|
- Product already delivered
|
|
- Payment no longer valid
|
|
|
|
**Implemented Solutions**:
|
|
- ✓ Higher confirmation requirements for high-value orders (20 confirms)
|
|
- ✓ Physical products always use maximum confirmations
|
|
|
|
**Note**: Further reorg protection marked as TRASH (over-engineering for extremely rare edge case)
|
|
|
|
General Solutions Architecture
|
|
------------------------------
|
|
|
|
1. **Payment Tracking System**
|
|
- Record ALL incoming transactions
|
|
- Track payment attempts, not just successful payments
|
|
- Link payments to addresses, quotes, and customers
|
|
|
|
2. **Refund Infrastructure**
|
|
- Optional refund address collection at checkout
|
|
- Manual refund initiation by shop admin
|
|
- Automated refund for specific scenarios
|
|
- Refund policy configuration per shop
|
|
|
|
3. **Communication Layer**
|
|
- Email notifications for payment issues
|
|
- In-app notifications for customers
|
|
- Admin alerts for shop owners
|
|
- Status page for payment processing
|
|
|
|
4. **Policy Framework**
|
|
- Configurable tolerance levels per shop
|
|
- Clear Terms of Service templates
|
|
- Automated policy enforcement
|
|
- Audit trail for all decisions
|
|
|
|
5. **Recovery Mechanisms**
|
|
- Manual payment verification tools
|
|
- Order completion override for admins
|
|
- Payment matching algorithms
|
|
- Orphaned fund recovery process
|
|
|
|
6. **Implemented Auto-Sweep Configuration**
|
|
|
|
The system now implements automatic sweeping of confirmed payments to minimize hot wallet exposure:
|
|
|
|
**Risk-Based Confirmation Requirements**:
|
|
- Confirmation thresholds are configured in INI files per coin type
|
|
- Three tiers based on payment amount and product type:
|
|
|
|
* **Petty Tier** (default: 2 confirmations for XMR):
|
|
- Amounts below shop's mid-tier threshold (default $10)
|
|
- Digital products only
|
|
- Configurable via: `monero.confirmations.petty`
|
|
|
|
* **Mid Tier** (default: 10 confirmations for XMR):
|
|
- Amounts between mid and high thresholds ($10-$100 default)
|
|
- Digital products only
|
|
- Configurable via: `monero.confirmations.mid`
|
|
|
|
* **High Tier** (default: 20 confirmations for XMR):
|
|
- Amounts above high threshold ($100+)
|
|
- ALL physical products regardless of amount
|
|
- Configurable via: `monero.confirmations.high`
|
|
|
|
**Auto-Sweep Process**:
|
|
- Executes immediately after required confirmations are reached
|
|
- Uses "sweep_all" to transfer entire account balance to cold wallet
|
|
- Each shop has dedicated Monero account (prevents cross-shop fund mixing)
|
|
- Account isolation: Shop A uses account 0, Shop B uses account 1, etc.
|
|
- Each payment swept individually using subaddress isolation
|
|
- 1:1 payment-to-sweep mapping for clear audit trail and accounting
|
|
- Insufficient balance handling: Payment retries later until funds unlock
|
|
- Failed sweeps are logged but don't block order fulfillment
|
|
|
|
**Per-Shop Risk Thresholds**:
|
|
- `payment_risk_threshold_mid_cents`: Boundary for petty/mid tiers
|
|
- `payment_risk_threshold_high_cents`: Boundary for mid/high tiers
|
|
- Shops can customize based on their risk tolerance
|
|
- Physical products always use maximum confirmations
|
|
|
|
Implementation Status & Priority
|
|
--------------------------------
|
|
|
|
**Completed Features**:
|
|
- ✓ Auto-sweep with minimal hot wallet exposure
|
|
- ✓ Risk-based confirmation tiers (petty/mid/high)
|
|
- ✓ Refund address collection at checkout
|
|
- ✓ Per-shop configurable risk thresholds
|
|
- ✓ Sweep failure logging and non-blocking order completion
|
|
- ✓ Configurable quote expiry windows
|
|
- ✓ Automated refund system with 9% restocking fee:
|
|
- ✓ Underpayment refunds (minus fee)
|
|
- ✓ Overpayment refunds (excess minus fee, 5% tolerance)
|
|
- ✓ Expired payment refunds (minus fee)
|
|
- ✓ PaymentRescue class handles all refund scenarios
|
|
- ✓ Clear payment rules displayed in checkout UI
|
|
|
|
**NEED TO HAVE** (Security/Operational Critical):
|
|
- **Invoice payment status tracking**: ✓ RESOLVED - Added derived properties to Invoice model (payment_status, payment_method, is_paid) that read from related CryptoPayment when present
|
|
- **Monero account creation**: ✓ RESOLVED - Now creates dedicated Monero accounts via RPC when shops configure crypto processors
|
|
- Cold wallet address validation on entry (prevent fund loss)
|
|
- Sweep failure alerts to shop owners (prevent hot wallet accumulation)
|
|
- Multiple/fallback RPC node support (prevent downtime)
|
|
- Sweep retry logic with exponential backoff (reliability)
|
|
|
|
**WANT TO HAVE** (Good UX/Business Value):
|
|
- Failed payment email notifications to customers
|
|
- Manual order completion tools in admin panel
|
|
- Payment attempt tracking for ALL transactions (analytics)
|
|
- Underpayment tolerance configuration (e.g., accept if within 1%)
|
|
- Customer crypto payment history tracking
|
|
|
|
**TRASH** (Over-engineering/Low ROI):
|
|
- 0-conf acceptance for trusted customers (high risk, complex trust system)
|
|
- Progressive order fulfillment for digital goods (unnecessarily complex)
|
|
- Blockchain reorg detection and protection (rare edge case)
|
|
- Payment status webhooks/callbacks (polling works fine)
|
|
- Credit system for overpayments (refunds work, adds account complexity)
|
|
- Custom refund policies per shop (9% standard works for all) |