Medusa plugins
T

Tkassa

T-Kassa payment provider for Medusa

Need customizations for this plugin?

Get in touch
npm install @gorgo/medusa-payment-tkassa
Category
other
Built by
gorgo
Type
unknown
Last updated
3 weeks ago
Monthly downloads
648
Github stars
7

Возможности

  • 🔗  Бесшовная интеграция с платёжной системой YooKassa
  • 🧾  Формирование онлайн-чеков в соответствии с 54-ФЗ
  • 1️⃣  Одностадийные (автосписание) и  2️⃣  двухстадийные (авторизация/холдирование) сценарии оплаты
  • 🔄  Возвраты и отмена заказов
  • 🔔  Вебхук-уведомления о статусах платежей в реальном времени
  • 🛡  Проверка вебхуков для обеспечения безопасности
  • 🔍  Подробное логирование для отладки

💬  Чат поддержки плагина T-Kassa

Есть вопросы или идеи по новым функциям плагина?
Присоединяйтесь к чату в Telegram – @medusajs_tkassa

👥  Чат сообщества Medusa.js

Общайтесь в Telegram с другими разработчиками Medusa – @medusajs_chat

Требования

Установка

yarn add @gorgo/medusa-payment-tkassa
# или
npm install @gorgo/medusa-payment-tkassa

Настройка

Добавьте конфигурацию провайдера в файл в приложении Medusa Admin:

// ...
module.exports = defineConfig({
// ...
modules: [
{
resolve: "@medusajs/medusa/payment",
options: {
providers: [
{
resolve: "@gorgo/medusa-payment-tkassa/providers/payment-tkassa",
id: "tkassa",
options: {
terminalKey: process.env.TKASSA_TERMINAL_KEY,
password: process.env.TKASSA_PASSWORD,
capture: true,
useReceipt: true,
ffdVersion: "1.05",
taxation: "osn",
taxItemDefault: "none",
taxShippingDefault: "none"
},
}
]
}
}
]
})

Добавьте переменные окружения и из личного кабинета T-Business:

Параметры провайдера

ПараметрОписаниеОбязательныйПо умолчанию
Ключ терминала, предоставленный T-Kassa (обязателен для аутентификации)Да-
Пароль для подписи запросов (обязателен для аутентификации)Да-
Определяет тип проведения платежа:- — одностадийная оплата ( в API)- — двухстадийная оплата ( в API)Нет
Включает формирование онлайн-чеков по 54-ФЗНет
Версия ФФД: или Применимо только при Нет-
Система налогообложения:- — общая СН- — упрощенная СН (доходы)- — упрощенная СН (доходы минус расходы)- — единый сельскохозяйственный налог- — патентная СНПрименимо только при Нет-
Ставка НДС по товарам:- — без НДС- — 0%- — 5%- — 7%- — 10%- — 20%- — 5/105- — 7/107- — 10/110- — 20/120Применимо только при Нет-
Ставка НДС для доставки (аналогично )Применимо только при Нет-

Интеграция с Storefront (витриной магазина)

Для интеграции платёжного провайдера T-Kassa с storefront на Next.js начните с добавления необходимых UI-компонентов. Таким образом провайдер будет отображаться на странице оформления заказа наряду с другими доступными методами оплаты.

Когда пользователь выбирает T-Kassa, витрина должна вызвать метод с нужными параметрами. Это создаст платёжную сессию через API T-Kassa и подготовит покупателя к перенаправлению. После этого кнопка Place Order должна отправить пользователя на страницу оплаты T-Kassa, где он сможет выбрать предпочтительный способ оплаты.

После завершения оплаты T-Kassa одновременно отправит вебхук и перенаправит покупателя обратно в витрину. То событие, которое придёт первым, завершит корзину и создаст новый заказ в Medusa.

Для запуска на Next.js необходимо внести следующие изменения:

1. Конфигурация платежного провайдера

Чтобы сделать T-Kassa доступным в качестве способа оплаты на странице оформления заказа витрины магазина, необходимо добавить её конфигурацию в маппинг платёжных провайдеров в файле с константами вашего storefront. Этот маппинг определяет как каждый провайдер отображается в интерфейсе.

