UnoPayv1.0.0
  1. خانه
  2. واحد پول

مفاهیم پایه

واحد پول

کل لایه واحد پول یک تابع صادرشده است. نه پیکربندی هست، نه locale، نه سیاست گرد کردن و نه اعتبارسنجی.

src/currency.ts ts
export function toRials(amount: number, currency: string): number {
  const norm = currency.toUpperCase();
  if (norm === 'IRT' || norm === 'TOMAN') {
    return amount * 10;
  }
  return amount; // default IRR
}

جدول کامل رفتار

همین تمام مشخصات است. چهار ردیف هر ورودی ممکن را پوشش می‌دهد.

toRials(50000, …) برای هر رشته واحد پولی که رفتار متفاوتی دارد
ورودی تطبیق آنچه کامپایلر استنتاج می‌کند نکته
'IRR' Neither branch 50000 Passed through unchanged — Rials is the target unit
'IRT' 'IRT' 500000 Toman, ×10
'TOMAN' 'TOMAN' 500000 Toman spelled out, ×10
'toml' Neither branch 50000 Silently treated as Rials. A typo is a factor-of-ten bug with no error.
کد واحد پول ناشناخته هرگز خطا نمی‌دهد

هر چیزی که IRT یا TOMAN نباشد به خط return amount می‌افتد. اگر رشته واحد پول را از فیلد فرم یا ستون پایگاه داده می‌سازید، پیش از رسیدن به PaymentRequest.currency اعتبارسنجی‌اش کنید — SDK این کار را برای شما نمی‌کند و هم به شما نمی‌گوید.

تبدیل چه زمانی اجرا می‌شود

دو بار، هر دو داخل ZarinpalAdapter، و هر دو نامرئی برای شما.

  • در رفت، createPayment مقدار req.amount را پیش از ساخت بدنه درخواست تبدیل می‌کند. شما 50000 تومان می‌فرستید؛ درگاه 500000 ریال دریافت می‌کند.
  • در برگشت، verifyCallback مبلغ را با req.query.currency || req.body.currency || 'IRR' تبدیل می‌کند. زرین‌پال واحدی نمی‌فرستد، پس پیش‌فرض ریال است. همان واحدی را بفرستید که در زمان ساخت استفاده کردید وگرنه بررسی مبلغ پیش از فراخوانی شبکه شکست می‌خورد.

هیچ گرد کردنی وجود ندارد. 500 تومان دقیقاً 5000 ریال می‌شود و اعداد صحیح شما صحیح می‌مانند. اگر روزی واحد اعشاری خواستید، خودتان قبل از فراخوانی حساب کنید.

تله ده‌برابر، از ابتدا تا انتها

این رایج‌ترین باگ گزارش‌شده در یکپارچه‌سازی درگاه‌های ایرانی است، و UnoPay نیمی از آن را حذف می‌کند و نیم دیگر را دست‌نخورده می‌گذارد.

units.ts ts
// Right: 50,000 Toman. The SDK converts to 500,000 Rials.
await unopay.createPayment('zarinpal', {
  amount: 50000,
  currency: 'IRT',
  callbackUrl,
});

// Wrong: 500,000 declared as Toman. The SDK converts again -> 5,000,000 Rials.
await unopay.createPayment('zarinpal', {
  amount: 500000,
  currency: 'IRT',
  callbackUrl,
});

// Also wrong: a Toman amount labelled IRR. No conversion happens at all,
// so the gateway is asked for 500,000 Toman and rejects it.
await unopay.createPayment('zarinpal', {
  amount: 500000,
  currency: 'IRR',
  callbackUrl,
});

برای کل کدبیس خود یک واحد انتخاب کنید و همان را روی رکوردی که به‌عنوان currency پاس می‌دهید ذخیره کنید. SDK سازگار است؛ اشتباه تقریباً همیشه در برچسب است نه در حساب.