Subscriptions only: Bazaar panel prices (598/898/1398k), assistant quota 5/3/3 from a cost calculation, packs off sale

- subscription.0016: prices equal to the Bazaar panel (senior), ai_daily_quota 5/3/3, card features; packs on_sale=False
  (one paid pack order, user 26, keeps its credits; pack paths stay for that order and for admin).
- Quota math in docs/ai-cost-and-guardrails.md: ~77% of a Bazaar sale reaches us; worst case (full quota every day)
  the assistant costs 23/27/35% of it.
- Assistant quota message points to the subscription, not packs.
982 tests green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 19:57:16 +03:30
parent c0fa46be44
commit 9c3adc3e60
13 changed files with 95 additions and 40 deletions

View File

@@ -33,27 +33,30 @@ Message.objects.filter(role='assistant', created_at__gte=since).values('conversa
.annotate(p=Sum('prompt_tokens'), c=Sum('completion_tokens')) # سنت = (0.4p + 1.6c) / 1e4
```
## بسته‌ی سوال و سقفِ روزانه (از ۲۰۲۶-۱۰-۰۲)
## اشتراک‌ها و سقفِ روزانه‌ی دستیار
اشتراکِ ماهانه/سالانه کنار رفت و **بسته‌ی سوال** جایش آمد (`subscription.0009`، `subscription.0010`):
فقط اشتراک فروخته می‌شود (`subscription.0016`، تصمیمِ سینیور). قیمت‌ها همان قیمتِ پیشخانِ بازار است و کاربر در هر دو
راهِ پرداخت همین را می‌بیند. بسته‌های سوال `on_sale=False` هستند؛ اعتبارِ کسی که قبلاً خریده (کاربرِ ۲۶، ۲۰ سوال)
همچنان خرج می‌شود.
| بسته | قیمت (تومان) | هدیه | سود اگر کامل خرج شود | حاشیه‌ی سود |
**فرض‌ها:** هر سوال ~۷۰۰ تومان (دستِ بالا، بخشِ بالا). از هر خریدِ بازار اول ۱۰٪ ارزشِ افزوده کم می‌شود، از باقی ۸۵٪
سهمِ ماست (زیرِ یک میلیارد تومان فروشِ سالانه؛ بالاترش ۷۰٪)، و ۱۲۰ تومان کارمزد (سندِ «محاسبه سهم توسعه‌دهنده در
بازار»). یعنی **~۷۷٪ِ قیمت** می‌رسد. زرین‌پال بی‌سهمِ بازار است (~۹۰٪، کارمزدش را نسنجیده‌ایم)، پس بازار بدترین حالت است.
| اشتراک | قیمت (تومان) | خالصِ بازار در روز | سقفِ دستیار | هزینه‌ی دستیار اگر هر روز کلِ سقف را بپرسد |
|---|---|---|---|---|
| ۲۰ سوال | ۴۵٬۰۰۰ | ۷ روز قلبِ نامحدود | ۲۴٬۰۰۰ | ۶۳٪ |
| ۶۰ سوال | ۱۱۹٬۰۰۰ | ۳۰ روز | ۵۹٬۰۰۰ | ۵۸٪ |
| ۱۵۰ سوال | ۲۵۹٬۰۰۰ | ۶۰ روز | ۱۱۵٬۰۰۰ | ۵۲٪ |
| یک‌ماهه | ۵۹۸٬۰۰۰ | ~۱۵٬۴۰۰ | ۵ در روز | ۳٬۵۰۰ در روز، ۲۳٪ |
| سه‌ماهه | ۸۹۸٬۰۰۰ | ~۷٬۷۰۰ | ۳ در روز | ۲٬۱۰۰ در روز، ۲۷٪ |
| شش‌ماهه | ۱٬۳۹۸٬۰۰۰ | ~۶٬۰۰۰ | ۳ در روز | ۲٬۱۰۰ در روز، ۳۵٪ |
با ۷۰۰ تومان برای هر سوال (دستِ بالا) و پس از ۱۵٪یِ کافه‌بازار؛ اگر همه دبیرستانی باشند ۴۸ تا ۶۰٪. چرا بسته: همه هر روز نمی‌آیند، ۱۷۹ هزار تومان در ماه برای خیلی‌ها زیاد
بود، و مشترکِ پرکار زیان می‌ساخت. با بسته هر سوال جدا سود دارد. مسیرِ قیمت‌ها پیش از این:
- سالانه ۲۹۹ هزار تومان، با ۱۵ سوال در روز برای همه.
- ماهانه/سالانه ۹۹ و ۹۹۰ هزار تومان، با ۵ سوال در روز.
- ماهانه/سالانه ۱۷۹ و ۱٬۷۹۰ هزار تومان، با ۱۰ سوال در روز.
پس حتی اگر هر مشترک هر روز تا آخرِ سقف بپرسد، دستِ‌کم ۶۵٪ِ درآمدِ بازار می‌ماند (هزینه‌ی سرور جدا). مصرفِ واقعی کمتر
است: روی سرور (فقط دمو و آزمونگرها، ۲۲ روز‌ـکاربر) میانه‌ی روزهایی که کسی پرسید ۳ سوال بود، و همه هر روز نمی‌آیند؛ با
کاربرِ واقعی دوباره بسنجید (پرس‌وجوی بالا). هر ردیف با دو برابر شدنِ سقف تقریباً دو برابر می‌شود: شش‌ماهه با ۵ در روز ۵۸٪.
سقف در ادمین (`Plan.ai_daily_quota`) عوض می‌شود و کارتِ خرید آن را از همان عدد نشان می‌دهد.
پلن‌های اشتراکی پاک نشدند (`on_sale=False`) تا مشترکِ فعلی سقفش را نگه دارد.
- **ترتیبِ خرج:** اول سقفِ روزانه (بی‌اشتراک `AI_DAILY_QUOTA_FREE`، پیش‌فرض ۲؛ مشترک `Plan.ai_daily_quota`،
برای یک/سه/شش‌ماهه ۳)، بعد اعتبارِ بسته. اشتراک محتوا و قلب می‌فروشد؛ سوالِ بیشتر از دستیار فقط با بسته.
بدترین حالتِ مشترکِ شش‌ماهه با سقفِ ۳: ~۶۳ هزار تومان در ماه، ۲۹٪ِ سهمِ ماهانه‌ی قیمت.
- **ترتیبِ خرج:** اول سقفِ روزانه (بی‌اشتراک `AI_DAILY_QUOTA_FREE`، پیش‌فرض ۲؛ مشترک `Plan.ai_daily_quota`)، بعد
اعتبارِ بسته‌ی قدیمی اگر مانده. سوالِ رایگانِ بی‌اشتراک‌ها هزینه‌ی خالص است: ۲ × ۷۰۰ = ۱٬۴۰۰ تومان برای هر کاربرِ
فعال در روز.
- **چه چیزی خرج می‌شود:** هر سوالی که به API برسد، از جمله ردِ «غیرِ ریاضی» توسطِ مدل. ردِ صافیِ سرور،
جوابِ کش‌شده و جوابی که ساخته نشد چیزی کم نمی‌کنند. `Message.charge` روی هر پیامِ کاربر می‌گوید
سوال از کجا پرداخت شد (`free` / `credit` / `none`).

View File

@@ -278,11 +278,12 @@ callbackِ زرین‌پال، برگشت از پرداخت، `BAZAAR_REDIRECT_U
«پرداخت‌ها و فاکتورها» می‌بیند. کد در `payment/services.py` (`refund_order`، `cancel_pending_order`)
است و تست‌هایش در `payment/tests_refund.py`.
## فروش در کافه‌بازار (اشتراک و بسته)
## فروش در کافه‌بازار
اپِ اندروید (پوسته‌ی WebViewِ همین سایت، `android/` در ریپوی فرانت) با پرداختِ درون‌برنامه‌ایِ بازار می‌فروشد. در
برگه‌ی پرداخت دو کاشی همیشه کنارِ هم‌اند و کاربر هر کدام را بخواهد می‌زند: «کارتِ بانکی» (زرین‌پال، پیش‌فرض) و
«کافه‌بازار». در مرورگر، یا وقتی پلن SKU ندارد (الان همه‌ی بسته‌ها)، کاشیِ بازار غیرفعال است و دلیلش را می‌گوید. داخلِ اپ
«کافه‌بازار». در مرورگر، یا وقتی پلن SKU ندارد، کاشیِ بازار غیرفعال است و دلیلش را می‌گوید. فقط اشتراک فروخته می‌شود
(بسته‌ها `on_sale=False`، `subscription.0016`)؛ مسیرِ بسته (`inapp`، consume) برای روزی که ادمین دوباره روشنش کند مانده. داخلِ اپ
زیرِ «کافه‌بازار» قیمتی می‌آید که خودِ بازار برای آن SKU دارد (Poolakey روی گوشی؛ API سرور قیمت نمی‌دهد).
تفاوتِ روش‌ها در یک جاست: `payment/providers.py` (هر روش یک کلاس، `provider_for`/`provider_for_method` انتخابش
@@ -290,9 +291,9 @@ callbackِ زرین‌پال، برگشت از پرداخت، `BAZAAR_REDIRECT_U
| چه | کجا | الان |
|---|---|---|
| محصول در پیشخانِ بازار | اشتراک = محصولِ «اشتراکی» (بازار خودکار تمدید می‌کند)، بسته = «مصرف‌شدنی» | یک‌ماهه `10342` (به گفته‌ی مالک)، سه‌ماهه `10343`، شش‌ماهه `10344`؛ بسته‌ها هنوز تعریف نشده‌اند |
| SKU روی پلن | `/admin/subscription/plan/` ← «Bazaar sku» (سرور SKU را فقط از این‌جا می‌گیرد) | سه اشتراکِ بالا (`subscription.0014`، `0015`)؛ بسته‌ای که در پیشخان تعریف شد، SKUاش این‌جا نوشته شود |
| قیمت | بازار قیمتِ پیشخان را می‌گیرد؛ ادمین باید با آن یکی باشد | داخلِ اپ قیمتِ بازار روی کاشی دیده می‌شود؛ برابری‌اش **سنجیده نشده** |
| محصول در پیشخانِ بازار | اشتراک = محصولِ «اشتراکی» (بازار خودکار تمدید می‌کند)، بسته = «مصرف‌شدنی» | یک‌ماهه `10342`، سه‌ماهه `10343`، شش‌ماهه `10344` (تأییدِ سینیور) |
| SKU روی پلن | `/admin/subscription/plan/` ← «Bazaar sku» (سرور SKU را فقط از این‌جا می‌گیرد) | سه اشتراکِ بالا (`subscription.0014`، `0015`) |
| قیمت | بازار قیمتِ پیشخان را می‌گیرد؛ ادمین باید با آن یکی باشد | ۵۹۸/۸۹۸/۱٬۳۹۸ هزار تومان در هر دو (`subscription.0016`، به گفته‌ی سینیور)؛ داخلِ اپ قیمتِ بازار روی کاشی دیده می‌شود |
| کلیدِ «تخفیف پویا» | `BAZAAR_DYNAMIC_PRICE_KEY` در `.env` سرور | با آن کدِ تخفیف روی خریدِ بازار هم کار می‌کند |
| کلیدِ RSAِ عمومی | `android/app/build.gradle.kts` | گذاشته شد |