UNPKG

medusa-payment-yookassa

Version:
275 lines 22.1 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"); class YookassaBase extends utils_1.AbstractPaymentProvider { static validateOptions(options) { 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"); } } 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:\n" + JSON.stringify({ currency_code, amount, data, context }, null, 2)); const additionalParameters = this.normalizePaymentParameters(data); const createPayload = { amount: { value: amount, currency: currency_code.toUpperCase(), // Medusa stores currency codes in lower case of ISO-4217 }, metadata: { session_id: data?.session_id }, ...additionalParameters }; try { const response = await this.yooCheckout_.createPayment(createPayload, context?.idempotency_key); const paymentId = "id" in response ? response.id : data?.session_id; return { id: paymentId, data: response, }; } catch (e) { throw this.buildError("An error occurred in initiatePayment", e); } } /** * Retrieve payment status and map it to Medusa status. */ async getPaymentStatus({ data }) { this.logger_.debug("YookassaBase.getPaymentStatus:\n" + JSON.stringify(data, null, 2)); const id = 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; switch (payment.status) { case yoo_checkout_1.PaymentStatuses.pending: return { status: utils_1.PaymentSessionStatus.PENDING, data: paymentData }; case yoo_checkout_1.PaymentStatuses.canceled: return { status: utils_1.PaymentSessionStatus.CANCELED, data: paymentData }; case yoo_checkout_1.PaymentStatuses.waiting_for_capture: return { status: utils_1.PaymentSessionStatus.AUTHORIZED, data: paymentData }; case yoo_checkout_1.PaymentStatuses.succeeded: return { status: utils_1.PaymentSessionStatus.CAPTURED, data: paymentData }; default: return { status: utils_1.PaymentSessionStatus.PENDING, data: paymentData }; } } catch (e) { throw this.buildError("An error occurred in getPaymentStatus", e); } } /** * Capture an existing payment. */ async capturePayment(input) { this.logger_.debug("YookassaBase.capturePayment:\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); return { data: response }; } 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:\n" + JSON.stringify(input, null, 2)); const statusResponse = await this.getPaymentStatus(input); return statusResponse; } /** * Cancel an existing payment. */ async cancelPayment(input) { this.logger_.debug("YookassaBase.cancelPayment:\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); return { data: response }; } catch (e) { throw this.buildError("An error occurred in cancelPayment", e); } } /** * Retrieve a payment. */ async retrievePayment(input) { this.logger_.debug("YookassaBase.retrievePayment:\n" + JSON.stringify(input, null, 2)); try { const payment = await this.yooCheckout_.getPayment(input.data?.id); return { data: payment }; } catch (e) { throw this.buildError("An error occurred in retrievePayment", e); } } /** * Refund a payment. */ async refundPayment({ amount, data, context, }) { this.logger_.debug("YookassaBase.refundPayment:\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 payload = { payment_id: id, amount: { value: new utils_1.BigNumber(amount).numeric.toString(), currency: payment?.amount?.currency, }, }; try { await this.yooCheckout_.createRefund(payload, context?.idempotency_key); return await this.retrievePayment({ data }); } 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:\n" + JSON.stringify(input, null, 2)); return input; } /** * Update a payment. * Payment update is not supported by YooKassa. */ async updatePayment(input) { this.logger_.debug("YookassaBase.updatePayment:\n" + JSON.stringify(input, null, 2)); return input; } /** * Process webhook event and map it to Medusa action. */ async getWebhookActionAndData(webhookData) { this.logger_.debug("YookassaBase.getWebhookActionAndData:\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; switch (event) { case yoo_checkout_1.WebHookEvents["payment.succeeded"]: return { action: utils_1.PaymentActions.SUCCESSFUL, data: { session_id: object.metadata.session_id, amount: object.amount.value, } }; case yoo_checkout_1.WebHookEvents["payment.waiting_for_capture"]: return { action: utils_1.PaymentActions.AUTHORIZED, data: { session_id: object.metadata.session_id, amount: object.amount.value, }, }; case yoo_checkout_1.WebHookEvents["payment.canceled"]: return { action: utils_1.PaymentActions.CANCELED, data: { session_id: object.metadata.session_id, amount: object.amount.value, }, }; default: return { action: utils_1.PaymentActions.NOT_SUPPORTED }; } } /** * 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()); } } exports.default = YookassaBase; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieW9va2Fzc2EtYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvcGF5bWVudC15b29rYXNzYS9jb3JlL3lvb2thc3NhLWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx3REFVOEI7QUFDOUIsa0RBQXlDO0FBQ3pDLHFEQU9rQztBQW1DbEMsTUFBZSxZQUFhLFNBQVEsK0JBQXdDO0lBSzFFLE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBd0I7UUFDN0MsSUFBSSxDQUFDLElBQUEsaUJBQVMsRUFBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUMvQixNQUFNLElBQUksS0FBSyxDQUFDLHdEQUF3RCxDQUFDLENBQUE7UUFDM0UsQ0FBQztRQUNELElBQUksQ0FBQyxJQUFBLGlCQUFTLEVBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDbEMsTUFBTSxJQUFJLEtBQUssQ0FBQywyREFBMkQsQ0FBQyxDQUFBO1FBQzlFLENBQUM7SUFDSCxDQUFDO0lBRUQsWUFBc0IsU0FBK0IsRUFBRSxPQUF3QjtRQUM3RSxhQUFhO1FBQ2IsS0FBSyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUE7UUFFbkIsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFBO1FBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFBO1FBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSwwQkFBVyxDQUFDO1lBQ2xDLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtZQUN0QixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7U0FDN0IsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUlELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQTtJQUN0QixDQUFDO0lBRU8sMEJBQTBCLENBQ2hDLEtBQStCO1FBRS9CLE1BQU0sR0FBRyxHQUFHLEVBQTZC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