medusa-payment-yookassa
Version:
YooKassa payment provider for Medusa
346 lines • 31.5 kB
JavaScript
;
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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