Декомпозиция BR 3.3 — PayKeeper Adapter P0

Источник

Затронутые сервисы / репозитории

СервисПортРепоЗадачи
Paykeeper Adapter (новый):3015erp-paykeeper-adapter (создать)Paykeeper Adapter
Catalog Service:3004erp-catalog-serviceCatalog Service
Order Service:3005erp-order-serviceOrder Service
Admin BFF:3020erp-admin (bff/)Admin BFF
Admin Franchise web:3020erp-admin (web/)Admin Franchise
Store Service:3003erp-store-service— изменений нет (adapter использует существующий GET /internal/stores/{id})
User Service:3002erp-user-service— изменений нет (adapter использует GET /internal/legal-entities/{id})
Nginx / Infrastructureerp-infrastructureDocker Compose entry :3015 + nginx route /pk-webhooks/*

POS (KOALa + наш legacy) — не трогаем в P0.

Последовательность выполнения

  1. Catalog Service — миграция 026 (vat_rate, payment_subject, payment_type на products) + Entity/DTO/API. Нужна первой, потому что Order Service на checkout’е будет читать эти поля для формирования fiscal_cart.
  2. Paykeeper Adapter (параллельно с 1) — создание репо, скелет Spring Boot, все таблицы, HTTP-клиент PK, webhook-receiver, outbox-worker, Kafka consumers/producers. Большой объём.
  3. Order Service — миграция 010 (pk_invoice_id, pk_invoice_url, pk_payment_id, pk_fop_receipt_key, fiscal_data, fiscal_failed) + Entity + Kafka consumers для paykeeper.* events + producer order.payment_requested / order.refund_requested + endpoint POST /internal/orders/{id}/refund (если ещё нет — надо создать).
  4. Admin BFF — прокси /api/v1/admin/paykeeper/*:3015/internal/paykeeper/*. Обновить shared types.
  5. Admin Franchise web — вкладка «PayKeeper» в карточке ЮЛ, секция в карточке ТТ, фискальные атрибуты в товаре, кнопка возврата и секция фискальных данных в карточке заказа.
  6. Infrastructure — добавить paykeeper-adapter в docker-compose, nginx route /pk-webhooks/*:3015, envs (секреты).

Риски / открытые вопросы на реализацию

  • Формат подписи informer — MD5 подтверждён боевым Koala-кодом. Убедиться что PK-инсталляция на test-стенде тоже MD5 (некоторые новые версии могут использовать HMAC-SHA256 с отдельным конфигом).
  • Длина orderid — передаём packed base64url(store_id_short:order_number). У PK нет документированного лимита — проверить на первом же запросе что влезает.
  • informer_seed генерация — мы принимаем от пользователя; альтернативно могли бы генерировать и пушить через /change/organization/setting/. В P0 — ручной ввод.
  • Dead-letter для outbox — после 10 попыток уведомление в админку; обсудить SLA.
  • Migration default для существующих товаровvat20/goods/full ставим всем подряд; бухгалтерия должна проверить если есть нестандартные категории.
  • orders.pk_invoice_id UNIQUE или нет? — один заказ — один инвойс. Делаем UNIQUE но с possibility revoke + пересоздать при TTL.
  • Кнопка Вернуть для legacy-заказов (без pk_payment_id) — в P0 не делаем, показываем «legacy-возврат недоступен в админке».

Прогресс

  • Catalog Service — миграция 026 + entity + DTO + enum-валидация + ProductService wiring (commit 84092ee)
  • Paykeeper Adapter — полная реализация: skeleton (commit 0477d3a) + бизнес-логика (commit 0947f80): security chain (JwtFilter/ServiceTokenFilter), PayKeeperClient со всеми PK endpoint’ами + Redis token cache + retry, SignatureValidator (MD5 + HMAC-SHA256), Account/Terminal CRUD controllers, 3 webhook receivers (informer/refund/receipt) с dedup + FiscalFetcher async, OrderEventsConsumer → outbox, PkOutboxWorker (exp backoff, dead_letter), InvoiceCheckScheduler (25мин+5мин poll), StuckReconcileJob (03:00 cron), RetentionJob (90д).
  • Order Service — миграция 010 + Order/RefundRecord entity (PK-поля + fiscal_data + status/error_message + cashier_id nullable) + PaykeeperEventConsumer (6 топиков) + publishPaymentRequested/publishRefundRequested + POST /internal/orders/{id}/request-payment + OrderResponse PK-поля (commit 579b4f3)
  • Admin BFF — прокси /api/v1/admin/paykeeper/* (14 endpoints) + config var + shared types (Product.vat_rate + Order.pk_* + FiscalData + PaykeeperAccount/Terminal/WebhookLog) (commit 70f3c4f)
  • Admin Franchise web — api/paykeeper.ts + PaykeeperTab (карточка ЮЛ) + PaykeeperTerminalSection (карточка ТТ) + webhook URLs modal (commit 7e52bc6) + фискальные атрибуты в товаре (3 select’а vat_rate/payment_subject/payment_type в Create/Edit) + секция «Фискальные данные» в карточке заказа (ФН/ФД/ФПД/смена/чек + ссылка «Открыть чек») + badge fiscal_failed (commit 92772e1)
  • Infrastructure — docker-compose (service paykeeper-adapter :3015) + nginx route /pk-webhooks/* (commit e35c5cc). Env файлы на VPS заливать вручную (инструкция в commit-message)
  • Deploy — ждёт env-провижининга на VPS + provisioning второго sandbox PK (чтобы не перебивать webhook у Koala)

Sandbox credentials

Получены 2026-04-23: koala-test.server.paykeeper.ru, admin / DX75^[<q, informer_seed=S=._E=rQgrEQ(8Ihbo8. Сохранены в memory reference_paykeeper_sandbox.md. Важно: webhook на этом ЛК уже указывает на Koala_TG_app — переключать с согласия коллеги или запросить второй sandbox.

Ссылки