وبلاگ سایاپی / راهنمای توسعه‌دهندگان

تفاوت ریال و تومان در API پرداخت؛ جلوگیری از خطای ده‌برابری

نمایش قیمت به تومان اشکالی ندارد؛ ارسال همان عدد به API ریالی، مبلغ را عوض می‌کند. واحد را صریح نگه دارید و تبدیل را فقط در یک مرز مشخص انجام دهید.

واحد نمایش فروشگاه با واحد API یکی نیست

در مثال‌های این راهنما، هر تومان برابر ۱۰ ریال است. سفارش ۱۲٬۰۰۰ تومانی باید با مبلغ ۱۲۰٬۰۰۰ و ارز IRR به API فعلی سایاپی فرستاده شود؛ نه با مبلغ ۱۲٬۰۰۰.

API آموزشی سایاپی فقط IRR می‌پذیرد. این یک قرارداد فنی مشخص است، نه فرضی که بتوان به همهٔ ارائه‌دهندگان تعمیم داد. قبل از اتصال هر سرویس، واحد مبلغ و محدودیت‌های همان نسخه را از مستنداتش بخوانید.

در دادهٔ سفارش، نام متغیرهایی مثل amountRial یا amountToman روشن‌تر از price هستند. مبلغ خام و واحد آن را کنار هم نگه دارید؛ رشتهٔ نمایشی «۱۲٬۰۰۰ تومان» برای رابط کاربری است، نه برای ارسال مستقیم به API.

تبدیل امن تومان به ریال با عدد صحیح

این مثال فقط ورودی عددیِ صحیح به تومان را می‌پذیرد. پس از ضرب در ۱۰، صحیح و امن‌بودن عدد و بازهٔ API فعلی را دوباره بررسی می‌کند: حداقل ۱٬۰۰۰ و حداکثر ۱٬۰۰۰٬۰۰۰٬۰۰۰٬۰۰۰ ریال. این بازهٔ اعتبارسنجی نرم‌افزار است، نه سقف بانکی یا مجوز تراکنش واقعی.

function tomanToRial(toman) {
  if (!Number.isSafeInteger(toman)) {
    throw new TypeError("Whole-number toman required");
  }
  const rial = toman * 10;
  if (!Number.isSafeInteger(rial) || rial < 1000 || rial > 1e12) {
    throw new RangeError("Amount outside Sayapay sandbox limits");
  }
  return rial;
}

tomanToRial(12000); // 120000 IRR

کدِ نمایش‌داده‌شده در آزمون‌های این پروژه اجرا شده است؛ متن، عدد اعشاری، اعداد خارج از بازه و عدد ناامن رد می‌شوند. این آزمون، صحت همین مثال را بررسی می‌کند و اثبات اتصال بانکی نیست.

اگر ورودی از فرم فارسی می‌آید، ابتدا قالب مجاز را مشخص کنید و ارقام و جداکننده‌ها را با اعتبارسنجی صریح به عدد تبدیل کنید. حذف کورکورانهٔ همهٔ نویسه‌های غیرعددی یا استفادهٔ بی‌بررسی از parseInt می‌تواند ورودی خراب را به مبلغ ظاهراً معتبر تبدیل کند. برای مبلغ اعشاری هم قرارداد جداگانه لازم است؛ این تابع عمداً آن را رد می‌کند.

مثالِ بدنهٔ درخواست آموزشی

برای سفارش مثالِ ۱۲٬۰۰۰ تومانی، بدنهٔ زیر با اعتبارسنجی واقعی ورودی API سایاپی آزمایش شده است. مسیر ساخت درخواست POST /api/v1/payments است. احراز هویت و کلید جلوگیری از تکرار درخواست را مطابق راهنمای API اضافه کنید؛ این بدنه به‌تنهایی یک درخواست اجرایی کامل نیست.

{
  "amount": 120000,
  "currency": "IRR",
  "title": "سفارش آموزشی",
  "order_id": "sandbox-order-12000-toman",
  "return_url": "https://shop.example/payment-return"
}

مقدار amount عدد JSON است؛ بدون کوتیشن، ویرگول هزارگان یا عبارت «ریال». نشانی shop.example فقط جای‌نگهدار است؛ آن را با مسیر بازگشت HTTPS فروشگاه آموزشی خودتان عوض کنید. کلید API را فقط سمت سرور نگه دارید.