Откройте и добавьте следующий код:

export const paymentInfoMap: Record<
string,
{ title: string; icon: React.ReactNode }
> = {
// ... другие провайдеры
pp_tkassa_tkassa: {
title: "T-Kassa",
icon: <CreditCard />,
},
}
// Вспомогательная функция для проверки, является ли провайдер T-Kassa
export const isTkassa = (providerId?: string) => {
return providerId?.startsWith("pp_tkassa")
}

Вы расширяете объект , добавляя в него запись . Эта запись определяет заголовок и иконку, которые будут отображаться для T-Kassa на странице оформления заказа.

Вспомогательная функция проверяет, принадлежит ли переданный к T-Kassa. Это используется при рендеринге UI-компонентов, специфичных для конкретного провайдера.

2. Настройки Сookie

При подключении T-Kassa настройте политику cookie так, чтобы поддерживались междоменные редиректы. Это нужно для сохранения платёжной сессии при возврате пользователя в магазин.

Откройте и обновите конфигурацию файлов cookie следующим образом:

export const setCartId = async (cartId: string) => {
cookies.set("_medusa_cart_id", cartId, {
// ... другие настройки cookie
sameSite: "lax", // Переключено с режима «Strict» для междоменных редиректов
})
}

Эта вспомогательная функция сохраняет идентификатор корзины в cookie с именем .

Опция установлена в значение вместо . Это изменение гарантирует, что cookie будет отправляться при кросс-доменных запросах во время процесса редиректа через T-Kassa, предотвращая потерю платёжной сессии.

3. Инициализация платёжной сессии

Чтобы перенаправить покупателя в T-Kassa, платёжная сессия должна быть корректно инициализирована с обязательными параметрами, включая return URL для обоих случаев: успешной и неуспешной оплаты.

Откройте и обновите логику инициализации платежа, включив в нее данные корзины и URL возврата для T-Kassa:

await initiatePaymentSession(cart, {
provider_id: selectedPaymentMethod,
data: {
SuccessURL: `${getBaseURL()}/api/capture-payment/${cart?.id}?country_code=${countryCode}`,
FailURL: `${getBaseURL()}/api/capture-payment/${cart?.id}?country_code=${countryCode}`,
cart: cart,
}
})

При инициализации платёжной сессии для T-Kassa параметры и определяют, куда будет перенаправлен покупатель после попытки оплаты. Оба URL динамически формируются на основе базового URL storefront, идентификатора корзины и выбранного кода страны.

Объект включается в данные инициализации для формирования чека в соответствии с Федеральным законом № 54.

4. Компонент кнопки оплаты

В storefront для каждого платёжного провайдера необходим отдельный компонент кнопки оплаты. Он отвечает за обработку оформления заказа после подтверждения пользователем и, используя данные платёжного сеанса, перенаправляет его на страницу оплаты T-Kassa.

Откройте и добавьте следующий код:

const TkassaPaymentButton: React.FC<TkassaPaymentProps> = ({ cart, notReady }) => {
const [submitting, setSubmitting] = useState(false)
const [errorMessage, setErrorMessage] = useState<string | null>(null)
const router = useRouter()
const paymentSession = cart.payment_collection?.payment_sessions?.find(
session => session.provider_id === "pp_tkassa_tkassa"
)
const handlePayment = () => {
setSubmitting(true)
const paymentUrl = (paymentSession?.data as any).PaymentURL
if (paymentUrl) {
router.push(paymentUrl)
} else {
setErrorMessage("Payment URL отсутствует")
setSubmitting(false)
}
}
}

Этот компонент находит для T-Kassa в текущей корзине и извлекает , предоставленный бэкендом. При нажатии кнопки Place order покупатель перенаправляется на этот URL для завершения транзакции на странице оплаты T-Kassa.

Если отсутствует, компонент выводит сообщение об ошибке, не позволяя продолжить. Состояние обеспечивает визуальную обратную связь во время подготовки перенаправления.

