feat(payments): per-channel Robokassa shops on the direct rail
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 19s
CI / ui (pull_request) Successful in 1m16s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 2m0s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 19s
CI / ui (pull_request) Successful in 1m16s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 2m0s
Split the single Robokassa direct rail into one merchant shop per channel (web / android; ios later), chosen by the trusted X-Platform subtype, while every shop still credits the one `direct` wallet — merchant-account separation for accounting and receipts, not a new wallet. - config: a channel-keyed shops registry (web seeds from the legacy vars or _WEB_*, android from _ANDROID_*); an empty shop leaves the rail dormant; per-shop validation. - intake: the order picks its shop by subtype (unknown falls back to web); the per-shop Result callback is verified by that shop's own Password2 at /pay/robokassa/result/<channel> (the gateway extracts the channel; Caddy's /pay/* glob already forwards it — no Caddyfile change). - persistence: an additive `shop` column on the order (migration 00015), recorded from the payment context, surfaced per entry in the admin report. - standalone apps sign in by email only, so a direct purchase keeps its email anchor. - docs: PAYMENTS (+ru) topology, deploy env vars + compose mapping, the decisions log (D41 revised for the ИП / 54-ФЗ move; D42-D44), the plan. Contour-safe: dormant until shops are configured; the migration is additive (no wipe); no client wire change. Fiscalization (Receipt/Email) and the gateway `direct/android` subtype follow when the ИП / RuStore are live.
This commit is contained in:
@@ -234,11 +234,40 @@ web+PWA / native Android+iOS через Capacitor). Владелец (самоз
|
||||
- **D40. Финансовый отчёт per-user в `/_gm`** — балансы сегментов, платежи, траты,
|
||||
гранты, возвраты, полная история — расширение существующей карточки
|
||||
(`UserDetailView`, `handlers_admin_console.go:343`). Плюс экспорт журнала (D27).
|
||||
- **D41. Налоги/чеки — авто через провайдера.** **Robokassa** (direct) — авточек НПД
|
||||
(режим самозанятого). **VK** — сам процессит Голоса через налоговую (владельцу делать
|
||||
нечего). **TG Stars** — налоговой стороны нет (для РФ-самозанятого невыводимы легально
|
||||
= не доход по НПД; принимаем, чек не формируем). ОРД по VK-рекламе — на стороне VK.
|
||||
*(Не юридическая консультация — точную схему НПД владелец сверяет с налоговой стороной.)*
|
||||
- **D41. Налоги/чеки — авто через провайдера (ревизия: владелец переходит на ИП).**
|
||||
**Robokassa** (direct) — фискальный чек по **54-ФЗ** через облачную кассу Robokassa
|
||||
(провайдер как фискальный агент): чек формирует касса, не банк (банковский слип об оплате —
|
||||
отдельный документ, не фискальный чек). Настраивается владельцем в ЛКК Robokassa
|
||||
(касса + ОФД + СНО). Код — опционально: слать детализированный `Receipt` + `Email`
|
||||
покупателя (берём подтверждённый email-якорь D36) → чек с точным названием пакета и ставкой
|
||||
по СНО; иначе — обобщённый дефолт-чек из кабинета. `Receipt` входит в подпись
|
||||
(`MerchantLogin:OutSum:InvId:Receipt:Пароль#1`, URL-кодируется), одна позиция влезает в
|
||||
текущий GET-redirect (POST-форма — фолбэк на длину URL). Источник чеков один — ИП/касса,
|
||||
независимо от числа магазинов Robokassa. **VK** — процессит Голоса через налоговую сам.
|
||||
**TG Stars** — вне рублёвого фискального контура (принимаем, чек не формируем). ОРД по
|
||||
VK-рекламе — на стороне VK. *(Не юрконсультация — схему по 54-ФЗ/СНО владелец сверяет с
|
||||
бухгалтером.)*
|
||||
- **D42. Direct-рельс — несколько магазинов Robokassa = маршрутизация merchant-аккаунтов по
|
||||
каналу при едином кошельке.** Кошелёк `direct` остаётся один. Отдельные магазины Robokassa
|
||||
(web, android; ios — позже) различаются только кредами / Return-URL / учётом и **все
|
||||
зачисляют в сегмент `direct`**. Модель кошельков, стенка трат и origin бенефитов не меняются.
|
||||
Магазин выбирается по трастовому сигналу канала (`X-Platform` вида `<kind>/<subtype>`:
|
||||
`direct/web`, `direct/android`), а не по подделываемому клиентскому полю; неизвестный подтип
|
||||
→ магазин `web` (безопасный дефолт). Зачисление от выбора магазина не зависит (всегда
|
||||
`direct`), поэтому ошибка маршрутизации влияет максимум на учёт, не на деньги.
|
||||
- **D43. Standalone-приложения (Android, iOS) — вход только по email; покупка требует
|
||||
email-якорь.** В нативной сборке доступны только guest + email: VK ID-логин (full-page
|
||||
redirect на `id.vk.com`) не возвращается в Capacitor, TG Login Widget в WebView ненадёжен —
|
||||
это уже действующая реальность сборки, не новое ограничение. Direct-покупка требует
|
||||
подтверждённого email-якоря (D36) — он же адрес фискального чека (D41); гость не покупает.
|
||||
Отдельный сегмент `apple` НЕ заводим: iOS-standalone — тот же `direct`-контекст, внешний гейт
|
||||
(Robokassa) фондирует единый `direct`. Сегмент `apple` со стенкой (по образцу vk/tg)
|
||||
понадобился бы только при Apple IAP (StoreKit) — отложено до решения по iOS; и identity-kind
|
||||
`apple→direct`, и отдельный сегмент — аддитивны, без риска, делаются на месте.
|
||||
- **D44. Канал платежа хранится на заказе для раздельного учёта/отчёта.** Заказ получает поле
|
||||
`shop` (web/android/…) — аддитивная колонка. Используется в финансовом отчёте (D40) для
|
||||
разбивки «из какого магазина/канала платёж». На зачисление и на сегмент кошелька не влияет
|
||||
(всегда `direct`, D42).
|
||||
|
||||
## Заметки к оформлению документов
|
||||
|
||||
@@ -254,10 +283,15 @@ web+PWA / native Android+iOS через Capacitor). Владелец (самоз
|
||||
ведёт к пропускам. Текст — только для фиксации решённого и пояснений. Усилить
|
||||
feedback-память `prefer-interview-mode` после plan mode.
|
||||
|
||||
## Все развилки закрыты (D1-D41)
|
||||
## Все развилки закрыты (D1-D44)
|
||||
|
||||
Интервью завершено. Дальше — оформление документов и реализация по релизам.
|
||||
|
||||
**Дополнение 2026-07-14 (интервью с владельцем).** D41 ревизована (владелец переходит на
|
||||
ИП: 54-ФЗ через облачную кассу Robokassa вместо авточека НПД); добавлены D42-D44 — сплит
|
||||
`direct`-рельса Robokassa на магазины по каналу (web/android; ios позже) при едином кошельке
|
||||
`direct` и входе email-only в standalone-приложениях. Реализация — новый этап E10 в `PLAN.md`.
|
||||
|
||||
## План внедрения (черновик PLAN.md — «слоями»)
|
||||
|
||||
Владелец выбрал слоёную стратегию: сначала вся механика без реальных денег (обкатка
|
||||
|
||||
Reference in New Issue
Block a user