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.
This commit is contained in:
parent
49747420ff
commit
e9c520b866
3 changed files with 32 additions and 9 deletions
|
|
@ -884,6 +884,10 @@ def process_payment(
|
|||
logger.info(
|
||||
f"Expired payment {crypto_payment.id} eligible for refund: {refund_details}"
|
||||
)
|
||||
|
||||
# Set status to expired-refunded immediately when refund is determined
|
||||
crypto_payment.status = CryptoPayment.STATUS_EXPIRED_REFUNDED
|
||||
|
||||
result = payment_rescue.execute_refund(
|
||||
refund_details, crypto_payment
|
||||
)
|
||||
|
|
@ -898,9 +902,7 @@ def process_payment(
|
|||
)
|
||||
crypto_payment.refund_tx_hash = result["tx_hash"]
|
||||
crypto_payment.refund_reason = refund_details["reason"]
|
||||
crypto_payment.status = (
|
||||
CryptoPayment.STATUS_EXPIRED_REFUNDED
|
||||
)
|
||||
# Status already set above
|
||||
|
||||
# Commit the refund first
|
||||
env_request.dbsession.add(crypto_payment)
|
||||
|
|
@ -1147,6 +1149,10 @@ def process_payment(
|
|||
logger.info(
|
||||
f"Underpayment {crypto_payment.id} eligible for refund: {refund_details}"
|
||||
)
|
||||
|
||||
# Set status to underpaid-refunded immediately when refund is determined
|
||||
crypto_payment.status = CryptoPayment.STATUS_UNDERPAID_REFUNDED
|
||||
|
||||
result = payment_rescue.execute_refund(
|
||||
refund_details, crypto_payment
|
||||
)
|
||||
|
|
@ -1154,11 +1160,12 @@ def process_payment(
|
|||
logger.info(
|
||||
f"Refund executed for underpayment {crypto_payment.id}: TX {result['tx_hash']}"
|
||||
)
|
||||
crypto_payment.status = CryptoPayment.STATUS_UNDERPAID_REFUNDED
|
||||
# Status already set above
|
||||
else:
|
||||
logger.error(
|
||||
f"Refund failed for underpayment {crypto_payment.id}: {result['error']}"
|
||||
)
|
||||
# Status remains underpaid-refunded, refund will be retried later
|
||||
else:
|
||||
# No refund possible - no refund address configured
|
||||
logger.warning(
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@
|
|||
{% else %}
|
||||
{{ '%.8f' % payment.received_crypto }} {{ payment.coin_type }}
|
||||
{% endif %}
|
||||
<br>
|
||||
<small style="color: #6c757d;">${{ '%.2f' % (payment.received_crypto * (payment.rate_usd_per_coin|float)) }} USD</small>
|
||||
{% if payment.confirmations > 0 %}
|
||||
<br>
|
||||
<small style="color: #6c757d;">{{ payment.confirmations }}/{{ payment.confirmations_required }} confirmations</small>
|
||||
|
|
@ -88,11 +90,20 @@
|
|||
{% elif payment.status.endswith('-refunded') %}
|
||||
<div style="background: #d1ecf1; border: 1px solid #bee5eb; border-radius: 3px; padding: 8px; margin-top: 10px;">
|
||||
<small>
|
||||
💸 This payment was automatically refunded.
|
||||
{% if payment.status == 'out-of-stock-refunded' %}
|
||||
The item became unavailable after your payment - full refund issued.
|
||||
{% if payment.refund_tx_hash %}
|
||||
💸 This payment was automatically refunded.
|
||||
{% if payment.status == 'out-of-stock-refunded' %}
|
||||
The item became unavailable after your payment - full refund issued.
|
||||
{% else %}
|
||||
A 9% restocking fee was deducted to cover network costs.
|
||||
{% endif %}
|
||||
{% else %}
|
||||
A 9% restocking fee was deducted to cover network costs.
|
||||
⏳ Refund pending - waiting for your payment to reach 10 confirmations before processing the refund.
|
||||
{% if payment.status == 'out-of-stock-refunded' %}
|
||||
The item became unavailable after your payment - full refund will be issued.
|
||||
{% else %}
|
||||
A 9% restocking fee will be deducted to cover network costs.
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</small>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -799,7 +799,7 @@ def crypto_cancel(request):
|
|||
# Clear the invoice reference BEFORE deleting the invoice (now that invoice_id is nullable)
|
||||
crypto_payment.invoice_id = None
|
||||
crypto_payment.invoice = None
|
||||
|
||||
|
||||
delete_result = delete_invoice_by_id(request.dbsession, invoice.id)
|
||||
# We don't fail the cancellation if invoice deletion fails
|
||||
# The payment cancellation is more important than invoice cleanup
|
||||
|
|
@ -879,6 +879,7 @@ def crypto_quotes_history(request):
|
|||
"invoice_id": payment.invoice.id if payment.invoice else None,
|
||||
"shop_name": payment.shop.name if payment.shop else "Unknown Shop",
|
||||
"refund_reason": payment.refund_reason,
|
||||
"refund_tx_hash": payment.refund_tx_hash,
|
||||
}
|
||||
payment_history.append(payment_data)
|
||||
|
||||
|
|
@ -955,6 +956,10 @@ def get_payment_status_info(status):
|
|||
"expired": {"label": "Expired", "color": "#6c757d"},
|
||||
"expired-refunded": {"label": "Expired - Refunded", "color": "#fd7e14"},
|
||||
"underpaid-refunded": {"label": "Underpaid - Refunded", "color": "#fd7e14"},
|
||||
"confirmed-overpaid-refunded": {
|
||||
"label": "Overpaid - Refunded",
|
||||
"color": "#fd7e14",
|
||||
},
|
||||
"cancelled": {"label": "Cancelled", "color": "#6c757d"},
|
||||
"out-of-stock-refunded": {
|
||||
"label": "Out of Stock - Refunded",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue