Commit graph

386 commits

Author SHA1 Message Date
3f313b6bba Add complete status enums for crypto refunds and fix cancelled payment viewing
- Add terminal -complete status enums for all refund types
- Update crypto watcher to transition refunds to complete status at 10+ confirmations
- Fix cancelled payment quote viewing with proper access control and USD calculation
- Update status mappings and templates to support complete statuses
- Move payment status display to breakdown section in checkout template
- Add View Quote buttons for cancelled and refunded payments

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 22:31:34 -04:00
e9c520b866 Fix crypto payment status display and USD conversion in payment history
STATUS DISPLAY IMPROVEMENTS:
- Set payment status to underpaid-refunded/expired-refunded immediately when refund is determined
- Status now reflects refund eligibility rather than waiting for refund execution
- Added confirmed-overpaid-refunded status mapping for UI display

PAYMENT HISTORY ENHANCEMENTS:
- Added USD conversion display for received amounts using locked exchange rate
- Fixed TypeError by properly handling float * Decimal multiplication in templates
- Added refund_tx_hash to payment data for refund status differentiation
- Show "Refund pending" vs "Refund completed" messages based on refund_tx_hash presence

USER EXPERIENCE IMPROVEMENTS:
- Clear messaging about 10-confirmation requirement for refunds
- Immediate status feedback when underpayment/expired payment is detected
- Proper distinction between refund eligibility and refund completion
- Enhanced refund status explanations with restocking fee information

This ensures users see accurate payment status immediately rather than confusing
"Payment Received" labels when their payment is actually being refunded.
2025-09-24 21:21:38 -04:00
49747420ff Implement comprehensive refund confirmation system with 10-confirmation safety
REFUND SAFETY IMPROVEMENTS:
- Refunds now require 10+ confirmations on incoming payment before execution
- Added REFUND_PENDING_STATUSES for continued confirmation monitoring
- Refund-pending payments stay in main queue until fully confirmed
- Automatic retry of failed refunds once confirmations are met

NEW STATUS TRANSITIONS:
- confirmed-overpaid → confirmed-overpaid-refunded (when refund confirms)
- Added refund_confirmations column to track outgoing refund TX status

ENHANCED MONITORING:
- Dual confirmation tracking: incoming payments + outgoing refunds
- Refund retry queue detects when blocked refunds can proceed
- Separate confirmation-only updates for refund-pending payments
- Comprehensive logging for refund delays and confirmations

SECURITY BENEFITS:
- Prevents refunding payments subject to blockchain reorganizations
- Eliminates double-spend attack vectors on underpaid/expired payments
- Ensures refunds only sent for truly irreversible incoming payments
- Maintains customer protection while maximizing merchant security

This resolves the fundamental security issue where refunds could be sent
for payments that might later be reversed due to insufficient confirmations.
2025-09-24 21:06:35 -04:00
581f2b2244 Fix crypto payment refund system with proper account balance handling
- Fix AttributeError by changing payment.crypto_type to payment.coin_type
- Fix Decimal * float error by using Decimal("1e12") instead of 1e12
- Add account-specific balance checking using payment.account_index
- Add comprehensive logging for refund attempts and wallet balance checks
- Update execute_refund to accept payment object for account context
- Ensure refunds are sent from correct account that received the funds

This resolves GroupR's underpayment refund issue and improves the reliability
of the crypto payment rescue system.
2025-09-24 20:28:59 -04:00
88566599ce Fix crypto payment processing errors and cancelled payment history
- Fix AttributeError: 'CryptoPayment' object has no attribute 'crypto_type'
  Changed payment.crypto_type to payment.coin_type in crypto_payment_rescue.py
  This was causing crypto watcher to crash on underpayment processing

- Make CryptoPayment.invoice_id nullable for cancelled payments
  Updated model and recreated table to allow NULL invoice_id

- Add user_id and shop_id columns to CryptoPayment
  Ensures cancelled payments can be filtered by user/shop for history

- Update crypto_quotes_history to show cancelled payments
  Uses direct user_id/shop_id filtering instead of JOIN with invoice

- Update crypto_cancel to properly clear invoice reference
  Sets invoice_id=None before deleting invoice to avoid foreign key errors

