mirror of
https://gitee.com/dromara/dax-pay
synced 2026-08-10 06:46:04 +08:00
refactor(union): 银联通道去 direct 子包, 配置类与商户管理扁平化
- 删除 union/**/direct/ 子包, Controller/Service/Entity/Param/Result/Convert/Manager/Mapper 上移至模块根包 - UnionDirectConfigAssembler → UnionConfigAssembler, UnionDirectKeyConfig* → UnionKeyConfig*, UnionDirectChannelMerchant* → UnionChannelMerchant* - 各 strategy/callback 引用同步更新 - pom 描述与产品策略注释「直连银联 ACP」→「银联 ACP」
This commit is contained in:
@@ -12,5 +12,5 @@
|
||||
|
||||
<artifactId>daxpay-channel-union</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>云闪付(直连银联 ACP)支付通道</description>
|
||||
<description>云闪付(银联 ACP)支付通道</description>
|
||||
</project>
|
||||
|
||||
@@ -6,9 +6,9 @@ import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/// # 云闪付(直连银联 ACP)支付实现
|
||||
/// # 云闪付(银联 ACP)支付实现
|
||||
///
|
||||
/// 云闪付直连银联全渠道支付平台, 通过证书签名支持主扫/被扫/H5 支付。
|
||||
/// 云闪付对接银联全渠道支付平台, 通过证书签名支持主扫/被扫/H5 支付。
|
||||
/// 主应用通过声明式 HTTP 客户端调用子应用 dax-pay-channel-one 完成实际通道交互。
|
||||
@AutoConfiguration
|
||||
@ConfigurationPropertiesScan
|
||||
|
||||
@@ -5,7 +5,7 @@ import lombok.Data;
|
||||
/// # 云闪付 SDK 凭证
|
||||
///
|
||||
/// 与子应用 dax-pay-channel-one 的 `UnionSdkCredential` 镜像, 跨 HTTP 传输时字段对齐。
|
||||
/// 主应用从直连配置(union_direct_key_config)提取商户号、签名类型与三证书后组装, 下发给子应用。
|
||||
/// 主应用从密钥配置(union_key_config)提取商户号、签名类型与三证书后组装, 下发给子应用。
|
||||
///
|
||||
/// 银联 ACP 采用 RSA2 证书签名(私钥证书 PKCS12 + 中级/根证书), 三证书均为 Base64 字符串。
|
||||
@Data
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package cn.daxpay.open.channel.union.controller.direct;
|
||||
package cn.daxpay.open.channel.union.controller;
|
||||
|
||||
import cn.daxpay.open.channel.union.param.direct.UnionDirectChannelMerchantCreateParam;
|
||||
import cn.daxpay.open.channel.union.param.direct.UnionDirectKeyConfigParam;
|
||||
import cn.daxpay.open.channel.union.result.direct.UnionDirectKeyConfigResult;
|
||||
import cn.daxpay.open.channel.union.service.direct.UnionDirectChannelMerchantService;
|
||||
import cn.daxpay.open.channel.union.service.direct.UnionDirectKeyConfigService;
|
||||
import cn.daxpay.open.channel.union.param.UnionChannelMerchantCreateParam;
|
||||
import cn.daxpay.open.channel.union.param.UnionKeyConfigParam;
|
||||
import cn.daxpay.open.channel.union.result.UnionKeyConfigResult;
|
||||
import cn.daxpay.open.channel.union.service.UnionChannelMerchantService;
|
||||
import cn.daxpay.open.channel.union.service.UnionKeyConfigService;
|
||||
import cn.daxpay.open.platform.core.annotation.PermCode;
|
||||
import cn.daxpay.open.platform.core.code.PermCodes;
|
||||
import cn.daxpay.open.platform.core.rest.Res;
|
||||
@@ -21,36 +21,36 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/// # 云闪付直连通道商户管理
|
||||
/// # 云闪付通道商户管理
|
||||
///
|
||||
/// 提供通道商户创建和 RSA2 证书配置管理。
|
||||
/// 银联商户号(merId)创建时录入, 私钥/中级/根证书由密钥配置维护。
|
||||
@PermCode(menuCode = PermCodes.Channel.Merchant.MENU)
|
||||
@Validated
|
||||
@Tag(name = "云闪付直连通道商户管理")
|
||||
@Tag(name = "云闪付通道商户管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/union/direct-channel-merchant")
|
||||
@RequestMapping("/admin/union/channel-merchant")
|
||||
@RequiredArgsConstructor
|
||||
public class UnionDirectChannelMerchantController {
|
||||
public class UnionChannelMerchantController {
|
||||
|
||||
private final UnionDirectChannelMerchantService unionDirectChannelMerchantService;
|
||||
private final UnionDirectKeyConfigService unionDirectKeyConfigService;
|
||||
private final UnionChannelMerchantService unionChannelMerchantService;
|
||||
private final UnionKeyConfigService unionKeyConfigService;
|
||||
|
||||
@PermCode(code = PermCodes.Action.MANAGE)
|
||||
@Operation(summary = "创建云闪付直连通道商户")
|
||||
@Operation(summary = "创建云闪付通道商户")
|
||||
@PostMapping("/create")
|
||||
public Result<Void> create(@RequestBody @Validated UnionDirectChannelMerchantCreateParam param) {
|
||||
unionDirectChannelMerchantService.create(param);
|
||||
public Result<Void> create(@RequestBody @Validated UnionChannelMerchantCreateParam param) {
|
||||
unionChannelMerchantService.create(param);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@PermCode(code = PermCodes.Action.VIEW)
|
||||
@Operation(summary = "根据通道商户号查询证书配置")
|
||||
@GetMapping("/find-key-config")
|
||||
public Result<UnionDirectKeyConfigResult> findKeyConfig(
|
||||
public Result<UnionKeyConfigResult> findKeyConfig(
|
||||
@NotBlank(message = "{validation.field.channelMerchantNo.notBlank}") String channelMchNo,
|
||||
@NotNull(message = "{validation.field.sandbox.notNull}") Boolean sandbox) {
|
||||
var config = unionDirectKeyConfigService.findByChannelMchNo(channelMchNo, sandbox);
|
||||
var config = unionKeyConfigService.findByChannelMchNo(channelMchNo, sandbox);
|
||||
var result = config.toResult();
|
||||
result.setKeyPrivateCertConfigured(config.getKeyPrivateCert() != null);
|
||||
result.setKeyPrivateCertPwdConfigured(config.getKeyPrivateCertPwd() != null);
|
||||
@@ -60,8 +60,8 @@ public class UnionDirectChannelMerchantController {
|
||||
@PermCode(code = PermCodes.Action.MANAGE)
|
||||
@Operation(summary = "保存证书配置")
|
||||
@PostMapping("/save-key-config")
|
||||
public Result<Void> saveKeyConfig(@RequestBody @Validated UnionDirectKeyConfigParam param) {
|
||||
unionDirectKeyConfigService.save(param);
|
||||
public Result<Void> saveKeyConfig(@RequestBody @Validated UnionKeyConfigParam param) {
|
||||
unionKeyConfigService.save(param);
|
||||
return Res.ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.daxpay.open.channel.union.convert;
|
||||
|
||||
import cn.daxpay.open.channel.union.entity.UnionKeyConfig;
|
||||
import cn.daxpay.open.channel.union.param.UnionKeyConfigParam;
|
||||
import cn.daxpay.open.channel.union.result.UnionKeyConfigResult;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.NullValuePropertyMappingStrategy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/// # 云闪付密钥配置转换
|
||||
@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
|
||||
public interface UnionKeyConfigConvert {
|
||||
UnionKeyConfigConvert CONVERT = Mappers.getMapper(UnionKeyConfigConvert.class);
|
||||
|
||||
UnionKeyConfigResult toResult(UnionKeyConfig entity);
|
||||
|
||||
void copy(UnionKeyConfigParam param, @MappingTarget UnionKeyConfig entity);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package cn.daxpay.open.channel.union.convert.direct;
|
||||
|
||||
import cn.daxpay.open.channel.union.entity.direct.UnionDirectKeyConfig;
|
||||
import cn.daxpay.open.channel.union.param.direct.UnionDirectKeyConfigParam;
|
||||
import cn.daxpay.open.channel.union.result.direct.UnionDirectKeyConfigResult;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.NullValuePropertyMappingStrategy;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/// # 云闪付直连密钥配置转换
|
||||
@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
|
||||
public interface UnionDirectKeyConfigConvert {
|
||||
UnionDirectKeyConfigConvert CONVERT = Mappers.getMapper(UnionDirectKeyConfigConvert.class);
|
||||
|
||||
UnionDirectKeyConfigResult toResult(UnionDirectKeyConfig entity);
|
||||
|
||||
void copy(UnionDirectKeyConfigParam param, @MappingTarget UnionDirectKeyConfig entity);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.daxpay.open.channel.union.dao;
|
||||
|
||||
import cn.daxpay.open.channel.union.entity.UnionKeyConfig;
|
||||
import cn.daxpay.open.platform.common.mybatisplus.impl.BaseManager;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/// # 云闪付密钥配置
|
||||
@Repository
|
||||
public class UnionKeyConfigManager extends BaseManager<UnionKeyConfigMapper, UnionKeyConfig> {
|
||||
|
||||
/// 根据通道商户号和沙箱标志查询(双环境并存)
|
||||
public Optional<UnionKeyConfig> findByChannelMchNoAndSandbox(String channelMchNo, boolean sandbox) {
|
||||
return lambdaQuery()
|
||||
.eq(UnionKeyConfig::getChannelMchNo, channelMchNo)
|
||||
.eq(UnionKeyConfig::getSandbox, sandbox)
|
||||
.oneOpt();
|
||||
}
|
||||
|
||||
/// 根据通道商户号删除
|
||||
public void deleteByChannelMchNo(String channelMchNo) {
|
||||
lambdaUpdate()
|
||||
.eq(UnionKeyConfig::getChannelMchNo, channelMchNo)
|
||||
.remove();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.daxpay.open.channel.union.dao;
|
||||
|
||||
import cn.daxpay.open.channel.union.entity.UnionKeyConfig;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/// # 云闪付密钥配置
|
||||
@Mapper
|
||||
public interface UnionKeyConfigMapper extends MPJBaseMapper<UnionKeyConfig> {
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package cn.daxpay.open.channel.union.dao.direct;
|
||||
|
||||
import cn.daxpay.open.channel.union.entity.direct.UnionDirectKeyConfig;
|
||||
import cn.daxpay.open.platform.common.mybatisplus.impl.BaseManager;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/// # 云闪付直连密钥配置
|
||||
@Repository
|
||||
public class UnionDirectKeyConfigManager extends BaseManager<UnionDirectKeyConfigMapper, UnionDirectKeyConfig> {
|
||||
|
||||
/// 根据通道商户号和沙箱标志查询(双环境并存)
|
||||
public Optional<UnionDirectKeyConfig> findByChannelMchNoAndSandbox(String channelMchNo, boolean sandbox) {
|
||||
return lambdaQuery()
|
||||
.eq(UnionDirectKeyConfig::getChannelMchNo, channelMchNo)
|
||||
.eq(UnionDirectKeyConfig::getSandbox, sandbox)
|
||||
.oneOpt();
|
||||
}
|
||||
|
||||
/// 根据通道商户号删除
|
||||
public void deleteByChannelMchNo(String channelMchNo) {
|
||||
lambdaUpdate()
|
||||
.eq(UnionDirectKeyConfig::getChannelMchNo, channelMchNo)
|
||||
.remove();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package cn.daxpay.open.channel.union.dao.direct;
|
||||
|
||||
import cn.daxpay.open.channel.union.entity.direct.UnionDirectKeyConfig;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/// # 云闪付直连密钥配置
|
||||
@Mapper
|
||||
public interface UnionDirectKeyConfigMapper extends MPJBaseMapper<UnionDirectKeyConfig> {
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.daxpay.open.channel.union.entity.direct;
|
||||
package cn.daxpay.open.channel.union.entity;
|
||||
|
||||
import cn.daxpay.open.channel.union.convert.direct.UnionDirectKeyConfigConvert;
|
||||
import cn.daxpay.open.channel.union.result.direct.UnionDirectKeyConfigResult;
|
||||
import cn.daxpay.open.channel.union.convert.UnionKeyConfigConvert;
|
||||
import cn.daxpay.open.channel.union.result.UnionKeyConfigResult;
|
||||
import cn.daxpay.open.payment.common.entity.MchBaseEntity;
|
||||
import cn.daxpay.open.platform.common.mybatisplus.function.ToResult;
|
||||
import cn.daxpay.open.platform.common.mybatisplus.handler.encrypt.DataEncryptTypeHandler;
|
||||
@@ -12,9 +12,9 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 云闪付直连配置
|
||||
/// # 云闪付密钥配置
|
||||
///
|
||||
/// 直连商户维度的通道配置, 含银联商户号(merId)与 RSA2 三证书, 敏感字段(私钥证书/密码)加密存储。
|
||||
/// 商户维度的通道配置, 含银联商户号(merId)与 RSA2 三证书, 敏感字段(私钥证书/密码)加密存储。
|
||||
/// merId 创建时录入不可修改, 三证书由密钥配置维护。
|
||||
///
|
||||
/// 银联 ACP 签名依赖证书(区别于银联商务的 HmacSHA256 无证书模式):
|
||||
@@ -23,8 +23,8 @@ import lombok.experimental.Accessors;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "union_direct_key_config", autoResultMap = true)
|
||||
public class UnionDirectKeyConfig extends MchBaseEntity implements ToResult<UnionDirectKeyConfigResult> {
|
||||
@TableName(value = "union_key_config", autoResultMap = true)
|
||||
public class UnionKeyConfig extends MchBaseEntity implements ToResult<UnionKeyConfigResult> {
|
||||
|
||||
/// 通道商户号
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
@@ -58,7 +58,7 @@ public class UnionDirectKeyConfig extends MchBaseEntity implements ToResult<Unio
|
||||
private Boolean sandbox;
|
||||
|
||||
@Override
|
||||
public UnionDirectKeyConfigResult toResult() {
|
||||
return UnionDirectKeyConfigConvert.CONVERT.toResult(this);
|
||||
public UnionKeyConfigResult toResult() {
|
||||
return UnionKeyConfigConvert.CONVERT.toResult(this);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
package cn.daxpay.open.channel.union.param.direct;
|
||||
package cn.daxpay.open.channel.union.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 云闪付直连通道商户绑定创建参数
|
||||
/// # 云闪付通道商户绑定创建参数
|
||||
///
|
||||
/// 创建时仅录入银联商户号(merId)与商户名称,
|
||||
/// RSA2 三证书(私钥/中级/根)由密钥配置单独维护,
|
||||
/// 沙箱环境由支付产品配置(pay_md_product_config.activeEnv)决定。
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "云闪付直连通道商户绑定创建参数")
|
||||
public class UnionDirectChannelMerchantCreateParam {
|
||||
@Schema(title = "云闪付通道商户绑定创建参数")
|
||||
public class UnionChannelMerchantCreateParam {
|
||||
|
||||
@NotBlank(message = "{validation.field.mchNo.notBlank}")
|
||||
@Schema(description = "商户号")
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.daxpay.open.channel.union.param.direct;
|
||||
package cn.daxpay.open.channel.union.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
@@ -6,14 +6,14 @@ import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 云闪付直连密钥配置保存参数
|
||||
/// # 云闪付密钥配置保存参数
|
||||
///
|
||||
/// 以 channelMchNo(通道商户号) 作为唯一标识定位记录,
|
||||
/// mchNo/merId(银联商户号) 为不可变身份字段, 创建时写入后永不可改, 不参与保存。
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "云闪付直连密钥配置保存参数")
|
||||
public class UnionDirectKeyConfigParam {
|
||||
@Schema(title = "云闪付密钥配置保存参数")
|
||||
public class UnionKeyConfigParam {
|
||||
|
||||
@NotBlank(message = "{validation.field.channelMerchantNo.notBlank}")
|
||||
@Schema(description = "通道商户号")
|
||||
@@ -1,14 +1,14 @@
|
||||
package cn.daxpay.open.channel.union.result.direct;
|
||||
package cn.daxpay.open.channel.union.result;
|
||||
|
||||
import cn.daxpay.open.platform.common.json.sensitive.SensitiveInfo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 云闪付直连密钥配置返回结果
|
||||
/// # 云闪付密钥配置返回结果
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UnionDirectKeyConfigResult {
|
||||
public class UnionKeyConfigResult {
|
||||
|
||||
/// 通道商户号
|
||||
private String channelMchNo;
|
||||
@@ -1,9 +1,9 @@
|
||||
package cn.daxpay.open.channel.union.service.direct;
|
||||
package cn.daxpay.open.channel.union.service;
|
||||
|
||||
import cn.daxpay.open.channel.union.code.UnionCode;
|
||||
import cn.daxpay.open.channel.union.dao.direct.UnionDirectKeyConfigManager;
|
||||
import cn.daxpay.open.channel.union.entity.direct.UnionDirectKeyConfig;
|
||||
import cn.daxpay.open.channel.union.param.direct.UnionDirectChannelMerchantCreateParam;
|
||||
import cn.daxpay.open.channel.union.dao.UnionKeyConfigManager;
|
||||
import cn.daxpay.open.channel.union.entity.UnionKeyConfig;
|
||||
import cn.daxpay.open.channel.union.param.UnionChannelMerchantCreateParam;
|
||||
import cn.daxpay.open.payment.merchant.dao.channel.ChannelMerchantManager;
|
||||
import cn.daxpay.open.payment.masterdata.dao.product.PayProductConfigManager;
|
||||
import cn.daxpay.open.payment.merchant.entity.channel.ChannelMerchant;
|
||||
@@ -14,25 +14,25 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/// # 云闪付直连通道商户管理
|
||||
/// # 云闪付通道商户管理
|
||||
///
|
||||
/// 管理通道商户绑定的创建。银联商户号(merId)在创建时录入直连配置表,
|
||||
/// 管理通道商户绑定的创建。银联商户号(merId)在创建时录入密钥配置表,
|
||||
/// RSA2 三证书(私钥/中级/根)由密钥配置单独维护。
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UnionDirectChannelMerchantService {
|
||||
public class UnionChannelMerchantService {
|
||||
|
||||
private final ChannelMerchantManager channelMerchantManager;
|
||||
private final PayProductConfigManager payProductConfigManager;
|
||||
private final UnionDirectKeyConfigManager unionDirectKeyConfigManager;
|
||||
private final UnionKeyConfigManager unionKeyConfigManager;
|
||||
|
||||
/// 创建通道商户绑定
|
||||
///
|
||||
/// 同时写入通用通道商户主表和云闪付直连配置表(含银联商户号 merId)。
|
||||
/// 同时写入通用通道商户主表和云闪付密钥配置表(含银联商户号 merId)。
|
||||
/// 三证书由密钥配置单独维护。
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void create(UnionDirectChannelMerchantCreateParam param) {
|
||||
public void create(UnionChannelMerchantCreateParam param) {
|
||||
// 生成通道商户号: 通道前缀 + 雪花ID
|
||||
String channelMchNo = ChannelMchNoGenerateUtil.generate("UNIONPAY");
|
||||
// 写通用通道商户主表
|
||||
@@ -47,14 +47,15 @@ public class UnionDirectChannelMerchantService {
|
||||
boolean sandbox = payProductConfigManager.isSandboxActive(param.getProduct());
|
||||
channelMerchant.setSandbox(sandbox);
|
||||
channelMerchantManager.save(channelMerchant);
|
||||
// 写云闪付直连配置(仅银联商户号 merId, 三证书由密钥配置单独维护)
|
||||
var keyConfig = new UnionDirectKeyConfig()
|
||||
// 写云闪付密钥配置(仅银联商户号 merId, 三证书由密钥配置单独维护)
|
||||
var keyConfig = new UnionKeyConfig()
|
||||
.setChannelMchNo(channelMchNo)
|
||||
.setMerId(param.getMerId())
|
||||
.setSignType(UnionCode.SIGN_TYPE_RSA2)
|
||||
.setCertSign(true);
|
||||
// mchNo 继承自 MchBaseEntity, 链式返回父类型, 单独赋值
|
||||
keyConfig.setMchNo(param.getMchNo());
|
||||
unionDirectKeyConfigManager.save(keyConfig);
|
||||
unionKeyConfigManager.save(keyConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.daxpay.open.channel.union.service.direct;
|
||||
package cn.daxpay.open.channel.union.service;
|
||||
|
||||
import cn.daxpay.open.channel.union.client.credential.UnionSdkCredential;
|
||||
import cn.daxpay.open.channel.union.entity.direct.UnionDirectKeyConfig;
|
||||
import cn.daxpay.open.channel.union.entity.UnionKeyConfig;
|
||||
import cn.daxpay.open.payment.merchant.dao.channel.ChannelMerchantManager;
|
||||
import cn.daxpay.open.payment.merchant.entity.channel.ChannelMerchant;
|
||||
import cn.daxpay.open.platform.core.exception.DataNotExistException;
|
||||
@@ -9,25 +9,25 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/// # 云闪付直连通道凭证组装器
|
||||
/// # 云闪付通道凭证组装器
|
||||
///
|
||||
/// 从通用通道商户主表([ChannelMerchant])读取固化 sandbox 标识,
|
||||
/// 从直连配置([UnionDirectKeyConfig])读取银联商户号(merId)与 RSA2 三证书,
|
||||
/// 从密钥配置([UnionKeyConfig])读取银联商户号(merId)与 RSA2 三证书,
|
||||
/// 组装为下发给子应用的通道调用凭证 [UnionSdkCredential]。
|
||||
///
|
||||
/// 沙箱标识直接读通道商户固化的 [ChannelMerchant#isSandbox]。
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UnionDirectConfigAssembler {
|
||||
public class UnionConfigAssembler {
|
||||
|
||||
private final UnionDirectKeyConfigService keyConfigService;
|
||||
private final UnionKeyConfigService keyConfigService;
|
||||
private final ChannelMerchantManager channelMerchantManager;
|
||||
|
||||
/// 组装直连商户的通道调用凭证(下发给子应用)
|
||||
/// 组装商户的通道调用凭证(下发给子应用)
|
||||
///
|
||||
/// @param mchNo 商户号(定位通用通道商户主表)
|
||||
/// @param channelMchNo 通道商户号(定位直连配置)
|
||||
/// @param channelMchNo 通道商户号(定位密钥配置)
|
||||
/// @param capability 支付能力编码(保留对齐签名, 银联不使用)
|
||||
/// @return 云闪付 SDK 凭证
|
||||
public UnionSdkCredential buildConfig(String mchNo, String channelMchNo, String capability) {
|
||||
@@ -35,8 +35,8 @@ public class UnionDirectConfigAssembler {
|
||||
ChannelMerchant channelMerchant = channelMerchantManager.findByMchNoAndChannelMchNo(mchNo, channelMchNo)
|
||||
.orElseThrow(() -> new DataNotExistException("error.payment.channel.channelMerchantNotExist"));
|
||||
boolean sandbox = channelMerchant.isSandbox();
|
||||
// 2. 直连配置(银联商户号 merId + RSA2 三证书)
|
||||
UnionDirectKeyConfig keyConfig = keyConfigService.findByChannelMchNo(channelMchNo, sandbox);
|
||||
// 2. 密钥配置(银联商户号 merId + RSA2 三证书)
|
||||
UnionKeyConfig keyConfig = keyConfigService.findByChannelMchNo(channelMchNo, sandbox);
|
||||
// 3. 组装凭证
|
||||
var credential = new UnionSdkCredential();
|
||||
credential.setMerId(keyConfig.getMerId());
|
||||
@@ -1,35 +1,35 @@
|
||||
package cn.daxpay.open.channel.union.service.direct;
|
||||
package cn.daxpay.open.channel.union.service;
|
||||
|
||||
import cn.daxpay.open.channel.union.code.UnionCode;
|
||||
import cn.daxpay.open.channel.union.convert.direct.UnionDirectKeyConfigConvert;
|
||||
import cn.daxpay.open.channel.union.dao.direct.UnionDirectKeyConfigManager;
|
||||
import cn.daxpay.open.channel.union.entity.direct.UnionDirectKeyConfig;
|
||||
import cn.daxpay.open.channel.union.param.direct.UnionDirectKeyConfigParam;
|
||||
import cn.daxpay.open.channel.union.convert.UnionKeyConfigConvert;
|
||||
import cn.daxpay.open.channel.union.dao.UnionKeyConfigManager;
|
||||
import cn.daxpay.open.channel.union.entity.UnionKeyConfig;
|
||||
import cn.daxpay.open.channel.union.param.UnionKeyConfigParam;
|
||||
import cn.daxpay.open.payment.merchant.dao.channel.ChannelMerchantManager;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/// # 云闪付直连密钥配置
|
||||
/// # 云闪付密钥配置
|
||||
///
|
||||
/// 管理直连商户维度的银联证书配置, 查询时不存在则创建默认记录, 保存时合并证书字段。
|
||||
/// 管理商户维度的银联证书配置, 查询时不存在则创建默认记录, 保存时合并证书字段。
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UnionDirectKeyConfigService {
|
||||
public class UnionKeyConfigService {
|
||||
|
||||
private final UnionDirectKeyConfigManager unionDirectKeyConfigManager;
|
||||
private final UnionKeyConfigManager unionKeyConfigManager;
|
||||
private final ChannelMerchantManager channelMerchantManager;
|
||||
|
||||
/// 根据通道商户号查询密钥配置, 不存在则创建默认记录
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UnionDirectKeyConfig findByChannelMchNo(String channelMchNo, boolean sandbox) {
|
||||
var existing = unionDirectKeyConfigManager.findByChannelMchNoAndSandbox(channelMchNo, sandbox);
|
||||
public UnionKeyConfig findByChannelMchNo(String channelMchNo, boolean sandbox) {
|
||||
var existing = unionKeyConfigManager.findByChannelMchNoAndSandbox(channelMchNo, sandbox);
|
||||
if (existing.isPresent()) {
|
||||
return existing.get();
|
||||
}
|
||||
var config = new UnionDirectKeyConfig()
|
||||
var config = new UnionKeyConfig()
|
||||
.setChannelMchNo(channelMchNo)
|
||||
.setSignType(UnionCode.SIGN_TYPE_RSA2)
|
||||
.setCertSign(true)
|
||||
@@ -37,7 +37,7 @@ public class UnionDirectKeyConfigService {
|
||||
// 查询通用通道商户主表填充平台商户号(运营端写 MchBaseEntity 必须显式 mchNo)
|
||||
channelMerchantManager.findByChannelMchNo(channelMchNo)
|
||||
.ifPresent(mch -> config.setMchNo(mch.getMchNo()));
|
||||
unionDirectKeyConfigManager.save(config);
|
||||
unionKeyConfigManager.save(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -46,14 +46,15 @@ public class UnionDirectKeyConfigService {
|
||||
/// 以 channelMchNo 定位记录, 仅更新证书字段;
|
||||
/// mchNo/merId 为不可变身份字段(实体 FieldStrategy.NEVER), 由 findByChannelMchNo 从 DB 加载后保持不变。
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(UnionDirectKeyConfigParam param) {
|
||||
public void save(UnionKeyConfigParam param) {
|
||||
var config = this.findByChannelMchNo(param.getChannelMchNo(), Boolean.TRUE.equals(param.getSandbox()));
|
||||
UnionDirectKeyConfigConvert.CONVERT.copy(param, config);
|
||||
unionDirectKeyConfigManager.updateById(config);
|
||||
UnionKeyConfigConvert.CONVERT.copy(param, config);
|
||||
unionKeyConfigManager.updateById(config);
|
||||
}
|
||||
|
||||
/// 根据通道商户号删除密钥配置
|
||||
public void deleteByChannelMchNo(String channelMchNo) {
|
||||
unionDirectKeyConfigManager.deleteByChannelMchNo(channelMchNo);
|
||||
unionKeyConfigManager.deleteByChannelMchNo(channelMchNo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import cn.daxpay.open.channel.union.client.credential.UnionSdkCredential;
|
||||
import cn.daxpay.open.channel.union.client.req.UnionCallbackParseReq;
|
||||
import cn.daxpay.open.channel.union.client.resp.UnionCallbackParseResp;
|
||||
import cn.daxpay.open.channel.union.code.UnionCode;
|
||||
import cn.daxpay.open.channel.union.service.direct.UnionDirectConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.UnionConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.util.UnionDateUtil;
|
||||
import cn.daxpay.open.payment.common.result.DaxResult;
|
||||
import cn.daxpay.open.payment.trade.record.service.PayCallbackRecordService;
|
||||
@@ -34,7 +34,7 @@ import java.util.Map;
|
||||
public class UnionPayCallbackService {
|
||||
|
||||
private final UnionChannelClient unionChannelClient;
|
||||
private final UnionDirectConfigAssembler configAssembler;
|
||||
private final UnionConfigAssembler configAssembler;
|
||||
private final PayCallbackService payCallbackService;
|
||||
private final PayCallbackRecordService payCallbackRecordService;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import cn.daxpay.open.channel.union.client.credential.UnionSdkCredential;
|
||||
import cn.daxpay.open.channel.union.client.req.UnionCallbackParseReq;
|
||||
import cn.daxpay.open.channel.union.client.resp.UnionCallbackParseResp;
|
||||
import cn.daxpay.open.channel.union.code.UnionCode;
|
||||
import cn.daxpay.open.channel.union.service.direct.UnionDirectConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.UnionConfigAssembler;
|
||||
import cn.daxpay.open.payment.common.result.DaxResult;
|
||||
import cn.daxpay.open.payment.trade.record.service.PayCallbackRecordService;
|
||||
import cn.daxpay.open.payment.trade.runtime.bo.RefundCallbackData;
|
||||
@@ -31,7 +31,7 @@ import java.util.Objects;
|
||||
public class UnionRefundCallbackService {
|
||||
|
||||
private final UnionChannelClient unionChannelClient;
|
||||
private final UnionDirectConfigAssembler configAssembler;
|
||||
private final UnionConfigAssembler configAssembler;
|
||||
private final RefundCallbackService refundCallbackService;
|
||||
private final PayCallbackRecordService payCallbackRecordService;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package cn.daxpay.open.channel.union.strategy.pay;
|
||||
|
||||
import cn.daxpay.open.channel.union.client.credential.UnionSdkCredential;
|
||||
import cn.daxpay.open.channel.union.client.enums.UnionPayMethod;
|
||||
import cn.daxpay.open.channel.union.service.direct.UnionDirectConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.UnionConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.payment.close.UnionCloseService;
|
||||
import cn.daxpay.open.channel.union.strategy.UnionStrategySupport;
|
||||
import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum;
|
||||
@@ -23,12 +23,12 @@ import org.springframework.stereotype.Service;
|
||||
public class UnionPayCloseStrategy extends AbsPayCloseStrategy {
|
||||
|
||||
private final UnionCloseService unionCloseService;
|
||||
private final UnionDirectConfigAssembler unionDirectConfigAssembler;
|
||||
private final UnionConfigAssembler unionConfigAssembler;
|
||||
|
||||
@Override
|
||||
public CloseTypeEnum doClose(PayStrategyContext context, boolean useCancel) {
|
||||
PayTrade trade = context.getTrade();
|
||||
UnionSdkCredential credential = unionDirectConfigAssembler.buildConfig(
|
||||
UnionSdkCredential credential = unionConfigAssembler.buildConfig(
|
||||
trade.getMchNo(), context.getChannelMchNo(), context.getCapability());
|
||||
UnionPayMethod method = UnionStrategySupport.resolveMethod(context.getCapability());
|
||||
return unionCloseService.close(trade, credential, useCancel, method);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.daxpay.open.channel.union.strategy.pay;
|
||||
|
||||
import cn.daxpay.open.channel.union.client.credential.UnionSdkCredential;
|
||||
import cn.daxpay.open.channel.union.service.direct.UnionDirectConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.UnionConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.payment.pay.UnionPayService;
|
||||
import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum;
|
||||
import cn.daxpay.open.payment.strategy.pay.AbsNormalPayStrategy;
|
||||
@@ -22,13 +22,13 @@ import org.springframework.stereotype.Service;
|
||||
public class UnionPayPayStrategy extends AbsNormalPayStrategy {
|
||||
|
||||
private final UnionPayService unionPayService;
|
||||
private final UnionDirectConfigAssembler unionDirectConfigAssembler;
|
||||
private final UnionConfigAssembler unionConfigAssembler;
|
||||
|
||||
/// 支付前预处理: 组装通道凭证写入上下文
|
||||
@Override
|
||||
public void doBeforePay(PayStrategyContext context) {
|
||||
NormalPayParam payParam = context.getPayParam();
|
||||
UnionSdkCredential credential = unionDirectConfigAssembler.buildConfig(
|
||||
UnionSdkCredential credential = unionConfigAssembler.buildConfig(
|
||||
payParam.getMchNo(), payParam.getChannelMchNo(), payParam.getCapability());
|
||||
context.setChannelConfig(credential);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.Map;
|
||||
|
||||
/// # 云闪付产品策略
|
||||
///
|
||||
/// 云闪付为单一产品(直连银联 ACP), 含主扫([PayMethodEnum#UNION_QR]) / H5([PayMethodEnum#UNION_H5])
|
||||
/// 云闪付为单一产品(银联 ACP), 含主扫([PayMethodEnum#UNION_QR]) / H5([PayMethodEnum#UNION_H5])
|
||||
/// / 被扫([PayMethodEnum#UNION_BARCODE]) 三种支付方式, 方式→能力一对一同码。
|
||||
@Slf4j
|
||||
@Service
|
||||
|
||||
@@ -2,7 +2,7 @@ package cn.daxpay.open.channel.union.strategy.refund;
|
||||
|
||||
import cn.daxpay.open.channel.union.client.credential.UnionSdkCredential;
|
||||
import cn.daxpay.open.channel.union.client.enums.UnionPayMethod;
|
||||
import cn.daxpay.open.channel.union.service.direct.UnionDirectConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.UnionConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.payment.refund.UnionRefundService;
|
||||
import cn.daxpay.open.channel.union.strategy.UnionStrategySupport;
|
||||
import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum;
|
||||
@@ -22,11 +22,11 @@ import org.springframework.stereotype.Service;
|
||||
public class UnionPayRefundStrategy extends AbsRefundStrategy {
|
||||
|
||||
private final UnionRefundService unionRefundService;
|
||||
private final UnionDirectConfigAssembler unionDirectConfigAssembler;
|
||||
private final UnionConfigAssembler unionConfigAssembler;
|
||||
|
||||
@Override
|
||||
public RefundResultBo doRefund(RefundOrder refundOrder) {
|
||||
UnionSdkCredential credential = unionDirectConfigAssembler.buildConfig(
|
||||
UnionSdkCredential credential = unionConfigAssembler.buildConfig(
|
||||
refundOrder.getMchNo(), refundOrder.getChannelMchNo(), refundOrder.getCapability());
|
||||
UnionPayMethod method = UnionStrategySupport.resolveMethod(refundOrder.getCapability());
|
||||
return unionRefundService.refund(refundOrder, credential, method);
|
||||
|
||||
@@ -2,7 +2,7 @@ package cn.daxpay.open.channel.union.strategy.refund;
|
||||
|
||||
import cn.daxpay.open.channel.union.client.credential.UnionSdkCredential;
|
||||
import cn.daxpay.open.channel.union.client.enums.UnionPayMethod;
|
||||
import cn.daxpay.open.channel.union.service.direct.UnionDirectConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.UnionConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.payment.refund.UnionRefundSyncService;
|
||||
import cn.daxpay.open.channel.union.strategy.UnionStrategySupport;
|
||||
import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum;
|
||||
@@ -22,11 +22,11 @@ import org.springframework.stereotype.Service;
|
||||
public class UnionPaySyncRefundStrategy extends AbsSyncRefundStrategy {
|
||||
|
||||
private final UnionRefundSyncService unionRefundSyncService;
|
||||
private final UnionDirectConfigAssembler unionDirectConfigAssembler;
|
||||
private final UnionConfigAssembler unionConfigAssembler;
|
||||
|
||||
@Override
|
||||
public RefundResultBo doSync(RefundOrder refundOrder) {
|
||||
UnionSdkCredential credential = unionDirectConfigAssembler.buildConfig(
|
||||
UnionSdkCredential credential = unionConfigAssembler.buildConfig(
|
||||
refundOrder.getMchNo(), refundOrder.getChannelMchNo(), refundOrder.getCapability());
|
||||
UnionPayMethod method = UnionStrategySupport.resolveMethod(refundOrder.getCapability());
|
||||
return unionRefundSyncService.sync(refundOrder, credential, method);
|
||||
|
||||
@@ -2,7 +2,7 @@ package cn.daxpay.open.channel.union.strategy.sync;
|
||||
|
||||
import cn.daxpay.open.channel.union.client.credential.UnionSdkCredential;
|
||||
import cn.daxpay.open.channel.union.client.enums.UnionPayMethod;
|
||||
import cn.daxpay.open.channel.union.service.direct.UnionDirectConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.UnionConfigAssembler;
|
||||
import cn.daxpay.open.channel.union.service.payment.sync.UnionSyncService;
|
||||
import cn.daxpay.open.channel.union.strategy.UnionStrategySupport;
|
||||
import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum;
|
||||
@@ -22,11 +22,11 @@ import org.springframework.stereotype.Service;
|
||||
public class UnionPaySyncStrategy extends AbsSyncPayOrderStrategy {
|
||||
|
||||
private final UnionSyncService unionSyncService;
|
||||
private final UnionDirectConfigAssembler unionDirectConfigAssembler;
|
||||
private final UnionConfigAssembler unionConfigAssembler;
|
||||
|
||||
@Override
|
||||
public PaySyncResultBo doSync(PayStrategyContext context) {
|
||||
UnionSdkCredential credential = unionDirectConfigAssembler.buildConfig(
|
||||
UnionSdkCredential credential = unionConfigAssembler.buildConfig(
|
||||
context.getTrade().getMchNo(), context.getChannelMchNo(), context.getCapability());
|
||||
UnionPayMethod method = UnionStrategySupport.resolveMethod(context.getCapability());
|
||||
return unionSyncService.sync(context.getTrade(), credential, method);
|
||||
|
||||
Reference in New Issue
Block a user