feat(payments): report direct-rail income to «Мой налог» #295
Reference in New Issue
Block a user
Delete Branch "feature/mynalog-export"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Registers the direct rail's rouble income with the professional-income tax service, annuls the receipt on a refund, and hands the buyer the receipt by email. Decisions D53-D60 (
docs/PAYMENTS_DECISIONS_ru.md).Why
On НПД the provider neither files with the tax service nor issues a receipt, so nobody was doing it. Doing it by hand stops scaling at the first hundred purchases a week, and the buyer currently gets nothing at all — neither a confirmation nor the receipt ст. 14 ФЗ-422 requires.
What shapes the design
The lknpd API is unofficial: no contract, no sandbox, and
POST /incometakes no idempotency key. So:Shape
backend/internal/mynalog— API client, no database.backend/internal/mynalogsync— orchestration. OneRunBatchserves both the console button (100 s budget) and the worker (13 min); there is no second implementation of the part that decides what a failed registration means./_gm/mynalog.csvlists exactly what would be sent, and a receipt filed by hand can have its number entered back — which keeps it annullable on a refund.payments.payment_eventsoutbox on its ownmailed_atcursor; the receipt and annulment letters ride columns on the export row.BACKEND_MYNALOG_KEY(our own 32 bytes, not a tax-service secret), so it does not travel in a database dump.Migration
00019_mynalog.sql— two new tables plus one nullable column. Strictly additive: applies forward with no data rewrite (no contour wipe) and an image rollback ignores it.Owner-side steps before deploy
openssl rand -base64 32) and add Gitea secretsPROD_MYNALOG_KEYandTEST_MYNALOG_KEY. Without them the rail stays dormant — no console section, no workers — so the PR is safe to merge before they exist.PROD_MYNALOG_TZ/TEST_MYNALOG_TZvariables; they default toEurope/Moscow.Verification
gofmt -l .clean;go build+go vetacross backend, gateway, telegram, loadtest.uijob is untouched (no file underui/).Not covered, deliberately
VK Votes and Telegram Stars: the ledger holds no rouble amount for them at all, and VK pays as a legal entity (6%, its INN in the receipt). Partial refunds stay manual on both sides, as they already were.
Cannot be verified before prod
«Мой налог» has no test environment — every call lands on a real tax account. Whether
/api/v1/receipt/<ИНН>/<uuid>/printis publicly readable is genuinely unknown (sources contradict), so the owner's own first real purchase decides whether the emailed link stands or we render the receipt ourselves. There are zero real direct payments on prod today, which is why that window is free.Catalog titles already name the pack ("50 фишек"), so appending the chip count produced "50 фишек — 50 фишек, 79.00 ₽". The letter now carries the title exactly as the storefront shows it, then the price. The tax receipt is unaffected: it states the quantity in the wording the tax service wants, which is a separate surface with separate requirements.