UNPKG

@gorgo/medusa-payment-tkassa

Version:
239 lines 19.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const utils_1 = require("@medusajs/framework/utils"); const crypto_1 = __importDefault(require("crypto")); const t_kassa_api_1 = require("t-kassa-api"); const types_1 = require("../types"); const get_smallest_unit_1 = require("../utils/get-smallest-unit"); class TkassaBase extends utils_1.AbstractPaymentProvider { constructor(container, options) { super(container, options); this.serverUrl_ = "https://securepay.tinkoff.ru"; this.options_ = options; this.logger_ = container.logger; this.client_ = new t_kassa_api_1.TKassa(options.terminalKey, options.password, { server: this.serverUrl_ }); } normalizePaymentParameters(extra) { const res = {}; if (extra?.SuccessURL) res.SuccessURL = extra?.SuccessURL; if (extra?.FailURL) res.FailURL = extra?.FailURL; if (extra?.PayType) { res.PayType = extra.PayType; } else { if (this.options_.capture !== undefined) { res.PayType = this.options_.capture ? "O" : "T"; } else { res.PayType = "O"; } } return res; } /** * Initiate a new payment. */ async initiatePayment({ currency_code, amount, data, context, }) { this.logger_.debug("TkassaBase.initiatePayment:\n" + JSON.stringify({ currency_code, amount, data, context }, null, 2)); const additionalParameters = this.normalizePaymentParameters(data); try { const response = await this.client_.init({ TerminalKey: this.options_.terminalKey, Password: this.options_.password, Amount: (0, get_smallest_unit_1.getSmallestUnit)(amount, currency_code), OrderId: data?.session_id, ...additionalParameters }); const paymentId = String(response.PaymentId); return { id: paymentId, data: response }; } catch (e) { throw this.buildError("An error occurred in initiatePayment", e); } } /** * Capture an existing payment. */ async capturePayment(input) { this.logger_.debug(`TkassaBase.capturePayment:\n${JSON.stringify(input, null, 2)}`); const paymentId = input.data?.PaymentId; try { const response = await this.client_.confirm({ TerminalKey: this.options_.terminalKey, Password: this.options_.password, PaymentId: paymentId }); return { data: response }; } catch (e) { throw this.buildError("An error occurred in capturePaymentt", e); } } /** * Authorize a payment by retrieving its status. */ async authorizePayment(input) { this.logger_.debug(`TkassaBase.authorizePayment:\n${JSON.stringify(input, null, 2)}`); const statusResponse = await this.getPaymentStatus(input); return statusResponse; } /** * Delete a payment. * Payment delete is not supported by T-Kassa. */ async deletePayment(input) { this.logger_.debug(`TkassaBase.deletePayment:\n${JSON.stringify(input, null, 2)}`); return input; } /** * Update a payment. * Payment update is not supported by T-Kassa. */ async updatePayment(input) { this.logger_.debug(`TkassaBase.updatePayment:\n${JSON.stringify(input, null, 2)}`); return input; } /** * Refund a payment. */ async refundPayment({ amount, data, }) { this.logger_.debug(`TkassaBase.refundPayment:\n${JSON.stringify({ amount, data }, null, 2)}`); const paymentId = data?.PaymentId; const amountValue = typeof amount === 'object' && 'value' in amount ? amount.value : typeof amount === 'string' || typeof amount === 'number' ? amount : ""; try { const response = await this.client_.cancel({ TerminalKey: this.options_.terminalKey, Password: this.options_.password, PaymentId: paymentId, ...(amountValue ? { Amount: (0, get_smallest_unit_1.getSmallestUnit)(Number(amountValue), 'RUB') } : {}) }); return { data: response }; } catch (e) { throw this.buildError("An error occurred in refundPayment", e); } } /** * Cancel an existing payment. */ async cancelPayment(input) { this.logger_.debug(`TkassaBase.cancelPayment:\n${JSON.stringify(input, null, 2)}`); const paymentId = input.data?.PaymentId; try { const response = await this.client_.cancel({ TerminalKey: this.options_.terminalKey, Password: this.options_.password, PaymentId: paymentId }); return { data: response }; } catch (e) { throw this.buildError("An error occurred in cancelPayment", e); } } /** * Retrieve a payment. */ async retrievePayment(input) { this.logger_.debug(`TkassaBase.retrievePayment input:\n${JSON.stringify(input, null, 2)}`); const paymentId = input.data?.PaymentId; try { const response = await this.client_.getState({ TerminalKey: this.options_.terminalKey, Password: this.options_.password, PaymentId: paymentId }); return { data: response }; } catch (e) { throw this.buildError("An error occurred in retrievePayment", e); } } /** * Retrieve payment status and map it to Medusa status. */ async getPaymentStatus(input) { this.logger_.debug(`TkassaProvider.getPaymentStatus:\n${JSON.stringify(input, null, 2)}`); const paymentId = input.data?.PaymentId; if (!paymentId || typeof paymentId !== 'string') { throw this.buildError("No payment ID provided while getting payment status", new Error("No payment ID provided")); } try { const response = await this.client_.getState({ TerminalKey: this.options_.terminalKey, Password: this.options_.password, PaymentId: paymentId, }); const status = response.Status; return { status: types_1.PaymentStatusesMap[status] ?? utils_1.PaymentSessionStatus.ERROR, data: response }; } catch (e) { throw this.buildError("An error occurred in getPaymentStatus", e); } } async getWebhookActionAndData(webhookData) { this.logger_.debug(`TkassaProvider.getWebhookActionAndData:\n${JSON.stringify(webhookData, null, 2)}`); const isValid = await this.isWebhookEventValid(webhookData); if (!isValid) return { action: utils_1.PaymentActions.NOT_SUPPORTED }; const data = webhookData.data; return { action: types_1.PaymentStatusesMap[types_1.PaymentStatuses[data.Status]] ?? utils_1.PaymentSessionStatus.ERROR, data: { session_id: data.OrderId, amount: data.Amount } }; } async isWebhookEventValid(payload) { const data = payload.data; if (!data || !data.Status || !data.OrderId || !data.Amount) { return false; } const incomingToken = data.Token; const requiredKeys = [ "TerminalKey", "OrderId", "Success", "Status", "PaymentId", "ErrorCode", "Amount", "CardId", "Pan", "ExpDate" ]; const params = {}; for (const key of requiredKeys) { const value = data[key]; params[key] = String(value); } params["Password"] = this.options_.password; const sortedKeys = Object.keys(params).sort(); let concat = ""; for (const key of sortedKeys) { concat += params[key]; } const hash = crypto_1.default.createHash("sha256").update(concat).digest("hex"); const valid = incomingToken === hash; return valid; } /** * Helper to build errors with additional context. */ buildError(message, error) { const errorDetails = "raw" in error ? error.raw : error; return new Error(`${message}: ${error.message}. ${"detail" in errorDetails ? errorDetails.detail : ""}`.trim()); } } TkassaBase.identifier = "tkassa"; exports.default = TkassaBase; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGthc3NhLWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3BheW1lbnQtdGthc3NhL2NvcmUvdGthc3NhLWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxxREFJa0M7QUFhbEMsb0RBQTJCO0FBQzNCLDZDQUFvQztBQUNwQyxvQ0FNaUI7QUFFakIsa0VBRW1DO0FBRW5DLE1BQWUsVUFBVyxTQUFRLCtCQUE4QztJQU85RSxZQUFZLFNBQTZCLEVBQUUsT0FBOEI7UUFDdkUsS0FBSyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQTtRQU5qQixlQUFVLEdBQUcsOEJBQThCLENBQUE7UUFPbkQsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUE7UUFDdkIsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFBO1FBQy9CLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxvQkFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQTtJQUMvRixDQUFDO0lBRU8sMEJBQTBCLENBQ2hDLEtBQStCO1FBRS9CLE1BQU0sR0FBRyxHQUFHLEVBQXNCLENBQUE7UUFFbEMsSUFBSSxLQUFLLEVBQUUsVUFBVTtZQUNuQixHQUFHLENBQUMsVUFBVSxHQUFHLEtBQUssRUFBRSxVQUFtQyxDQUFBO1FBRTdELElBQUksS0FBSyxFQUFFLE9BQU87WUFDaEIsR0FBRyxDQUFDLE9BQU8sR0FBRyxLQUFLLEVBQUUsT0FBNkIsQ0FBQTtRQUVwRCxJQUFJLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUNuQixHQUFHLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUE2QixDQUFBO1FBQ25ELENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxJQUFJLENBQUMsUUFB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