مسیر sandbox برای آموزش فنی و جدا از دریافت بانکی حساب کسب‌وکار است. برای آزمون از سفارش و کلید آموزشی استفاده کنید؛ نتیجهٔ این مثال را رسید پرداخت واقعی به مشتری معرفی نکنید.

دو خطایی که مبلغ را ده‌برابر تغییر می‌دهند

  • ارسال عدد تومان با برچسب IRR: مبلغ ۱۲٬۰۰۰ به‌جای ۱۲۰٬۰۰۰ ریال، یک‌دهم مبلغ مورد نظر است.
  • تبدیل دوباره: اگر سفارش از قبل ۱۲۰٬۰۰۰ ریال است و دوباره در ۱۰ ضرب شود، درخواست ۱٬۲۰۰٬۰۰۰ ریالی ساخته می‌شود.

هر سه عدد می‌توانند از نظر نوع و بازه معتبر باشند. اعتبارسنجی API به‌تنهایی نمی‌فهمد واحد اولیه را اشتباه گرفته‌اید. تبدیل را در یک نقطهٔ مشخص انجام دهید و برای سفارش مثال، مبلغ مورد انتظار را مستقل از تابع تبدیل در تست بنویسید.

در اتصال آمادهٔ فروشگاه، واحد تنظیم‌شده و رفتار تبدیل افزونه را هم بررسی کنید. اگر افزونه تبدیل تومان را انجام می‌دهد، مبلغ را پیش از تحویل به آن دوباره تبدیل نکنید. نصب واقعی و آزمون کامل افزونهٔ ووکامرس سایاپی هنوز شرط جداگانهٔ تأیید آن است.

قبل و بعد از پرداخت، مبلغ سفارش را تطبیق دهید

  1. مبلغ نهایی را سمت سرور از سفارش معتبر، تخفیف و هزینه‌های آن محاسبه کنید؛ مقدار ارسالی مرورگر مرجع نیست.
  2. پیش از درخواست، واحد و عدد ریالی را با سفارش تطبیق دهید و شناسهٔ سفارش را برای پیگیری نگه دارید.
  3. پس از بازگشت، وضعیت را سمت سرور بررسی کنید و شناسهٔ پرداخت، سفارش، ارز و مبلغ را با دادهٔ ذخیره‌شده مقایسه کنید.
  4. تنها پس از نتیجهٔ معتبر و تطبیق کامل، سفارش را پرداخت‌شده کنید. در timeout یا وضعیت نامعلوم، پیگیری لازم است؛ نه موفقیت یا شکست قطعیِ حدسی.

در لاگ تشخیصی می‌توانید شناسهٔ سفارش، واحد ورودی و مبلغ تبدیل‌شده را ثبت کنید، اما کلید API، رمز یا اطلاعات حساس مشتری را ننویسید. برای روند ساخت و تأیید، راهنمای لینک پرداخت را بخوانید.

پرسش‌های رایج

آیا currency: IRT باعث تبدیل خودکار می‌شود؟

خیر. ورودی فعلی API سایاپی ارز غیر از IRR را رد می‌کند؛ تبدیل واحد، مسئولیت اتصال شماست. واحد نمایش تومان را از ارز درخواست جدا کنید.

آیا عدد فارسی یا مبلغ به‌صورت رشته پذیرفته می‌شود؟

در فیلد amount خیر؛ مقدار باید عدد صحیح JSON باشد. قالب‌بندی فارسی را برای نمایش نگه دارید و ارسال داده را با قرارداد API انجام دهید.

آیا Number.isSafeInteger جلوی تبدیل دوباره را می‌گیرد؟

خیر؛ فقط صحیح و قابل‌نمایش دقیق‌بودن عدد را در محدودهٔ عددهای امن JavaScript بررسی می‌کند. کنترل واحد و تطبیق مبلغ مورد انتظار، آزمون دیگری است.

منابع و حدود این راهنما

واحد، حداقل و حداکثر مبلغ و مثال بدنه با کد اعتبارسنجی فعلی سایاپی تطبیق داده شده‌اند؛ قرارداد اتصال را در مستندات توسعه‌دهندگان بررسی کنید. تعریف عدد صحیح امن در مشخصات رسمی ECMAScript برای Number.isSafeInteger آمده است.

این مقاله با کمک هوش مصنوعی تدوین شده است. آموزشِ نسخهٔ آموزشی است و جایگزین مستندات ارائه‌دهندهٔ پرداخت، قرارداد یا بازبینی اتصال فروشگاه نیست. برای گزارش خطای محتوا از تماس با سایاپی استفاده کنید.