UNPKG

medusa-payment-yookassa

Version:
346 lines 31.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const yoo_checkout_1 = require("@a2seven/yoo-checkout"); const axios_1 = __importDefault(require("axios")); const utils_1 = require("@medusajs/framework/utils"); const telemetry_1 = require("@gorgo/telemetry"); const utils_2 = require("../utils"); const types_1 = require("../types"); class YookassaBase extends utils_1.AbstractPaymentProvider { static validateOptions(options) { YookassaBase.telemetry_.track("plugin.started"); if (!(0, utils_1.isDefined)(options.shopId)) { throw new Error("Required option `shopId` is missing in YooKassa plugin"); } if (!(0, utils_1.isDefined)(options.secretKey)) { throw new Error("Required option `secretKey` is missing in YooKassa plugin"); } if ((0, utils_1.isDefined)(options.useReceipt)) { if (options.useAtolOnlineFFD120) { if (!(0, utils_1.isDefined)(options.taxSystemCode)) { throw new Error("Required option `taxSystemCode` is missing in YooKassa provider"); } else if (!types_1.taxSystemCodes.includes(options.taxSystemCode)) { throw new Error(`Invalid option \`taxSystemCode\` provided in YooKassa provider. Valid values are: ${types_1.taxSystemCodes.join(", ")}`); } } if (!(0, utils_1.isDefined)(options.taxItemDefault)) { throw new Error("Required option `taxItemDefault` is missing in YooKassa provider"); } else if (!types_1.vatCodes.includes(options.taxItemDefault)) { throw new Error(`Invalid option \`taxItemDefault\` provided in YooKassa provider. Valid values are: ${types_1.vatCodes.join(", ")}`); } if (!(0, utils_1.isDefined)(options.taxShippingDefault)) { throw new Error("Required option `taxShippingDefault` is missing in YooKassa provider"); } else if (!types_1.vatCodes.includes(options.taxShippingDefault)) { throw new Error(`Invalid option \`taxShippingDefault\` provided in YooKassa provider. Valid values are: ${types_1.vatCodes.join(", ")}`); } } } constructor(container, options) { // @ts-ignore super(...arguments); this.logger_ = container.logger; this.options_ = options; this.yooCheckout_ = new yoo_checkout_1.YooCheckout({ shopId: options.shopId, secretKey: options.secretKey, }); } get options() { return this.options_; } normalizePaymentParameters(extra) { const res = {}; res.description = extra?.description ?? this.options_?.paymentDescription; res.capture = extra?.capture ?? this.paymentOptions.capture ?? this.options_.capture; res.payment_method_data = this.paymentOptions?.payment_method_data; res.confirmation = extra?.confirmation; return res; } /** * Initiate a new payment. */ async initiatePayment({ currency_code, amount, data, context, }) { this.logger_.debug(`YookassaBase.initiatePayment input:\n${JSON.stringify({ currency_code, amount, data, context }, null, 2)}`); const cart = data?.cart; const additionalParameters = this.normalizePaymentParameters(data); let receipt = {}; if (this.options_.useReceipt && cart) { try { receipt = (0, utils_2.generateReceipt)(this.options_.taxSystemCode, this.options_.taxItemDefault, this.options_.taxShippingDefault, cart); } catch (e) { this.logger_.warn(`Receipt generation failed in YookassaBase.initiatePayment for cart ${cart?.id}: ${e instanceof Error ? e.message : String(e)}. Skipping receipt generation.`); } } const receiptTemplate = (0, utils_2.buildReceiptTemplate)(receipt); const createPayload = { amount: { value: String(Number(amount).toFixed(2)), currency: currency_code.toUpperCase(), // Medusa stores currency codes in lower case of ISO-4217 }, metadata: { session_id: data?.session_id, receip_tmp: receiptTemplate }, ...additionalParameters, ...(this.options_.useReceipt && receipt?.items?.length ? { receipt } : {}), }; try { const response = await this.yooCheckout_.createPayment(createPayload, context?.idempotency_key); const paymentId = "id" in response ? response.id : data?.session_id; const output = { id: paymentId, data: response, }; this.logger_.debug(`YookassaBase.initiatePayment output:\n${JSON.stringify(output, null, 2)}`); return output; } catch (e) { throw this.buildError("An error occurred in initiatePayment", e); } } /** * Retrieve payment status and map it to Medusa status. */ async getPaymentStatus(input) { this.logger_.debug(`YookassaBase.getPaymentStatus input:\n${JSON.stringify(input, null, 2)}`); const id = input.data?.id; if (!id) { throw this.buildError("No payment ID provided while getting payment status", new Error("No payment ID provided")); } try { const payment = await this.yooCheckout_.getPayment(id); const paymentData = payment; let output; switch (payment.status) { case yoo_checkout_1.PaymentStatuses.pending: output = { status: utils_1.PaymentSessionStatus.PENDING, data: paymentData }; break; case yoo_checkout_1.PaymentStatuses.canceled: output = { status: utils_1.PaymentSessionStatus.CANCELED, data: paymentData }; break; case yoo_checkout_1.PaymentStatuses.waiting_for_capture: output = { status: utils_1.PaymentSessionStatus.AUTHORIZED, data: paymentData }; break; case yoo_checkout_1.PaymentStatuses.succeeded: output = { status: utils_1.PaymentSessionStatus.CAPTURED, data: paymentData }; break; default: output = { status: utils_1.PaymentSessionStatus.PENDING, data: paymentData }; } this.logger_.debug(`YookassaBase.getPaymentStatus output:\n${JSON.stringify(output, null, 2)}`); return output; } catch (e) { throw this.buildError("An error occurred in getPaymentStatus", e); } } /** * Capture an existing payment. */ async capturePayment(input) { this.logger_.debug(`YookassaBase.capturePayment input:\n${JSON.stringify(input, null, 2)}`); const payment = input.data; // Avoid autoCapture in https://github.com/medusajs/medusa/blob/ceb504db2ce44dec43dff652fb306eb4e4f6059e/packages/modules/payment/src/services/payment-module.ts#L590 if (payment.status === yoo_checkout_1.PaymentStatuses.succeeded) return { data: input }; const payload = { amount: payment.amount }; const idempotencyKey = input.context?.idempotency_key; try { const response = await this.yooCheckout_.capturePayment(payment.id, payload, idempotencyKey); const output = { data: response }; this.logger_.debug(`YookassaBase.capturePayment output:\n${JSON.stringify(output, null, 2)}`); return output; } catch (e) { throw this.buildError("An error occurred in capturePayment", e); } } /** * Authorize a payment by retrieving its status. */ async authorizePayment(input) { this.logger_.debug(`YookassaBase.authorizePayment input:\n${JSON.stringify(input, null, 2)}`); const output = await this.getPaymentStatus(input); this.logger_.debug(`YookassaBase.authorizePayment output:\n${JSON.stringify(output, null, 2)}`); return output; } /** * Cancel an existing payment. */ async cancelPayment(input) { this.logger_.debug(`YookassaBase.cancelPayment input:\n${JSON.stringify(input, null, 2)}`); const paymentId = input.data?.id; const idempotencyKey = input.context?.idempotency_key; try { const response = await this.yooCheckout_.cancelPayment(paymentId, idempotencyKey); const output = { data: response }; this.logger_.debug(`YookassaBase.cancelPayment output:\n${JSON.stringify(output, null, 2)}`); return output; } catch (e) { throw this.buildError("An error occurred in cancelPayment", e); } } /** * Retrieve a payment. */ async retrievePayment(input) { this.logger_.debug(`YookassaBase.retrievePayment input:\n${JSON.stringify(input, null, 2)}`); try { const payment = await this.yooCheckout_.getPayment(input.data?.id); const output = { data: payment }; this.logger_.debug(`YookassaBase.retrievePayment output:\n${JSON.stringify(output, null, 2)}`); return output; } catch (e) { throw this.buildError("An error occurred in retrievePayment", e); } } /** * Refund a payment. */ async refundPayment({ amount, data, context, }) { this.logger_.debug(`YookassaBase.refundPayment input:\n${JSON.stringify({ amount, data, context }, null, 2)}`); const payment = data; const id = payment?.id; if (!id) { throw this.buildError("No payment ID provided while refunding payment", new Error("No payment ID provided")); } const refundAmount = (0, utils_2.formatCurrency)(new utils_1.BigNumber(amount).numeric.toString(), payment?.amount?.currency); const receipt = (0, utils_2.buildRefundReceiptSimple)(refundAmount, payment.metadata.receip_tmp); const payload = { payment_id: id, amount: { value: new utils_1.BigNumber(amount).numeric.toString(), currency: payment?.amount?.currency, }, ...(this.options_.useReceipt && refundAmount !== payment?.amount?.value ? { receipt: receipt } : {}), }; try { await this.yooCheckout_.createRefund(payload, context?.idempotency_key); const output = await this.retrievePayment({ data }); this.logger_.debug(`YookassaBase.refundPayment output:\n${JSON.stringify(output, null, 2)}`); return output; } catch (e) { throw this.buildError("An error occurred in refundPayment", e); } } /** * Delete a payment. * Payment deletion is not supported by YooKassa. */ async deletePayment(input) { this.logger_.debug(`YookassaBase.deletePayment input:\n${JSON.stringify(input, null, 2)}`); const output = input; this.logger_.debug(`YookassaBase.deletePayment output:\n${JSON.stringify(output, null, 2)}`); return output; } /** * Update a payment. * Payment update is not supported by YooKassa. */ async updatePayment(input) { this.logger_.debug(`YookassaBase.updatePayment input:\n${JSON.stringify(input, null, 2)}`); const output = input; this.logger_.debug(`YookassaBase.updatePayment output:\n${JSON.stringify(output, null, 2)}`); return output; } /** * Process webhook event and map it to Medusa action. */ async getWebhookActionAndData(webhookData) { this.logger_.debug(`YookassaBase.getWebhookActionAndData payload:\n${JSON.stringify(webhookData, null, 2)}`); const isValid = await this.isWebhookEventValid(webhookData); if (!isValid) return { action: utils_1.PaymentActions.NOT_SUPPORTED }; const { event, object } = webhookData.data; let result; switch (event) { case yoo_checkout_1.WebHookEvents["payment.succeeded"]: result = { action: utils_1.PaymentActions.SUCCESSFUL, data: { session_id: object.metadata.session_id, amount: object.amount.value, } }; break; case yoo_checkout_1.WebHookEvents["payment.waiting_for_capture"]: result = { action: utils_1.PaymentActions.AUTHORIZED, data: { session_id: object.metadata.session_id, amount: object.amount.value, }, }; break; case yoo_checkout_1.WebHookEvents["payment.canceled"]: result = { action: utils_1.PaymentActions.CANCELED, data: { session_id: object.metadata.session_id, amount: object.amount.value, }, }; break; default: result = { action: utils_1.PaymentActions.NOT_SUPPORTED }; } this.logger_.debug(`YookassaBase.getWebhookActionAndData result:\n${JSON.stringify(result, null, 2)}`); return result; } /** * Validate Webhook event * @param {object} webhookData - the data of the webhook request: req.body * @returns {boolean} - stutus of validation */ async isWebhookEventValid(webhookData) { const [object, status] = webhookData.data.event.split('.'); try { switch (object) { case "payment": const payment = await this.yooCheckout_.getPayment(webhookData.data.object.id); return payment.status === status; case "refund": const refund = await this.yooCheckout_.getRefund(webhookData.data.object.id); return refund.status === status; default: return false; } } catch (e) { throw this.buildError(`An error occurred in isWebhookEventValid when validating a ${object}`, e); } } /** * Helper to build errors with additional context. */ buildError(message, error) { if (axios_1.default.isAxiosError(error)) { return new Error(`${message}: ${error.response?.status} ${error.response?.data?.code} - ${error.response?.data?.description}`.trim()); } return new Error(`${message}: ${error.message}`.trim()); } } YookassaBase.telemetry_ = (0, telemetry_1.createTelemetryClient)({ packageDir: __dirname }); exports.default = YookassaBase; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieW9va2Fzc2EtYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvcGF5bWVudC15b29rYXNzYS9jb3JlL3lvb2thc3NhLWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx3REFXOEI7QUFDOUIsa0RBQXlDO0FBQ3pDLHFEQU1rQztBQXdCbEMsZ0RBQXdEO0FBQ3hELG9DQUtpQjtBQUNqQixvQ0FNaUI7QUFNakIsTUFBZSxZQUFhLFNBQVEsK0JBQXdDO0lBTTFFLE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBd0I7UUFDN0MsWUFBWSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQTtRQUMvQyxJQUFJLENBQUMsSUFBQSxpQkFBUyxFQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsd0RBQXdELENBQUMsQ0FBQTtRQUMzRSxDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUEsaUJBQVMsRUFBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUNsQyxNQUFNLElBQUksS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUE7UUFDOUUsQ0FBQztRQUNELElBQUksSUFBQSxpQkFBUyxFQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ2xDLElBQUksT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7Z0JBQ2hDLElBQUksQ0FBQyxJQUFBLGlCQUFTLEVBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7b0JBQ3RDLE1BQU0sSUFBSSxLQUFLLENBQUMsaUVBQWlFLENBQUMsQ0FBQTtnQkFDcEYsQ0FBQztxQkFBTSxJQUFJLENBQUMsc0JBQWMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7b0JBQzNELE1BQU0sSUFBSSxLQUFLLENBQUMscUZB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