mirror of
https://gitee.com/dromara/dax-pay
synced 2026-08-12 07:25:39 +08:00
refactor(transfer): 移除转账应用号(appId)依赖, 幂等键改为 bizTransferNo+mchNo
转账 appId 在通道发起/确认收款/回调全流程零消费, 纯属冗余: 前端不传 appId, 后端 resolveApp 强行解析商户默认应用塞入订单。删除4张转账表 app_id 列+升级脚本, 实体/Result/Query/Param/Manager/编排层全部去 appId, 幂等键由同一应用改为同一商户(回归DB注释语义)。
This commit is contained in:
@@ -3612,7 +3612,6 @@ CREATE TABLE "public"."pay_transfer_order_alipay" (
|
||||
"channel_mch_no" varchar(64) COLLATE "pg_catalog"."default",
|
||||
"out_transfer_no" varchar(150) COLLATE "pg_catalog"."default",
|
||||
"mch_no" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"app_id" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"amount" int8 NOT NULL,
|
||||
"currency" varchar(8) COLLATE "pg_catalog"."default" NOT NULL DEFAULT 'CNY'::character varying,
|
||||
"title" varchar(100) COLLATE "pg_catalog"."default",
|
||||
@@ -3627,6 +3626,7 @@ CREATE TABLE "public"."pay_transfer_order_alipay" (
|
||||
"payee_account" varchar(100) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"payee_name" varchar(100) COLLATE "pg_catalog"."default",
|
||||
"transfer_scene" varchar(50) COLLATE "pg_catalog"."default",
|
||||
"report_infos" varchar(4000) COLLATE "pg_catalog"."default",
|
||||
"pay_fund_order_id" varchar(64) COLLATE "pg_catalog"."default",
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
@@ -3641,7 +3641,6 @@ COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."biz_transfer_no" IS '商
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."channel_mch_no" IS '通道商户号(路由确定后写入, 凭证组装用)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."out_transfer_no" IS '通道转账单号(支付宝 order_id)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."app_id" IS '应用号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."amount" IS '转账金额(最小货币单位/分)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."currency" IS '币种';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."title" IS '转账标题';
|
||||
@@ -3656,6 +3655,7 @@ COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."payee_type" IS '收款
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."payee_account" IS '收款人账号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."payee_name" IS '收款人姓名';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."transfer_scene" IS '转账场景标识(支付宝=转账场景配置ID, FAIL重试时恢复场景用)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."report_infos" IS '转账场景报备信息(JSON序列化, FAIL重试时恢复报备用)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."pay_fund_order_id" IS '支付宝资金流水号(财务对账,区别于 out_transfer_no)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."create_time" IS '创建时间';
|
||||
@@ -3676,7 +3676,6 @@ CREATE TABLE "public"."pay_transfer_order_douyin" (
|
||||
"channel_mch_no" varchar(64) COLLATE "pg_catalog"."default",
|
||||
"out_transfer_no" varchar(150) COLLATE "pg_catalog"."default",
|
||||
"mch_no" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"app_id" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"amount" int8 NOT NULL,
|
||||
"currency" varchar(8) COLLATE "pg_catalog"."default" NOT NULL DEFAULT 'CNY'::character varying,
|
||||
"title" varchar(100) COLLATE "pg_catalog"."default",
|
||||
@@ -3691,6 +3690,7 @@ CREATE TABLE "public"."pay_transfer_order_douyin" (
|
||||
"payee_account" varchar(100) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"payee_name" varchar(100) COLLATE "pg_catalog"."default",
|
||||
"transfer_scene" varchar(50) COLLATE "pg_catalog"."default",
|
||||
"report_infos" varchar(4000) COLLATE "pg_catalog"."default",
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
"last_modifier" int8,
|
||||
@@ -3704,7 +3704,6 @@ COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."biz_transfer_no" IS '商
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."channel_mch_no" IS '通道商户号(路由确定后写入, 凭证组装用)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."out_transfer_no" IS '通道转账单号(抖音 orderId)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."app_id" IS '应用号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."amount" IS '转账金额(最小货币单位/分)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."currency" IS '币种';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."title" IS '转账标题';
|
||||
@@ -3718,6 +3717,8 @@ COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."error_msg" IS '错误信
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."payee_type" IS '收款人账号类型';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."payee_account" IS '收款人账号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."payee_name" IS '收款人姓名';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."transfer_scene" IS '转账场景标识(抖音=转账场景配置ID, FAIL重试时恢复场景用)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."report_infos" IS '转账场景报备信息(JSON序列化, FAIL重试时恢复报备用)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_douyin"."last_modifier" IS '最后修改人';
|
||||
@@ -3737,7 +3738,6 @@ CREATE TABLE "public"."pay_transfer_order_wechat" (
|
||||
"channel_mch_no" varchar(64) COLLATE "pg_catalog"."default",
|
||||
"out_transfer_no" varchar(150) COLLATE "pg_catalog"."default",
|
||||
"mch_no" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"app_id" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"amount" int8 NOT NULL,
|
||||
"currency" varchar(8) COLLATE "pg_catalog"."default" NOT NULL DEFAULT 'CNY'::character varying,
|
||||
"title" varchar(100) COLLATE "pg_catalog"."default",
|
||||
@@ -3765,7 +3765,6 @@ COMMENT ON COLUMN "public"."pay_transfer_order_wechat"."biz_transfer_no" IS '商
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_wechat"."channel_mch_no" IS '通道商户号(路由确定后写入, 凭证组装用)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_wechat"."out_transfer_no" IS '通道转账单号(微信 paymentNo)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_wechat"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_wechat"."app_id" IS '应用号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_wechat"."amount" IS '转账金额(最小货币单位/分)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_wechat"."currency" IS '币种';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_wechat"."title" IS '转账标题';
|
||||
@@ -3807,7 +3806,6 @@ CREATE TABLE "public"."pay_transfer_trade" (
|
||||
"relation_no" varchar(150) COLLATE "pg_catalog"."default",
|
||||
"finish_time" timestamptz(6),
|
||||
"title" varchar(100) COLLATE "pg_catalog"."default",
|
||||
"app_id" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"mch_no" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
|
||||
"creator" int8,
|
||||
"create_time" timestamptz(6),
|
||||
@@ -3830,7 +3828,6 @@ COMMENT ON COLUMN "public"."pay_transfer_trade"."out_transfer_no" IS '通道转
|
||||
COMMENT ON COLUMN "public"."pay_transfer_trade"."relation_no" IS '实际上送通道的商户转账号(反查权威)';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_trade"."finish_time" IS '转账完成时间';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_trade"."title" IS '转账标题';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_trade"."app_id" IS '应用号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_trade"."mch_no" IS '商户号';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_trade"."creator" IS '创建人';
|
||||
COMMENT ON COLUMN "public"."pay_transfer_trade"."create_time" IS '创建时间';
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
-- ----------------------------
|
||||
-- 数据库升级脚本(增量)
|
||||
-- 按时间顺序追加, 已有列/表请勿重复执行
|
||||
-- ----------------------------
|
||||
|
||||
-- 支付宝转账单新增转账场景标识列(支付宝=转账场景配置ID, FAIL重试时恢复场景用)
|
||||
ALTER TABLE "public"."pay_transfer_order_alipay" ADD COLUMN "transfer_scene" varchar(50) COLLATE "pg_catalog"."default";
|
||||
COMMENT ON COLUMN "public"."pay_transfer_order_alipay"."transfer_scene" IS '转账场景标识(支付宝=转账场景配置ID, FAIL重试时恢复场景用)';
|
||||
|
||||
@@ -104,7 +104,6 @@ public class TradeNoticeBridge {
|
||||
String content = JacksonUtil.toJson(TransferTradeConvert.CONVERT.toResult(trade));
|
||||
noticeDispatcher.dispatch(new NoticeDispatchCommand()
|
||||
.setMchNo(trade.getMchNo())
|
||||
.setAppId(trade.getAppId())
|
||||
.setEvent(event.getCode())
|
||||
.setBizId(trade.getId())
|
||||
.setBizNo(trade.getTradeNo())
|
||||
|
||||
@@ -24,11 +24,11 @@ public class AlipayTransferOrderManager
|
||||
return findByField(AlipayTransferOrder::getTransferNo, transferNo);
|
||||
}
|
||||
|
||||
/// 根据商户转账号和应用号查询(幂等查重主路径)
|
||||
public Optional<AlipayTransferOrder> findByBizTransferNo(String bizTransferNo, String appId) {
|
||||
/// 根据商户转账号和商户号查询(幂等查重主路径, 同一商户下唯一)
|
||||
public Optional<AlipayTransferOrder> findByBizTransferNo(String bizTransferNo, String mchNo) {
|
||||
return lambdaQuery()
|
||||
.eq(AlipayTransferOrder::getBizTransferNo, bizTransferNo)
|
||||
.eq(AlipayTransferOrder::getAppId, appId)
|
||||
.eq(AlipayTransferOrder::getMchNo, mchNo)
|
||||
.oneOpt();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@ public class DouyinTransferOrderManager
|
||||
return findByField(DouyinTransferOrder::getTransferNo, transferNo);
|
||||
}
|
||||
|
||||
/// 根据商户转账号和应用号查询(幂等查重主路径)
|
||||
public Optional<DouyinTransferOrder> findByBizTransferNo(String bizTransferNo, String appId) {
|
||||
/// 根据商户转账号和商户号查询(幂等查重主路径, 同一商户下唯一)
|
||||
public Optional<DouyinTransferOrder> findByBizTransferNo(String bizTransferNo, String mchNo) {
|
||||
return lambdaQuery()
|
||||
.eq(DouyinTransferOrder::getBizTransferNo, bizTransferNo)
|
||||
.eq(DouyinTransferOrder::getAppId, appId)
|
||||
.eq(DouyinTransferOrder::getMchNo, mchNo)
|
||||
.oneOpt();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,11 @@ public class WechatTransferOrderManager
|
||||
return findByField(WechatTransferOrder::getTransferNo, transferNo);
|
||||
}
|
||||
|
||||
/// 根据商户转账号和应用号查询(幂等查重主路径)
|
||||
public Optional<WechatTransferOrder> findByBizTransferNo(String bizTransferNo, String appId) {
|
||||
/// 根据商户转账号和商户号查询(幂等查重主路径, 同一商户下唯一)
|
||||
public Optional<WechatTransferOrder> findByBizTransferNo(String bizTransferNo, String mchNo) {
|
||||
return lambdaQuery()
|
||||
.eq(WechatTransferOrder::getBizTransferNo, bizTransferNo)
|
||||
.eq(WechatTransferOrder::getAppId, appId)
|
||||
.eq(WechatTransferOrder::getMchNo, mchNo)
|
||||
.oneOpt();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,6 @@ public class AlipayTransferOrder extends MchBaseEntity {
|
||||
|
||||
// ===== 身份 =====
|
||||
|
||||
/// 应用号
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private String appId;
|
||||
|
||||
/// 平台转账单号
|
||||
private String transferNo;
|
||||
|
||||
|
||||
@@ -28,10 +28,6 @@ public class DouyinTransferOrder extends MchBaseEntity {
|
||||
|
||||
// ===== 身份 =====
|
||||
|
||||
/// 应用号
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private String appId;
|
||||
|
||||
/// 平台转账单号
|
||||
private String transferNo;
|
||||
|
||||
|
||||
@@ -30,10 +30,6 @@ public class TransferTrade extends MchBaseEntity {
|
||||
/// 商户转账号(冗余自容器, 同步记录/日志免回容器; 权威在容器 bizTransferNo)
|
||||
private String bizTransferNo;
|
||||
|
||||
/// 应用号
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private String appId;
|
||||
|
||||
/// 关联通道转账单ID(容器主键)
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private Long containerId;
|
||||
|
||||
@@ -28,10 +28,6 @@ public class WechatTransferOrder extends MchBaseEntity {
|
||||
|
||||
// ===== 身份 =====
|
||||
|
||||
/// 应用号
|
||||
@TableField(updateStrategy = FieldStrategy.NEVER)
|
||||
private String appId;
|
||||
|
||||
/// 平台转账单号
|
||||
private String transferNo;
|
||||
|
||||
|
||||
@@ -19,11 +19,6 @@ public class AlipayTransferOrderQuery {
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
/// 应用号
|
||||
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
|
||||
@Schema(description = "应用号")
|
||||
private String appId;
|
||||
|
||||
/// 平台转账单号
|
||||
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
|
||||
@Schema(description = "平台转账单号")
|
||||
|
||||
@@ -19,11 +19,6 @@ public class DouyinTransferOrderQuery {
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
/// 应用号
|
||||
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
|
||||
@Schema(description = "应用号")
|
||||
private String appId;
|
||||
|
||||
/// 平台转账单号
|
||||
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
|
||||
@Schema(description = "平台转账单号")
|
||||
|
||||
@@ -26,11 +26,6 @@ public class TransferParam {
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
/// 应用号(可空, 默认取商户默认应用)
|
||||
@Size(max = 32, message = "应用号不可超过32位")
|
||||
@Schema(description = "应用号")
|
||||
private String appId;
|
||||
|
||||
/// 通道商户号(凭证组装与通道路由用)
|
||||
@NotBlank(message = "通道商户号必填")
|
||||
@Size(max = 64, message = "通道商户号不可超过64位")
|
||||
|
||||
@@ -19,11 +19,6 @@ public class TransferTradeQuery {
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
/// 应用号
|
||||
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
|
||||
@Schema(description = "应用号")
|
||||
private String appId;
|
||||
|
||||
/// 平台转账交易号
|
||||
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
|
||||
@Schema(description = "平台转账交易号")
|
||||
|
||||
@@ -19,11 +19,6 @@ public class WechatTransferOrderQuery {
|
||||
@Schema(description = "商户号")
|
||||
private String mchNo;
|
||||
|
||||
/// 应用号
|
||||
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
|
||||
@Schema(description = "应用号")
|
||||
private String appId;
|
||||
|
||||
/// 平台转账单号
|
||||
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
|
||||
@Schema(description = "平台转账单号")
|
||||
|
||||
@@ -31,10 +31,6 @@ public class AlipayTransferOrderResult extends BaseResult {
|
||||
@Schema(description = "商户名称")
|
||||
private String mchName;
|
||||
|
||||
/// 应用号
|
||||
@Schema(description = "应用号")
|
||||
private String appId;
|
||||
|
||||
/// 通道商户号
|
||||
@Schema(description = "通道商户号")
|
||||
private String channelMchNo;
|
||||
|
||||
@@ -31,10 +31,6 @@ public class DouyinTransferOrderResult extends BaseResult {
|
||||
@Schema(description = "商户名称")
|
||||
private String mchName;
|
||||
|
||||
/// 应用号
|
||||
@Schema(description = "应用号")
|
||||
private String appId;
|
||||
|
||||
/// 通道商户号
|
||||
@Schema(description = "通道商户号")
|
||||
private String channelMchNo;
|
||||
|
||||
@@ -31,10 +31,6 @@ public class TransferTradeResult extends BaseResult {
|
||||
@Schema(description = "商户名称")
|
||||
private String mchName;
|
||||
|
||||
/// 应用号
|
||||
@Schema(description = "应用号")
|
||||
private String appId;
|
||||
|
||||
/// 平台转账交易号
|
||||
@Schema(description = "平台转账交易号")
|
||||
private String tradeNo;
|
||||
|
||||
@@ -31,10 +31,6 @@ public class WechatTransferOrderResult extends BaseResult {
|
||||
@Schema(description = "商户名称")
|
||||
private String mchName;
|
||||
|
||||
/// 应用号
|
||||
@Schema(description = "应用号")
|
||||
private String appId;
|
||||
|
||||
/// 通道商户号
|
||||
@Schema(description = "通道商户号")
|
||||
private String channelMchNo;
|
||||
|
||||
@@ -61,17 +61,17 @@ public class TransferAssistService {
|
||||
return transferTradeManager.findByContainerId(containerId, channel);
|
||||
}
|
||||
|
||||
/// 幂等查重: 按商户转账号+应用号查容器主键(同一通道内唯一)
|
||||
/// 幂等查重: 按商户转账号+商户号查容器主键(同一商户下唯一)
|
||||
///
|
||||
/// 容器存在即视为该商户转账号已发起过; 凭证缺失属数据异常, 由调用方按失败重试兜底。
|
||||
public Optional<Long> findExist(String channel, String bizTransferNo, String appId) {
|
||||
public Optional<Long> findExist(String channel, String bizTransferNo, String mchNo) {
|
||||
return switch (channel) {
|
||||
case "wechat" -> wechatTransferOrderManager
|
||||
.findByBizTransferNo(bizTransferNo, appId).map(WechatTransferOrder::getId);
|
||||
.findByBizTransferNo(bizTransferNo, mchNo).map(WechatTransferOrder::getId);
|
||||
case "alipay" -> alipayTransferOrderManager
|
||||
.findByBizTransferNo(bizTransferNo, appId).map(AlipayTransferOrder::getId);
|
||||
.findByBizTransferNo(bizTransferNo, mchNo).map(AlipayTransferOrder::getId);
|
||||
case "douyin" -> douyinTransferOrderManager
|
||||
.findByBizTransferNo(bizTransferNo, appId).map(DouyinTransferOrder::getId);
|
||||
.findByBizTransferNo(bizTransferNo, mchNo).map(DouyinTransferOrder::getId);
|
||||
default -> throw new IllegalArgumentException("未知转账通道: " + channel);
|
||||
};
|
||||
}
|
||||
@@ -109,10 +109,9 @@ public class TransferAssistService {
|
||||
///
|
||||
/// @param channel 通道编码
|
||||
/// @param param 转账参数(公共字段 + 通道特有收款人字段)
|
||||
/// @param appId 解析后的应用号
|
||||
/// @param mchNo 商户号(上下文已装载, 显式传入避免依赖线程上下文)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public TransferStrategyContext createOrder(String channel, TransferParam param, String appId, String mchNo) {
|
||||
public TransferStrategyContext createOrder(String channel, TransferParam param, String mchNo) {
|
||||
String transferNo = TradeNoGenerateUtil.transfer();
|
||||
long amount = CurrencyAmountUtil.majorToMinor(param.getAmount(), CurrencyEnum.CNY);
|
||||
switch (channel) {
|
||||
@@ -129,7 +128,6 @@ public class TransferAssistService {
|
||||
.setReason(param.getReason())
|
||||
.setNotifyUrl(param.getNotifyUrl())
|
||||
.setAttach(param.getAttach())
|
||||
.setAppId(appId)
|
||||
.setStatus("processing")
|
||||
.setReqTime(OffsetDateTime.now());
|
||||
// 商户号独立赋值(父类 setter 返回 MchBaseEntity, 禁止链式)
|
||||
@@ -154,7 +152,6 @@ public class TransferAssistService {
|
||||
.setReason(param.getReason())
|
||||
.setNotifyUrl(param.getNotifyUrl())
|
||||
.setAttach(param.getAttach())
|
||||
.setAppId(appId)
|
||||
.setStatus("processing")
|
||||
.setReqTime(OffsetDateTime.now());
|
||||
// 商户号独立赋值(父类 setter 返回 MchBaseEntity, 禁止链式)
|
||||
@@ -184,7 +181,6 @@ public class TransferAssistService {
|
||||
.setReason(param.getReason())
|
||||
.setNotifyUrl(param.getNotifyUrl())
|
||||
.setAttach(param.getAttach())
|
||||
.setAppId(appId)
|
||||
.setStatus("processing")
|
||||
.setReqTime(OffsetDateTime.now());
|
||||
// 商户号独立赋值(父类 setter 返回 MchBaseEntity, 禁止链式)
|
||||
@@ -215,8 +211,7 @@ public class TransferAssistService {
|
||||
.setCurrency(order.getCurrency())
|
||||
.setStatus("processing")
|
||||
.setRelationNo(transferNo)
|
||||
.setTitle(order.getTitle())
|
||||
.setAppId(order.getAppId());
|
||||
.setTitle(order.getTitle());
|
||||
// 商户号独立赋值(父类 setter 返回 MchBaseEntity, 禁止链式)
|
||||
trade.setMchNo(order.getMchNo());
|
||||
return trade;
|
||||
@@ -235,8 +230,7 @@ public class TransferAssistService {
|
||||
.setCurrency(order.getCurrency())
|
||||
.setStatus("processing")
|
||||
.setRelationNo(transferNo)
|
||||
.setTitle(order.getTitle())
|
||||
.setAppId(order.getAppId());
|
||||
.setTitle(order.getTitle());
|
||||
// 商户号独立赋值(父类 setter 返回 MchBaseEntity, 禁止链式)
|
||||
trade.setMchNo(order.getMchNo());
|
||||
return trade;
|
||||
@@ -255,8 +249,7 @@ public class TransferAssistService {
|
||||
.setCurrency(order.getCurrency())
|
||||
.setStatus("processing")
|
||||
.setRelationNo(transferNo)
|
||||
.setTitle(order.getTitle())
|
||||
.setAppId(order.getAppId());
|
||||
.setTitle(order.getTitle());
|
||||
// 商户号独立赋值(父类 setter 返回 MchBaseEntity, 禁止链式)
|
||||
trade.setMchNo(order.getMchNo());
|
||||
return trade;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.daxpay.open.payment.trade.transfer.runtime.service;
|
||||
|
||||
import cn.daxpay.open.payment.common.access.MchAppInfoAccessInfo;
|
||||
import cn.daxpay.open.payment.common.context.MerchantContextLoader;
|
||||
import cn.daxpay.open.payment.common.context.PaymentContext;
|
||||
import cn.daxpay.open.payment.strategy.transfer.AbsTransferStrategy;
|
||||
@@ -30,7 +29,7 @@ import java.util.Optional;
|
||||
|
||||
/// # 转账发起编排服务
|
||||
///
|
||||
/// 锁内编排:商户身份装载 → 应用解析 → 幂等查重(仅 FAIL 可复用原单重试)
|
||||
/// 锁内编排:商户身份装载 → 幂等查重(仅 FAIL 可复用原单重试)
|
||||
/// → 通道参数校验 → 建单(容器+凭证双写, 独立事务)→ 通道发起(事务外, 远程调用)
|
||||
/// → 结果处理(成功/处理中/失败, 独立事务 CAS 双写 + 通知)。
|
||||
/// 容器读写全部收敛在 [TransferAssistService],本服务只面向凭证与策略上下文。
|
||||
@@ -72,10 +71,8 @@ public class TransferStartService {
|
||||
public String startHandle(String channel, TransferParam param) {
|
||||
// 商户身份装载: 商户端强制当前登录商户, 运营端按传入 mchNo 代发
|
||||
merchantContextLoader.initMch(param.getMchNo());
|
||||
// 应用解析: 空则取商户默认应用, 校验启用与归属
|
||||
MchAppInfoAccessInfo mchApp = merchantContextLoader.resolveApp(param.getMchNo(), param.getAppId());
|
||||
// 幂等查重: bizTransferNo + appId
|
||||
Optional<Long> existOpt = assistService.findExist(channel, param.getBizTransferNo(), mchApp.getAppId());
|
||||
// 幂等查重: bizTransferNo + mchNo(同一商户下唯一)
|
||||
Optional<Long> existOpt = assistService.findExist(channel, param.getBizTransferNo(), paymentContext.getMchNo());
|
||||
if (existOpt.isPresent()) {
|
||||
Long containerId = existOpt.get();
|
||||
TransferTrade existTrade = assistService.findTradeByContainer(channel, containerId)
|
||||
@@ -93,19 +90,19 @@ public class TransferStartService {
|
||||
throw new BizInfoException(CommonCode.FAIL_CODE, "pay.error.transfer.noDuplicate");
|
||||
}
|
||||
// 新单: 建单(独立事务)后发起
|
||||
TransferStrategyContext context = self.createOrder(channel, param, mchApp.getAppId());
|
||||
TransferStrategyContext context = self.createOrder(channel, param);
|
||||
this.transfer(channel, context);
|
||||
return context.getTransferNo();
|
||||
}
|
||||
|
||||
/// 建单(事务内: 通道参数校验 + 容器/凭证双写)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public TransferStrategyContext createOrder(String channel, TransferParam param, String appId) {
|
||||
public TransferStrategyContext createOrder(String channel, TransferParam param) {
|
||||
// 通道特有参数校验(微信金额档位/收款人类型等)
|
||||
AbsTransferStrategy strategy = TransferStrategyFactory.create(channel);
|
||||
strategy.doValidateParam(param);
|
||||
// 商户号取上下文(initMch 已装载), 显式传给辅助服务避免依赖线程上下文
|
||||
return assistService.createOrder(channel, param, appId, paymentContext.getMchNo());
|
||||
return assistService.createOrder(channel, param, paymentContext.getMchNo());
|
||||
}
|
||||
|
||||
/// 重试重置(事务内: 原单回 PROCESSING, 清空通道单号/完成时间/错误信息)
|
||||
|
||||
@@ -97,7 +97,6 @@ public class TransferSyncService {
|
||||
private void saveSyncRecord(String channel, TransferTrade trade, TransferResultBo result,
|
||||
boolean adjust, String errorMsg) {
|
||||
PaySyncRecord record = new PaySyncRecord()
|
||||
.setAppId(trade.getAppId())
|
||||
.setTradeNo(trade.getTradeNo())
|
||||
.setBizTradeNo(trade.getBizTransferNo())
|
||||
.setOutTradeNo(trade.getOutTransferNo())
|
||||
|
||||
Reference in New Issue
Block a user