""" پورسانتِ معرف: فقط روی پرداختِ واقعی، فقط یک بار برای هر کاربرِ معرفی‌شده. تا ۲۰۲۶-۰۹-۲۵ هیچ کدی Conversion را از «pending» جلو نمی‌برد و پورسانتی حساب نمی‌شد؛ برنامه‌ی معرفی فقط یک جدولِ ثبت بود. حالا اولین سفارشِ پرداخت‌شده‌ی کاربرِ معرفی‌شده *بعد از ثبتِ کد* Conversion را `paid` می‌کند و `commission_amount = مبلغِ پرداختی × commission_rate` را ثبت می‌کند. ⚠️ «کاربرِ تازه» بررسی نمی‌شود: مشتریِ قدیمی هم هر وقت بخواهد کد ثبت می‌کند و تمدیدِ بعدی‌اش پورسانت می‌سازد (بازبینیِ ۲۰۲۶-۰۹-۲۵، بازتولید شد). جلوی معرفیِ خود با شماره‌ی دوم هم چیزی نیست. پرداختِ خودِ پورسانت به معرف (تسویه) هنوز دستی و از پنلِ ادمین است. ثبت‌نام یا ورودِ مهمان هیچ پورسانتی نمی‌سازد؛ فقط پول جابه‌جا شدنِ واقعی. """ import logging from django.db import transaction from .models import Conversion logger = logging.getLogger(__name__) def record_paid_order(order) -> Conversion | None: """از apply_order_payment_result صدا زده می‌شود، داخلِ همان تراکنش.""" if not order.amount: return None try: with transaction.atomic(): conversion = ( Conversion.objects.select_for_update() .select_related('affiliate_account') .filter(referred_user_id=order.user_id, status='pending') .first() ) if conversion is None: return None rate = conversion.affiliate_account.commission_rate or 0 conversion.status = 'paid' conversion.order_id = order.id conversion.commission_amount = int(order.amount * rate) conversion.save(update_fields=['status', 'order_id', 'commission_amount']) return conversion except Exception: # noqa: BLE001 — پورسانت نباید تاییدِ پرداختِ خودِ کاربر را خراب کند logger.exception('affiliate: ثبتِ پورسانتِ سفارش %s شکست خورد', order.id) return None