mirror of
https://gitee.com/dromara/dax-pay
synced 2026-08-10 14:56:06 +08:00
feat: 微信直连通道管理功能
This commit is contained in:
@@ -1,27 +1,28 @@
|
||||
-- =====================================================================
|
||||
-- 支付宝通道相关表 (DROP + CREATE 重建)
|
||||
-- 微信通道相关表 (DROP + CREATE 重建)
|
||||
-- 对应实体:
|
||||
-- org.dromara.daxpay.channel.alipay.entity.isv.AlipayIsvApp
|
||||
-- org.dromara.daxpay.channel.alipay.entity.isv.AlipayIsvAppKeyConfig
|
||||
-- org.dromara.daxpay.channel.alipay.entity.isv.AlipayIsvAppAuthConfig
|
||||
-- org.dromara.daxpay.channel.alipay.entity.isv.AlipayIsvChannelMerchant
|
||||
-- org.dromara.daxpay.channel.alipay.entity.direct.AlipayDirectApp
|
||||
-- org.dromara.daxpay.channel.alipay.entity.direct.AlipayDirectAppKeyConfig
|
||||
-- org.dromara.daxpay.channel.alipay.entity.direct.AlipayDirectAppAuthConfig
|
||||
-- org.dromara.daxpay.channel.alipay.entity.direct.AlipayDirectChannelMerchant
|
||||
-- org.dromara.daxpay.channel.wechat.entity.isv.WechatIsvApp
|
||||
-- org.dromara.daxpay.channel.wechat.entity.isv.WechatIsvAppAuthConfig
|
||||
-- org.dromara.daxpay.channel.wechat.entity.isv.WechatIsvKeyConfig
|
||||
-- org.dromara.daxpay.channel.wechat.entity.isv.WechatIsvChannelMerchant
|
||||
-- org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectApp
|
||||
-- org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectKeyConfig
|
||||
-- org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectAppAuthConfig
|
||||
-- org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectChannelMerchant
|
||||
-- 执行方式: 手动执行(业务表 DDL 不入库, 由开发者按需在数据库执行)
|
||||
-- 注意: 加密字段(DataEncryptTypeHandler)在数据库层均为普通 text, 加解密在应用层完成
|
||||
-- =====================================================================
|
||||
|
||||
-- =========================
|
||||
-- 1. 支付宝服务商应用 alipay_isv_app
|
||||
-- 1. 微信服务商应用 wechat_isv_app
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."alipay_isv_app";
|
||||
DROP TABLE IF EXISTS "public"."wechat_isv_app";
|
||||
|
||||
CREATE TABLE "public"."alipay_isv_app" (
|
||||
CREATE TABLE "public"."wechat_isv_app" (
|
||||
"id" int8 NOT NULL,
|
||||
"app_name" varchar(64),
|
||||
"ali_app_id" varchar(64),
|
||||
"app_type" varchar(32),
|
||||
"wx_app_id" varchar(64),
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
"last_modifier" int8,
|
||||
@@ -30,74 +31,31 @@ CREATE TABLE "public"."alipay_isv_app" (
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."alipay_isv_app" IS '支付宝服务商应用';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app"."app_name" IS '应用名称';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app"."ali_app_id" IS '支付宝应用ID';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app"."deleted" IS '逻辑删除标志';
|
||||
COMMENT ON TABLE "public"."wechat_isv_app" IS '微信服务商应用';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."app_name" IS '应用名称';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."app_type" IS '应用类型';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."wx_app_id" IS '微信应用AppId';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."alipay_isv_app"
|
||||
ADD CONSTRAINT "pk_alipay_isv_app" PRIMARY KEY ("id");
|
||||
ALTER TABLE "public"."wechat_isv_app"
|
||||
ADD CONSTRAINT "pk_wechat_isv_app" PRIMARY KEY ("id");
|
||||
|
||||
|
||||
-- =========================
|
||||
-- 2. 支付宝服务商应用密钥配置 alipay_isv_app_key_config
|
||||
-- 2. 微信服务商应用授权配置 wechat_isv_app_auth_config
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."alipay_isv_app_key_config";
|
||||
DROP TABLE IF EXISTS "public"."wechat_isv_app_auth_config";
|
||||
|
||||
CREATE TABLE "public"."alipay_isv_app_key_config" (
|
||||
CREATE TABLE "public"."wechat_isv_app_auth_config" (
|
||||
"id" int8 NOT NULL,
|
||||
"alipay_isv_app_id" int8,
|
||||
"auth_type" varchar(32),
|
||||
"alipay_public_key" text,
|
||||
"private_key" text,
|
||||
"app_cert" text,
|
||||
"alipay_cert" text,
|
||||
"alipay_root_cert" text,
|
||||
"secret_key" text,
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
"last_modifier" int8,
|
||||
"last_modified_time" timestamptz(6),
|
||||
"version" int4 DEFAULT 0 NOT NULL,
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."alipay_isv_app_key_config" IS '支付宝服务商应用密钥配置';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."alipay_isv_app_id" IS '支付宝服务商应用ID(指向 alipay_isv_app.id)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."auth_type" IS '认证类型';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."alipay_public_key" IS '支付宝公钥';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."private_key" IS '应用私钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."app_cert" IS '应用公钥证书(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."alipay_cert" IS '支付宝公钥证书(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."alipay_root_cert" IS '支付宝CA根证书(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."secret_key" IS 'AES通信密钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_key_config"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."alipay_isv_app_key_config"
|
||||
ADD CONSTRAINT "pk_alipay_isv_app_key_config" PRIMARY KEY ("id");
|
||||
|
||||
|
||||
-- =========================
|
||||
-- 3. 支付宝服务商应用授权配置 alipay_isv_app_auth_config
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."alipay_isv_app_auth_config";
|
||||
|
||||
CREATE TABLE "public"."alipay_isv_app_auth_config" (
|
||||
"id" int8 NOT NULL,
|
||||
"alipay_isv_app_id" int8,
|
||||
"user_id_type" varchar(32),
|
||||
"wechat_isv_app_id" int8,
|
||||
"app_secret" text,
|
||||
"auth_callback_url" varchar(255),
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
@@ -107,38 +65,78 @@ CREATE TABLE "public"."alipay_isv_app_auth_config" (
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."alipay_isv_app_auth_config" IS '支付宝服务商应用授权配置';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."alipay_isv_app_id" IS '支付宝服务商应用ID(指向 alipay_isv_app.id)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."user_id_type" IS '用户标识类型';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."auth_callback_url" IS '授权回调地址';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_app_auth_config"."deleted" IS '逻辑删除标志';
|
||||
COMMENT ON TABLE "public"."wechat_isv_app_auth_config" IS '微信服务商应用授权配置';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."wechat_isv_app_id" IS '关联服务商应用ID(指向 wechat_isv_app.id)';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."app_secret" IS '应用密钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."auth_callback_url" IS '授权回调地址(仅公众号)';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_app_auth_config"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."alipay_isv_app_auth_config"
|
||||
ADD CONSTRAINT "pk_alipay_isv_app_auth_config" PRIMARY KEY ("id");
|
||||
ALTER TABLE "public"."wechat_isv_app_auth_config"
|
||||
ADD CONSTRAINT "pk_wechat_isv_app_auth_config" PRIMARY KEY ("id");
|
||||
|
||||
|
||||
-- =========================
|
||||
-- 4. 支付宝服务商通道商户绑定 alipay_isv_channel_merchant
|
||||
-- 一条记录代表子商户挂靠在某个服务商应用下的授权关系
|
||||
-- 同一子商户挂不同应用 = 不同行(不同 channel_mch_no)
|
||||
-- 3. 微信服务商密钥配置 wechat_isv_key_config
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."mch_alipay_isv_channel_merchant";
|
||||
DROP TABLE IF EXISTS "public"."alipay_isv_channel_merchant";
|
||||
DROP TABLE IF EXISTS "public"."wechat_isv_key_config";
|
||||
|
||||
CREATE TABLE "public"."alipay_isv_channel_merchant" (
|
||||
CREATE TABLE "public"."wechat_isv_key_config" (
|
||||
"id" int8 NOT NULL,
|
||||
"product" varchar(32),
|
||||
"wx_mch_id" varchar(32),
|
||||
"api_key_v3" text,
|
||||
"public_key" text,
|
||||
"public_key_id" varchar(128),
|
||||
"private_key" text,
|
||||
"private_cert" text,
|
||||
"cert_serial_no" varchar(128),
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
"last_modifier" int8,
|
||||
"last_modified_time" timestamptz(6),
|
||||
"version" int4 DEFAULT 0 NOT NULL,
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."wechat_isv_key_config" IS '微信服务商密钥配置';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."product" IS '产品编码';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."wx_mch_id" IS '微信服务商商户号';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."api_key_v3" IS 'APIv3密钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."public_key" IS '支付公钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."public_key_id" IS '支付公钥ID';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."private_key" IS '商户私钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."private_cert" IS '商户证书(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."cert_serial_no" IS '证书序列号';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."wechat_isv_key_config"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."wechat_isv_key_config"
|
||||
ADD CONSTRAINT "pk_wechat_isv_key_config" PRIMARY KEY ("id");
|
||||
|
||||
|
||||
-- =========================
|
||||
-- 4. 微信服务商通道商户绑定 mch_wechat_isv_channel_merchant
|
||||
-- 微信特约商户关联到服务商本身, 不挂靠具体服务商应用
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."mch_wechat_isv_channel_merchant";
|
||||
|
||||
CREATE TABLE "public"."mch_wechat_isv_channel_merchant" (
|
||||
"id" int8 NOT NULL,
|
||||
"mch_no" varchar(32) NOT NULL,
|
||||
"channel_mch_no" varchar(64) NOT NULL,
|
||||
"product" varchar(32) NOT NULL,
|
||||
"isv_app_id" int8,
|
||||
"alipay_user_id" varchar(64),
|
||||
"app_auth_token" varchar(128),
|
||||
"sub_mch_id" varchar(32),
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
"last_modifier" int8,
|
||||
@@ -147,37 +145,72 @@ CREATE TABLE "public"."alipay_isv_channel_merchant" (
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."alipay_isv_channel_merchant" IS '支付宝服务商通道商户绑定';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."channel_mch_no" IS '通道商户号(AISV+雪花)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."product" IS '所属支付产品';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."isv_app_id" IS '关联服务商应用ID(指向 alipay_isv_app.id)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."alipay_user_id" IS '子商户支付宝识别码(2088开头的16位数字)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."app_auth_token" IS '应用授权令牌(服务商代子商户调用接口的凭据, 会过期/刷新)';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."alipay_isv_channel_merchant"."deleted" IS '逻辑删除标志';
|
||||
COMMENT ON TABLE "public"."mch_wechat_isv_channel_merchant" IS '微信服务商通道商户绑定';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."channel_mch_no" IS '通道商户号(WISV+雪花)';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."product" IS '所属支付产品';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."sub_mch_id" IS '微信特约商户号/二级商户号(V3服务商支付 sub_mchid)';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_isv_channel_merchant"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."alipay_isv_channel_merchant"
|
||||
ADD CONSTRAINT "pk_alipay_isv_channel_merchant" PRIMARY KEY ("id");
|
||||
ALTER TABLE "public"."mch_wechat_isv_channel_merchant"
|
||||
ADD CONSTRAINT "pk_mch_wechat_isv_channel_merchant" PRIMARY KEY ("id");
|
||||
|
||||
|
||||
-- =========================
|
||||
-- 5. 支付宝直连商户应用 alipay_direct_app
|
||||
-- 每个应用关联一个通道商户号, 拥有独立的支付宝应用ID
|
||||
-- 5. 微信直连通道商户绑定 mch_wechat_direct_channel_merchant
|
||||
-- 一个微信商户号(wx_mch_id)对应一个channelMchNo, 商户的多个应用共享此绑定
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."alipay_direct_app";
|
||||
DROP TABLE IF EXISTS "public"."mch_wechat_direct_channel_merchant";
|
||||
|
||||
CREATE TABLE "public"."alipay_direct_app" (
|
||||
CREATE TABLE "public"."mch_wechat_direct_channel_merchant" (
|
||||
"id" int8 NOT NULL,
|
||||
"mch_no" varchar(32) NOT NULL,
|
||||
"channel_mch_no" varchar(64) NOT NULL,
|
||||
"product" varchar(32) NOT NULL,
|
||||
"wx_mch_id" varchar(32),
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
"last_modifier" int8,
|
||||
"last_modified_time" timestamptz(6),
|
||||
"version" int4 DEFAULT 0 NOT NULL,
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."mch_wechat_direct_channel_merchant" IS '微信直连通道商户绑定';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."channel_mch_no" IS '通道商户号(系统生成雪花号)';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."product" IS '所属支付产品';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."wx_mch_id" IS '微信直连商户号';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."mch_wechat_direct_channel_merchant"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."mch_wechat_direct_channel_merchant"
|
||||
ADD CONSTRAINT "pk_mch_wechat_direct_channel_merchant" PRIMARY KEY ("id");
|
||||
|
||||
|
||||
-- =========================
|
||||
-- 6. 微信直连商户应用 wechat_direct_app
|
||||
-- 每个应用关联一个通道商户号, 拥有独立的微信应用ID
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."wechat_direct_app";
|
||||
|
||||
CREATE TABLE "public"."wechat_direct_app" (
|
||||
"id" int8 NOT NULL,
|
||||
"mch_no" varchar(32) NOT NULL,
|
||||
"channel_mch_no" varchar(64) NOT NULL,
|
||||
"app_name" varchar(64),
|
||||
"ali_app_id" varchar(64),
|
||||
"wx_app_id" varchar(64),
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
"last_modifier" int8,
|
||||
@@ -186,41 +219,39 @@ CREATE TABLE "public"."alipay_direct_app" (
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."alipay_direct_app" IS '支付宝直连商户应用';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."channel_mch_no" IS '通道商户号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."app_name" IS '应用名称';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."ali_app_id" IS '支付宝应用ID';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app"."deleted" IS '逻辑删除标志';
|
||||
COMMENT ON TABLE "public"."wechat_direct_app" IS '微信直连商户应用';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."channel_mch_no" IS '通道商户号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."app_name" IS '应用名称';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."wx_app_id" IS '微信应用AppId';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."alipay_direct_app"
|
||||
ADD CONSTRAINT "pk_alipay_direct_app" PRIMARY KEY ("id");
|
||||
ALTER TABLE "public"."wechat_direct_app"
|
||||
ADD CONSTRAINT "pk_wechat_direct_app" PRIMARY KEY ("id");
|
||||
|
||||
|
||||
-- =========================
|
||||
-- 6. 支付宝直连商户应用密钥配置 alipay_direct_app_key_config
|
||||
-- 支持公钥模式和证书模式两种认证方式, 敏感字段加密存储
|
||||
-- 7. 微信直连密钥配置 wechat_direct_key_config
|
||||
-- 直连商户维度的APIv3密钥和证书, 按通道商户号关联, 与具体应用无关, 敏感字段加密存储
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."alipay_direct_app_key_config";
|
||||
DROP TABLE IF EXISTS "public"."wechat_direct_key_config";
|
||||
|
||||
CREATE TABLE "public"."alipay_direct_app_key_config" (
|
||||
CREATE TABLE "public"."wechat_direct_key_config" (
|
||||
"id" int8 NOT NULL,
|
||||
"mch_no" varchar(32) NOT NULL,
|
||||
"channel_mch_no" varchar(64) NOT NULL,
|
||||
"alipay_direct_app_id" int8,
|
||||
"auth_type" varchar(32),
|
||||
"alipay_public_key" text,
|
||||
"api_key_v3" text,
|
||||
"public_key" text,
|
||||
"public_key_id" varchar(128),
|
||||
"private_key" text,
|
||||
"app_cert" text,
|
||||
"alipay_cert" text,
|
||||
"alipay_root_cert" text,
|
||||
"secret_key" text,
|
||||
"private_cert" text,
|
||||
"cert_serial_no" varchar(128),
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
"last_modifier" int8,
|
||||
@@ -229,40 +260,38 @@ CREATE TABLE "public"."alipay_direct_app_key_config" (
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."alipay_direct_app_key_config" IS '支付宝直连商户应用密钥配置';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."channel_mch_no" IS '通道商户号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."alipay_direct_app_id" IS '关联应用ID(指向 alipay_direct_app.id)';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."auth_type" IS '认证类型';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."alipay_public_key" IS '支付宝公钥';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."private_key" IS '应用私钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."app_cert" IS '应用公钥证书(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."alipay_cert" IS '支付宝公钥证书(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."alipay_root_cert" IS '支付宝CA根证书(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."secret_key" IS 'AES通信密钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_key_config"."deleted" IS '逻辑删除标志';
|
||||
COMMENT ON TABLE "public"."wechat_direct_key_config" IS '微信直连密钥配置';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."channel_mch_no" IS '通道商户号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."api_key_v3" IS 'APIv3密钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."public_key" IS '支付公钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."public_key_id" IS '支付公钥ID';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."private_key" IS '商户私钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."private_cert" IS '商户证书(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."cert_serial_no" IS '证书序列号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_key_config"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."alipay_direct_app_key_config"
|
||||
ADD CONSTRAINT "pk_alipay_direct_app_key_config" PRIMARY KEY ("id");
|
||||
ALTER TABLE "public"."wechat_direct_key_config"
|
||||
ADD CONSTRAINT "pk_wechat_direct_key_config" PRIMARY KEY ("id");
|
||||
|
||||
|
||||
-- =========================
|
||||
-- 7. 支付宝直连商户应用授权配置 alipay_direct_app_auth_config
|
||||
-- 8. 微信直连商户应用授权配置 wechat_direct_app_auth_config
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."alipay_direct_app_auth_config";
|
||||
DROP TABLE IF EXISTS "public"."wechat_direct_app_auth_config";
|
||||
|
||||
CREATE TABLE "public"."alipay_direct_app_auth_config" (
|
||||
CREATE TABLE "public"."wechat_direct_app_auth_config" (
|
||||
"id" int8 NOT NULL,
|
||||
"mch_no" varchar(32) NOT NULL,
|
||||
"channel_mch_no" varchar(64) NOT NULL,
|
||||
"alipay_direct_app_id" int8,
|
||||
"user_id_type" varchar(32),
|
||||
"wechat_direct_app_id" int8,
|
||||
"app_secret" text,
|
||||
"auth_callback_url" varchar(255),
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
@@ -272,57 +301,19 @@ CREATE TABLE "public"."alipay_direct_app_auth_config" (
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."alipay_direct_app_auth_config" IS '支付宝直连商户应用授权配置';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."channel_mch_no" IS '通道商户号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."alipay_direct_app_id" IS '关联应用ID(指向 alipay_direct_app.id)';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."user_id_type" IS '用户标识类型';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."auth_callback_url" IS '授权回调地址';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_app_auth_config"."deleted" IS '逻辑删除标志';
|
||||
COMMENT ON TABLE "public"."wechat_direct_app_auth_config" IS '微信直连商户应用授权配置';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."channel_mch_no" IS '通道商户号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."wechat_direct_app_id" IS '关联应用ID(指向 wechat_direct_app.id)';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."app_secret" IS '应用密钥(加密存储)';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."auth_callback_url" IS '授权回调地址';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."wechat_direct_app_auth_config"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."alipay_direct_app_auth_config"
|
||||
ADD CONSTRAINT "pk_alipay_direct_app_auth_config" PRIMARY KEY ("id");
|
||||
|
||||
|
||||
-- =========================
|
||||
-- 8. 支付宝直连通道商户绑定 alipay_direct_channel_merchant
|
||||
-- 一个商户PID对应一个channelMchNo, 商户的多个应用共享此绑定
|
||||
-- =========================
|
||||
DROP TABLE IF EXISTS "public"."mch_alipay_direct_channel_merchant";
|
||||
DROP TABLE IF EXISTS "public"."alipay_direct_channel_merchant";
|
||||
|
||||
CREATE TABLE "public"."alipay_direct_channel_merchant" (
|
||||
"id" int8 NOT NULL,
|
||||
"mch_no" varchar(32) NOT NULL,
|
||||
"channel_mch_no" varchar(64) NOT NULL,
|
||||
"product" varchar(32) NOT NULL,
|
||||
"alipay_user_id" varchar(64),
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
"last_modifier" int8,
|
||||
"last_modified_time" timestamptz(6),
|
||||
"version" int4 DEFAULT 0 NOT NULL,
|
||||
"deleted" bool DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE "public"."alipay_direct_channel_merchant" IS '支付宝直连通道商户绑定';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."id" IS '主键';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."channel_mch_no" IS '通道商户号(系统生成雪花号)';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."product" IS '所属支付产品';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."alipay_user_id" IS '支付宝商家唯一识别码(2088开头的16位数字)';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."last_modifier" IS '最后修改人';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."last_modified_time" IS '最后修改时间';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."version" IS '乐观锁版本号';
|
||||
COMMENT ON COLUMN "public"."alipay_direct_channel_merchant"."deleted" IS '逻辑删除标志';
|
||||
|
||||
ALTER TABLE "public"."alipay_direct_channel_merchant"
|
||||
ADD CONSTRAINT "pk_alipay_direct_channel_merchant" PRIMARY KEY ("id");
|
||||
ALTER TABLE "public"."wechat_direct_app_auth_config"
|
||||
ADD CONSTRAINT "pk_wechat_direct_app_auth_config" PRIMARY KEY ("id");
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.dromara.daxpay.channel.wechat.code;
|
||||
|
||||
/// # 微信支付常量
|
||||
///
|
||||
/// 定义微信支付相关的常量,包括认证方式(仅APIv3证书模式)和用户标识类型等。
|
||||
///
|
||||
public interface WechatCode {
|
||||
|
||||
/// # 认证方式
|
||||
///
|
||||
interface AuthType {
|
||||
/// APIv3 证书模式
|
||||
String AUTH_TYPE_CERT = "cert";
|
||||
}
|
||||
|
||||
/// # 用户标识类型
|
||||
///
|
||||
interface UserIdType {
|
||||
/// 用户标识(OpenId)
|
||||
String OPENID = "openid";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package org.dromara.daxpay.channel.wechat.controller.direct;
|
||||
|
||||
import org.dromara.daxpay.platform.core.annotation.PermCode;
|
||||
import org.dromara.daxpay.platform.core.rest.Res;
|
||||
import org.dromara.daxpay.platform.core.rest.result.Result;
|
||||
import org.dromara.daxpay.platform.core.util.ValidationUtil;
|
||||
import org.dromara.daxpay.platform.core.validation.ValidationGroup;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectAppParam;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectAppAuthConfigParam;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectAppResult;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectAppAuthConfigResult;
|
||||
import org.dromara.daxpay.channel.wechat.service.direct.WechatDirectAppService;
|
||||
import org.dromara.daxpay.channel.wechat.service.direct.WechatDirectAppAuthConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/// # 微信直连商户应用管理
|
||||
///
|
||||
/// 提供直连商户应用及其密钥配置、授权认证配置的 REST API,支持按商户号和通道商户号查询列表。
|
||||
///
|
||||
@PermCode(menuCode = "payment:wechat:mch-app")
|
||||
@Validated
|
||||
@Tag(name = "微信直连商户应用管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/wechat/mch-app")
|
||||
@RequiredArgsConstructor
|
||||
public class WechatDirectAppController {
|
||||
|
||||
private final WechatDirectAppService wechatDirectAppService;
|
||||
private final WechatDirectAppAuthConfigService wechatDirectAppAuthConfigService;
|
||||
|
||||
@PermCode(code = "view", nameCn = "通道商户查看", nameEn = "Channel Merchant View")
|
||||
@Operation(summary = "根据商户号和通道商户号查询应用列表")
|
||||
@GetMapping("/list-by-channel-mch-no")
|
||||
public Result<List<WechatDirectAppResult>> listByChannelMchNo(
|
||||
@NotBlank(message = "{validation.field.mchNo.notBlank}") String mchNo,
|
||||
@NotBlank(message = "{validation.field.channelMerchantNo.notBlank}") String channelMchNo) {
|
||||
return Res.ok(wechatDirectAppService.listByMchNoAndChannelMchNo(mchNo, channelMchNo));
|
||||
}
|
||||
|
||||
@PermCode(code = "view", nameCn = "通道商户查看", nameEn = "Channel Merchant View")
|
||||
@Operation(summary = "查询应用详情")
|
||||
@GetMapping("/find-by-id")
|
||||
public Result<WechatDirectAppResult> findById(
|
||||
@NotNull(message = "{validation.field.id.notNull}") Long id) {
|
||||
return Res.ok(wechatDirectAppService.findById(id));
|
||||
}
|
||||
|
||||
@PermCode(code = "view", nameCn = "通道商户查看", nameEn = "Channel Merchant View")
|
||||
@Operation(summary = "同一通道商户下微信应用ID是否已存在")
|
||||
@GetMapping("/exists-wx-app-id-by-channel")
|
||||
public Result<Boolean> existsWxAppIdByChannel(
|
||||
@NotBlank(message = "{validation.field.mchNo.notBlank}") String mchNo,
|
||||
@NotBlank(message = "{validation.field.channelMerchantNo.notBlank}") String channelMchNo,
|
||||
@NotBlank(message = "{validation.field.wxAppId.notBlank}") String wxAppId) {
|
||||
return Res.ok(wechatDirectAppService.existsWxAppIdByChannel(mchNo, channelMchNo, wxAppId, null));
|
||||
}
|
||||
|
||||
@PermCode(code = "view", nameCn = "通道商户查看", nameEn = "Channel Merchant View")
|
||||
@Operation(summary = "同一通道商户下微信应用ID是否已存在(排除自身)")
|
||||
@GetMapping("/exists-wx-app-id-by-channel-not-id")
|
||||
public Result<Boolean> existsWxAppIdByChannelNotId(
|
||||
@NotBlank(message = "{validation.field.mchNo.notBlank}") String mchNo,
|
||||
@NotBlank(message = "{validation.field.channelMerchantNo.notBlank}") String channelMchNo,
|
||||
@NotBlank(message = "{validation.field.wxAppId.notBlank}") String wxAppId,
|
||||
@NotNull(message = "{validation.field.id.notNull}") Long id) {
|
||||
return Res.ok(wechatDirectAppService.existsWxAppIdByChannel(mchNo, channelMchNo, wxAppId, id));
|
||||
}
|
||||
|
||||
@PermCode(code = "add", nameCn = "通道商户新增", nameEn = "Channel Merchant Add")
|
||||
@Operation(summary = "新增直连商户应用")
|
||||
@PostMapping("/add")
|
||||
public Result<Void> add(@RequestBody @Validated(ValidationGroup.add.class) WechatDirectAppParam param) {
|
||||
ValidationUtil.validateParam(param, ValidationGroup.add.class);
|
||||
wechatDirectAppService.add(param);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@PermCode(code = "edit", nameCn = "通道商户编辑", nameEn = "Channel Merchant Edit")
|
||||
@Operation(summary = "修改直连商户应用")
|
||||
@PostMapping("/update")
|
||||
public Result<Void> update(@RequestBody @Validated(ValidationGroup.edit.class) WechatDirectAppParam param) {
|
||||
ValidationUtil.validateParam(param, ValidationGroup.edit.class);
|
||||
wechatDirectAppService.update(param);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@PermCode(code = "edit", nameCn = "通道商户编辑", nameEn = "Channel Merchant Edit")
|
||||
@Operation(summary = "删除直连商户应用")
|
||||
@PostMapping("/delete")
|
||||
public Result<Void> delete(@NotNull(message = "{validation.field.id.notNull}") Long id) {
|
||||
wechatDirectAppService.delete(id);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@PermCode(code = "view", nameCn = "通道商户查看", nameEn = "Channel Merchant View")
|
||||
@Operation(summary = "查询应用授权认证配置")
|
||||
@GetMapping("/find-auth-config-by-app-id")
|
||||
public Result<WechatDirectAppAuthConfigResult> findAuthConfigByAppId(
|
||||
@NotNull(message = "{validation.field.wechatDirectAppId.notNull}") Long wechatDirectAppId) {
|
||||
var config = wechatDirectAppAuthConfigService.findByWechatDirectAppId(wechatDirectAppId);
|
||||
var result = config.toResult();
|
||||
result.setAppSecretConfigured(config.getAppSecret() != null);
|
||||
return Res.ok(result);
|
||||
}
|
||||
|
||||
@PermCode(code = "edit", nameCn = "通道商户编辑", nameEn = "Channel Merchant Edit")
|
||||
@Operation(summary = "保存应用授权认证配置")
|
||||
@PostMapping("/save-auth-config")
|
||||
public Result<Void> saveAuthConfig(@RequestBody @Validated WechatDirectAppAuthConfigParam param) {
|
||||
wechatDirectAppAuthConfigService.save(param);
|
||||
return Res.ok();
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,11 @@ import org.dromara.daxpay.platform.core.annotation.PermCode;
|
||||
import org.dromara.daxpay.platform.core.rest.Res;
|
||||
import org.dromara.daxpay.platform.core.rest.result.Result;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectChannelMerchantCreateParam;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectKeyConfigParam;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectChannelMerchantResult;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectKeyConfigResult;
|
||||
import org.dromara.daxpay.channel.wechat.service.direct.WechatDirectChannelMerchantService;
|
||||
import org.dromara.daxpay.channel.wechat.service.direct.WechatDirectKeyConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
@@ -28,6 +31,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
public class WechatDirectChannelMerchantController {
|
||||
|
||||
private final WechatDirectChannelMerchantService wechatDirectChannelMerchantService;
|
||||
private final WechatDirectKeyConfigService wechatDirectKeyConfigService;
|
||||
|
||||
@PermCode(code = "view", nameCn = "商户通道商户查看", nameEn = "Merchant Channel Merchant View")
|
||||
@Operation(summary = "根据通道商户号查询微信直连通道商户配置")
|
||||
@@ -44,4 +48,20 @@ public class WechatDirectChannelMerchantController {
|
||||
wechatDirectChannelMerchantService.create(param);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@PermCode(code = "view", nameCn = "商户通道商户查看", nameEn = "Merchant Channel Merchant View")
|
||||
@Operation(summary = "根据通道商户号查询密钥配置")
|
||||
@GetMapping("/find-key-config")
|
||||
public Result<WechatDirectKeyConfigResult> findKeyConfig(
|
||||
@NotBlank(message = "{validation.field.channelMerchantNo.notBlank}") String channelMchNo) {
|
||||
return Res.ok(wechatDirectKeyConfigService.findByChannelMchNo(channelMchNo).toResult());
|
||||
}
|
||||
|
||||
@PermCode(code = "edit", nameCn = "商户通道商户编辑", nameEn = "Merchant Channel Merchant Edit")
|
||||
@Operation(summary = "保存密钥配置")
|
||||
@PostMapping("/save-key-config")
|
||||
public Result<Void> saveKeyConfig(@RequestBody @Validated WechatDirectKeyConfigParam param) {
|
||||
wechatDirectKeyConfigService.save(param);
|
||||
return Res.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.dromara.daxpay.channel.wechat.convert.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectAppAuthConfig;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectAppAuthConfigParam;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectAppAuthConfigResult;
|
||||
import org.mapstruct.BeanMapping;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.NullValuePropertyMappingStrategy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/// # 微信直连商户应用授权认证配置转换
|
||||
///
|
||||
/// MapStruct转换器,负责微信直连商户应用授权认证配置在实体、参数和返回结果之间的转换,更新时空值不覆盖。
|
||||
///
|
||||
@Mapper
|
||||
public interface WechatDirectAppAuthConfigConvert {
|
||||
|
||||
WechatDirectAppAuthConfigConvert CONVERT = Mappers.getMapper(WechatDirectAppAuthConfigConvert.class);
|
||||
|
||||
/// 转换为返回对象
|
||||
WechatDirectAppAuthConfigResult toResult(WechatDirectAppAuthConfig entity);
|
||||
|
||||
/// 转换为实体
|
||||
WechatDirectAppAuthConfig toEntity(WechatDirectAppAuthConfigParam param);
|
||||
|
||||
/// 更新源数据到实体(空值不覆盖)
|
||||
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
|
||||
void copy(WechatDirectAppAuthConfigParam param, @MappingTarget WechatDirectAppAuthConfig entity);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.dromara.daxpay.channel.wechat.convert.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectApp;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectAppParam;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectAppResult;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/// # 微信直连商户应用转换
|
||||
///
|
||||
/// MapStruct转换器,负责微信直连商户应用在实体、参数和返回结果之间的相互转换。
|
||||
///
|
||||
@Mapper
|
||||
public interface WechatDirectAppConvert {
|
||||
|
||||
WechatDirectAppConvert CONVERT = Mappers.getMapper(WechatDirectAppConvert.class);
|
||||
|
||||
/// 转换为返回对象
|
||||
WechatDirectAppResult toResult(WechatDirectApp entity);
|
||||
|
||||
/// 转换为实体
|
||||
WechatDirectApp toEntity(WechatDirectAppParam param);
|
||||
|
||||
/// 更新源数据到实体(忽略空值)
|
||||
void copy(WechatDirectAppParam param, @MappingTarget WechatDirectApp entity);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.dromara.daxpay.channel.wechat.convert.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectKeyConfig;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectKeyConfigParam;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectKeyConfigResult;
|
||||
import org.mapstruct.BeanMapping;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.NullValuePropertyMappingStrategy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/// # 微信直连密钥配置转换
|
||||
///
|
||||
/// MapStruct转换器,负责微信直连密钥配置在实体、参数和返回结果之间的转换,更新时空值不覆盖。
|
||||
///
|
||||
@Mapper
|
||||
public interface WechatDirectKeyConfigConvert {
|
||||
|
||||
WechatDirectKeyConfigConvert CONVERT = Mappers.getMapper(WechatDirectKeyConfigConvert.class);
|
||||
|
||||
/// 转换为返回对象
|
||||
WechatDirectKeyConfigResult toResult(WechatDirectKeyConfig entity);
|
||||
|
||||
/// 转换为实体
|
||||
WechatDirectKeyConfig toEntity(WechatDirectKeyConfigParam param);
|
||||
|
||||
/// 更新源数据到实体(空值不覆盖,密钥/证书为空时保留原值)
|
||||
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
|
||||
void copy(WechatDirectKeyConfigParam param, @MappingTarget WechatDirectKeyConfig entity);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.dromara.daxpay.channel.wechat.dao.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectAppAuthConfig;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.impl.BaseManager;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/// # 微信直连商户应用授权认证配置
|
||||
///
|
||||
/// 直连商户应用授权认证配置数据访问管理器,提供按应用ID查询和删除授权认证配置的方法。
|
||||
///
|
||||
@Repository
|
||||
public class WechatDirectAppAuthConfigManager extends BaseManager<WechatDirectAppAuthConfigMapper, WechatDirectAppAuthConfig> {
|
||||
|
||||
/// 根据应用ID查询授权认证配置
|
||||
public Optional<WechatDirectAppAuthConfig> findByWechatDirectAppId(Long wechatDirectAppId) {
|
||||
return lambdaQuery()
|
||||
.eq(WechatDirectAppAuthConfig::getWechatDirectAppId, wechatDirectAppId)
|
||||
.oneOpt();
|
||||
}
|
||||
|
||||
/// 根据应用ID删除授权认证配置
|
||||
public void deleteByWechatDirectAppId(Long wechatDirectAppId) {
|
||||
lambdaUpdate()
|
||||
.eq(WechatDirectAppAuthConfig::getWechatDirectAppId, wechatDirectAppId)
|
||||
.remove();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.dromara.daxpay.channel.wechat.dao.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectAppAuthConfig;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/// # 微信直连商户应用授权认证配置
|
||||
///
|
||||
/// 微信直连商户应用授权认证配置 MyBatis-Plus Mapper,继承 MPJBaseMapper 支持多表联查。
|
||||
///
|
||||
@Mapper
|
||||
public interface WechatDirectAppAuthConfigMapper extends MPJBaseMapper<WechatDirectAppAuthConfig> {
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.dromara.daxpay.channel.wechat.dao.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectApp;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.impl.BaseManager;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/// # 微信直连商户应用
|
||||
///
|
||||
/// 直连商户应用数据访问管理器,提供按商户号和通道商户号查询列表、同一通道下应用ID唯一性校验等方法。
|
||||
///
|
||||
@Repository
|
||||
public class WechatDirectAppManager extends BaseManager<WechatDirectAppMapper, WechatDirectApp> {
|
||||
|
||||
/// 根据商户号和通道商户号查询应用列表(按创建时间升序)
|
||||
public List<WechatDirectApp> listByMchNoAndChannelMchNo(String mchNo, String channelMchNo) {
|
||||
return lambdaQuery()
|
||||
.eq(WechatDirectApp::getMchNo, mchNo)
|
||||
.eq(WechatDirectApp::getChannelMchNo, channelMchNo)
|
||||
.orderByAsc(WechatDirectApp::getCreateTime)
|
||||
.orderByAsc(WechatDirectApp::getId)
|
||||
.list();
|
||||
}
|
||||
|
||||
/// 校验同一通道商户下wxAppId是否已存在(排除自身)
|
||||
public boolean existsByChannelMchNoAndWxAppId(String mchNo, String channelMchNo, String wxAppId, Long excludeId) {
|
||||
return lambdaQuery()
|
||||
.eq(WechatDirectApp::getMchNo, mchNo)
|
||||
.eq(WechatDirectApp::getChannelMchNo, channelMchNo)
|
||||
.eq(WechatDirectApp::getWxAppId, wxAppId)
|
||||
.ne(excludeId != null, WechatDirectApp::getId, excludeId)
|
||||
.exists();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.dromara.daxpay.channel.wechat.dao.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectApp;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/// # 微信直连商户应用
|
||||
///
|
||||
/// 微信直连商户应用 MyBatis-Plus Mapper,继承 MPJBaseMapper 支持多表联查。
|
||||
///
|
||||
@Mapper
|
||||
public interface WechatDirectAppMapper extends MPJBaseMapper<WechatDirectApp> {
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectChannelMercha
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.impl.BaseManager;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/// # 微信直连通道商户绑定
|
||||
///
|
||||
@Repository
|
||||
@@ -16,4 +18,11 @@ public class WechatDirectChannelMerchantManager extends BaseManager<WechatDirect
|
||||
.eq(WechatDirectChannelMerchant::getWxMchId, wxMchId)
|
||||
.exists();
|
||||
}
|
||||
|
||||
/// 根据通道商户号查询
|
||||
public Optional<WechatDirectChannelMerchant> findByChannelMchNo(String channelMchNo) {
|
||||
return lambdaQuery()
|
||||
.eq(WechatDirectChannelMerchant::getChannelMchNo, channelMchNo)
|
||||
.oneOpt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.dromara.daxpay.channel.wechat.dao.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectKeyConfig;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.impl.BaseManager;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/// # 微信直连密钥配置
|
||||
///
|
||||
/// 直连密钥配置数据访问管理器,提供按通道商户号查询和删除密钥配置的方法。
|
||||
///
|
||||
@Repository
|
||||
public class WechatDirectKeyConfigManager extends BaseManager<WechatDirectKeyConfigMapper, WechatDirectKeyConfig> {
|
||||
|
||||
/// 根据通道商户号查询密钥配置
|
||||
public Optional<WechatDirectKeyConfig> findByChannelMchNo(String channelMchNo) {
|
||||
return lambdaQuery()
|
||||
.eq(WechatDirectKeyConfig::getChannelMchNo, channelMchNo)
|
||||
.oneOpt();
|
||||
}
|
||||
|
||||
/// 根据通道商户号删除密钥配置
|
||||
public void deleteByChannelMchNo(String channelMchNo) {
|
||||
lambdaUpdate()
|
||||
.eq(WechatDirectKeyConfig::getChannelMchNo, channelMchNo)
|
||||
.remove();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.dromara.daxpay.channel.wechat.dao.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectKeyConfig;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/// # 微信直连密钥配置
|
||||
///
|
||||
/// 微信直连密钥配置 MyBatis-Plus Mapper,继承 MPJBaseMapper 支持多表联查。
|
||||
///
|
||||
@Mapper
|
||||
public interface WechatDirectKeyConfigMapper extends MPJBaseMapper<WechatDirectKeyConfig> {
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.dromara.daxpay.channel.wechat.entity.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.convert.direct.WechatDirectAppConvert;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectAppResult;
|
||||
import org.dromara.daxpay.payment.common.entity.merchant.MchBaseEntity;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.function.ToResult;
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 微信直连商户应用
|
||||
///
|
||||
/// 表示微信直连模式下商户注册的应用实体,每个应用关联一个通道商户号,拥有独立的微信应用ID。
|
||||
///
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "wechat_direct_app", autoResultMap = true)
|
||||
public class WechatDirectApp extends MchBaseEntity implements ToResult<WechatDirectAppResult> {
|
||||
|
||||
/// 通道商户号
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private String channelMchNo;
|
||||
|
||||
/// 应用名称
|
||||
private String appName;
|
||||
|
||||
/// 微信应用AppId
|
||||
private String wxAppId;
|
||||
|
||||
/// 转换
|
||||
@Override
|
||||
public WechatDirectAppResult toResult() {
|
||||
return WechatDirectAppConvert.CONVERT.toResult(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.dromara.daxpay.channel.wechat.entity.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.convert.direct.WechatDirectAppAuthConfigConvert;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectAppAuthConfigResult;
|
||||
import org.dromara.daxpay.payment.common.entity.merchant.MchBaseEntity;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.function.ToResult;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.handler.encrypt.DataEncryptTypeHandler;
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 微信直连商户应用授权认证配置
|
||||
///
|
||||
/// 配置直连商户应用的应用密钥和授权回调地址,用于微信OAuth授权流程中的身份验证与回调跳转。
|
||||
///
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "wechat_direct_app_auth_config", autoResultMap = true)
|
||||
public class WechatDirectAppAuthConfig extends MchBaseEntity implements ToResult<WechatDirectAppAuthConfigResult> {
|
||||
|
||||
/// 通道商户号
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private String channelMchNo;
|
||||
|
||||
/// 关联应用ID
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private Long wechatDirectAppId;
|
||||
|
||||
/// 应用密钥(加密存储)
|
||||
@TableField(typeHandler = DataEncryptTypeHandler.class)
|
||||
private String appSecret;
|
||||
|
||||
/// 授权回调地址
|
||||
private String authCallbackUrl;
|
||||
|
||||
/// 转换
|
||||
@Override
|
||||
public WechatDirectAppAuthConfigResult toResult() {
|
||||
return WechatDirectAppAuthConfigConvert.CONVERT.toResult(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.dromara.daxpay.channel.wechat.entity.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.convert.direct.WechatDirectKeyConfigConvert;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectKeyConfigResult;
|
||||
import org.dromara.daxpay.payment.common.entity.merchant.MchBaseEntity;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.function.ToResult;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.handler.encrypt.DataEncryptTypeHandler;
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 微信直连密钥配置
|
||||
///
|
||||
/// 直连商户维度的APIv3密钥和证书配置,一个微信商户号共享一套密钥/证书,与具体应用无关,敏感字段加密存储。
|
||||
///
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "wechat_direct_key_config", autoResultMap = true)
|
||||
public class WechatDirectKeyConfig extends MchBaseEntity implements ToResult<WechatDirectKeyConfigResult> {
|
||||
|
||||
/// 通道商户号
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private String channelMchNo;
|
||||
|
||||
/// APIv3密钥(加密存储)
|
||||
@TableField(typeHandler = DataEncryptTypeHandler.class)
|
||||
private String apiKeyV3;
|
||||
|
||||
/// 支付公钥(加密存储)
|
||||
@TableField(typeHandler = DataEncryptTypeHandler.class)
|
||||
private String publicKey;
|
||||
|
||||
/// 支付公钥ID
|
||||
private String publicKeyId;
|
||||
|
||||
/// 商户私钥(加密存储)
|
||||
@TableField(typeHandler = DataEncryptTypeHandler.class)
|
||||
private String privateKey;
|
||||
|
||||
/// 商户证书(加密存储)
|
||||
@TableField(typeHandler = DataEncryptTypeHandler.class)
|
||||
private String privateCert;
|
||||
|
||||
/// 证书序列号
|
||||
private String certSerialNo;
|
||||
|
||||
/// 转换
|
||||
@Override
|
||||
public WechatDirectKeyConfigResult toResult() {
|
||||
return WechatDirectKeyConfigConvert.CONVERT.toResult(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.dromara.daxpay.channel.wechat.param.direct;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 微信直连商户应用授权认证配置保存参数
|
||||
///
|
||||
/// 保存/更新微信直连商户应用授权认证配置时接收的请求参数,含商户号、通道商户号、应用密钥和授权回调地址。
|
||||
///
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "微信直连商户应用授权认证配置保存参数")
|
||||
public class WechatDirectAppAuthConfigParam {
|
||||
|
||||
@NotNull(message = "{validation.field.wechatDirectAppId.notNull}")
|
||||
@Schema(description = "关联应用ID")
|
||||
private Long wechatDirectAppId;
|
||||
|
||||
@NotBlank(message = "{validation.field.mchNo.notBlank}")
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
@NotBlank(message = "{validation.field.channelMerchantNo.notBlank}")
|
||||
@Schema(description = "通道商户号")
|
||||
private String channelMchNo;
|
||||
|
||||
@Schema(description = "应用密钥")
|
||||
private String appSecret;
|
||||
|
||||
@NotBlank(message = "{validation.field.authCallbackUrl.notBlank}")
|
||||
@Size(max = 512, message = "{validation.field.authCallbackUrl.size}")
|
||||
@Schema(description = "授权回调地址")
|
||||
private String authCallbackUrl;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.dromara.daxpay.channel.wechat.param.direct;
|
||||
|
||||
import org.dromara.daxpay.platform.core.validation.ValidationGroup;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 微信直连商户应用保存参数
|
||||
///
|
||||
/// 保存/更新微信直连商户应用时接收的请求参数,含商户号、通道商户号、应用名称和微信应用AppId。
|
||||
///
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "微信直连商户应用保存参数")
|
||||
public class WechatDirectAppParam {
|
||||
|
||||
@NotNull(message = "{validation.field.id.notNull}", groups = ValidationGroup.edit.class)
|
||||
@Schema(description = "主键,新增时不传")
|
||||
private Long id;
|
||||
|
||||
@NotBlank(message = "{validation.field.mchNo.notBlank}")
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
@NotBlank(message = "{validation.field.channelMerchantNo.notBlank}")
|
||||
@Schema(description = "通道商户号")
|
||||
private String channelMchNo;
|
||||
|
||||
@NotBlank(message = "{validation.field.appName.notBlank}")
|
||||
@Schema(description = "应用名称")
|
||||
private String appName;
|
||||
|
||||
@NotBlank(message = "{validation.field.wxAppId.notBlank}")
|
||||
@Schema(description = "微信应用AppId")
|
||||
private String wxAppId;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.dromara.daxpay.channel.wechat.param.direct;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 微信直连密钥配置保存参数
|
||||
///
|
||||
/// 保存/更新微信直连密钥和证书时接收的请求参数,含通道商户号和APIv3密钥等信息。
|
||||
///
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "微信直连密钥配置保存参数")
|
||||
public class WechatDirectKeyConfigParam {
|
||||
|
||||
@NotBlank(message = "{validation.field.channelMerchantNo.notBlank}")
|
||||
@Schema(description = "通道商户号")
|
||||
private String channelMchNo;
|
||||
|
||||
@NotBlank(message = "{validation.field.mchNo.notBlank}")
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
@Schema(description = "APIv3密钥")
|
||||
private String apiKeyV3;
|
||||
|
||||
@Schema(description = "支付公钥")
|
||||
private String publicKey;
|
||||
|
||||
@Schema(description = "支付公钥ID")
|
||||
private String publicKeyId;
|
||||
|
||||
@Schema(description = "商户私钥")
|
||||
private String privateKey;
|
||||
|
||||
@Schema(description = "商户证书")
|
||||
private String privateCert;
|
||||
|
||||
@Schema(description = "证书序列号")
|
||||
private String certSerialNo;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.dromara.daxpay.channel.wechat.result.direct;
|
||||
|
||||
import org.dromara.daxpay.platform.core.result.BaseResult;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 微信直连商户应用授权认证配置
|
||||
///
|
||||
/// 微信直连商户应用授权认证配置的返回结果对象,含商户号、通道商户号,以及应用密钥配置状态和授权回调地址。
|
||||
///
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "微信直连商户应用授权认证配置")
|
||||
public class WechatDirectAppAuthConfigResult extends BaseResult {
|
||||
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
@Schema(description = "通道商户号")
|
||||
private String channelMchNo;
|
||||
|
||||
@Schema(description = "关联应用ID")
|
||||
private Long wechatDirectAppId;
|
||||
|
||||
@Schema(description = "是否已配置应用密钥")
|
||||
private Boolean appSecretConfigured;
|
||||
|
||||
@Schema(description = "授权回调地址")
|
||||
private String authCallbackUrl;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.dromara.daxpay.channel.wechat.result.direct;
|
||||
|
||||
import org.dromara.daxpay.payment.common.result.MchTradeBaseResult;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 微信直连商户应用
|
||||
///
|
||||
/// 微信直连商户应用的返回结果对象,包含通道商户号、应用名称和微信应用AppId等信息。
|
||||
///
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "微信直连商户应用")
|
||||
public class WechatDirectAppResult extends MchTradeBaseResult {
|
||||
|
||||
@Schema(description = "通道商户号")
|
||||
private String channelMchNo;
|
||||
|
||||
@Schema(description = "应用名称")
|
||||
private String appName;
|
||||
|
||||
@Schema(description = "微信应用AppId")
|
||||
private String wxAppId;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.dromara.daxpay.channel.wechat.result.direct;
|
||||
|
||||
import org.dromara.daxpay.platform.common.json.sensitive.SensitiveInfo;
|
||||
import org.dromara.daxpay.platform.core.result.BaseResult;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 微信直连密钥配置
|
||||
///
|
||||
/// 微信直连密钥和证书的返回结果对象,含商户号、通道商户号信息,敏感字段脱敏展示。
|
||||
///
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "微信直连密钥配置")
|
||||
public class WechatDirectKeyConfigResult extends BaseResult {
|
||||
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
@Schema(description = "通道商户号")
|
||||
private String channelMchNo;
|
||||
|
||||
@SensitiveInfo(front = 12, end = 12)
|
||||
@Schema(description = "APIv3密钥")
|
||||
private String apiKeyV3;
|
||||
|
||||
@SensitiveInfo(front = 12, end = 12)
|
||||
@Schema(description = "支付公钥")
|
||||
private String publicKey;
|
||||
|
||||
@Schema(description = "支付公钥ID")
|
||||
private String publicKeyId;
|
||||
|
||||
@SensitiveInfo(front = 12, end = 12)
|
||||
@Schema(description = "商户私钥")
|
||||
private String privateKey;
|
||||
|
||||
@SensitiveInfo(front = 12, end = 12)
|
||||
@Schema(description = "商户证书")
|
||||
private String privateCert;
|
||||
|
||||
@Schema(description = "证书序列号")
|
||||
private String certSerialNo;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.dromara.daxpay.channel.wechat.service.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.convert.direct.WechatDirectAppAuthConfigConvert;
|
||||
import org.dromara.daxpay.channel.wechat.dao.direct.WechatDirectAppManager;
|
||||
import org.dromara.daxpay.channel.wechat.dao.direct.WechatDirectAppAuthConfigManager;
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectApp;
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectAppAuthConfig;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectAppAuthConfigParam;
|
||||
import org.dromara.daxpay.platform.core.code.CommonErrorCode;
|
||||
import org.dromara.daxpay.platform.core.exception.BizInfoException;
|
||||
import org.dromara.daxpay.platform.core.exception.DataNotExistException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/// # 微信直连商户应用授权认证配置
|
||||
///
|
||||
/// 管理直连商户应用的授权认证配置,查询时不存在则创建默认记录,保存时校验应用归属关系。
|
||||
///
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class WechatDirectAppAuthConfigService {
|
||||
|
||||
private final WechatDirectAppAuthConfigManager wechatDirectAppAuthConfigManager;
|
||||
private final WechatDirectAppManager wechatDirectAppManager;
|
||||
|
||||
/// 根据应用ID查询授权认证配置, 不存在则创建默认记录
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public WechatDirectAppAuthConfig findByWechatDirectAppId(Long wechatDirectAppId) {
|
||||
var app = wechatDirectAppManager.findById(wechatDirectAppId)
|
||||
.orElseThrow(() -> new DataNotExistException("error.channel.wechat.appNotFound"));
|
||||
var existing = wechatDirectAppAuthConfigManager.findByWechatDirectAppId(wechatDirectAppId);
|
||||
if (existing.isPresent()) {
|
||||
return existing.get();
|
||||
}
|
||||
var config = new WechatDirectAppAuthConfig()
|
||||
.setChannelMchNo(app.getChannelMchNo())
|
||||
.setWechatDirectAppId(wechatDirectAppId);
|
||||
config.setMchNo(app.getMchNo());
|
||||
wechatDirectAppAuthConfigManager.save(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
/// 保存应用授权认证配置(更新)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(WechatDirectAppAuthConfigParam param) {
|
||||
var app = wechatDirectAppManager.findById(param.getWechatDirectAppId())
|
||||
.orElseThrow(() -> new DataNotExistException("error.channel.wechat.appNotFound"));
|
||||
if (!app.getMchNo().equals(param.getMchNo()) || !app.getChannelMchNo().equals(param.getChannelMchNo())) {
|
||||
throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "error.channel.wechat.appNotFound");
|
||||
}
|
||||
var config = this.findByWechatDirectAppId(param.getWechatDirectAppId());
|
||||
config.setAuthCallbackUrl(param.getAuthCallbackUrl());
|
||||
WechatDirectAppAuthConfigConvert.CONVERT.copy(param, config);
|
||||
wechatDirectAppAuthConfigManager.updateById(config);
|
||||
}
|
||||
|
||||
/// 删除应用授权认证配置
|
||||
public void deleteByWechatDirectAppId(Long wechatDirectAppId) {
|
||||
wechatDirectAppAuthConfigManager.deleteByWechatDirectAppId(wechatDirectAppId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package org.dromara.daxpay.channel.wechat.service.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.convert.direct.WechatDirectAppConvert;
|
||||
import org.dromara.daxpay.channel.wechat.dao.direct.WechatDirectAppManager;
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectApp;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectAppParam;
|
||||
import org.dromara.daxpay.channel.wechat.result.direct.WechatDirectAppResult;
|
||||
import org.dromara.daxpay.channel.wechat.service.direct.WechatDirectAppAuthConfigService;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.util.MpUtil;
|
||||
import org.dromara.daxpay.platform.core.code.CommonErrorCode;
|
||||
import org.dromara.daxpay.platform.core.exception.BizInfoException;
|
||||
import org.dromara.daxpay.platform.core.exception.DataNotExistException;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/// # 微信直连商户应用管理
|
||||
///
|
||||
/// 提供直连商户应用的增删改查功能,包含同一通道商户下应用ID的唯一性校验和操作范围校验(防止跨商户操作)。
|
||||
///
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class WechatDirectAppService {
|
||||
|
||||
private final WechatDirectAppManager wechatDirectAppManager;
|
||||
private final WechatDirectAppAuthConfigService wechatDirectAppAuthConfigService;
|
||||
|
||||
/// 根据商户号和通道商户号查询应用列表
|
||||
public List<WechatDirectAppResult> listByMchNoAndChannelMchNo(String mchNo, String channelMchNo) {
|
||||
var list = wechatDirectAppManager.listByMchNoAndChannelMchNo(mchNo, channelMchNo);
|
||||
return MpUtil.toListResult(list);
|
||||
}
|
||||
|
||||
/// 根据ID查询应用详情
|
||||
public WechatDirectAppResult findById(Long id) {
|
||||
return wechatDirectAppManager.findById(id)
|
||||
.map(WechatDirectApp::toResult)
|
||||
.orElseThrow(() -> new DataNotExistException("error.channel.wechat.appNotFound"));
|
||||
}
|
||||
|
||||
/// 判断同一通道商户下微信应用ID是否已存在
|
||||
public boolean existsWxAppIdByChannel(String mchNo, String channelMchNo, String wxAppId, Long excludeId) {
|
||||
if (StrUtil.hasBlank(mchNo, channelMchNo, wxAppId)) {
|
||||
return false;
|
||||
}
|
||||
return wechatDirectAppManager.existsByChannelMchNoAndWxAppId(mchNo, channelMchNo, wxAppId, excludeId);
|
||||
}
|
||||
|
||||
/// 新增微信直连商户应用
|
||||
public void add(WechatDirectAppParam param) {
|
||||
this.assertWxAppIdUnique(param.getMchNo(), param.getChannelMchNo(), param.getWxAppId(), null);
|
||||
var entity = WechatDirectAppConvert.CONVERT.toEntity(param);
|
||||
wechatDirectAppManager.save(entity);
|
||||
}
|
||||
|
||||
/// 更新微信直连商户应用
|
||||
public void update(WechatDirectAppParam param) {
|
||||
var entity = wechatDirectAppManager.findById(param.getId())
|
||||
.orElseThrow(() -> new DataNotExistException("error.channel.wechat.appNotFound"));
|
||||
this.assertScopeMatch(entity, param.getMchNo(), param.getChannelMchNo());
|
||||
this.assertWxAppIdUnique(entity.getMchNo(), entity.getChannelMchNo(), param.getWxAppId(), param.getId());
|
||||
WechatDirectAppConvert.CONVERT.copy(param, entity);
|
||||
wechatDirectAppManager.updateById(entity);
|
||||
}
|
||||
|
||||
/// 删除应用(级联删除授权认证配置)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long id) {
|
||||
wechatDirectAppManager.findById(id)
|
||||
.orElseThrow(() -> new DataNotExistException("error.channel.wechat.appNotFound"));
|
||||
wechatDirectAppAuthConfigService.deleteByWechatDirectAppId(id);
|
||||
wechatDirectAppManager.deleteById(id);
|
||||
}
|
||||
|
||||
/// 校验同一通道商户下应用ID唯一
|
||||
private void assertWxAppIdUnique(String mchNo, String channelMchNo, String wxAppId, Long excludeId) {
|
||||
if (this.existsWxAppIdByChannel(mchNo, channelMchNo, wxAppId, excludeId)) {
|
||||
throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "error.channel.wechat.appIdDuplicate");
|
||||
}
|
||||
}
|
||||
|
||||
/// 校验操作范围与记录归属一致
|
||||
private void assertScopeMatch(WechatDirectApp entity, String mchNo, String channelMchNo) {
|
||||
if (!entity.getMchNo().equals(mchNo) || !entity.getChannelMchNo().equals(channelMchNo)) {
|
||||
throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "error.channel.wechat.appNotFound");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.dromara.daxpay.channel.wechat.service.direct;
|
||||
|
||||
import org.dromara.daxpay.channel.wechat.convert.direct.WechatDirectKeyConfigConvert;
|
||||
import org.dromara.daxpay.channel.wechat.dao.direct.WechatDirectChannelMerchantManager;
|
||||
import org.dromara.daxpay.channel.wechat.dao.direct.WechatDirectKeyConfigManager;
|
||||
import org.dromara.daxpay.channel.wechat.entity.direct.WechatDirectKeyConfig;
|
||||
import org.dromara.daxpay.channel.wechat.param.direct.WechatDirectKeyConfigParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/// # 微信直连密钥配置
|
||||
///
|
||||
/// 管理直连商户维度的密钥和证书配置,查询时不存在则创建默认记录,保存时合并敏感字段。
|
||||
///
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class WechatDirectKeyConfigService {
|
||||
|
||||
private final WechatDirectKeyConfigManager wechatDirectKeyConfigManager;
|
||||
private final WechatDirectChannelMerchantManager wechatDirectChannelMerchantManager;
|
||||
|
||||
/// 根据通道商户号查询密钥配置, 不存在则创建默认记录
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public WechatDirectKeyConfig findByChannelMchNo(String channelMchNo) {
|
||||
var existing = wechatDirectKeyConfigManager.findByChannelMchNo(channelMchNo);
|
||||
if (existing.isPresent()) {
|
||||
return existing.get();
|
||||
}
|
||||
var config = new WechatDirectKeyConfig()
|
||||
.setChannelMchNo(channelMchNo);
|
||||
// 查询通道商户记录填充商户号
|
||||
wechatDirectChannelMerchantManager.findByChannelMchNo(channelMchNo)
|
||||
.ifPresent(mch -> config.setMchNo(mch.getMchNo()));
|
||||
wechatDirectKeyConfigManager.save(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
/// 保存密钥配置(更新)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(WechatDirectKeyConfigParam param) {
|
||||
var config = this.findByChannelMchNo(param.getChannelMchNo());
|
||||
config.setMchNo(param.getMchNo());
|
||||
WechatDirectKeyConfigConvert.CONVERT.copy(param, config);
|
||||
wechatDirectKeyConfigManager.updateById(config);
|
||||
}
|
||||
|
||||
/// 根据通道商户号删除密钥配置
|
||||
public void deleteByChannelMchNo(String channelMchNo) {
|
||||
wechatDirectKeyConfigManager.deleteByChannelMchNo(channelMchNo);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user