Overview
Icon for T-Kassa

T-Kassa

Enable seamless payments with TKassa via Medusa plugin

Платежи T-Kassa для Medusa

Плагин Medusa для приёма платежей через T-Kassa.
Read README in English →


Возможности

  • 🔗 Бесшовная интеграция с платёжной системой 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

Настройка

Добавьте конфигурацию провайдера в файл Copy to clipboardmedusa-config.js в приложении 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"

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

TKASSA_TERMINAL_KEY=123456789
TKASSA_PASSWORD=supersecret

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

Параметр Описание Обязательный По умолчанию Copy to clipboardterminalKey Ключ терминала, предоставленный T-Kassa (обязателен для аутентификации) Да - Copy to clipboardpassword Пароль для подписи запросов (обязателен для аутентификации) Да - Copy to clipboardcapture Определяет тип проведения платежа:
- Copy to clipboardtrue — одностадийная оплата (Copy to clipboardO в API)
- Copy to clipboardfalse — двухстадийная оплата (Copy to clipboardT в API) Нет Copy to clipboardtrue Copy to clipboarduseReceipt Включает формирование онлайн-чеков по 54-ФЗ Нет Copy to clipboardfalse Copy to clipboardffdVersion Версия ФФД: Copy to clipboard1.2 или Copy to clipboard1.05
Применимо только при Copy to clipboarduseReceipt=true Нет - Copy to clipboardtaxation Система налогообложения:
- Copy to clipboardosn — общая СН
- Copy to clipboardusn_income — упрощенная СН (доходы)
- Copy to clipboardusn_income_outcome — упрощенная СН (доходы минус расходы)
- Copy to clipboardesn — единый сельскохозяйственный налог
- Copy to clipboardpatent — патентная СН
Применимо только при Copy to clipboarduseReceipt=true Нет - Copy to clipboardtaxItemDefault Ставка НДС по товарам:
- Copy to clipboardnone — без НДС
- Copy to clipboardvat0 — 0%
- Copy to clipboardvat5 — 5%
- Copy to clipboardvat7 — 7%
- Copy to clipboardvat10 — 10%
- Copy to clipboardvat20 — 20%
- Copy to clipboardvat105 — 5/105
- Copy to clipboardvat107 — 7/107
- Copy to clipboardvat110 — 10/110
- Copy to clipboardvat120 — 20/120
Применимо только при Copy to clipboarduseReceipt=true Нет - Copy to clipboardtaxShippingDefault Ставка НДС для доставки (аналогично Copy to clipboardtaxItemDefault)
Применимо только при Copy to clipboarduseReceipt=true Нет -

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

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

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

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

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

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

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

Откройте Copy to clipboardsrc/lib/constants.tsx и добавьте следующий код:

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")
}

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

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

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

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

Откройте Copy to clipboardsrc/lib/data/cookies.ts и обновите конфигурацию файлов cookie следующим образом:

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

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

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

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

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

Откройте Copy to clipboardsrc/modules/checkout/components/payment/index.tsx и обновите логику инициализации платежа, включив в нее данные корзины и 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 параметры Copy to clipboardSuccessURL и Copy to clipboardFailURL определяют, куда будет перенаправлен покупатель после попытки оплаты. Оба URL динамически формируются на основе базового URL storefront, идентификатора корзины и выбранного кода страны.

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

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

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

Откройте Copy to clipboardsrc/modules/checkout/components/payment-button/index.tsx и добавьте следующий код:

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)
}
}
}

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

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

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

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

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

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

Создайте файл Copy to clipboardsrc/app/api/capture-payment/[cartId]/route.ts со следующим содержимым:

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()) }
// Получить актуальные значения корзины

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

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

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

Пример

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

Полный код интеграции можно посмотреть в разделе сomparison page, откройте вкладку Copy to clipboardFiles changed и изучите различия в каталоге Copy to clipboardexamples/payment-tkassa/medusa-storefront. Или запустите Copy to clipboarddiff в терминале:

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. Перейдите в раздел Copy to clipboardИнтернет-эквайрингCopy to clipboardМагазины → Выберите свой магазин → Copy to clipboardТерминалы → Выберите Copy to clipboardТестовый или Copy to clipboardРабочий терминал → Нажмите Copy to clipboardНастройки, чтобы открыть окно настроек.
  2. Установите отправку уведомлений Copy to clipboardПо протоколу HTTP.
  3. Укажите URL вида: Замените Copy to clipboard{YOUR_MEDUSA_DOMAIN} на домен вашей витрины Medusa.
https://{YOUR_MEDUSA_DOMAIN}/hooks/payment/tkassa_tkassa
Внимание! T-Kassa ожидает сообщение Copy to clipboardOK в ответе, чтобы подтвердить успешную обработку вебхука и избежать повторных уведомлений. В настоящее время Medusa не поддерживает кастомные ответные сообщения вебхуков «из коробки», но сами вебхуки обрабатываются корректно и без этого. Подробнее см. связанное обсуждение.

Разработка

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

Лицензия

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

You may also like

Browse all integrations

Build your own

Develop your own custom integraiton

Build your own integration with our API to speed up your processes. Make your integration available via npm for it to be shared in our Library with the broader Medusa community.

gift card interface

Ready to build your custom commerce setup?