49 lines
1.7 KiB
Python
49 lines
1.7 KiB
Python
"""Gateway operations whose responses must be interpreted conservatively."""
|
|
|
|
from django.conf import settings
|
|
import requests
|
|
|
|
|
|
class PaymentVerificationUncertain(Exception):
|
|
"""The gateway response does not prove either payment success or failure."""
|
|
|
|
|
|
def request_payment_verification(payment):
|
|
try:
|
|
response = requests.post(
|
|
settings.ZARINPAL_VERIFY_URL,
|
|
json={
|
|
"merchant_id": settings.ZARINPAL_MERCHANT_ID,
|
|
"amount": payment.amount,
|
|
"authority": payment.authority,
|
|
},
|
|
headers={"accept": "application/json", "content-type": "application/json"},
|
|
timeout=15,
|
|
)
|
|
status_code = getattr(response, "status_code", 200)
|
|
if isinstance(status_code, int) and status_code >= 400:
|
|
raise PaymentVerificationUncertain(
|
|
f"ZarinPal verification returned HTTP {status_code}"
|
|
)
|
|
body = response.json()
|
|
except PaymentVerificationUncertain:
|
|
raise
|
|
except Exception as exc:
|
|
raise PaymentVerificationUncertain("ZarinPal verification request failed") from exc
|
|
|
|
if not isinstance(body, dict) or not isinstance(body.get("data"), dict):
|
|
raise PaymentVerificationUncertain("ZarinPal returned an invalid verification response")
|
|
|
|
code = body["data"].get("code")
|
|
try:
|
|
code = int(code)
|
|
except (TypeError, ValueError) as exc:
|
|
raise PaymentVerificationUncertain("ZarinPal returned no verification code") from exc
|
|
|
|
if code not in (100, 101, -51):
|
|
raise PaymentVerificationUncertain(
|
|
f"ZarinPal returned an inconclusive verification code: {code}"
|
|
)
|
|
|
|
return code, body["data"]
|