Fix unit tests: correct product unlock check and overpayment logic
- Replace non-existent is_unlocked_for_user with get_userproduct_for_user check - Move overpayment refund logic outside elif branch to apply to both new and stuck payments - All crypto watcher tests now pass 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
800b7965b5
commit
4ed53ba062
1 changed files with 36 additions and 33 deletions
|
|
@ -524,8 +524,11 @@ def process_payment(
|
|||
if crypto_payment.invoice and crypto_payment.invoice.line_items:
|
||||
# Check if any products are still locked for this user
|
||||
for line_item in crypto_payment.invoice.line_items:
|
||||
if not line_item.product.is_unlocked_for_user(
|
||||
crypto_payment.invoice.user
|
||||
if (
|
||||
line_item.product.get_userproduct_for_user(
|
||||
crypto_payment.invoice.user
|
||||
)
|
||||
is None
|
||||
):
|
||||
invoice_needs_finalization = True
|
||||
break
|
||||
|
|
@ -541,42 +544,42 @@ def process_payment(
|
|||
)
|
||||
finalize_invoice(env_request, crypto_payment)
|
||||
|
||||
# Check for overpayment refund AFTER confirming the order
|
||||
if (
|
||||
payment_rescue
|
||||
and crypto_payment.received_amount > crypto_payment.expected_amount
|
||||
and crypto_payment.invoice
|
||||
and crypto_payment.invoice.user
|
||||
):
|
||||
coin_config = get_coin_config(crypto_payment.coin_type)
|
||||
atomic_units = coin_config["atomic_units"]
|
||||
received_xmr = Decimal(crypto_payment.received_amount) / atomic_units
|
||||
expected_xmr = Decimal(crypto_payment.expected_amount) / atomic_units
|
||||
# Check for overpayment refund AFTER confirming the order (applies to both new and stuck payments)
|
||||
if (
|
||||
payment_rescue
|
||||
and crypto_payment.received_amount > crypto_payment.expected_amount
|
||||
and crypto_payment.invoice
|
||||
and crypto_payment.invoice.user
|
||||
):
|
||||
coin_config = get_coin_config(crypto_payment.coin_type)
|
||||
atomic_units = coin_config["atomic_units"]
|
||||
received_xmr = Decimal(crypto_payment.received_amount) / atomic_units
|
||||
expected_xmr = Decimal(crypto_payment.expected_amount) / atomic_units
|
||||
|
||||
refund_details = payment_rescue.handle_overpayment(
|
||||
crypto_payment,
|
||||
expected_xmr,
|
||||
received_xmr,
|
||||
crypto_payment.invoice.user,
|
||||
refund_details = payment_rescue.handle_overpayment(
|
||||
crypto_payment,
|
||||
expected_xmr,
|
||||
received_xmr,
|
||||
crypto_payment.invoice.user,
|
||||
)
|
||||
|
||||
if refund_details:
|
||||
logger.info(
|
||||
f"Overpayment detected for {crypto_payment.id}: {refund_details}"
|
||||
)
|
||||
|
||||
if refund_details:
|
||||
result = payment_rescue.execute_refund(refund_details)
|
||||
if result["success"]:
|
||||
logger.info(
|
||||
f"Overpayment detected for {crypto_payment.id}: {refund_details}"
|
||||
f"Excess refunded for payment {crypto_payment.id}: TX {result['tx_hash']}"
|
||||
)
|
||||
# Mark as confirmed with overpayment refunded
|
||||
crypto_payment.status = "confirmed_overpaid"
|
||||
else:
|
||||
logger.error(
|
||||
f"Excess refund failed for payment {crypto_payment.id}: {result['error']}"
|
||||
)
|
||||
result = payment_rescue.execute_refund(refund_details)
|
||||
if result["success"]:
|
||||
logger.info(
|
||||
f"Excess refunded for payment {crypto_payment.id}: TX {result['tx_hash']}"
|
||||
)
|
||||
# Mark as confirmed with overpayment refunded
|
||||
crypto_payment.status = "confirmed_overpaid"
|
||||
else:
|
||||
logger.error(
|
||||
f"Excess refund failed for payment {crypto_payment.id}: {result['error']}"
|
||||
)
|
||||
|
||||
# Note: Auto-sweep is handled separately based on unlocked balance, not confirmation status
|
||||
# Note: Auto-sweep is handled separately based on unlocked balance, not confirmation status
|
||||
else:
|
||||
if crypto_payment.received_amount > 0 and crypto_payment.status != "received":
|
||||
crypto_payment.status = "received"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue