▤ Руководства

Коммерция

Содержание

Включение

  1. Тарифы включены (SEOMASTER_PLANS=1 или «Админка → Тарифы»).
  2. «Админка → Оплата»: цены (₽ за месяц, при желании за 12 месяцев), НДС, реквизиты продавца. Пока нет ни одной цены, оплата выключена и всё работает как раньше (plans_contact).
  3. Карты и СБП: SEOMASTER_YK_SHOP, SEOMASTER_YK_KEY (+ SEOMASTER_YK_RECEIPT=1, чтобы ЮKassa пробивала чек 54-ФЗ). В кабинете ЮKassa укажите адрес уведомлений <base_url>/billing/webhook/yookassa (события payment.succeeded, payment.canceled). SEOMASTER_BASE_URL желательно задать.
  4. Cron: 37 6 * * * php bin/billing.php.

Настройки хранятся в storage/commerce.json (ключи ЮKassa туда не пишутся).

Правила

  • Суммы — в копейках. Счёт: new → pending → paid / canceled / expired / refunded. Счёт на 1/3/6/12 месяцев; 12 месяцев — годовая цена, если задана.
  • Оплата идемпотентна (атомарный переход статуса): повторный вебхук или кнопка не продлевают тариф дважды. Просроченный или отменённый счёт при поступлении денег оплачивается.
  • Продление: тот же тариф — от конца текущего срока; другой тариф — от даты оплаты, а неиспользованный остаток прежнего тарифа зачитывается в цену (v89, см. ниже).
  • Вебхук ЮKassa не подписан: по id платежа запрашиваем платёж у ЮKassa и сверяем метку счёта, сумму, валюту и статус. Несовпадение суммы — событие владельцу, тариф не продлевается. Если проверка не удалась, вебхук отвечает 502 и ЮKassa повторит.
  • Возврат (v89): карта и СБП — через API ЮKassa, сумма полная или частичная; для счетов на перевод и ручных оплат — отметка (деньги возвращаются в банке). Счёт остаётся «Оплачен» до полного возврата, затем «Возврат»; полный возврат с опцией «снять тариф» переводит пользователя на тариф по умолчанию и удаляет сохранённую карту.
  • Счета остаются при удалении аккаунта (бухгалтерский учёт; в них e-mail и название плательщика), входят в выгрузку данных пользователя без ключей платёжной системы.

Затраты, перерасход, экономика

  • Расход берётся из pv_usage; стоимость = единицы × цена за 1000. Цена: персональная из бюджета пользователя, иначе общая («Экономика → Цены»). Провайдер без цены считается как 0 и подсвечивается.
  • Бюджет затрат месяца: события владельцу при 80% и 100%. Потолок на пользователя по тарифу: событие «перерасход» (до 10 за запуск).
  • Выручка по начислению: оплата на N месяцев делится на N месяцев с месяца оплаты. Тариф в разрезе — текущий, поэтому прошлые месяцы приблизительны.

Зачёт остатка (v89)

  • Условие: пользователь платит за другой тариф, его текущий срок не истёк, это не пробный период и тариф куплен (а не выдан владельцем).
  • Расчёт: оставшиеся дни × уплаченное за день. Счета текущего тарифа берутся от новых к старым, каждый покрывает свой срок (месяц = 30,4375 дня); вычитаются частичные возвраты. Зачёт не превышает цену минус 1 ₽.
  • Счёт хранит credit, credit_plan, credit_until. После оплаты любого счёта остальные открытые счета с зачётом отменяются (цена считалась от прежнего тарифа). Если тариф изменился между выпиской и оплатой счёта, оплата проходит, но в журнале появляется credit-stale и событие владельцу — зачёт проверяется вручную.
  • Выручка по начислению старого тарифа продолжает делиться на прежние месяцы (приближение).

Автопродление (v89)

  • Включается галочкой при оплате картой («Запомнить карту…»); согласие пишется в журнал счёта. В платеже передаётся save_payment_method; если банк карту не сохранил, автопродления нет. Хранится только токен способа оплаты и подпись («Visa •••• 4242»).
  • bin/billing.php (или кнопка «Закрыть просроченные…» в админке): за 3 дня до конца срока для того же тарифа и срока выписывается счёт (auto=2) и отправляется платёж без участия пользователя; ключ идемпотентности — sm-inv-<id>. Платёж в обработке ждёт сверки (вебхук или cron), второй счёт не выписывается.
  • Неудача (отказ банка, требование 3-D Secure, ошибка связи): счёт отменяется, повтор через 1 и 2 суток; третья неудача отключает автопродление, пользователь получает событие и письмо. Отключается также при истёкшем сроке (+3 дня), снятом с продажи тарифе, выключенной функции. Бессрочные тарифы пропускаются.
  • Пользователь управляет на странице «Оплата» (отключить / включить / забыть карту), владелец — в «Админка → Оплата». Удаление аккаунта удаляет карту.

Ограничения

Нет собственных фискальных чеков и закрывающих документов, автоматической блокировки при перерасходе затрат (только события), уведомления о возврате по вебхуку refund.succeeded (статус возврата не перепроверяется). Счёт — информационная форма: подпись, печать и соответствие налоговому режиму проверяет бухгалтер. ЮKassa проверена только на подставных ответах, не на реальном магазине.