# apps/billing/providers/bazaar.py """ تایید خرید کافه‌بازار — سمت سرور، طبق مستندات عمومی devapi کافه‌بازار (https://developers.cafebazaar.ir/fa/docs/iab). این تنها API ای است که اجازه دارد جم واقعا اضافه کند؛ کلاینت هرچقدر هم بگوید «پرداخت کردم»، تا این تابع True برنگرداند هیچ جمی اضافه نمی‌شود. فرض مستنداتِ مسیر/پاسخ (اگر ساختار حساب توسعه‌دهنده‌ی خودت فرق دارد، فقط همین یک تابع را با مستندات واقعی هماهنگ کن — بقیه‌ی پروژه فقط `verify_purchase(product_id, purchase_token)` را صدا می‌زند): GET https://pardakht.cafebazaar.ir/devapi/v2/api/validate/{package_name} /inapp/{product_id}/purchases/{purchase_token}/?access_token=... پاسخ موفق شامل purchaseState=0 (خریداری‌شده، نه refund‌شده) است. access_token از BazaarSettings (پنل ادمین) خوانده می‌شود، نه .env — چون باید بدون ری‌دیپلوی قابل‌تعویض باشد (مثلا وقتی منقضی شد). """ import logging import requests from apps.billing.models import BazaarSettings logger = logging.getLogger(__name__) REQUEST_TIMEOUT_SECONDS = 15 BASE_URL = "https://pardakht.cafebazaar.ir/devapi/v2/api" def verify_purchase(product_id: str, purchase_token: str) -> bool: settings_obj = BazaarSettings.get_solo() if not settings_obj.access_token or not settings_obj.package_name: logger.error("BazaarSettings.access_token یا package_name در پنل ادمین تنظیم نشده") return False url = f"{BASE_URL}/validate/{settings_obj.package_name}/inapp/{product_id}/purchases/{purchase_token}/" try: response = requests.get( url, params={"access_token": settings_obj.access_token}, timeout=REQUEST_TIMEOUT_SECONDS, ) response.raise_for_status() body = response.json() purchase_state = body.get("purchaseState") is_valid = purchase_state == 0 if not is_valid: logger.warning(f"❌ خرید کافه‌بازار نامعتبر: {body}") return is_valid except (requests.RequestException, ValueError) as exc: logger.error(f"❌ خطا در تایید خرید کافه‌بازار ({product_id}/{purchase_token}): {exc}") return False