|
|
@@ -0,0 +1,126 @@
|
|
|
+-- 统一支付平台三张表(2026-10-20)。执行由用户做;本脚本必须可重复执行。
|
|
|
+
|
|
|
+-- 租户 ↔ 上游商户配置
|
|
|
+CREATE TABLE IF NOT EXISTS pay_unified_merchant (
|
|
|
+ id BIGINT PRIMARY KEY,
|
|
|
+ tenant_id BIGINT NOT NULL,
|
|
|
+ mch_no VARCHAR(64) NOT NULL,
|
|
|
+ app_id VARCHAR(64) NOT NULL,
|
|
|
+ app_secret VARCHAR(128) NOT NULL,
|
|
|
+ merchant_name VARCHAR(128),
|
|
|
+ channel_user_if_code VARCHAR(16) NOT NULL DEFAULT 'fuioupay',
|
|
|
+ status VARCHAR(10) NOT NULL DEFAULT '0',
|
|
|
+ description TEXT,
|
|
|
+ created_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ updated_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ version INT NOT NULL DEFAULT 0
|
|
|
+);
|
|
|
+-- mch_no 是上游全局唯一的商户号:上游通知只带 mchNo,无认证上下文必须能唯一定位租户。
|
|
|
+CREATE UNIQUE INDEX IF NOT EXISTS uk_unified_merchant_mch_no ON pay_unified_merchant (mch_no);
|
|
|
+CREATE INDEX IF NOT EXISTS idx_unified_merchant_tenant ON pay_unified_merchant (tenant_id);
|
|
|
+
|
|
|
+-- 支付订单
|
|
|
+CREATE TABLE IF NOT EXISTS pay_unified_order (
|
|
|
+ id BIGINT PRIMARY KEY,
|
|
|
+ tenant_id BIGINT NOT NULL,
|
|
|
+ merchant_id BIGINT NOT NULL,
|
|
|
+ mch_no VARCHAR(64) NOT NULL,
|
|
|
+ app_id VARCHAR(64) NOT NULL,
|
|
|
+ order_no VARCHAR(64) NOT NULL,
|
|
|
+ out_trade_no VARCHAR(64),
|
|
|
+ api_key VARCHAR(128),
|
|
|
+ source VARCHAR(16) NOT NULL DEFAULT 'OPENAPI',
|
|
|
+ way_code VARCHAR(16) NOT NULL,
|
|
|
+ amount BIGINT NOT NULL,
|
|
|
+ refunded_amount BIGINT NOT NULL DEFAULT 0,
|
|
|
+ currency VARCHAR(3) NOT NULL DEFAULT 'cny',
|
|
|
+ client_ip VARCHAR(64),
|
|
|
+ subject VARCHAR(128) NOT NULL,
|
|
|
+ body VARCHAR(512),
|
|
|
+ callback_url VARCHAR(512),
|
|
|
+ ext_param VARCHAR(512),
|
|
|
+ channel_extra_keys VARCHAR(128),
|
|
|
+ upstream_pay_order_id VARCHAR(64),
|
|
|
+ upstream_channel_order_no VARCHAR(64),
|
|
|
+ pay_data_type VARCHAR(32),
|
|
|
+ pay_data TEXT,
|
|
|
+ trade_status VARCHAR(8) NOT NULL DEFAULT '0',
|
|
|
+ err_code VARCHAR(64),
|
|
|
+ err_msg VARCHAR(512),
|
|
|
+ pay_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ upstream_created_at TIMESTAMP WITH TIME ZONE,
|
|
|
+ upstream_data_json TEXT,
|
|
|
+ last_query_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ next_query_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ query_count INT NOT NULL DEFAULT 0,
|
|
|
+ notify_status VARCHAR(16) NOT NULL DEFAULT 'PENDING',
|
|
|
+ notify_count INT NOT NULL DEFAULT 0,
|
|
|
+ last_notify_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ status VARCHAR(10) NOT NULL DEFAULT '0',
|
|
|
+ description TEXT,
|
|
|
+ created_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ updated_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ version INT NOT NULL DEFAULT 0
|
|
|
+);
|
|
|
+-- order_no 是我方单号(上游 mchOrderNo),全局唯一:通知/轮询在无认证上下文里按它点查。
|
|
|
+CREATE UNIQUE INDEX IF NOT EXISTS uk_unified_order_order_no ON pay_unified_order (order_no);
|
|
|
+-- 部分唯一:收银台单没有调用方单号,NULL 不参与唯一。
|
|
|
+CREATE UNIQUE INDEX IF NOT EXISTS uk_unified_order_tenant_out_trade_no
|
|
|
+ ON pay_unified_order (tenant_id, out_trade_no) WHERE out_trade_no IS NOT NULL;
|
|
|
+-- 部分唯一:防两笔本地单抢同一个上游单;同步响应回来前为空。
|
|
|
+CREATE UNIQUE INDEX IF NOT EXISTS uk_unified_order_upstream_pay_order_id
|
|
|
+ ON pay_unified_order (upstream_pay_order_id) WHERE upstream_pay_order_id IS NOT NULL;
|
|
|
+CREATE INDEX IF NOT EXISTS idx_unified_order_mch_created
|
|
|
+ ON pay_unified_order (mch_no, created_time DESC);
|
|
|
+CREATE INDEX IF NOT EXISTS idx_unified_order_poll
|
|
|
+ ON pay_unified_order (trade_status, next_query_time);
|
|
|
+CREATE INDEX IF NOT EXISTS idx_unified_order_notify_retry
|
|
|
+ ON pay_unified_order (notify_status, last_notify_time) WHERE notify_status = 'FAILED';
|
|
|
+
|
|
|
+-- 退款单
|
|
|
+CREATE TABLE IF NOT EXISTS pay_unified_refund (
|
|
|
+ id BIGINT PRIMARY KEY,
|
|
|
+ tenant_id BIGINT NOT NULL,
|
|
|
+ order_id BIGINT NOT NULL,
|
|
|
+ order_no VARCHAR(64) NOT NULL,
|
|
|
+ refund_no VARCHAR(64) NOT NULL,
|
|
|
+ out_refund_no VARCHAR(64),
|
|
|
+ mch_no VARCHAR(64) NOT NULL,
|
|
|
+ app_id VARCHAR(64) NOT NULL,
|
|
|
+ api_key VARCHAR(128),
|
|
|
+ source VARCHAR(16) NOT NULL DEFAULT 'OPENAPI',
|
|
|
+ amount BIGINT NOT NULL,
|
|
|
+ currency VARCHAR(3) NOT NULL DEFAULT 'cny',
|
|
|
+ refund_reason VARCHAR(64) NOT NULL,
|
|
|
+ callback_url VARCHAR(512),
|
|
|
+ ext_param VARCHAR(512),
|
|
|
+ upstream_refund_order_id VARCHAR(64),
|
|
|
+ upstream_channel_order_no VARCHAR(64),
|
|
|
+ state VARCHAR(8) NOT NULL DEFAULT '0',
|
|
|
+ err_code VARCHAR(64),
|
|
|
+ err_msg VARCHAR(512),
|
|
|
+ success_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ upstream_created_at TIMESTAMP WITH TIME ZONE,
|
|
|
+ upstream_data_json TEXT,
|
|
|
+ last_query_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ next_query_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ query_count INT NOT NULL DEFAULT 0,
|
|
|
+ notify_status VARCHAR(16) NOT NULL DEFAULT 'PENDING',
|
|
|
+ notify_count INT NOT NULL DEFAULT 0,
|
|
|
+ last_notify_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ status VARCHAR(10) NOT NULL DEFAULT '0',
|
|
|
+ description TEXT,
|
|
|
+ created_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ updated_time TIMESTAMP WITH TIME ZONE,
|
|
|
+ version INT NOT NULL DEFAULT 0
|
|
|
+);
|
|
|
+-- refund_no 是我方退款号(上游 mchRefundNo),全局唯一:无认证回调按它点查。
|
|
|
+CREATE UNIQUE INDEX IF NOT EXISTS uk_unified_refund_refund_no ON pay_unified_refund (refund_no);
|
|
|
+CREATE UNIQUE INDEX IF NOT EXISTS uk_unified_refund_tenant_out_refund_no
|
|
|
+ ON pay_unified_refund (tenant_id, out_refund_no) WHERE out_refund_no IS NOT NULL;
|
|
|
+CREATE UNIQUE INDEX IF NOT EXISTS uk_unified_refund_upstream_refund_order_id
|
|
|
+ ON pay_unified_refund (upstream_refund_order_id) WHERE upstream_refund_order_id IS NOT NULL;
|
|
|
+CREATE INDEX IF NOT EXISTS idx_unified_refund_order_no ON pay_unified_refund (order_no);
|
|
|
+CREATE INDEX IF NOT EXISTS idx_unified_refund_poll ON pay_unified_refund (state, next_query_time);
|
|
|
+CREATE INDEX IF NOT EXISTS idx_unified_refund_notify_retry
|
|
|
+ ON pay_unified_refund (notify_status, last_notify_time) WHERE notify_status = 'FAILED';
|