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:
Russell Ballestrini 2025-09-23 12:57:21 -04:00
parent 800b7965b5
commit 4ed53ba062

View file

@ -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"