mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
Replace iframe-based external payment with native implementation: Backend (Go): - 5 new Ent schemas: PaymentOrder, PaymentAuditLog, PaymentChannel, SubscriptionPlan, PaymentProviderInstance - 5 SQL migrations (090-094) - Payment provider interface + registry + load balancer - 4 provider implementations (EasyPay, Alipay, WxPay, Stripe) - PaymentService (order lifecycle, fulfillment, refund 3-phase) - PaymentConfigService (settings, instance/channel/plan CRUD) - 31 API endpoints (9 user + 4 webhook + 18 admin) - Wire DI integration Frontend (Vue3): - Payment types, API modules, store, router changes - Sidebar: payment_enabled controls visibility, new menu items - User pages: PaymentView (replace iframe), QR payment, Stripe, result page, order list - Admin pages: Order management (4 tabs), provider instance mgmt - Settings: new payment tab, removed old purchase iframe config - i18n: full payment namespace (en + zh) Docs: - PAYMENT_FRONTEND_MIGRATION_PLAN.md - PAYMENT_BACKEND_MIGRATION_PLAN.md - PAYMENT_IMPLEMENTATION_ROADMAP.md
48 lines
2.0 KiB
SQL
48 lines
2.0 KiB
SQL
CREATE TABLE IF NOT EXISTS payment_orders (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT NOT NULL,
|
|
user_email VARCHAR(255) NOT NULL DEFAULT '',
|
|
user_name VARCHAR(100) NOT NULL DEFAULT '',
|
|
user_notes TEXT,
|
|
amount DECIMAL(20,2) NOT NULL,
|
|
pay_amount DECIMAL(20,2) NOT NULL,
|
|
fee_rate DECIMAL(10,4) NOT NULL DEFAULT 0,
|
|
recharge_code VARCHAR(64) NOT NULL DEFAULT '',
|
|
payment_type VARCHAR(30) NOT NULL DEFAULT '',
|
|
payment_trade_no VARCHAR(128) NOT NULL DEFAULT '',
|
|
pay_url TEXT,
|
|
qr_code TEXT,
|
|
qr_code_img TEXT,
|
|
order_type VARCHAR(20) NOT NULL DEFAULT 'balance',
|
|
plan_id BIGINT,
|
|
subscription_group_id BIGINT,
|
|
subscription_days INT,
|
|
provider_instance_id VARCHAR(64),
|
|
status VARCHAR(30) NOT NULL DEFAULT 'PENDING',
|
|
refund_amount DECIMAL(20,2) NOT NULL DEFAULT 0,
|
|
refund_reason TEXT,
|
|
refund_at TIMESTAMPTZ,
|
|
force_refund BOOLEAN NOT NULL DEFAULT FALSE,
|
|
refund_requested_at TIMESTAMPTZ,
|
|
refund_request_reason TEXT,
|
|
refund_requested_by VARCHAR(20),
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
paid_at TIMESTAMPTZ,
|
|
completed_at TIMESTAMPTZ,
|
|
failed_at TIMESTAMPTZ,
|
|
failed_reason TEXT,
|
|
client_ip VARCHAR(50) NOT NULL DEFAULT '',
|
|
src_host VARCHAR(255) NOT NULL DEFAULT '',
|
|
src_url TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
-- Indexes
|
|
CREATE INDEX IF NOT EXISTS idx_payment_orders_user_id ON payment_orders(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_payment_orders_status ON payment_orders(status);
|
|
CREATE INDEX IF NOT EXISTS idx_payment_orders_expires_at ON payment_orders(expires_at);
|
|
CREATE INDEX IF NOT EXISTS idx_payment_orders_created_at ON payment_orders(created_at);
|
|
CREATE INDEX IF NOT EXISTS idx_payment_orders_paid_at ON payment_orders(paid_at);
|
|
CREATE INDEX IF NOT EXISTS idx_payment_orders_type_paid ON payment_orders(payment_type, paid_at);
|
|
CREATE INDEX IF NOT EXISTS idx_payment_orders_order_type ON payment_orders(order_type);
|