Grades 4 and 5, Bazaar purchase from the app, pack SKUs

- rag: MATH_4 / MATH_5 textbooks (TOC and page offsets read from the PDFs)
- content: grades 4 and 5 in the seed files: 7 units / 28 nodes each,
  204 + 194 questions (every node >= 4), all re-solved blind once
- subscription: Plan.bazaar_sku (admin); POST /api/subscription/purchase
  accepts paymentMethod=bazaar for packs, rejects unknown methods (was ignored)
- payment: idempotency key cannot switch provider; discount codes refused
  on Bazaar orders (Bazaar charges the fixed SKU price)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 20:01:44 +03:30
parent ab5e53730a
commit 8cb326ba94
15 changed files with 16699 additions and 3897 deletions

View File

@@ -197,6 +197,23 @@ callbackِ زرین‌پال، برگشت از پرداخت، `BAZAAR_REDIRECT_U
«پرداخت‌ها و فاکتورها» می‌بیند. کد در `payment/services.py` (`refund_order`، `cancel_pending_order`)
است و تست‌هایش در `payment/tests_refund.py`.
## فروشِ بسته در کافه‌بازار
از ۲۰۲۶-۱۰-۰۳. اپِ اندروید (پوسته‌ی WebViewِ همین سایت، `android/` در ریپوی فرانت) بسته‌ها را با
پرداختِ درون‌برنامه‌ایِ بازار می‌فروشد؛ در مرورگرِ معمولی همه‌چیز مثلِ قبل از زرین‌پال است.
1. در پیشخانِ بازار برای هر بسته یک **محصولِ مصرف‌شدنی** با همان قیمت بسازید.
2. شناسه‌ی آن (SKU) را در `/admin/subscription/plan/` در فیلدِ «Bazaar sku» همان بسته بنویسید. سرور SKU
را فقط از همین‌جا می‌گیرد، نه از اپ؛ بسته‌ی بی‌SKU داخلِ اپ «به‌زودی در بازار» نشان داده می‌شود و
درخواستش ۴۰۰ است. یک SKU روی دو بسته نمی‌نشیند.
3. کلیدِ RSAِ عمومیِ اپ (از پیشخان) در `android/app/build.gradle.kts` می‌رود، نه در `.env`.
مسیر: `POST /api/subscription/purchase` با `paymentMethod: "bazaar"` (فقط بسته) سفارش می‌سازد و
`bazaarSku` برمی‌گرداند؛ اپ با Poolakey می‌خرد (`payload` = شماره‌ی سفارش)؛ `POST /api/payment/bazaar/verify`
توکن را از خودِ بازار می‌سنجد و اعتبار می‌دهد. کدِ تخفیف روی سفارشِ بازار رد می‌شود (بازار قیمتِ
ثابتِ محصول را می‌گیرد). تست‌ها: `payment/tests_bazaar_pack.py`. **هنوز هیچ خریدِ واقعی‌ای از بازار
انجام نشده.**
## ورودِ توسعه‌دهنده‌ها (بدونِ سرویسِ پیامک)
تا وقتی `KAVENEGAR_API_KEY` ست نشده، با `DEBUG=0` هیچ‌کس نمی‌تواند با شماره