Files
MathApp/.env.example
Zareian b5476e1c5d connect Zarinpal as the real payment gateway
payment.services.call_payment_gateway was a stub returning a fake
payment.gateway/pay/{id} URL. It's replaced with a real Zarinpal
integration (payment/zarinpal.py, Payment API v4):

- create_order/CreateOrderView still never call Zarinpal directly —
  paymentUrl points at our own GET /api/payment/orders/{id}/pay
  (PaymentRedirectView), which requests the real Zarinpal authority on
  first visit and redirects to StartPay. This keeps order creation from
  depending on Zarinpal's uptime/latency, and means none of the existing
  purchase/idempotency tests needed to change.
- GET /api/payment/zarinpal/callback (ZarinpalCallbackView) is where
  Zarinpal redirects the user back to; it always re-verifies
  server-to-server via zarinpal.verify_payment before marking an order
  paid, so a forged Status=OK in the query string alone does nothing.
- zarinpal.py fails closed (503 / invalid) when ZARINPAL_MERCHANT_ID
  isn't configured, matching payment/bazaar.py's existing convention —
  never a fake successful payment.

Adds Order.gateway_authority, PUBLIC_BASE_URL/ZARINPAL_* settings, and
a payment_pay throttle scope.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 13:27:13 +03:30

79 lines
4.7 KiB
Plaintext
Raw 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.
# این فایل نمونه‌ست؛ در صورتِ نیاز کپی کنید به .env و مقداردهی کنید:
# cp .env.example .env
#
# اگه .env نسازید، docker-compose.yml از همین مقادیرِ دیفالتِ پایین
# استفاده می‌کنه (که برای اجرای محلی/دِمو کافیه، نه برای پروداکشن).
# DEBUG=1 یعنی SECRET_KEY و CACHE_URL دیفالتِ dev دارن و DEV_MASTER_OTP
# (کدِ 0000) فعاله؛ برای شبیه‌سازیِ پروداکشن این رو 0 کنید (اون‌وقت
# DJANGO_SECRET_KEY و CACHE_URL رو هم باید صریحاً بدید).
DJANGO_DEBUG=1
DJANGO_SECRET_KEY=
DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1
CACHE_URL=
# اختیاری — بدونش OTP واقعی ارسال نمی‌شه (فقط خطای صریح ۵۰۳ برمی‌گرده،
# طبق رفتارِ موجودِ accounts/services.py)
KAVENEGAR_API_KEY=
# رمزِ ادمینِ Grafana (کاربرِ admin) — فقط برای دسترسیِ محلی
GRAFANA_ADMIN_PASSWORD=admin
# -----------------------------------------------------------------------
# RAG / AI tutor (اپ rag) — موقعِ تست پر کنید
# -----------------------------------------------------------------------
# بدونِ OPENAI_API_KEY و QDRANT_API_KEY، مسیرِ RAG غیرفعاله و
# POST /api/ai/ask همون پاسخِ stubِ قبلی رو می‌ده (سازگاریِ عقب‌رو).
# فعلاً از GapGPT (پروکسیِ OpenAI برای ایران) استفاده می‌کنیم.
OPENAI_API_KEY=
OPENAI_BASE_URL=https://api.gapgpt.app/v1
# اگه بعداً خواستی مستقیم OpenAI واقعی رو تست کنی: کلیدِ واقعی رو این پایین
# پارک کن، بعد فقط دو خطِ بالا رو باهاش عوض کن. هیچ منطقِ سوییچی در کد نیست
# تا ساده و بی‌اشتباه بمونه.
# OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_API_KEY_OPENAI_DIRECT=
OPENAI_CHAT_MODEL=gpt-4o-mini
OPENAI_VISION_MODEL=gpt-4o
# این رو تغییر نده؛ باید با مدلی که تیمِ دیگه باهاش collectionها رو ساخته یکی باشه.
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
QDRANT_URL=https://qdrant.tadrisino2.ir:443
QDRANT_API_KEY=
# نامِ collection = f"{subject} {grade}".lower() . collectionهای موجود روی
# سرورِ تیمِ دیگه (بررسی‌شده): «علوم تجربی سوم» ، «مطالعات اجتماعی چهارم» ،
# «مطالعات اجتماعی ششم» ، «ریاضی سوم» ، «ریاضی ششم» ، «ریاضی هفتم».
# یعنی جزءِ گرید فقط «سوم/چهارم/ششم/هفتم» است (بدونِ «دبستان»).
#
# کلیدِ فیلترِ درس دستی تنظیم نمی‌شه — rag/services/known_collections.py خودش
# تشخیص می‌ده: ریاضی → `chapter` (و شماره‌ی فصل رو به رشته‌ی دقیق تبدیل می‌کنه)،
# بقیه → `lesson_number`.
RAG_COLLECTION_NAME_TEMPLATE={subject} {grade}
RAG_RETRIEVAL_TOP_K=4
# RAG_FORCE_MOCK=1 یعنی حتی با وجودِ کلیدها هم مسیرِ RAG خاموش بمونه.
RAG_FORCE_MOCK=
# -----------------------------------------------------------------------
# زرین‌پال (اپ payment) — درگاهِ اصلیِ پرداختِ ما
# -----------------------------------------------------------------------
# بدونِ ZARINPAL_MERCHANT_ID، مسیرِ پرداخت fail-closed می‌مونه (خطای صریحِ
# ۵۰۳ به‌جایِ پرداختِ ساختگیِ موفق).
PUBLIC_BASE_URL=
ZARINPAL_MERCHANT_ID=
# 1 = محیطِ sandbox زرین‌پال (برای تست بدونِ پرداختِ واقعی)
ZARINPAL_SANDBOX=1
# اختیاری — بعدِ تاییدِ پرداخت، کاربر به این URL (مثلاً یک deep link اپ) با
# ?orderId=...&status=... ریدایرکت می‌شه. خالی = پاسخِ JSON ساده.
ZARINPAL_REDIRECT_URL=
# -----------------------------------------------------------------------
# تنظیماتِ مقیاس‌پذیری (همه دیفالتِ امن دارن)
# -----------------------------------------------------------------------
# persistent DB connection (ثانیه). با SQLite بی‌اثر؛ بعد از Postgres مهم.
DB_CONN_MAX_AGE=60
# کشِ کوتاهِ ردیفِ کاربر در auth تا هر request یک SELECT نزنه. 0 = خاموش
# (پیش‌فرض). توصیه‌ی پروداکشن با Redis: 30. با هر save/delete روی User باطل می‌شه.
AUTH_USER_CACHE_TTL=0
# سقفِ ارزانِ خواندن روی endpointهای پرترافیکِ GET (home/leaderboard/summary/...).
READ_THROTTLE_RATE=120/min