Перейти к содержанию

ЮKassa: магазин ИП Головин Артём Романович

Задача: TODO #43
Компания в CRM: korobochka
Статус: активна в production с 26.08.2026 Назначение: розничные заявки и покупки с сайта. Для ИП Головин Роман ЮKassa не используется, оплата идёт банковским переводом.

Архитектурное решение

  • В production используется один магазин ЮKassa, зарегистрированный на ИП Головин Артём Романович.
  • Новая заявка с сайта без назначенного ИП по умолчанию оплачивается через korobochka.
  • Если менеджер назначил заявке ИП Головин Роман, backend блокирует создание платежа ЮKassa.
  • Для счёта из заявки магазин определяется по quick_orders.own_company_id.
  • Для счёта без заявки требуется invoices.md_company_code=korobochka, иначе онлайн-оплата блокируется как неоднозначная.
  • Код компании передаётся в metadata.companyCode платежа.

Защита реализована в PR alatyr-service #82.

Обязательный чек 54-ФЗ и корректный возврат после оплаты реализованы в:

  • PR #83 — безопасная диагностика ошибок API без Shop ID и секретного ключа;
  • PR #84 — объект receipt;
  • PR #85 — возврат клиента в существующий маршрут /#/dashboard;
  • PR #86 — доступный раздел «Счета» в админке, возврат администратора к счетам, обновление данных после оплаты, назначение и дата оплаты в карточке заявки, а также явная диагностика блокировки автоконвертации;
  • PR #87 — повторная автоконвертация оплаченной заявки после сохранения недостающих данных объекта;
  • PR #88 — финансовая сводка заявки, отдельная карточка платёжного счёта и переход к ней из заявки, общего списка счетов и связанного объекта.

Финансовая сводка заявки

  • До появления основного договора итоговая сумма берётся из сохранённой сметы заявки (quick_orders.amount).
  • После появления договора приоритет получает сумма последнего основного договора. Повторные версии основных договоров не суммируются.
  • Если договор отличается от сметы, карточка показывает величину расхождения. Пояснение берётся из последнего допсоглашения, затем из комментария договора.
  • «Выставлено» считается по всем неотменённым платёжным счетам заявки.
  • «Оплачено» считается только по платежам со статусом succeeded; рядом показываются общая сумма и остаток.
  • Карточка платёжного счёта показывает назначение, плательщика, получателя, связь с заявкой и объектом, сумму, остаток и историю платежей.
  • В объекте отдельно показаны платёжные счета и сформированные PDF-счета. Статус оплаты является свойством платёжного счёта из таблицы invoices; PDF-документ object_contracts.kind=invoice сам по себе такого статуса не имеет и отображается как скачиваемый документ.

Параметры чека 54-ФЗ

Подтверждённые владельцем параметры ИП Головин Артём Романович:

  • система налогообложения: УСН «доходы», tax_system_code=2;
  • НДС: без НДС, vat_code=1;
  • способ расчёта: полная оплата, payment_mode=full_payment;
  • предмет расчёта: service для услуг, commodity для shop_order;
  • контакт покупателя: email, при его отсутствии телефон;
  • одна позиция чека равна полной сумме платежа.

ЮKassa требует передавать receipt для этого магазина. Без него API отвечает HTTP 400: Receipt is missing or illegal.

Переменные production

Файл на VPS: /etc/alatyr-service.env, права 600, владелец root:root.

YOOKASSA_SHOP_ID=<идентификатор магазина>
YOOKASSA_SECRET_KEY=<секретный ключ>
YOOKASSA_COMPANY_CODE=korobochka

Значения YOOKASSA_SHOP_ID и YOOKASSA_SECRET_KEY запрещено записывать в Git, KB, чат и команды shell. Секретный ключ хранится в Vaultwarden и показывается ЮKassa только при выпуске.

Получение реквизитов

  1. В кабинете ЮKassa открыть «Настройки» → «Магазин» и скопировать shopId.
  2. Открыть «Интеграция» → «Ключи API».
  3. Выпустить секретный ключ и подтвердить действие кодом из SMS.
  4. Сразу сохранить оба значения в Vaultwarden в записи ЮKassa - ИП Головин Артём (Коробочка).

Официальная документация:

  • https://yookassa.ru/docs/support/merchant/payments/implement/keys
  • https://yookassa.ru/developers/using-api/interaction-format

Webhook

В кабинете ЮKassa открыть «Интеграция» → «HTTP-уведомления» и указать:

https://alatyr-service.ru/api/yookassa/webhook

События:

  • payment.succeeded
  • payment.canceled
  • payment.waiting_for_capture

Endpoint работает по HTTPS на 443 и дополнительно проверяет IP-адреса ЮKassa. YOOKASSA_SKIP_IP_CHECK в production не включать.

Официальная документация:

  • https://yookassa.ru/developers/using-api/webhooks

Выполненная активация

  1. PR #82–85 смержены, production deploy завершён успешно.
  2. Переменные добавлены в /etc/alatyr-service.env безопасным вводом.
  3. /api/yookassa/status проверен: enabled=true, testMode=false, companyCode=korobochka.
  4. Webhook настроен в кабинете ЮKassa.
  5. Контрольный счёт 2026-0003 на 1 ₽ оплачен 26.08.2026.
  6. Создание платежа вернуло HTTP 201.
  7. Webhook payment.succeeded вернул HTTP 200 и применил локальный статус succeeded.
  8. В production-базе подтверждены: payments.status=succeeded, invoices.status=paid, quick_orders.payment_status=paid.
  9. Тестовая заявка №10 не конвертирована в объект до заполнения обязательных полей: название объекта, адрес объекта и типы объекта.

Откат

Удалить из /etc/alatyr-service.env:

YOOKASSA_SHOP_ID
YOOKASSA_SECRET_KEY
YOOKASSA_COMPANY_CODE

Затем выполнить systemctl restart alatyr-service. Без ключей модуль возвращается в выключенный режим, а /api/yookassa/status показывает enabled=false.