UNPKG

yoomoney-sdk

Version:

⭐ Typed YooMoney Wallet SDK for NodeJS. Supported API's: Auth, Wallet & Notifications

318 lines (282 loc) 8.87 kB
import { FormBuilder } from "redirect-form-builder"; import type { URL } from "url"; import type { AutoComplete } from "./autocomplete"; export const PaymentType = { FromCard: "AC", FromWallet: "PC", /** @deprecated **Вариант игнорируется ЮMoney**. Используйте {@link PaymentType.FromCard} (`"AC"`) */ FromMobileBalance: "MC" } as const; export type PaymentType = (typeof PaymentType)[keyof typeof PaymentType]; export const QuickPayForm = { Button: "button" } as const; export type QuickPayForm = (typeof QuickPayForm)[keyof typeof QuickPayForm]; export type FormConfig = { /** * Номер кошелька ЮMoney, на который нужно зачислять деньги отправителей. */ receiver: string; /** * Возможные значения: * * `button` — единственное валидной значение; * * Остальные сохранены для обратной совместимости * * */ quickPayForm?: AutoComplete<QuickPayForm>; /** * Назначение платежа. (До 150 символов) * * @deprecated **Поле игнорируется ЮMoney** */ targets?: string; /** * Способ оплаты. Возможные значения: * * `PC` — оплата из кошелька ЮMoney; * * `AC` — с банковской карты; * */ paymentType?: AutoComplete<PaymentType>; /** * Сумма перевода (спишется с отправителя). */ sum: number; /** * Название перевода в истории отправителя (для переводов из кошелька или с привязанной карты). Отображается в кошельке отправителя. * * Удобнее всего формировать его из названий магазина и товара. Например: `Мой магазин: валенки белые` * * @deprecated **Поле игнорируется ЮMoney** */ formComment?: string; /** * Название перевода на странице подтверждения. Рекомендуем делать его таким же, как `formComment`. * * @deprecated **Поле игнорируется ЮMoney** * */ shortDest?: string; /** Метка, которую сайт или приложение присваивает конкретному переводу. Например, в качестве метки можно указывать код или идентификатор заказа. (До 64 символов) */ label?: string; /** * Поле, в котором можно передать комментарий отправителя перевода. (До 200 символов) * * @deprecated **Поле игнорируется ЮMoney** * */ comment?: string; /** URL-адрес для редиректа после совершения перевода. */ successURL?: string; /** * Нужны ФИО отправителя. * * @deprecated **Поле игнорируется ЮMoney** * * */ needFio?: boolean; /** * Нужна электронная почты отправителя. * * @deprecated **Поле игнорируется ЮMoney** * **/ needEmail?: boolean; /** * Нужен телефон отправителя. * * @deprecated **Поле игнорируется ЮMoney** * * */ needPhone?: boolean; /** * Нужен адрес отправителя. * * @deprecated **Поле игнорируется ЮMoney** * * */ needAddress?: boolean; }; type FormQueryObject = Record< "receiver" | "quickpay-form" | "paymentType" | "sum", string > & Partial< Record< | "formcomment" | "short-dest" | "label" | "comment" | "successURL" | "need-fio" | "need-email" | "need-phone" | "need-address" | "targets", string > >; /** * * @param {FormConfig} config * @return {FormQueryObject} */ function convert(config: FormConfig): FormQueryObject { return { "quickpay-form": config.quickPayForm ?? "button", paymentType: config.paymentType ?? PaymentType.FromCard, receiver: config.receiver, sum: config.sum.toString(), targets: config.targets, "need-address": String(!!config.needAddress), "need-email": String(!!config.needEmail), "need-fio": String(!!config.needFio), "need-phone": String(!!config.needPhone), "short-dest": config.shortDest, comment: config.comment, formcomment: config.formComment, label: config.label, successURL: config.successURL }; } const FORM_ACTION_URL = "https://yoomoney.ru/quickpay/confirm.xml"; /** * Генерирует HTML формы для переводов * @class PaymentFormBuilder */ export class PaymentFormBuilder { /** * * Creates an instance of PaymentFormBuilder. * @param {FormConfig} [config={ * receiver: "", * sum: 10, * }] Изначальные настройки формы */ constructor( public readonly config: FormConfig = { receiver: "", sum: 10 }, public readonly url = FORM_ACTION_URL ) {} /** * Генерирует стандартные сеттеры * * @param {string} field * @return {Function} * @private */ private _makeSetter<T extends keyof FormConfig>( field: T ): (value: FormConfig[T]) => this { return (value: FormConfig[T]) => Object.defineProperty(this, field, { value }); } /** * Задаёт сумму платежа * * @alias {@link setSum} * @param {string | number} amount Сумма * @return {this} */ setAmount(amount: number | string): this { this.config.sum = Number.parseFloat( Number.parseFloat(amount.toString()).toFixed(2) ); return this; } /** * Задаёт сумму платежа * * @alias {@link setAmount} * @param {string | number} amount Сумма * @return {this} */ setSum(amount: number | string): this { this.config.sum = Number.parseFloat( Number.parseFloat(amount.toString()).toFixed(2) ); return this; } /** * Задаёт получателя платежа * * @param {string | number} receiver Получатель * @return {this} */ setReceiver(receiver: number | string): this { this.config.receiver = receiver.toString(); return this; } /** * Задаёт URL перенаправления после успешного платежа * * @param {string | URL} url URL * @return {this} */ setSuccessURL(url: string | URL): this { this.config.successURL = url.toString(); return this; } readonly setQuickPayForm = this._makeSetter("quickPayForm"); readonly setPaymentType = this._makeSetter("paymentType"); readonly setLabel = this._makeSetter("label"); /** @deprecated **Поле игнорируется ЮMoney** */ readonly setTargets = this._makeSetter("targets"); /** @deprecated **Поле игнорируется ЮMoney** */ readonly setFormComment = this._makeSetter("formComment"); /** @deprecated **Поле игнорируется ЮMoney** */ readonly setShortDest = this._makeSetter("shortDest"); /** @deprecated **Поле игнорируется ЮMoney** */ readonly setComment = this._makeSetter("comment"); /** * @deprecated **Поле игнорируется ЮMoney** * * @param {boolean} [doRequire=true] * @return {this} */ requireFio(doRequire = true): this { this.config.needFio = doRequire; return this; } /** * @deprecated **Поле игнорируется ЮMoney** * * @param {boolean} [doRequire=true] * @return {this} */ requireAddress(doRequire = true): this { this.config.needAddress = doRequire; return this; } /** * @deprecated **Поле игнорируется ЮMoney** * * @param {boolean} [doRequire=true] * @return {this} */ requireEmail(doRequire = true): this { this.config.needEmail = doRequire; return this; } /** * @deprecated **Поле игнорируется ЮMoney** * * @param {boolean} [doRequire=true] * @return {this} */ requirePhone(doRequire = true): this { this.config.needPhone = doRequire; return this; } /** * Генерирует HTML на основе заданных параметров * @param {boolean} [fullPage=false] * @return {string} */ buildHtml(fullPage = false): string { const fields = convert(this.config); return new FormBuilder(this.url, "POST", fields).buildHtml(fullPage); } }