Компонент определяет, принадлежит ли текущая платёжная сессия к T-Kassa, с помощью вспомогательной функции . Если да, он рендерит для обработки процесса оплаты.

Интеграция этого компонента гарантирует, что процесс оплаты через T-Kassa будет запускаться при оформлении заказа.

5. API-роут подтверждения платежа

После того как покупатель завершает оплату на странице T-Kassa, он перенаправляется обратно на витрину магазина. Необходимо создать API-роут, который обработает этот callback, проверит статус платежа и завершит корзину.

Создайте файл со следующим содержимым:

import { NextRequest, NextResponse } from "next/server"
import { revalidateTag } from "next/cache"
import {
getCacheTag,
getAuthHeaders,
removeCartId
} from "@lib/data/cookies"
import { sdk } from "@lib/config"
import { placeOrder } from "@lib/data/cart"
type Params = Promise<{ cartId: string }>
export async function GET(req: NextRequest, { params }: { params: Params }) {
const { cartId } = await params
const { origin, searchParams } = req.nextUrl
const countryCode = searchParams.get("country_code") || ""
const headers = { ...(await getAuthHeaders()) }
// Получить актуальные значения корзины
const cartCacheTag = await getCacheTag("carts")
revalidateTag(cartCacheTag)
const { cart } = await sdk.store.cart.retrieve(cartId, {
fields: "id, order_link.order_id"
},
headers
)
if (!cart) {
return NextResponse.redirect(`${origin}/${countryCode}`)
}
const orderId = (cart as unknown as Record<string, any>).order_link?.order_id
if (!orderId) {
await placeOrder(cartId)
// Ошибка при неавторизованном платеже
return NextResponse.redirect(
`${origin}/${countryCode}/checkout?step=review&error=payment_failed`
)
}
const orderCacheTag = await getCacheTag("orders")
revalidateTag(orderCacheTag)
removeCartId()
return NextResponse.redirect(
`${origin}/${countryCode}/order/${orderId}/confirmed`
)
}

Этот API-роут обрабатывает редирект от T-Kassa после попытки оплаты. Он получает актуальное состояние корзины, чтобы убедиться, что все изменения, внесённые во время оплаты, были отражены.

Если в корзине нет связанного идентификатора заказа, обработчик роута пытается оформить заказ. В случае успеха покупатель перенаправляется на страницу подтверждения заказа. Если же при обработке корзины возникла ошибка, покупатель возвращается на страницу оформления заказа с указанием ошибки и может повторить процесс оплаты заказа.

Когда оплата проходит успешно, роут повторно валидирует кэшированные данные корзины и заказа, удаляет cookie корзины и перенаправляет покупателя на страницу подтверждения заказа. Это гарантирует корректное завершение платёжного процесса и сохранение актуальных данных в storefront.

Пример

Вы можете ознакомиться с изменениями, внесенными в стартовый шаблон Medusa Next.js Starter Template, в директории .

Полный код интеграции можно посмотреть в разделе сomparison page, откройте вкладку и изучите различия в каталоге . Или запустите в терминале:

git clone https://github.com/gorgojs/medusa-plugins
cd medusa-plugins
git diff @gorgo/medusa-payment-tkassa@0.0.1...main -- examples/payment-tkassa/medusa-storefront

Настройка вебхуков

Чтобы корректно обрабатывать платёжные уведомления от T-Kassa, настройте вебхуки в своём аккаунте T-Business следующим образом:

  1. Перейдите в раздел → Выберите свой магазин → → Выберите или терминал → Нажмите , чтобы открыть окно настроек.

  2. Установите отправку уведомлений .

  3. Укажите URL вида:

    Замените на домен вашей витрины Medusa.

Внимание! T-Kassa ожидает сообщение в ответе, чтобы подтвердить успешную обработку вебхука и избежать повторных уведомлений. В настоящее время Medusa не поддерживает кастомные ответные сообщения вебхуков «из коробки», но сами вебхуки обрабатываются корректно и без этого. Подробнее см. связанное обсуждение.

Разработка

Документацию по развертыванию окружения для разработки можно найти здесь.

Лицензия

Распространяется на условиях лицензии MIT.