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:
@@ -91,10 +91,12 @@ class RedeemDiscountView(APIView):
|
||||
from payment.models import Order
|
||||
# سفارش باید متعلق به همان کاربر احرازهویتشده باشد (جلوگیری از اعمال تخفیف روی سفارش دیگران).
|
||||
order = get_object_or_404(Order, pk=order_id, user_id=request.user.id)
|
||||
# بازار قیمتِ ثابتِ SKU را میگیرد، هرچه مبلغِ سفارش باشد؛ تخفیف روی سفارشِ بازار فقط
|
||||
# کد را میسوزاند و کاربر همان قیمتِ کامل را میپرداخت.
|
||||
# بازار بی«تخفیف پویا» قیمتِ ثابتِ پیشخان را میگیرد؛ تخفیف آنوقت فقط کد را میسوزاند. با کلید،
|
||||
# مبلغِ کمشده در JWT به بازار میرود (payment.views.BazaarStartPurchaseView).
|
||||
if order.provider == 'bazaar':
|
||||
raise ValidationError({'orderId': 'کدِ تخفیف روی خرید از کافهبازار اعمال نمیشود.'})
|
||||
from payment import bazaar
|
||||
if not bazaar.dynamic_price_configured():
|
||||
raise ValidationError({'orderId': 'کدِ تخفیف روی خرید از کافهبازار اعمال نمیشود.'})
|
||||
|
||||
try:
|
||||
with transaction.atomic():
|
||||
@@ -121,6 +123,9 @@ class RedeemDiscountView(APIView):
|
||||
# اشتراکی فعال نمیشود.
|
||||
if order_locked.gateway_authority:
|
||||
raise ValidationError({'code': 'کدِ تخفیف را پیش از رفتن به درگاهِ پرداخت وارد کنید.'})
|
||||
# همان قاعده برای بازار: قیمت در JWT امضا شده و خرید در بازار شروع شده است.
|
||||
if order_locked.bazaar_price_rial is not None:
|
||||
raise ValidationError({'code': 'کدِ تخفیف را پیش از رفتن به صفحهی خریدِ بازار وارد کنید.'})
|
||||
|
||||
# یک کد برای هر سفارش: کدهای درصدی روی هم جمع میشدند.
|
||||
if Redemption.objects.filter(order_id=order_locked.id).exists():
|
||||
|
||||
Reference in New Issue
Block a user