Payment buttons and QR codes are completely removed from the page once payment is received, not just disabled
340 lines
No EOL
14 KiB
ReStructuredText
340 lines
No EOL
14 KiB
ReStructuredText
Cryptocurrency Payment Problems and Solutions
|
|
=============================================
|
|
|
|
This document outlines the various failure modes in cryptocurrency payment processing and proposed solutions for each.
|
|
|
|
Payment Processing UI Behavior
|
|
------------------------------
|
|
|
|
**Real-Time Status Updates**:
|
|
- Quote page polls for payment status and updates immediately when payment detected
|
|
- Status changes from "pending" → "received" → "confirmed" in real-time
|
|
- Payment buttons and QR codes are REMOVED once payment is received
|
|
- Prevents duplicate payments by removing all payment methods from the page
|
|
|
|
**Automatic Redirects**:
|
|
- Upon confirmation (as fast as 2 confirmations for small digital goods)
|
|
- Users are automatically redirected to invoice or product download page
|
|
- Digital products: Direct to download page
|
|
- Physical products: To invoice with shipping details
|
|
|
|
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 and user redirected to invoice/download
|
|
- 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 and user redirected to invoice/download
|
|
- Quote page shows "payment received" status, preventing duplicate attempts
|
|
- Second payment automatically refunded minus 9% restocking fee (✓ RESOLVED)
|
|
- Multiple duplicate payments handled correctly (✓ RESOLVED - see "The MONERO DOOM Scenario")
|
|
|
|
**Implemented Solutions**:
|
|
- ✓ Refund address collected at checkout for potential refunds
|
|
- ✓ Duplicate payments detected and marked as STATUS_DOUBLEPAY_REFUND
|
|
- ✓ Automatic refund minus 9% restocking fee
|
|
- ✓ Safe restocking fee collection using min(balance, expected_fee) logic
|
|
- ✓ Priority system ensures refunds complete before fee collection
|
|
|
|
**The MONERO DOOM Scenario (✓ RESOLVED)**:
|
|
Multiple duplicate payments to same address exposed a critical design flaw where restocking fee sweeps
|
|
could steal funds from other payments sharing the same subaddress. The solution implemented:
|
|
- Each restocking fee sweep only takes min(balance, expected_fee)
|
|
- Prevents fund theft between payments
|
|
- 9% fee is exact (network fees deducted from refund, not restocking)
|
|
- Priority 4 (lowest) for restocking sweeps with mid-tier confirmation requirements
|
|
|
|
**Remaining Solutions Needed**:
|
|
- **WANT**: Email notification about duplicate payment
|
|
|
|
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
|
|
- Upon reaching required confirmations, user automatically redirected to invoice/download
|
|
|
|
**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
|
|
- Sweeps exact payment amounts to cold wallet (not entire balance)
|
|
- 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 precise amount accounting
|
|
- 1:1 payment-to-sweep mapping for clear audit trail
|
|
- Restocking fees use min(balance, expected_fee) to prevent fund theft
|
|
- 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) |