Merge branch 'feature/economically-unviable-refund-emails' into 'master'

Add email notifications for economically unviable refunds

See merge request engineering/make-post-sell/make_post_sell!52
This commit is contained in:
Russell Ballestrini 2025-10-03 20:54:16 +00:00
commit b0dc15b06a
2 changed files with 95 additions and 8 deletions

View file

@ -1767,6 +1767,30 @@ def process_payment(
refund_details["refund_amount"]
* coin_config["atomic_units"]
)
# Send refund email notification
if crypto_payment.invoice and crypto_payment.invoice.user:
try:
# Create shop context request
email_request = create_shop_context_request(
env_request, crypto_payment
)
send_refund_email(
email_request,
crypto_payment.invoice.user.email,
crypto_payment,
refund_details,
)
log.payment_info(
crypto_payment,
"Sent refund email for economically unviable duplicate payment",
)
except Exception as e:
log.payment_error(
crypto_payment,
f"Failed to send refund email for economically unviable duplicate payment: {e}",
)
env_request.dbsession.add(crypto_payment)
env_request.dbsession.flush()
return # Exit early - no refund to process
@ -2116,6 +2140,26 @@ def process_payment(
refund_details["refund_amount"]
* coin_config["atomic_units"]
)
# Send refund email notification
if crypto_payment.invoice and crypto_payment.invoice.user:
try:
send_refund_email(
env_request,
crypto_payment.invoice.user.email,
crypto_payment,
refund_details,
)
log.payment_info(
crypto_payment,
"Sent refund email for economically unviable expired payment",
)
except Exception as e:
log.payment_error(
crypto_payment,
f"Failed to send refund email for economically unviable expired payment: {e}",
)
# Delete invoice for terminal state
delete_invoice_for_terminal_state(
env_request.dbsession, crypto_payment
@ -2856,6 +2900,26 @@ def process_payment(
refund_details["refund_amount"]
* coin_config["atomic_units"]
)
# Send refund email notification
if crypto_payment.invoice and crypto_payment.invoice.user:
try:
send_refund_email(
env_request,
crypto_payment.invoice.user.email,
crypto_payment,
refund_details,
)
log.payment_info(
crypto_payment,
"Sent refund email for economically unviable underpayment",
)
except Exception as e:
log.payment_error(
crypto_payment,
f"Failed to send refund email for economically unviable underpayment: {e}",
)
# Delete invoice for terminal state
delete_invoice_for_terminal_state(
env_request.dbsession, crypto_payment
@ -3211,6 +3275,30 @@ def process_refund_confirmations(request, settings):
"economically unviable refund",
)
payment.refund_reason = f"Underpayment - refund economically unviable ({refund_details['refund_amount']} {payment.coin_type})"
# Send refund email notification
if payment.invoice and payment.invoice.user:
try:
# Create a basic request object for email context
from pyramid.testing import DummyRequest
email_request = DummyRequest()
email_request.registry = request.registry
send_refund_email(
email_request,
payment.invoice.user.email,
payment,
refund_details,
)
log.payment_info(
payment,
"Sent refund email for economically unviable underpayment (passive monitoring)",
)
except Exception as e:
log.payment_error(
payment,
f"Failed to send refund email for economically unviable underpayment (passive monitoring): {e}",
)
db.add(payment)
continue

View file

@ -389,8 +389,13 @@ def send_refund_email(request, to_email, crypto_payment, refund_details):
CryptoPayment.STATUS_OUT_OF_STOCK_NOT_REFUNDED,
CryptoPayment.STATUS_DOUBLEPAY_NOT_REFUNDED,
]:
subject = f"Payment Issue - No Refund Address - {crypto_payment.coin_type}"
explanation = "We were unable to process a refund for your payment because no refund address was configured. Please contact support if you need assistance."
# Check if it's economically unviable vs no refund address
if crypto_payment.refund_reason and "economically unviable" in crypto_payment.refund_reason:
subject = f"Payment Issue - Refund Too Small - {crypto_payment.coin_type}"
explanation = f"Your payment of {received_amount} {crypto_payment.coin_type} results in a refund amount too small to cover network transaction fees. The refund would cost more to send than its value."
else:
subject = f"Payment Issue - No Refund Address - {crypto_payment.coin_type}"
explanation = "We were unable to process a refund for your payment because no refund address was configured."
has_fee = False # No refund means no fee calculation
else:
@ -417,8 +422,6 @@ Refund Details:
{fee_note}
Please allow up to 10 confirmations for the refund to be fully processed.
If you have any questions, please contact support with your payment ID: {crypto_payment.id}
"""
# Build the HTML message
@ -457,10 +460,6 @@ If you have any questions, please contact support with your payment ID: {crypto_
<p style="color: #666; font-style: italic;">
Please allow up to 10 confirmations for the refund to be fully processed.
</p>
<p style="font-size: 0.9em; color: #999;">
If you have any questions, please contact support with your payment ID: <code>{crypto_payment.id}</code>
</p>
</body>
</html>
"""