Шаг 0.13 плана production-готовности: - интерфейс PaymentProvider (createPayment/verifyWebhook/getPaymentStatus) - MockPaymentProvider с настоящим webhook (sha256-подпись, идемпотентность) - applySucceededPayment: транзакция с guard, credit, авто-снятие billingBlocked - роуты payments + confirm-test (только mock) + публичный webhook - Billing.tsx: Пополнить/Подтвердить (тест), фикс setLocation в рендере - миграция 0080 billing_payments, 13 новых тестов (78/78)
23 lines
1.1 KiB
SQL
23 lines
1.1 KiB
SQL
-- Шаг 0.13 плана production-готовности: платежи самообслуживания биллинга.
|
||
-- Пополнение баланса админом организации через платёжного провайдера (сейчас — mock).
|
||
-- Без RLS: запись — только серверные роуты (auth + billing.manage) и webhook провайдера,
|
||
-- чтение — только через роуты с явным фильтром organization_id.
|
||
CREATE TABLE IF NOT EXISTS billing_payments (
|
||
id SERIAL PRIMARY KEY,
|
||
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
||
provider VARCHAR(30) NOT NULL,
|
||
external_id VARCHAR(255) NOT NULL,
|
||
amount NUMERIC(10,2) NOT NULL,
|
||
currency VARCHAR(10) NOT NULL DEFAULT 'RUB',
|
||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||
idempotency_key VARCHAR(255) NOT NULL,
|
||
metadata JSONB,
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
updated_at TIMESTAMP DEFAULT NOW(),
|
||
UNIQUE (external_id),
|
||
UNIQUE (idempotency_key)
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS billing_payments_org_status_idx
|
||
ON billing_payments (organization_id, status);
|