let the Bazaar verify URL double as the OAuth redirect URI

The Bazaar account owner registered /api/payment/bazaar/verify as the
redirect URI. POST stays the app's purchase check; GET now takes Bazaar's
?code=, exchanges it for a refresh token and stores it in the new
BazaarCredential row, so connecting needs no SSH or .env edit.

The GET is unauthenticated, so it only acts inside a window opened from
the admin (or bazaar_authorize_link): 72 h by default, closed by the first
successful exchange, state checked when Bazaar echoes it. Authorize/token
URL shapes follow the known devapi v2 flow; not checked against Bazaar's
current docs, which did not load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 21:30:44 +03:30
parent 5d490edaf9
commit 8763ffd7bf
9 changed files with 414 additions and 9 deletions

View File

@@ -430,6 +430,7 @@ REST_FRAMEWORK = {
'otp_login': os.environ.get('OTP_LOGIN_IP_RATE', '30/hour'),
'guest_session': os.environ.get('GUEST_SESSION_IP_RATE', '60/hour'),
'bazaar_verify': '10/hour',
'bazaar_oauth': '20/hour',
'ai_ask': '20/hour',
'rag_ingest': '30/hour',
# سقفِ ارزانِ خواندن روی endpointهای پرترافیکِ GET (home/leaderboard/
@@ -723,6 +724,16 @@ BAZAAR_CLIENT_ID = os.environ.get('BAZAAR_CLIENT_ID', '')
BAZAAR_CLIENT_SECRET = os.environ.get('BAZAAR_CLIENT_SECRET', '')
BAZAAR_REFRESH_TOKEN = os.environ.get('BAZAAR_REFRESH_TOKEN', '')
BAZAAR_API_BASE = os.environ.get('BAZAAR_API_BASE', 'https://pardakht.cafebazaar.ir/devapi/v2')
# Redirect URI که در پنل بازار ثبت شده؛ باید با آن *عیناً* یکی باشد. به
# خواستِ مدیرِ حسابِ بازار (۲۰۲۶-۰۹-۲۶) همان آدرسِ verify است: GETِ آن codeِ
# بازار را می‌گیرد و POSTِ آن خریدِ اپ را. PUBLIC_BASE_URL پایین‌تر تعریف
# شده، پس آدرس اینجا کامل نوشته می‌شود.
BAZAAR_REDIRECT_URI = (
os.environ.get('BAZAAR_REDIRECT_URI', '').strip()
or 'https://api.math.tadrisino2.ir/api/payment/bazaar/verify'
)
# چند ساعت لینکِ «اجازه»ی بازار باز می‌ماند؛ بعد از اتصالِ موفق خودش بسته می‌شود.
BAZAAR_AUTHORIZE_WINDOW_HOURS = int(os.environ.get('BAZAAR_AUTHORIZE_WINDOW_HOURS', '72'))
# -----------------------------------------------------------------------
# Zarinpal (درگاهِ اصلیِ پرداختِ ما — Payment API v4)