feat 转账订单调试

This commit is contained in:
bootx
2024-06-23 23:11:02 +08:00
parent 975ceb213d
commit d42da8fd62
27 changed files with 159 additions and 52 deletions

View File

@@ -2,7 +2,7 @@
2.0.8: 转账/撤销接口和系统优化
- [x] 支持撤销接口
- [x] 增加转账接口功能
- [ ] 转账订单功能
- [x] 转账订单前端页面
- [ ] DEMO增加转账演示功能
- [x] 手动发起分账重试参数修正
- [x] 细分各种支付异常类和编码(部分+初版)
@@ -42,6 +42,7 @@
- [x] 支付和退款达到终态不可以再回退回之前的状态
- [x] 修复支付关闭参数名称不正确问题
- [X] 去除消息通知模块
- [x] 退款回调消息字段不一致导致验签不通过问题
2.0.9: 消息通知改版和系统优化
- [ ] 增加类似支付宝应用通知的方式, 先支持http方式通信

View File

@@ -85,6 +85,12 @@
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.daxpay.single</groupId>
<artifactId>daxpay-single-core</artifactId>
<version>2.0.7</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>

View File

@@ -16,18 +16,16 @@ import java.util.List;
@AllArgsConstructor
public enum TransferPayeeTypeEnum {
/** 微信 个人 */
WX_PERSONAL("wx_personal","openid", "个人"),
WX_PERSONAL("wx_personal", "OpenId"),
/** 支付宝 userId 以2088开头的纯16位数字 */
ALI_USER_ID("ali_user_id","ALIPAY_USERID", "用户ID"),
ALI_USER_ID("ali_user_id", "用户ID"),
/** 支付宝 openId */
ALI_OPEN_ID("ali_open_id","ALIPAY_OPENID", "openId"),
ALI_OPEN_ID("ali_open_id", "OpenId"),
/** 支付宝 账号 支持邮箱和手机号格式 */
ALI_LOGIN_NAME("ali_login_name","ALIPAY_LOGONID", "账号");
ALI_LOGIN_NAME("ali_login_name", "账号");
/** 编码 */
private final String code;
/** 外部编码, 三方支付系统使用的编码 */
private final String outCode;
/** 名称 */
private final String name;

View File

@@ -1,5 +1,6 @@
package cn.daxpay.single.sdk.model.notice;
import cn.daxpay.single.core.code.RefundStatusEnum;
import cn.daxpay.single.sdk.code.PayChannelEnum;
import cn.daxpay.single.sdk.net.DaxPayResponseModel;
import lombok.Getter;
@@ -57,6 +58,11 @@ public class RefundNoticeModel extends DaxPayResponseModel {
/** 退款创建时间 */
private Long createTime;
/**
* 退款状态
* @see RefundStatusEnum
*/
private String status;
/** 商户扩展参数,回调时会原样返回 */
private String attach;

View File

@@ -51,9 +51,6 @@ public class TransferOrderModel extends DaxPayResponseModel {
*/
private String transferType;
/** 付款方 */
private String payer;
/**
* 收款人类型
* @see TransferPayeeTypeEnum

View File

@@ -46,7 +46,6 @@ public class TransferParam extends DaxPayRequest<TransferModel> {
*/
private String transferType;
/**
* 收款人账号类型
* @see TransferPayeeTypeEnum

View File

@@ -39,15 +39,14 @@ public class RefundOrderTest {
public void refund(){
RefundParam param = new RefundParam();
param.setBizRefundNo("R" + RandomUtil.randomNumbers(5));
param.setBizOrderNo("SDK_1715341621498");
param.setBizOrderNo("P1719153314573");
param.setAmount(1);
param.setAttach("{回调参数}");
param.setNotifyUrl("https://abc.com/callback");
param.setNotifyUrl("http://127.0.0.1:9000/demo/callback/refundObject");
param.setClientIp("127.0.0.1");
DaxPayResult<RefundModel> execute = DaxPayKit.execute(param);
System.out.println(JSONUtil.toJsonStr(execute));
System.out.println(PaySignUtil.verifyHmacSha256Sign(execute.getData(), "123456", execute.getData().getSign()));
}

View File

@@ -10,6 +10,7 @@ import cn.daxpay.single.sdk.param.transfer.TransferParam;
import cn.daxpay.single.sdk.response.DaxPayResult;
import cn.hutool.json.JSONUtil;
import org.junit.Before;
import org.junit.Test;
/**
* 转账测试
@@ -33,16 +34,19 @@ public class TransferOrderTest {
/**
* 发起转账操作
*/
@Test
public void transfer() {
// 构建参数
TransferParam param = new TransferParam();
param.setBizTransferNo("T"+System.currentTimeMillis());
param.setTitle("测试转账");
param.setReason("我要转个账");
param.setAmount(500);
param.setChannel(PayChannelEnum.ALI.getCode());
param.setPayeeType(TransferPayeeTypeEnum.ALI_OPEN_ID.getCode());
param.setClientIp("127.0.0.1");
// 使用OpenId
param.setPayeeAccount("");
param.setPayeeAccount("065a9aEjER9Fa__hxYyvgYDlkhUiw_6RINhYHB2oegpWAo5");
// 发起请求
DaxPayResult<TransferModel> execute = DaxPayKit.execute(param);
System.out.println(JSONUtil.toJsonStr(execute));

View File

@@ -8,7 +8,6 @@ import cn.daxpay.single.core.code.PaymentApiCode;
import cn.daxpay.single.core.param.payment.transfer.TransferParam;
import cn.daxpay.single.service.annotation.InitPaymentContext;
import cn.daxpay.single.service.core.order.transfer.service.TransferOrderQueryService;
import cn.daxpay.single.service.core.order.transfer.service.TransferOrderService;
import cn.daxpay.single.service.core.payment.transfer.service.TransferService;
import cn.daxpay.single.service.dto.order.transfer.TransferOrderDto;
import cn.daxpay.single.service.param.order.TransferOrderQuery;
@@ -28,7 +27,6 @@ import org.springframework.web.bind.annotation.*;
@RequiredArgsConstructor
public class TransferOrderController {
private final TransferOrderQueryService queryService;
private final TransferOrderService transferOrderService;
private final TransferService transferService;
@@ -38,12 +36,18 @@ public class TransferOrderController {
return Res.ok(queryService.page(pageParam, query));
}
@Operation(summary = "查询退款订单详情")
@Operation(summary = "根据转账号查询")
@GetMapping("/findByTransferNo")
public ResResult<TransferOrderDto> findByTransferNo(String refundNo){
return Res.ok(queryService.findByTransferNo(refundNo));
}
@Operation(summary = "根据商户转账号查询")
@GetMapping("/findByBizTransferNo")
public ResResult<TransferOrderDto> findByBizTransferNo(String bizTransferNo){
return Res.ok(queryService.findByBizTransferNo(bizTransferNo));
}
@Operation(summary = "查询单条")
@GetMapping("/findById")
public ResResult<TransferOrderDto> findById(Long id){

View File

@@ -1,5 +1,6 @@
package cn.daxpay.single.core.code;
import cn.daxpay.single.core.exception.UnsupportedAbilityException;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -41,7 +42,7 @@ public enum AllocReceiverTypeEnum {
return Arrays.stream(AllocReceiverTypeEnum.values())
.filter(e -> e.getCode().equals(code))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("未找到对应的分账接收方类型"));
.orElseThrow(() -> new UnsupportedAbilityException("未找到对应的分账接收方类型"));
}
/** 微信支持类型 */

View File

@@ -1,5 +1,6 @@
package cn.daxpay.single.core.code;
import cn.daxpay.single.core.exception.UnsupportedAbilityException;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -16,13 +17,13 @@ import java.util.List;
@AllArgsConstructor
public enum TransferPayeeTypeEnum {
/** 微信 个人 */
WX_PERSONAL("wx_personal","openid", "个人"),
WX_PERSONAL("wx_personal","openid", "OpenId"),
/** 支付宝 userId 以2088开头的纯16位数字 */
ALI_USER_ID("ali_user_id","ALIPAY_USERID", "用户ID"),
ALI_USER_ID("ali_user_id","ALIPAY_USER_ID", "用户ID"),
/** 支付宝 openId */
ALI_OPEN_ID("ali_open_id","ALIPAY_OPENID", "openId"),
ALI_OPEN_ID("ali_open_id","ALIPAY_OPEN_ID", "OpenId"),
/** 支付宝 账号 支持邮箱和手机号格式 */
ALI_LOGIN_NAME("ali_login_name","ALIPAY_LOGONID", "账号");
ALI_LOGIN_NAME("ali_login_name","ALIPAY_LOGON_ID", "账号");
/** 编码 */
private final String code;
@@ -38,7 +39,7 @@ public enum TransferPayeeTypeEnum {
return Arrays.stream(TransferPayeeTypeEnum.values())
.filter(e -> e.getCode().equals(code))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("未找到对应的分账接收方类型"));
.orElseThrow(() -> new UnsupportedAbilityException("未找到对应的分账接收方类型"));
}
/** 微信支持类型 */

View File

@@ -14,8 +14,7 @@ public enum TransferStatusEnum {
TRANSFERRING("transferring", "转账中"),
SUCCESS("success", "转账成功"),
FAIL("fail", "转账失败"),
;
FAIL("fail", "转账失败"),;
private final String code;
private final String name;

View File

@@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 转账类型注解
* 转账类型 微信使用
* @author xxm
* @since 2024/6/6
*/

View File

@@ -1,11 +1,17 @@
package cn.daxpay.single.core.result.order;
import cn.daxpay.single.core.code.PayChannelEnum;
import cn.daxpay.single.core.code.TransferPayeeTypeEnum;
import cn.daxpay.single.core.code.TransferStatusEnum;
import cn.daxpay.single.core.code.TransferTypeEnum;
import cn.daxpay.single.core.result.PaymentCommonResult;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* 转账订单数据
* @author xxm
@@ -16,4 +22,80 @@ import lombok.experimental.Accessors;
@Accessors(chain = true)
@Schema(title = "转账订单数据")
public class TransferOrderResult extends PaymentCommonResult {
/** 商户转账号 */
@Schema(description = "商户转账号")
private String bizTransferNo;
/** 转账号 */
@Schema(description = "转账号")
private String transferNo;
/** 通道转账号 */
@Schema(description = "通道转账号")
private String outTransferNo;
/**
* 支付通道
* @see PayChannelEnum
*/
@Schema(description = "支付通道")
private String channel;
/** 转账金额 */
@Schema(description = "转账金额")
private Integer amount;
/** 标题 */
@Schema(description = "标题")
private String title;
/** 转账原因/备注 */
@Schema(description = "转账原因/备注")
private String reason;
/**
* 转账类型, 微信使用
* @see TransferTypeEnum
*/
@Schema(description = "转账类型, 微信使用")
private String transferType;
/**
* 收款人类型
* @see TransferPayeeTypeEnum
*/
@Schema(description = "收款人类型")
private String payeeType;
/** 收款人账号 */
@Schema(description = "收款人账号")
private String payeeAccount;
/** 收款人姓名 */
@Schema(description = "收款人姓名")
private String payeeName;
/**
* 状态
* @see TransferStatusEnum
*/
@Schema(description = "状态")
private String status;
/** 成功时间 */
@Schema(description = "成功时间")
private LocalDateTime successTime;
/**
* 错误码
*/
@Schema(description = "错误码")
private String errorCode;
/**
* 错误原因
*/
@Schema(description = "错误原因")
private String errorMsg;
}

View File

@@ -13,10 +13,12 @@ import cn.daxpay.single.core.result.order.AllocOrderResult;
import cn.daxpay.single.core.result.allocation.AllocReceiversResult;
import cn.daxpay.single.core.result.order.PayOrderResult;
import cn.daxpay.single.core.result.order.RefundOrderResult;
import cn.daxpay.single.core.result.order.TransferOrderResult;
import cn.daxpay.single.service.annotation.PaymentVerify;
import cn.daxpay.single.service.annotation.InitPaymentContext;
import cn.daxpay.single.service.core.order.pay.service.PayOrderQueryService;
import cn.daxpay.single.service.core.order.refund.service.RefundOrderQueryService;
import cn.daxpay.single.service.core.order.transfer.service.TransferOrderQueryService;
import cn.daxpay.single.service.core.payment.allocation.service.AllocationReceiverService;
import cn.daxpay.single.service.core.payment.allocation.service.AllocationService;
import cn.daxpay.single.core.util.DaxRes;
@@ -43,6 +45,7 @@ public class UniQueryController {
private final PayOrderQueryService payOrderQueryService;
private final RefundOrderQueryService refundOrderQueryService;
private final TransferOrderQueryService transferOrderQueryService;
private final AllocationReceiverService allocationReceiverService;
private final AllocationService allocationService;
@@ -74,8 +77,8 @@ public class UniQueryController {
@InitPaymentContext(PaymentApiCode.QUERY_TRANSFER_ORDER)
@Operation(summary = "转账订单查询接口")
@PostMapping("/transferOrder")
public DaxResult<Void> transferOrder(@RequestBody QueryTransferParam param){
return DaxRes.ok();
public DaxResult<TransferOrderResult> transferOrder(@RequestBody QueryTransferParam param){
return DaxRes.ok(transferOrderQueryService.queryTransferOrder(param));
}
@PaymentVerify

View File

@@ -1,6 +1,7 @@
package cn.daxpay.single.service.core.channel.alipay.service;
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
import cn.daxpay.single.core.code.TransferPayeeTypeEnum;
import cn.daxpay.single.core.code.TransferStatusEnum;
import cn.daxpay.single.core.exception.TradeFaileException;
import cn.daxpay.single.service.code.AliPayCode;
@@ -75,12 +76,16 @@ public class AliPayTransferService {
model.setOutBizNo(order.getTransferNo());
// 设置订单总金额
model.setTransAmount(PayUtil.conversionAmount(order.getAmount()).toString());
// 设置收款方信息
Participant payeeInfo = new Participant();
// 收款人账号
payeeInfo.setIdentity(order.getPayeeAccount());
// 收款人姓名
payeeInfo.setName(order.getPayeeName());
payeeInfo.setIdentityType(order.getPayeeType());
// 收款人类型
String identityType = TransferPayeeTypeEnum.findByCode(order.getPayeeType())
.getOutCode();
payeeInfo.setIdentityType(identityType);
model.setPayeeInfo(payeeInfo);
model.setRemark(order.getReason());
request.setBizModel(model);

View File

@@ -81,7 +81,7 @@ public class ClientNoticeTask extends MpBaseEntity implements EntityBaseFunction
private String url;
/** 最后发送时间 */
@DbColumn(comment = "最后发送时间", isNull = false)
@DbColumn(comment = "最后发送时间")
private LocalDateTime latestTime;
/**

View File

@@ -73,10 +73,6 @@ public class TransferOrder extends MpBaseEntity implements EntityBaseFunction<Tr
@DbColumn(comment = "转账类型, 微信使用", length = 20)
private String transferType;
/** 付款方 */
@DbColumn(comment = "付款方", length = 100)
private String payer;
/**
* 收款人类型
* @see TransferPayeeTypeEnum

View File

@@ -5,7 +5,6 @@ import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.daxpay.single.core.exception.ParamValidationFailException;
import cn.daxpay.single.core.exception.PayFailureException;
import cn.daxpay.single.core.exception.TradeNotExistException;
import cn.daxpay.single.core.param.payment.transfer.QueryTransferParam;
import cn.daxpay.single.core.result.order.TransferOrderResult;
@@ -55,7 +54,16 @@ public class TransferOrderQueryService {
*/
public TransferOrderDto findByTransferNo(String transferNo){
return transferOrderManager.findByTransferNo(transferNo).map(TransferOrder::toDto)
.orElseThrow(() -> new DataNotExistException("转账订单扩展信息不存在"));
.orElseThrow(() -> new DataNotExistException("转账订单信息不存在"));
}
/**
* 根据转账号查询
*/
public TransferOrderDto findByBizTransferNo(String bizTransferNo){
return transferOrderManager.findByBizTransferNo(bizTransferNo).map(TransferOrder::toDto)
.orElseThrow(() -> new DataNotExistException("转账订单信息不存在"));
}

View File

@@ -22,7 +22,7 @@ public class AllocationAssistService {
private final AllocationOrderManager allocationOrderManager;
/**
* 根据新传入的分账订单更新订单和扩展信息
* 根据新传入的分账订单更新订单信息
*/
@Transactional(rollbackFor = Exception.class)
public void updateOrder(AllocationParam allocationParam, AllocOrder orderExtra) {

View File

@@ -169,7 +169,7 @@ public class AllocationService {
allocationStrategy.initParam(order, details);
// 分账预处理
allocationStrategy.doBeforeHandler();
// 更新分账单扩展信息
// 更新分账单信息
allocationAssistService.updateOrder(param, order);
try {
// 重复分账处理

View File

@@ -85,7 +85,7 @@ public class PayAssistService {
}
/**
* 根据新传入的支付订单更新订单和扩展信息
* 根据新传入的支付订单更新订单信息
*/
@Transactional(rollbackFor = Exception.class)
public void updatePayOrder(PayParam payParam,PayOrder order) {

View File

@@ -175,7 +175,7 @@ public class RefundService {
}
/**
* 更新退款订单扩展信息
* 更新退款订单信息
*/
private void updateOrder(RefundParam param, RefundOrder order){
order.setAttach(param.getAttach())

View File

@@ -3,6 +3,7 @@ package cn.daxpay.single.service.core.payment.transfer.service;
import cn.daxpay.single.core.code.RefundStatusEnum;
import cn.daxpay.single.core.param.payment.transfer.TransferParam;
import cn.daxpay.single.core.result.transfer.TransferResult;
import cn.daxpay.single.service.common.context.TransferLocal;
import cn.daxpay.single.service.common.local.PaymentContextLocal;
import cn.daxpay.single.service.core.order.transfer.dao.TransferOrderManager;
import cn.daxpay.single.service.core.order.transfer.entity.TransferOrder;
@@ -63,7 +64,11 @@ public class TransferService {
*/
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void successHandler(TransferOrder order){
order.setStatus(RefundStatusEnum.SUCCESS.getCode());
TransferLocal transferInfo = PaymentContextLocal.get()
.getTransferInfo();
order.setStatus(transferInfo.getStatus().getCode())
.setSuccessTime(transferInfo.getFinishTime())
.setOutTransferNo(transferInfo.getOutTransferNo());
transferOrderManager.updateById(order);
}
}

View File

@@ -48,7 +48,7 @@ public class WeChatTransferStrategy extends AbsTransferStrategy {
// 转账接收方类型校验
String payeeType = transferParam.getPayeeType();
if (!Objects.equals(WX_PERSONAL.getCode(), payeeType)){
throw new ParamValidationFailException("支付宝不支持该类型收款人");
throw new ParamValidationFailException("微信不支持该类型收款人");
}
}

View File

@@ -61,10 +61,6 @@ public class TransferOrderDto extends BaseDto {
@Schema(description = "转账类型, 微信使用")
private String transferType;
/** 付款方 */
@Schema(description = "付款方")
private String payer;
/**
* 收款人类型
* @see TransferPayeeTypeEnum

View File

@@ -62,9 +62,6 @@ public class TransferOrderQuery extends QueryOrder {
@Schema(description = "转账类型, 微信使用")
private String transferType;
/** 付款方 */
@Schema(description = "付款方")
private String payer;
/**
* 收款人类型