Skip to content

YooKassa (ЮKassa)

Основная российская касса: карта, СБП, SberPay. Валюта — RUB. Интеграция через API v3: юзер уходит на платёжную страницу ЮKassa по редиректу, подтверждение приходит вебхуком.

Самый «полный» шлюз в базе: единственный из рублёвых умеет возвраты по API, сохранённые карты и автосписания (автопродление подписки без участия юзера).

Что понадобится

Магазин в личном кабинете ЮKassa. Оттуда — две креды:

  • shopId — идентификатор магазина;
  • секретный ключ API.

Для автосписаний дополнительно нужны включённые рекуррентные платежи на стороне ЮKassa — это отдельное соглашение с кассой. Без него платёж с сохранением карты получит 400.

Настройка в кабинете

ПолеЧто этоОбязательное
shop_idshopId магазинаДа
secret_keyСекретный ключ API (шифруется Fernet при сохранении)Да
return_urlКуда вернуть юзера после оплаты. Если пусто — https://t.me; при оплате из мини-аппы подставляется URL мини-аппыНет
recurrent_enabledtrue — платежи создаются с save_payment_method, карта сохраняется для автосписаний. Требует включённого рекуррента на стороне ЮKassaНет

Включение — переключатель активности в карточке; после этого способ появляется у юзеров в боте и мини-аппе. Кнопка «Тест» дергает GET /v3/me с вашими кредами и показывает id и статус магазина — сразу видно, приняты ли ключи.

Вебхук

URL для уведомлений: https://ваш-домен/api/v1/payments/yookassa — укажите его в кабинете ЮKassa как адрес HTTP-уведомлений о платежах.

Уведомления ЮKassa не подписаны, поэтому шлюз им не верит на слово: по id платежа из уведомления он перезапрашивает платёж через API (Basic-auth shop_id:secret_key) и берёт статус, сумму и метаданные только из ответа API. Это надёжнее IP-allowlist'ов, которые ломаются за прокси. Если перезапрос не удался, шлюз отвечает не-2xx — ЮKassa пришлёт уведомление повторно, платёж не потеряется.

Маппинг статусов:

Статус ЮKassaТранзакция
succeededЗавершена, покупка фулфиллится
canceledОтменена
waiting_for_capture, pendingОстаётся в ожидании

Особенности

  • Идемпотентность списаний. Платёж создаётся с заголовком Idempotence-Key, равным внутреннему payment_id, — ретраи создания никогда не спишут деньги дважды.
  • Возвраты по API. POST /v3/refunds, один полный возврат на платёж (идемпотентный ключ refund-<id платежа>). Кнопка возврата в кабинете работает при включённом REFUND_ENABLED (по умолчанию выключен); подробнее — /payments/refunds.
  • Сохранённая карта. При recurrent_enabled вебхук возвращает сохранённый метод оплаты — его id хранится у юзера в зашифрованном виде, юзеру показывается название вида «Bank card *1234».
  • Автопродление. Фоновая задача сначала пытается продлить с внутреннего баланса; если денег не хватает и юзер включил списание с карты — заряжает сохранённую карту без шага подтверждения (charge_saved). Неудачная попытка по карте не долбится в каждом цикле: повтор не чаще, чем раз в ~20 часов.
  • Поллинг статуса есть — это один из немногих шлюзов, где реконсилятор может сам опросить API и добить платёж, даже если вебхук так и не дошёл.

Платёж не пришёл?

Реконсилятор каждые 5 минут опрашивает зависшие платежи через API ЮKassa и доводит их до конца — потерянный вебхук не теряет деньги. Подробнее: /payments/webhooks.

MIT License · сделано для тех, кто продаёт VPN, а не настраивает ботов