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>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
جنگوییه (نه میکروسرویس واقعی)، «فراخوانی سرور-به-سرور» با یک import مستقیم
|
||||
پیادهسازی شده، نه یک HTTP call به خودمون.
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.db import IntegrityError
|
||||
from django.db import transaction as db_transaction
|
||||
from django.utils import timezone
|
||||
@@ -38,11 +39,15 @@ def _ensure_idempotent_match(order: Order, *, user_id: int, amount: int, currenc
|
||||
|
||||
def call_payment_gateway(order: Order) -> str:
|
||||
"""
|
||||
استاب فراخوانی درگاه پرداخت واقعی؛ فعلاً یک paymentUrl ساختگی برمیگرداند
|
||||
تا کل جریان (ساخت سفارش → پرداخت → webhook) بدون کلید API واقعی قابل تست باشد.
|
||||
برای اتصال واقعی، این تابع با فراخوانی HTTP به API درگاه جایگزین شود.
|
||||
paymentUrlی که به کلاینت برمیگردد: آدرسِ داخلیِ خودمان
|
||||
(PaymentRedirectView)، نه مستقیماً StartPay زرینپال. فراخوانیِ واقعیِ
|
||||
PaymentRequest به زرینپال (یک HTTP call خارجی) عمداً همینجا انجام
|
||||
نمیشود — create_order از subscription صدا زده میشود و نباید موفقیتِ
|
||||
ساختِ سفارش به دسترسبودن/سرعتِ زرینپال گره بخورد؛ PaymentRequest اولین
|
||||
باری که کاربر واقعاً این URL را باز کند زده میشود (نگاه کنید به
|
||||
payment/zarinpal.py و PaymentRedirectView در views.py).
|
||||
"""
|
||||
return f'https://payment.gateway/pay/{order.id}'
|
||||
return f'{settings.PUBLIC_BASE_URL}/api/payment/orders/{order.id}/pay'
|
||||
|
||||
|
||||
def create_order(*, user_id: int, amount: int, currency: str = 'IRT',
|
||||
|
||||
Reference in New Issue
Block a user