Оплата и подписка
Тариф покупается картой на странице платёжного провайдера. Предиктека не видит данных карты и поэтому не попадает в область PCI DSS: браузер уходит на страницу провайдера, а к нам возвращается только состояние заказа.
Что происходит при покупке
- Владелец или администратор нажимает «Перейти» у нужного тарифа.
- Кабинет сначала записывает заказ — номер, тариф, сумму — и только потом идёт к провайдеру. Поэтому уведомление, пришедшее на неизвестный номер, не может поднять тариф: такого заказа здесь нет.
- Человек платит на странице провайдера и возвращается в кабинет.
- Провайдер присылает уведомление. Оно подписано ключом установки, проверяется по телу запроса и зачитывается ровно один раз.
Период считается от даты окончания текущего, а не от сегодняшнего дня: продление заранее не съедает уже оплаченные дни.
Кто платит
Купить или продлить тариф может владелец и администратор workspace. Участник видит тариф, цену и дату окончания, но кнопки оплаты у него нет: он не отвечает за счёт.
Что приходит от провайдера
Уведомление (IPN) — это JSON с подписью в заголовках. Предиктека отвечает 200 на всё, что
поняла, включая повтор: провайдер повторяет отправку до пятидесяти раз в течение семи дней, и
200 на повтор — это способ остановить очередь, а не признание, что что-то изменилось.
Отказы:
| Ответ | Когда |
|---|---|
401 |
подпись не сходится или ключ принадлежит другому продавцу |
400 |
тело не разобрано, нет номера заказа, либо сумма не совпадает с заказом |
503 |
на установке не настроена оплата — обещать «принято» нельзя |
200 |
всё понято: оплачено, отклонено, возвращено, повтор, или заказ не наш |
Сумма проверяется по заказу. Уведомление, которое зачитывает месяц за один рубль, — это либо ошибка, либо попытка, и без сверки они выглядят одинаково.
Возврат
На странице «Тарифы» у оплаченного заказа есть «Вернуть». Запрос уходит провайдеру, заказ помечается возвращённым, событие пишется в журнал.
Тариф при возврате не снимается автоматически: человек мог уже напечатать документы. Если нужно закрыть доступ, это отдельное, видимое действие. Возврат закрывает заказ: даже если после него придёт запоздавшее «оплачено», второго месяца за те же деньги не будет.
Когда период заканчивается
Период заканчивается в дату, которую никто не караулит. Раз в шесть часов прогон проверяет workspace с датой окончания и переводит просроченные на бесплатный тариф:
- документы, справочники и участники остаются;
- шаблоны, исследования и лишние участники становятся недоступны;
- в кабинете за неделю до конца появляется предупреждение.
Прогон живёт в Temporal (ExpireSubscriptions), а не в кабинете: срок истекает и тогда, когда
никто не открывает страницы. Он запускается один раз на установку и переживает перезапуск воркера.
Настройка
export YPMN_BASE_URL=https://sandbox.ypmn.ru/api # боевой: https://secure.ypmn.ru/api
export YPMN_MERCHANT=MERCHANT_CODE # «Код продавца» в кабинете провайдера
export YPMN_SECRET=... # «Секретный ключ», только в окружении
Без YPMN_MERCHANT и YPMN_SECRET установка работает, но кнопок оплаты нет: страница говорит,
чего не хватает, вместо кнопки, которая падает.
Два секрета установки: YPMN_SECRET подписывает запросы и проверяет уведомления, HUB_SECRET
подписывает сессии. Оба живут в окружении, не в репозитории и не в образе.
Адрес для уведомлений
В кабинете провайдера регистрируется адрес установки:
https://<адрес установки>/payments/ipn
Адрес публичный — провайдер не держит сессию — и защищён подписью, а не списком адресов. Если
установка стоит за прокси, который переписывает путь, подпись всё равно сходится: проверяются и
путь запроса, и X-Forwarded-Uri.
Налоги
Ставка НДС уходит в заказе построчно; по умолчанию 22%. Это значение — для бухгалтера клиента, а не для кода: если у продавца другая ставка или другая страна, она задаётся в позиции заказа.