Bazaar: subscriptions (10343/10344), dynamic price (discount codes on Bazaar), auto-renewal sync
- Purchase with paymentMethod=bazaar now works for subscription plans with a bazaar_sku (not only packs);
response carries bazaarProductType. Migration subscription.0014 puts 10343/10344 on the 90/180-day plans.
- Verify asks Bazaar for the right product type (from the order) and stores validUntil (payment.0012).
- POST /api/payment/bazaar/orders/{id}/start: SKU, type, and an HS256 dynamic-price JWT when a discount
code lowered the price (BAZAAR_DYNAMIC_PRICE_KEY); discount on Bazaar orders allowed only with that key
and only before start.
- Auto-renewal: sync_bazaar_renewals re-asks Bazaar when the paid period is near its end (status page and
the paywall via has_subscription_access); each new period becomes a paid order.
- Default BAZAAR_PACKAGE_NAME = com.tadrisino.math.app; health shows bazaarDynamicPrice.
979 tests green. No real Bazaar purchase or renewal tested.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,19 @@ def has_active_subscription(user_id: int) -> bool:
|
||||
models.Q(expires_at__isnull=True) | models.Q(expires_at__gt=now)).exists()
|
||||
|
||||
|
||||
def has_subscription_access(user_id: int) -> bool:
|
||||
"""
|
||||
دیوارِ پرداخت (نقشه و فصلها). مثلِ has_active_subscription، با این فرق که اگر اشتراک تمام شده، اول
|
||||
تمدیدِ خودکارِ بازار را میپرسد (payment.services.sync_bazaar_renewals): بازار خبر نمیدهد، و بیاین
|
||||
مشترکی که بازار تمدیدش کرده تا باز کردنِ فروشگاه پشتِ دیوار میماند. برای کسی که سفارشِ اشتراکِ بازار
|
||||
ندارد فقط یک کوئری است؛ فراخوانیِ بازار هر توکن ساعتی یک بار.
|
||||
"""
|
||||
if has_active_subscription(user_id):
|
||||
return True
|
||||
from payment.services import sync_bazaar_renewals
|
||||
return bool(sync_bazaar_renewals(user_id)) and has_active_subscription(user_id)
|
||||
|
||||
|
||||
def hearts_pass_until(user_id: int):
|
||||
"""تا کِی قلبِ نامحدودِ بسته برقرار است؛ None اگر ندارد یا تمام شده."""
|
||||
hp = HeartsPass.objects.filter(user_id=user_id, expires_at__gt=timezone.now()).first()
|
||||
|
||||
Reference in New Issue
Block a user