Fixes critical crypto watcher crash that was preventing payment processing
2025-09-24 19:41:25 -04:00
1c957534d5 Move status, expiry and payment ID next to QR code
- Use two-column grid: QR code on left, all payment info on right
- Move status, expiry countdown, and payment ID into right column
- Keep payment address and amount at top of right column
- Maintains visual hierarchy with all payment details together
- Buttons remain below in separate grid
2025-09-24 18:32:30 -04:00
2732036fcf Fix crypto checkout layout overflow with single column grid
- Change from two-column (auto 1fr) to single column (1fr) grid
- Center QR code at top with inline-block display
- Payment instructions below in full width
- Prevents content from overflowing parent grid bounds
- Update JavaScript selector to match new grid structure
2025-09-24 18:31:20 -04:00
02e1130834 Restructure crypto checkout layout with QR code grid
- Put QR code and payment instructions in a grid layout
- QR code takes fixed space on left, payment info expands on right
- Use grid-template-columns: auto 1fr for optimal spacing
- Update JavaScript to handle new grid structure when hiding elements
2025-09-24 18:28:20 -04:00
44cd038370 Add 'Copied' feedback to copy buttons for 3 seconds 2025-09-24 18:26:45 -04:00
cce99a8fc2 Add mps-button-red CSS class and use it for crypto page buttons
- Add mps-button-red class with #bc2131 color and 0.8 opacity
- Replace inline button styles with CSS classes on crypto checkout
- Use mps-button-green for copy/wallet buttons
- Use mps-button-red for cancel button
- Fix TypeError by converting Decimal fee_buffer to float
- Update JavaScript invoice link to use mps-button-blue class
2025-09-24 18:23:01 -04:00
91042ff4ba Use CSS color classes instead of inline styles for crypto history buttons 2025-09-24 18:19:23 -04:00
d92d940a44 Remove '💰 Quote Details' heading 2025-09-24 18:15:59 -04:00
633eabfe15 Reorganize crypto checkout template layout
- Move Quote Details section up closer to payment information
- Remove "⚠️ Payment Information" heading
- Keep quote details well-styled for clarity
- Improve visual flow of checkout page
2025-09-24 18:14:42 -04:00
ddab2fadf9 Fix doubled fee display on crypto quote page
- Use same fee estimation logic on quote display as during payment creation
- Call estimate_monero_fee_for_quote() for XMR to get doubled fee
- Call estimate_dogecoin_fee_for_quote() for DOGE to get doubled fee
- Fallback to doubled settings value for other coins
- Ensures "Processing Fee (inbound + outbound)" shows correct doubled amount
2025-09-24 18:12:20 -04:00
d579af10a9 Remove 'You can start a new checkout from your cart' text from expired quote message 2025-09-24 18:01:06 -04:00
bff5fd49aa Use proper mps-button-small class instead of inline CSS for buttons 2025-09-24 16:58:13 -04:00
506a88faa0 Make View Quote and View Invoice buttons smaller with form-style CSS 2025-09-24 16:57:29 -04:00
2ec9c5fc74 Convert crypto quotes history to use CSS Grid consistently
- Replace flexbox layout with CSS Grid for header section
- Add align-items: start for proper grid alignment
- Add justify-self: end for button positioning
- Add empty div placeholder when no received amount to maintain grid structure
- Ensure all layouts use CSS Grid for consistency
2025-09-24 16:55:11 -04:00
eff2808371 Change 'View Payment' to 'View Quote' for pending/received crypto payments 2025-09-24 16:50:33 -04:00
7303ad570f Replace out-of-stock-no-refund with generic no-refund status
- Add STATUS_NO_REFUND constant to replace STATUS_OUT_OF_STOCK_NO_REFUND
- Add REFUND_REDIRECT_STATUSES enum for JavaScript redirect logic
- Update crypto watcher to set STATUS_NO_REFUND for all no-refund scenarios:
  - Expired payments without refund address
  - Underpaid payments without refund address
  - Out of stock payments without refund address
