UnoPayv1.0.0
  1. خانه
  2. UnoPay

مرجع API

UnoPay

یک کلاس، یک سازنده، دو متد. یک بار در زمان راه‌اندازی بسازید و نمونه را برای عمر فرایند نگه دارید.

classUnoPay

نقطه ورود. یک بار با درگاه‌هایی که پیکربندی کرده‌اید آن را می‌سازید؛ از آن پس کلید درگاه در هر فراخوانی در زمان کامپایل با همان نگاشت بررسی می‌شود.

export class UnoPay<TGateways extends Record<string, GatewayAdapter>> {
  constructor(adapters: TGateways, logger?: PaymentLogger);
}

فیلدها

فیلدتایپالزامیتوضیح
adaptersTGatewaysبلهخصوصی. نگاشتی از کلید درگاه به GatewayAdapter. همین کلید است که بعداً به‌عنوان provider پاس می‌دهید و به اتحادی تحت‌اللفظی از providerهای مجاز تبدیل می‌شود.
loggerPaymentLogger | undefinedاختیاریخصوصی و اختیاری. هر رویداد چرخه حیات از طریق آن با آبجکت context ساختاریافته منتشر می‌شود.

متدها

نکته

پارامتر جنریک از آبجکت استنتاج می‌شود، پس هرگز آن را نمی‌نویسید. بهای این استنتاج آن است که افزودن درگاه در آینده یعنی ساخت کلاینت جدید، نه تغییر همین کلاینت — چون adapters خصوصی است.

نمونه کد

UnoPay.tsts
const unopay = new UnoPay(
  { zarinpal: new ZarinpalAdapter({ merchantId: process.env.ZARINPAL_MERCHANT_ID! }) },
  logger
);
methodUnoPay.createPayment

از درگاه نام‌برده می‌خواهد پرداخت را آغاز کند و محل ارسال پرداخت‌کننده را برمی‌گرداند. قید K یک درگاه ناشناخته را به خطای کامپایل تبدیل می‌کند نه خطای زمان اجرا.

createPayment<K extends keyof TGateways>(
  provider: K,
  request: PaymentRequest
): Promise<PaymentResult>

پارامترها

نامتایپالزامیتوضیح
providerK extends keyof TGatewaysبلهکلیدی از آبجکت adapters که به سازنده داده شده است.
requestPaymentRequestبلهمبلغ، واحد پول، نشانی کال‌بک و متادیتای اختیاری.

خروجی

Promise<PaymentResult> — نشانی ریدایرکت، آتوریتی به‌عنوان transactionId و توکن درگاه.

خطاها

  • PaymentError — کد ADAPTER_NOT_FOUND وقتی provider کلیدی از آبجکت adapters نباشد. همگام است؛ پرامیس بازگشتی رد می‌شود.
  • PaymentError and subclasses — بدون تغییر دوباره پرتاب می‌شود وقتی خود آداپتور یک PaymentError تولید کند.
  • GatewayProviderError — هر مقدار پرتاب‌شده دیگری را در خود می‌پیچد، بنابراین باگ درون آداپتور هم با کدی به شکل خطای پرداخت ظاهر می‌شود.
نکته

رویدادهای payment_started و provider_request_sent پشت سر هم و پیش از انتظار آداپتور لاگ می‌شوند. هیچ رویداد سومی برای پاسخ وجود ندارد — موفقیت در لاگ ساکت است.

نکته

بررسی adapter-not-found پیش از payment_started انجام می‌شود، پس کلید ناشناخته بدون تولید هیچ رویدادی رد می‌شود. یک لاگر به‌تنهایی این اشتباه را به شما نشان نمی‌دهد.

نمونه کد

UnoPay.example.tsts
const payment = await unopay.createPayment('zarinpal', {
  amount: 50000,
  currency: 'IRT',
  callbackUrl: 'https://yoursite.com/api/payment/callback',
  metadata: { description: 'Order #1024' },
});
return Response.redirect(payment.redirectUrl, 302);
methodUnoPay.verifyCallback

پرداخت را نزد درگاه تایید می‌کند و پاسخ را یکسان‌سازی می‌کند. پرداخت‌کننده‌ای که پرداخت را رها کرده به‌صورت نتیجه false برمی‌گردد، نه استثنا.

verifyCallback<K extends keyof TGateways>(
  provider: K,
  request: CallbackRequest
): Promise<VerificationResult>

پارامترها

نامتایپالزامیتوضیح
providerK extends keyof TGatewaysبلهکلیدی از آبجکت adapters که به سازنده داده شده است.
requestCallbackRequestبلهدرخواست فریم‌ورک تخت‌شده به method، query و body.

خروجی

Promise<VerificationResult> — isSuccessful به‌همراه ref_id درگاه، مبلغ بازتابیده و errorReason وقتی پرداخت تایید نشد.

خطاها

  • PaymentError — کد ADAPTER_NOT_FOUND برای درگاه ناشناخته.
  • GatewayProviderError — هر خطای غیر PaymentError را در خود می‌پیچد، از جمله خطای شبکه هنگام تماس با درگاه.
  • PaymentValidationError — از ZarinpalAdapter وقتی Authority یا مبلغ عددی غایب باشد. بدون تغییر دوباره پرتاب می‌شود.
نکته

رویداد verification_completed روی هر فراخوانی resolve‌شده لاگ می‌شود، چه isSuccessful درست باشد چه نادرست. فقط خطای پرتاب‌شده باعث verification_failed می‌شود.

نمونه کد

UnoPay.example.tsts
const result = await unopay.verifyCallback('zarinpal', {
  method: req.method,
  query: req.query as Record<string, string>,
  body: req.body ?? {},
});

if (result.isSuccessful) {
  return res.send(`Paid. Ref ${result.transactionId}`);
}
return res.status(400).send(`Failed: ${result.errorReason}`);