- خانه
- دامهای مبلغ و واحد پول
راهنماها
دامهای مبلغ و واحد پول
درگاههای پرداخت ایرانی به ریال تسویه میکنند. خریدار به تومان فکر میکند و اغلب به هزاران تومان. 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صادر شده اگر بخواهید، ولی چیزی بیرون از آن دو نقطه آن را برای شما صدا نمیزند.
چهار راه برای اشتباه
- تبدیل دوبل. خودتان به ریال تبدیل میکنید و بعد
'IRT'پاس میدهید. SDK دوباره تبدیل میکند. - برچسب اشتباه. رقم ریالی با
'IRT'ارسال میشود. هیچچیز تشخیصش نمیدهد؛ ده برابر ارزش سفارش را دریافت میکنید. - غلط املایی. کدهایی مثل «TOMN» یا «TMN»، یا «IRT» با فاصله انتهایی. هر چیزی که پس از
toUpperCase()برابرIRTیاTOMANنباشد بیصدا ریال فرض میشود — بدون خطا، بدون لاگ. - ذخیره سمت غلط تبدیل. ذخیره
settledAmountکنار سفارش بدون ثبت اینکه در چه واحدی است. شش ماه بعد مغایرتگیری ناخواناست.
واحد را در مرز اعتبارسنجی کنید
SDK این کار را نمیکند، پس یک بار در لبه انجامش دهید و باقی کدبیس خود را ناتوان از اشتباه کنید.
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 شناسه پذیرنده و کالبک را اعتبارسنجی میکند، هرگز مبلغ خروجی شما را.