feat: add recharge create and status APIs

This commit is contained in:
QiuSW
2026-07-03 09:34:07 +08:00
parent c15a07a5c2
commit fa87359a2c
18 changed files with 808 additions and 22 deletions
+60
View File
@@ -27,12 +27,15 @@ from apps.billing.pricing import (
get_pricing_rule,
quote_recharge_points,
)
from apps.billing.payment_gateways import PaymentOrderCode
from apps.billing.services import (
InsufficientPointsError,
InvalidCallStateError,
RechargeAmountMismatchError,
RechargeOrderCreateError,
RechargePayment,
apply_recharge_payment,
create_recharge_order,
mark_call_success,
precharge_call,
query_and_apply_recharge_payment,
@@ -409,6 +412,63 @@ class BillingServiceTests(TestCase):
points_granted=points_granted,
)
def create_exchange_rate(self, *, points_per_unit="10.0000", effective_from=None):
return ExchangeRate.objects.create(
currency="CNY",
points_per_unit=Decimal(points_per_unit),
effective_from=effective_from or timezone.now() - timedelta(minutes=1),
)
def test_create_recharge_order_locks_exchange_rate_points_and_qr_code(self):
self.create_exchange_rate(points_per_unit="12.5000")
expires_at = timezone.now() + timedelta(minutes=10)
def fake_payment_order(order):
return PaymentOrderCode(
code_url=f"mockpay://{order.pay_method}/{order.order_no}",
expires_at=expires_at,
)
order = create_recharge_order(
user=self.user,
amount=Decimal("8.88"),
pay_method=RechargeOrder.PayMethod.WEIXIN,
payment_order_func=fake_payment_order,
)
self.assertEqual(order.user, self.user)
self.assertEqual(order.status, RechargeOrder.Status.PENDING)
self.assertEqual(order.amount_money, Decimal("8.88"))
self.assertEqual(order.currency, "CNY")
self.assertEqual(order.pay_method, RechargeOrder.PayMethod.WEIXIN)
self.assertEqual(order.exchange_rate, Decimal("12.5000"))
self.assertEqual(order.points_granted, 111)
self.assertTrue(order.code_url.startswith("mockpay://weixin/"))
self.assertEqual(order.expires_at, expires_at)
self.create_exchange_rate(points_per_unit="99.0000")
order.refresh_from_db()
self.assertEqual(order.exchange_rate, Decimal("12.5000"))
self.assertEqual(order.points_granted, 111)
def test_create_recharge_order_marks_order_failed_when_gateway_fails(self):
self.create_exchange_rate(points_per_unit="10.0000")
def failing_payment_order(_order):
raise RechargeOrderCreateError("gateway failed")
with self.assertRaises(RechargeOrderCreateError):
create_recharge_order(
user=self.user,
amount=Decimal("20.00"),
pay_method=RechargeOrder.PayMethod.ALIPAY,
payment_order_func=failing_payment_order,
)
order = RechargeOrder.objects.get(user=self.user, amount_money=Decimal("20.00"))
self.assertEqual(order.status, RechargeOrder.Status.FAILED)
self.assertEqual(order.code_url, "")
def test_precharge_call_debits_wallet_and_writes_pending_call_and_consume_ledger(self):
charge = precharge_call(
user=self.user,