Files
MathApp/subscription/serializers.py
Zareian 947f946909 Question packs removed at the root; all subscriptions 4 assistant questions a day; Bazaar is subscription-only
- subscription.0017/0018, payment.0013: pack plans deleted, QuestionCredit/HeartsPass models and Plan.kind /
  question_credits / hearts_days / Order.question_credits / hearts_days dropped. The only paid pack order was the
  company owner's test account (user 26).
- Assistant: no credit spending; quota is the daily cap only (free 2, every plan 4, gift subscription 4).
- Bazaar: verify_purchase is subscription-only (no inapp guess), start/purchase responses lose productType,
  verify refuses an order without a subscription. A paid order with no subscription now logs ERROR.
- Removed POST /api/payment/orders (internal; no caller). Its permission tests stay.
- Pack-based tests rewritten on subscriptions (refund, security, Bazaar token); pack-only test files deleted.
- docs: profit table for 4/day on both payment routes plus free users; handbook, operations, CLAUDE.md current.
949 tests green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 20:33:38 +03:30

50 lines
3.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from rest_framework import serializers
class PlanSerializer(serializers.Serializer):
id = serializers.CharField()
title = serializers.CharField()
price = serializers.IntegerField()
currency = serializers.CharField(required=False)
popular = serializers.BooleanField()
discountPercent = serializers.IntegerField(required=False)
durationDays = serializers.IntegerField(required=False)
features = serializers.ListField(child=serializers.CharField())
badge = serializers.CharField(allow_blank=True)
aiDailyQuota = serializers.IntegerField(help_text='سوال در روز از دستیار برای مشترکِ این پلن.')
bazaarSku = serializers.CharField(
allow_blank=True, help_text='SKUِ همین اشتراک در کافه‌بازار (محصولِ «اشتراکی»)؛ خالی یعنی در بازار خریدنی نیست.')
class PlansListResponseSerializer(serializers.Serializer):
plans = PlanSerializer(many=True)
# تا کارتِ پلن بتواند بگوید «۵ سوال در روز (رایگان: ۳)» بی‌آن‌که عدد در فرانت هاردکد شود.
freeAiDailyQuota = serializers.IntegerField()
class PurchaseRequestSerializer(serializers.Serializer):
# هدر Idempotency-Key هم روی همین درخواست لازمه (بخش ۴.۳ سند API)؛
# از request.headers خونده می‌شه، نه از بدنه.
planId = serializers.CharField()
# تا ۲۰۲۶-۱۰-۰۳ هر مقداری پذیرفته و نادیده گرفته می‌شد، پس «bazaar» بی‌صدا به زرین‌پال می‌رفت.
paymentMethod = serializers.ChoiceField(choices=['zarinpal', 'bazaar'], required=False, default='zarinpal',
help_text='payment/providers.py: هر مقدار یک کلاسِ PaymentProvider.')
class PurchaseResponseSerializer(serializers.Serializer):
orderId = serializers.CharField()
paymentUrl = serializers.CharField(
allow_null=True, help_text='زرین‌پال: آدرسی که کاربر به آن برود. بازار: null.')
bazaarSku = serializers.CharField(
required=False, help_text='فقط بازار: SKUی که اپِ اندروید با Poolakey می‌خرد؛ '
'developerPayload همان orderId باشد.')
class SubscriptionStatusResponseSerializer(serializers.Serializer):
active = serializers.BooleanField(help_text='اشتراکِ زمانی فعال (یک/سه/شش‌ماهه).')
planTitle = serializers.CharField(allow_null=True, help_text='نامِ پلنِ اشتراکِ فعال؛ null بی‌اشتراک.')
planDurationDays = serializers.IntegerField(allow_null=True, help_text='طولِ دوره‌ی پلنِ فعال به روز.')
aiDailyQuota = serializers.IntegerField(help_text='سقفِ سوالِ روزانه‌ی همین کاربر از دستیار.')
planId = serializers.CharField(allow_null=True)
expiresAt = serializers.DateTimeField(allow_null=True)