Overview
Icon for Robokassa

Robokassa

Accept Robokassa payments

Платежи Robokassa для Medusa

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


Возможности

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

💬 Чат поддержки плагина Robokassa

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

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

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

Требования

Установка

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

Настройка

Добавьте конфигурацию провайдера в Copy to clipboardmedusa-config.js вашего приложения Medusa:

// ...
module.exports = defineConfig({
// ...
modules: [
{
resolve: "@medusajs/medusa/payment",
options: {
providers: [
{
resolve: "@gorgo/medusa-payment-robokassa/providers/payment-robokassa",
id: "robokassa",
options: {
merchantLogin: process.env.ROBOKASSA_MERCHANT_LOGIN,
hashAlgorithm: process.env.ROBOKASSA_HASH_ALGORITHM,
password1: process.env.ROBOKASSA_PASSWORD_1,
password2: process.env.ROBOKASSA_PASSWORD_2,
testPassword1: process.env.ROBOKASSA_TEST_PASSWORD_1,
testPassword2: process.env.ROBOKASSA_TEST_PASSWORD_2,
capture: false, // по умолчанию true
isTest: true, // по умолчанию false

Добавьте следующие переменные окружения: идентификатор магазина Copy to clipboardmerchantLogin, алгоритм подписи Copy to clipboardhashAlgorithm, секретные пароли Copy to clipboardpassword1, Copy to clipboardpassword2, а также тестовые пароли Copy to clipboardtestPassword1, Copy to clipboardtestPassword2:

ROBOKASSA_MERCHANT_LOGIN=test-shop
ROBOKASSA_HASH_ALGORITHM=md5
ROBOKASSA_PASSWORD_1=supersecret
ROBOKASSA_PASSWORD_2=supersecret
ROBOKASSA_TEST_PASSWORD_1=supersecret
ROBOKASSA_TEST_PASSWORD_2=supersecret
Важно! Значение Copy to clipboardROBOKASSA_HASH_ALGORITHM должно совпадать с настройкой в аккаунте Robokassa и быть одним из: Copy to clipboardmd5, Copy to clipboardsha1, Copy to clipboardsha256, Copy to clipboardsha384, Copy to clipboardsha512 или Copy to clipboardripemd160 (обратите внимание: для Copy to clipboardripemd160 возможны ошибки на стороне провайдера).

В настройках магазина Robokassa укажите Метод отправки данных на Result URLCopy to clipboardGET или Copy to clipboardPOST, и задайте Result URL в формате:

https://{YOUR_MEDUSA_DOMAIN}/hooks/payment/robokassa_robokassa

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

Опция Описание Обязательный По умолчанию Copy to clipboardmerchantLogin Идентификатор магазина Robokassa Да - Copy to clipboardhashAlgorithm Алгоритм подписи: Copy to clipboardmd5, Copy to clipboardsha1, Copy to clipboardsha256, Copy to clipboardsha384, Copy to clipboardsha512 Да - Copy to clipboardpassword1 Технический пароль №1 для расчёта подписи при инициализации платежа Да - Copy to clipboardpassword2 Технический пароль №2 для проверки подписи в уведомлениях об оплате Да - Copy to clipboardtestPassword1 Тестовый пароль №1 для подписи в тестовом режиме (если Copy to clipboardisTest=true) Нет - Copy to clipboardtestPassword2 Тестовый пароль №2 для уведомлений в тестовом режиме (если Copy to clipboardisTest=true) Нет - Copy to clipboardcapture Автосписание: Copy to clipboardtrue — 1‑стадийно; Copy to clipboardfalse — предавторизация (двухстадийно) Нет Copy to clipboardtrue Copy to clipboardisTest Включает тестовый режим Нет Copy to clipboardfalse Copy to clipboarduseReceipt Включает формирование онлайн-чеков по 54-ФЗ Нет Copy to clipboardfalse 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 (витриной магазина)

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

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

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

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

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

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

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

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

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

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

При подключении Robokassa настройте политику 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 будет отправляться при кросс-доменных запросах во время процесса редиректа через Robokassa, предотвращая потерю платёжной сессии.

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

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

Откройте Copy to clipboardsrc/modules/checkout/components/payment/index.tsx и обновите логику инициализации платежа, включив в нее данные корзины и URL возврата для Robokassa:

await initiatePaymentSession(cart, {
provider_id: selectedPaymentMethod,
data: {
SuccessUrl2: `${getBaseURL()}/api/capture-payment/${cart?.id}?country_code=${countryCode}`,
SuccessUrl2Method: "GET",
FailUrl2: `${getBaseURL()}/api/capture-payment/${cart?.id}?country_code=${countryCode}`,
FailUrl2Method: "GET",
EMail: cart?.email,
Culture: countryCode === "ru" ? "ru" : "en",
cart: cart
}
})

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

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

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

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

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

const PaymentButton: React.FC<PaymentButtonProps> = ({
cart,
"data-testid": dataTestId,
}) => {
// ...
switch (true) {
// ... другие проверки
case isRobokassa(paymentSession?.provider_id):
return (
<RobokassaPaymentButton
notReady={notReady}
cart={cart}
data-testid={dataTestId}
/>
)
default:
return <Button disabled>Select a payment method</Button>
}
}

Этот компонент находит в активной корзине платёжную сессию Robokassa и читает Copy to clipboarddata.paymentUrl. При клике по Place order пользователь перенаправляется на этот URL, чтобы завершить оплату на странице Robokassa.

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

Родительский Copy to clipboardPaymentButton использует Copy to clipboardisRobokassa, чтобы отрисовать Copy to clipboardRobokassaPaymentButton для текущей сессии; иначе показывается неактивная кнопка Select a payment method.

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

После того как покупатель завершает оплату на странице Robokassa, он перенаправляется обратно на витрину магазина. Необходимо создать 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-роут обрабатывает редирект от Robokassa после попытки оплаты. Он получает актуальное состояние корзины, чтобы убедиться, что все изменения, внесённые во время оплаты, были отражены.

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

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

Пример

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

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

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

Разработка

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

Лицензия

Распространяется на условиях лицензии 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?