UnoPayv1.0.0
  1. خانه
  2. دام‌های مبلغ و واحد پول

راهنماها

دام‌های مبلغ و واحد پول

درگاه‌های پرداخت ایرانی به ریال تسویه می‌کنند. خریدار به تومان فکر می‌کند و اغلب به هزاران تومان. UnoPay مالک تبدیل است؛ برچسب مال شماست.

سه کد، و فقط دو تای آن‌ها ویژه‌اند

IRR و IRT هر دو کد واقعی ایرانی برای یک پول در مقیاس‌های متفاوت‌اند. TOMAN کد ISO 4217 نیست — چیزی است که مردم واقعاً می‌گویند. تابع هر سه را می‌پذیرد و فقط دو تای آن‌ها عدد را تغییر می‌دهد.

نردبان واحد، با یک نمونه واقعی پرداخت
معنا کد برای سفارش ۵٬۰۰۰٬۰۰۰ ریالی UnoPay می‌فرستد
Rial, the settlement unit IRR 5,000,000 5000000
Toman, ten Rials IRT or TOMAN 500,000 5000000
Rial, mislabelled as Toman IRT 5,000,000 50000000 — ten times too much

تبدیل کجا انجام می‌شود و کجا نمی‌شود

  • در رفت، داخل ZarinpalAdapter.createPayment. عدد در بدنه درخواست شما وقتی بیرون می‌رود از قبل ریال است.
  • در برگشت، داخل ZarinpalAdapter.verifyCallback، با استفاده از req.query.currency || req.body.currency || 'IRR'. زرین‌پال واحدی نمی‌فرستد، پس این به ریال پیش‌فرض می‌شود.
  • هیچ جای دیگر. settledAmount مبلغ بازتابیده کال‌بک است، نه رقم تبدیل‌شده. toRials صادر شده اگر بخواهید، ولی چیزی بیرون از آن دو نقطه آن را برای شما صدا نمی‌زند.

چهار راه برای اشتباه

  1. تبدیل دوبل. خودتان به ریال تبدیل می‌کنید و بعد 'IRT' پاس می‌دهید. SDK دوباره تبدیل می‌کند.
  2. برچسب اشتباه. رقم ریالی با 'IRT' ارسال می‌شود. هیچ‌چیز تشخیصش نمی‌دهد؛ ده برابر ارزش سفارش را دریافت می‌کنید.
  3. غلط املایی. کدهایی مثل «TOMN» یا «TMN»، یا «IRT» با فاصله انتهایی. هر چیزی که پس از toUpperCase() برابر IRT یا TOMAN نباشد بی‌صدا ریال فرض می‌شود — بدون خطا، بدون لاگ.
  4. ذخیره سمت غلط تبدیل. ذخیره settledAmount کنار سفارش بدون ثبت اینکه در چه واحدی است. شش ماه بعد مغایرت‌گیری ناخواناست.
واحد را در مرز اعتبارسنجی کنید

SDK این کار را نمی‌کند، پس یک بار در لبه انجامش دهید و باقی کدبیس خود را ناتوان از اشتباه کنید.

money.ts ts
import { PaymentValidationError, toRials } from 'unopay';

const UNITS = ['IRR', 'IRT', 'TOMAN'] as const;
type Unit = (typeof UNITS)[number];

export function assertUnit(value: string): asserts value is Unit {
  const norm = value.toUpperCase();
  if (!UNITS.includes(norm as Unit)) {
    // catch it here, because toRials will not
    throw new PaymentValidationError('unknown currency unit: ' + value);
  }
}

// Amounts are always integers. Reject fractional input before it reaches a gateway.
export function assertAmount(amount: number): void {
  if (!Number.isInteger(amount) || amount <= 0) {
    throw new PaymentValidationError('amount must be a positive integer, got ' + amount);
  }
}

// One place converts. Everything else works in the unit the shopper sees.
export function toRial(amount: number, unit: Unit): number {
  return toRials(amount, unit);
}

toRials بخشی از سطح عمومی است، پس صدا زدنش از کد خودتان پشتیبانی‌شده است نه یک ترفند. توجه کنید که اعتبارسنجی مبلغ بالا بر عهده شماست — SDK شناسه پذیرنده و کال‌بک را اعتبارسنجی می‌کند، هرگز مبلغ خروجی شما را.