- Pass refund_redirect_statuses enum from backend to frontend
- Update JavaScript to use enum for crypto quotes redirect logic
- Enhance crypto quotes history to show detailed refund reasons
- Update status display labels and templates
2025-09-24 16:44:18 -04:00
df372a5ea1 Redirect to cart when quote expires on page
- Add 3-second delay redirect to /cart when quote expires while user is on page
- Provides clear navigation path after expiry warning message
- Prevents users from staying on expired quote pages
2025-09-24 16:30:06 -04:00
f25404eac3 Filter crypto payment history by shop
- Add shop_id filtering to crypto_quotes_history view
- Only show payments for the current shop context
- Maintains user privacy by filtering cross-shop payments
2025-09-24 16:28:30 -04:00
3de1abdd7b Remove target='_blank' from crypto refund address configuration links
- XMR and DOGE refund address setup links now open in same window
- Improves user experience by not opening unwanted new tabs/windows
2025-09-24 16:23:12 -04:00
26c63010ee Apply black formatting to crypto files 2025-09-24 16:13:42 -04:00
4da524965f Double fee estimates to cover both inbound and outbound transaction costs
- Update Monero fee estimation to double the fee (customer pays for both inbound + outbound)
- Update Dogecoin fee estimation to double the fee (customer pays for both inbound + outbound)
- Apply doubling to both dynamic RPC estimates and fallback hardcoded fees
- Update UI to show 'Processing Fee (inbound + outbound)' instead of 'Transaction Fee Buffer'
- Customer now fully covers all transaction processing costs for complete payment flow
- Sweep operations still use single fee estimates since they only do one transaction
2025-09-24 16:10:57 -04:00
cb606256ce Restore automatic redirect on payment confirmation via JavaScript polling
- Add redirect logic when status changes from non-confirmed to confirmed
- Only redirect when detected via JavaScript polling, not when browsing to already-confirmed quote
- Uses existing lastKnownStatus tracking to detect legitimate status changes
- 2 second delay to show confirmation message before redirect
- Fixes regression where payments stayed on quote page after confirmation
2025-09-24 16:06:43 -04:00
c3c05796da Remove pooled sweep behavior and implement individual payment sweeping
- 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
2025-09-24 16:03:50 -04:00
de757fdf76 Add bold formatting to 'Out of stock:' and 'Wrong address:' in both refund sections
- Apply <strong> tags to both labels including the colon for consistency
- Matches the formatting of other payment warning items like 'Overpayment:' and 'Underpayment:'
2025-09-24 15:49:07 -04:00
bffc690ecd Remove bold formatting from 'Out of stock:' text in payment warning
- Change '<strong>Out of stock:</strong>' to 'Out of stock:'
- Makes text consistent with other warning items that are not bold
2025-09-24 15:44:48 -04:00
1b0932e8e0 Simplify late payment warning text
- Change 'Late payments after X minutes are kept' to 'Late payments are kept'
- Removes dynamic time calculation and makes message clearer
2025-09-24 15:44:11 -04:00
4d1cddd544 Remove bold formatting from 'Out of Stock' status when no refund address configured
- Apply conditional font-weight: bold only when status \!= 'out-of-stock-no-refund'
- This makes the out-of-stock-no-refund status appear less emphasized since no refund was possible
2025-09-24 15:42:57 -04:00
d292ab88e2 Apply black formatting to crypto files 2025-09-24 15:40:32 -04:00
d3f2c1caa4 Fix Monero mempool detection in crypto watcher
- Add fallback to check all account transfers when subaddress filter returns no results
- This helps detect mempool transactions that may not immediately appear in subaddress-filtered queries
- Include both 'in' and 'pool' transfers from get_transfers RPC call
- Filter results to match the specific subaddress we're monitoring
- Addresses issue where mempool transactions are visible in wallet but not detected by watcher
2025-09-24 15:37:54 -04:00
fa8ca79988 Use dynamic fee estimation for crypto quote creation
- Add estimate_monero_fee_for_quote() using test transfer with do_not_relay
- Add estimate_dogecoin_fee_for_quote() using estimatesmartfee RPC
- Update Monero quote creation to use dynamic fees instead of hardcoded 0.0001 XMR
- Update Dogecoin quote creation to use dynamic fees instead of hardcoded 0.01 DOGE
- Maintains fallback to hardcoded fees if RPC calls fail
- Should provide more accurate quotes and reduce dust further
2025-09-24 15:32:42 -04:00
87471f2290 Implement dynamic fee estimation for crypto payments
- Monero: Use test transfer with do_not_relay=true for exact fee calculation
- Dogecoin: Use estimatesmartfee RPC for current network fee rates
- Replaces hardcoded fee estimates (0.0001 XMR, min_sweep_balance DOGE)
- Should reduce dust amounts by using more accurate fees
- Maintains fallback to hardcoded fees if RPC calls fail
2025-09-24 15:28:28 -04:00
e4990a5462 Document Monero RPC get_transfers unlocked field defect
- Add comprehensive documentation of RPC inconsistency
- Include symptoms, impact, workarounds, and references
- Establishes framework for documenting future Monero RPC issues
2025-09-24 15:03:31 -04:00
e9e6aa920b Fix Jinja2 template error - replace moment() with server-side timestamp formatting 2025-09-24 14:34:41 -04:00
1cce8c679e Fix AttributeError: use shop.name instead of shop.display_name 2025-09-24 14:31:36 -04:00
03683d55f5 Remove auto-redirect from crypto payment page and add payment history link
- Remove automatic redirect when payment is confirmed - users must click link
- Add 'Crypto Payment History' link to user settings page
- Users can now view all their crypto payment attempts at /u/crypto-quotes
2025-09-24 14:30:49 -04:00
76c804a3ac Fix sweep logic to use subaddress isolation
- Change from sweep_all to sweep_single to only sweep funds from specific subaddress
- Prevents sweeping funds from other payments in the same account
- Each payment already uses its own subaddress for proper isolation
2025-09-24 13:40:36 -04:00
4796d83eae Fix auto-sweep bug for locked Monero funds
- Fix critical bug where payments were incorrectly marked as 'swept' when funds were still locked
- Auto-sweep now properly retries until funds unlock (after Monero's 10-block lock time)
- Fix test expectation for expired-refunded status (hyphen not underscore)
2025-09-24 13:09:38 -04:00
13eb2abbb2 user experience
modified:   CLAUDE.md
	modified:   make_post_sell/lib/crypto_watcher.py
	modified:   make_post_sell/models/invoice.py
	modified:   make_post_sell/routes.py
	modified:   make_post_sell/scripts/alembic/versions/5bbb5df5bf1b_add_refund_tracking_columns_to_crypto_.py
	modified:   make_post_sell/templates/crypto_checkout.j2
	new file:   make_post_sell/templates/crypto_quotes_history.j2
	modified:   make_post_sell/views/cart.py
	modified:   make_post_sell/views/crypto.py
2025-09-24 12:49:09 -04:00
b352430b63 Delete invoice when crypto payment is cancelled
When a crypto payment is cancelled, delete the associated invoice and
line items since no actual purchase occurred. Keep the crypto_payment
record for transaction history and audit trails.

This prevents cancelled quotes from cluttering user purchase history.
2025-09-24 11:53:31 -04:00
2c7dd8e6ca Remove QR code and payment instructions when quote is cancelled
When a crypto quote is cancelled or becomes non-pending, completely
remove the QR code and payment instructions (amount + address) instead
of just disabling them. This provides cleaner UI for cancelled quotes.
2025-09-24 11:51:23 -04:00
7879816143 Remove bold formatting from 'Full refund' text
Remove strong tags from 'full refund' text in out-of-stock messaging
for consistent formatting.
2025-09-24 11:46:40 -04:00
6fa9eed4c9 Update crypto checkout for out-of-stock refund scenarios and left-align QR code
- Add specific messaging for out-of-stock-refunded status (full refund, no fee)
- Add specific messaging for out-of-stock-no-refund status
- Add out-of-stock item to refund policy lists
- Left-align QR code instead of centering it
2025-09-24 11:46:02 -04:00
444f9d2d5f Move QR code above payment amount text
Position QR code directly above the 'Send exactly X XMR to this address'
text for better visual flow and easier wallet scanning.
2025-09-24 11:43:56 -04:00
93b807aab9 Add modern QR code library and update crypto checkout template
- Replace old insecure qrcodejs (v1.0.0 from 2013) with QRious v4.0.2 (2017)
- Update crypto checkout template to use QRious API instead of old QRCode.js
- QRious uses canvas element and modern security practices
2025-09-24 11:40:20 -04:00
5dc9b0d1bb Add missing fee_amount field to PaymentRescue test mock
The real PaymentRescue.handle_expired_payment() method returns fee_amount
but the test mock was missing this field, causing KeyError in tests.
2025-09-24 11:39:34 -04:00
4a3bf49c24 Fix crypto watcher tests after enum changes and refund tracking
- Add missing 'refund_amount' and 'reason' fields to test mocks
- Update status expectation from 'confirmed_overpaid' to 'confirmed-overpaid'
  to match dash-based enum format
2025-09-24 11:29:23 -04:00