Commit ab19228ca63cbe87659ce723d8597cb0553c5c4c
1 parent
6dc65234
完成支付的下单和提交订单的逻辑
Showing
24 changed files
with
251 additions
and
94 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayChannelCodeEnum.java deleted
| 1 | -package cn.iocoder.yudao.adminserver.modules.pay.enums; | ||
| 2 | - | ||
| 3 | -import lombok.AllArgsConstructor; | ||
| 4 | -import lombok.Getter; | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * 支付渠道的编码的枚举 | ||
| 8 | - * | ||
| 9 | - * @author 芋道源码 | ||
| 10 | - */ | ||
| 11 | -@Getter | ||
| 12 | -@AllArgsConstructor | ||
| 13 | -public enum PayChannelCodeEnum { | ||
| 14 | - | ||
| 15 | - wx_pub("wx_pub", "微信 JSAPI 支付"); | ||
| 16 | - | ||
| 17 | - /** | ||
| 18 | - * 编码 | ||
| 19 | - * | ||
| 20 | - * 参考 https://www.pingxx.com/api/支付渠道属性值.html | ||
| 21 | - */ | ||
| 22 | - private String code; | ||
| 23 | - /** | ||
| 24 | - * 名字 | ||
| 25 | - */ | ||
| 26 | - private String name; | ||
| 27 | - | ||
| 28 | -} |
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderDO.java
| @@ -3,16 +3,15 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order; | @@ -3,16 +3,15 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order; | ||
| 3 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; | 3 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; |
| 4 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; | 4 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; |
| 5 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; | 5 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; |
| 6 | +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum; | ||
| 7 | +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderRefundStatusEnum; | ||
| 6 | import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; | 8 | import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; |
| 7 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 9 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 8 | import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; | 10 | import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; |
| 9 | -import com.baomidou.mybatisplus.annotation.TableField; | ||
| 10 | import com.baomidou.mybatisplus.annotation.TableName; | 11 | import com.baomidou.mybatisplus.annotation.TableName; |
| 11 | -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||
| 12 | import lombok.*; | 12 | import lombok.*; |
| 13 | 13 | ||
| 14 | import java.util.Date; | 14 | import java.util.Date; |
| 15 | -import java.util.Map; | ||
| 16 | 15 | ||
| 17 | /** | 16 | /** |
| 18 | * 支付订单 DO | 17 | * 支付订单 DO |
| @@ -61,7 +60,7 @@ public class PayOrderDO extends BaseDO { | @@ -61,7 +60,7 @@ public class PayOrderDO extends BaseDO { | ||
| 61 | 60 | ||
| 62 | /** | 61 | /** |
| 63 | * 商户订单编号 | 62 | * 商户订单编号 |
| 64 | - * 例如说,内部系统 A 的订单号。需要保证每个 PayMerchantDO 唯一 TODO 芋艿:需要在测试下 | 63 | + * 例如说,内部系统 A 的订单号。需要保证每个 PayMerchantDO 唯一 |
| 65 | */ | 64 | */ |
| 66 | private String merchantOrderId; | 65 | private String merchantOrderId; |
| 67 | /** | 66 | /** |
| @@ -72,6 +71,16 @@ public class PayOrderDO extends BaseDO { | @@ -72,6 +71,16 @@ public class PayOrderDO extends BaseDO { | ||
| 72 | * 商品描述信息 | 71 | * 商品描述信息 |
| 73 | */ | 72 | */ |
| 74 | private String body; | 73 | private String body; |
| 74 | + /** | ||
| 75 | + * 异步通知地址 | ||
| 76 | + */ | ||
| 77 | + private String notifyUrl; | ||
| 78 | + /** | ||
| 79 | + * 通知商户支付结果的回调状态 | ||
| 80 | + * | ||
| 81 | + * 枚举 {@link PayOrderNotifyStatusEnum} | ||
| 82 | + */ | ||
| 83 | + private Integer notifyStatus; | ||
| 75 | // /** | 84 | // /** |
| 76 | // * 商户拓展参数 | 85 | // * 商户拓展参数 |
| 77 | // */ | 86 | // */ |
| @@ -100,11 +109,6 @@ public class PayOrderDO extends BaseDO { | @@ -100,11 +109,6 @@ public class PayOrderDO extends BaseDO { | ||
| 100 | */ | 109 | */ |
| 101 | private Integer status; | 110 | private Integer status; |
| 102 | /** | 111 | /** |
| 103 | - * 通知商户支付结果的回调状态 | ||
| 104 | - * TODO 芋艿:0 未发送 1 已发送 | ||
| 105 | - */ | ||
| 106 | - private Integer notifyStatus; | ||
| 107 | - /** | ||
| 108 | * 用户 IP | 112 | * 用户 IP |
| 109 | */ | 113 | */ |
| 110 | private String userIp; | 114 | private String userIp; |
| @@ -122,23 +126,12 @@ public class PayOrderDO extends BaseDO { | @@ -122,23 +126,12 @@ public class PayOrderDO extends BaseDO { | ||
| 122 | * 关联 {@link PayOrderDO#getId()} | 126 | * 关联 {@link PayOrderDO#getId()} |
| 123 | */ | 127 | */ |
| 124 | private Long successExtensionId; | 128 | private Long successExtensionId; |
| 125 | - /** | ||
| 126 | - * 支付渠道的额外参数 | ||
| 127 | - * | ||
| 128 | - * 参见 https://www.pingxx.com/api/支付渠道%20extra%20参数说明.html | ||
| 129 | - */ | ||
| 130 | - @TableField(typeHandler = JacksonTypeHandler.class) | ||
| 131 | - private Map<String, String> channelExtras; | ||
| 132 | - /** | ||
| 133 | - * 异步通知地址 | ||
| 134 | - */ | ||
| 135 | - private String notifyUrl; | ||
| 136 | 129 | ||
| 137 | // ========== 退款相关字段 ========== | 130 | // ========== 退款相关字段 ========== |
| 138 | /** | 131 | /** |
| 139 | * 退款状态 | 132 | * 退款状态 |
| 140 | * | 133 | * |
| 141 | - * TODO 芋艿:0 - 未退款;1 - 部分退款; 2 - 全额退款 | 134 | + * 枚举 {@link PayOrderRefundStatusEnum} |
| 142 | */ | 135 | */ |
| 143 | private Integer refundStatus; | 136 | private Integer refundStatus; |
| 144 | /** | 137 | /** |
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java
| @@ -3,9 +3,13 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order; | @@ -3,9 +3,13 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order; | ||
| 3 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; | 3 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; |
| 4 | import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; | 4 | import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; |
| 5 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 5 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 6 | +import com.baomidou.mybatisplus.annotation.TableField; | ||
| 6 | import com.baomidou.mybatisplus.annotation.TableName; | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||
| 7 | import lombok.*; | 9 | import lombok.*; |
| 8 | 10 | ||
| 11 | +import java.util.Map; | ||
| 12 | + | ||
| 9 | /** | 13 | /** |
| 10 | * 支付订单拓展 DO | 14 | * 支付订单拓展 DO |
| 11 | * | 15 | * |
| @@ -49,7 +53,7 @@ public class PayOrderExtensionDO extends BaseDO { | @@ -49,7 +53,7 @@ public class PayOrderExtensionDO extends BaseDO { | ||
| 49 | /** | 53 | /** |
| 50 | * 渠道编码 | 54 | * 渠道编码 |
| 51 | */ | 55 | */ |
| 52 | - private Integer channelCode; | 56 | + private String channelCode; |
| 53 | /** | 57 | /** |
| 54 | * 用户 IP | 58 | * 用户 IP |
| 55 | */ | 59 | */ |
| @@ -62,6 +66,13 @@ public class PayOrderExtensionDO extends BaseDO { | @@ -62,6 +66,13 @@ public class PayOrderExtensionDO extends BaseDO { | ||
| 62 | */ | 66 | */ |
| 63 | private Integer status; | 67 | private Integer status; |
| 64 | /** | 68 | /** |
| 69 | + * 支付渠道的额外参数 | ||
| 70 | + * | ||
| 71 | + * 参见 https://www.pingxx.com/api/支付渠道%20extra%20参数说明.html | ||
| 72 | + */ | ||
| 73 | + @TableField(typeHandler = JacksonTypeHandler.class) | ||
| 74 | + private Map<String, String> channelExtras; | ||
| 75 | + /** | ||
| 65 | * 支付渠道异步通知的内容 | 76 | * 支付渠道异步通知的内容 |
| 66 | * | 77 | * |
| 67 | * 在支持成功后,会记录回调的数据 | 78 | * 在支持成功后,会记录回调的数据 |
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java
| @@ -71,6 +71,15 @@ public class PayRefundDO extends BaseDO { | @@ -71,6 +71,15 @@ public class PayRefundDO extends BaseDO { | ||
| 71 | // * 商户拓展参数 | 71 | // * 商户拓展参数 |
| 72 | // */ | 72 | // */ |
| 73 | // private String merchantExtra; | 73 | // private String merchantExtra; |
| 74 | + /** | ||
| 75 | + * 异步通知地址 | ||
| 76 | + */ | ||
| 77 | + private String notifyUrl; | ||
| 78 | + /** | ||
| 79 | + * 通知商户退款结果的回调状态 | ||
| 80 | + * TODO 芋艿:0 未发送 1 已发送 | ||
| 81 | + */ | ||
| 82 | + private Integer notifyStatus; | ||
| 74 | 83 | ||
| 75 | // ========== 退款相关字段 ========== | 84 | // ========== 退款相关字段 ========== |
| 76 | /** | 85 | /** |
| @@ -80,11 +89,6 @@ public class PayRefundDO extends BaseDO { | @@ -80,11 +89,6 @@ public class PayRefundDO extends BaseDO { | ||
| 80 | */ | 89 | */ |
| 81 | private Integer status; | 90 | private Integer status; |
| 82 | /** | 91 | /** |
| 83 | - * 通知商户退款结果的回调状态 | ||
| 84 | - * TODO 芋艿:0 未发送 1 已发送 | ||
| 85 | - */ | ||
| 86 | - private Integer notifyStatus; | ||
| 87 | - /** | ||
| 88 | * 用户 IP | 92 | * 用户 IP |
| 89 | */ | 93 | */ |
| 90 | private String userIp; | 94 | private String userIp; |
| @@ -110,10 +114,6 @@ public class PayRefundDO extends BaseDO { | @@ -110,10 +114,6 @@ public class PayRefundDO extends BaseDO { | ||
| 110 | * 参见 https://www.pingxx.com/api/Refunds%20退款概述.html | 114 | * 参见 https://www.pingxx.com/api/Refunds%20退款概述.html |
| 111 | */ | 115 | */ |
| 112 | private String channelExtra; | 116 | private String channelExtra; |
| 113 | - /** | ||
| 114 | - * 异步通知地址 | ||
| 115 | - */ | ||
| 116 | - private String notifyUrl; | ||
| 117 | 117 | ||
| 118 | // ========== 渠道相关字段 ========== | 118 | // ========== 渠道相关字段 ========== |
| 119 | /** | 119 | /** |
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderNotifyStatusEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.coreservice.modules.pay.enums.order; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||
| 4 | +import lombok.AllArgsConstructor; | ||
| 5 | +import lombok.Getter; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 支付订单的通知状态枚举 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +@Getter | ||
| 13 | +@AllArgsConstructor | ||
| 14 | +public enum PayOrderNotifyStatusEnum implements IntArrayValuable { | ||
| 15 | + | ||
| 16 | + NO(0, "未通知"), | ||
| 17 | + SUCCESS(10, "通知成功"), | ||
| 18 | + FAILURE(20, "通知失败") | ||
| 19 | + ; | ||
| 20 | + | ||
| 21 | + private final Integer status; | ||
| 22 | + private final String name; | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public int[] array() { | ||
| 26 | + return new int[0]; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | +} |
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderRefundStatusEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.coreservice.modules.pay.enums.order; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||
| 4 | +import lombok.AllArgsConstructor; | ||
| 5 | +import lombok.Getter; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 支付订单的退款状态枚举 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +@Getter | ||
| 13 | +@AllArgsConstructor | ||
| 14 | +public enum PayOrderRefundStatusEnum implements IntArrayValuable { | ||
| 15 | + | ||
| 16 | + NO(0, "未退款"), | ||
| 17 | + SOME(10, "部分退款"), | ||
| 18 | + ALL(20, "全部退款") | ||
| 19 | + ; | ||
| 20 | + | ||
| 21 | + private final Integer status; | ||
| 22 | + private final String name; | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public int[] array() { | ||
| 26 | + return new int[0]; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | +} |
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayChannelCoreServiceImpl.java
| @@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; | ||
| 12 | import org.springframework.scheduling.annotation.Scheduled; | 12 | import org.springframework.scheduling.annotation.Scheduled; |
| 13 | import org.springframework.stereotype.Service; | 13 | import org.springframework.stereotype.Service; |
| 14 | 14 | ||
| 15 | +import javax.annotation.PostConstruct; | ||
| 15 | import javax.annotation.Resource; | 16 | import javax.annotation.Resource; |
| 16 | import javax.validation.Valid; | 17 | import javax.validation.Valid; |
| 17 | 18 | ||
| @@ -50,6 +51,7 @@ public class PayChannelCoreServiceImpl implements PayChannelCoreService { | @@ -50,6 +51,7 @@ public class PayChannelCoreServiceImpl implements PayChannelCoreService { | ||
| 50 | private PayClientFactory payClientFactory; | 51 | private PayClientFactory payClientFactory; |
| 51 | 52 | ||
| 52 | @Override | 53 | @Override |
| 54 | + @PostConstruct | ||
| 53 | public void initPayClients() { | 55 | public void initPayClients() { |
| 54 | // 获取支付渠道,如果有更新 | 56 | // 获取支付渠道,如果有更新 |
| 55 | List<PayChannelDO> payChannels = this.loadPayChannelIfUpdate(maxUpdateTime); | 57 | List<PayChannelDO> payChannels = this.loadPayChannelIfUpdate(maxUpdateTime); |
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java
| @@ -28,6 +28,6 @@ public interface PayOrderCoreService { | @@ -28,6 +28,6 @@ public interface PayOrderCoreService { | ||
| 28 | * @param reqDTO 提交请求 | 28 | * @param reqDTO 提交请求 |
| 29 | * @return 提交结果 | 29 | * @return 提交结果 |
| 30 | */ | 30 | */ |
| 31 | - PayOrderSubmitRespDTO submitPayOrder(PayOrderSubmitReqDTO reqDTO); | 31 | + PayOrderSubmitRespDTO submitPayOrder(@Valid PayOrderSubmitReqDTO reqDTO); |
| 32 | 32 | ||
| 33 | } | 33 | } |
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java
| 1 | package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto; | 1 | package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto; |
| 2 | 2 | ||
| 3 | +import com.baomidou.mybatisplus.annotation.TableField; | ||
| 4 | +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||
| 3 | import lombok.Data; | 5 | import lombok.Data; |
| 4 | import lombok.experimental.Accessors; | 6 | import lombok.experimental.Accessors; |
| 5 | 7 | ||
| 6 | import javax.validation.constraints.NotEmpty; | 8 | import javax.validation.constraints.NotEmpty; |
| 7 | import javax.validation.constraints.NotNull; | 9 | import javax.validation.constraints.NotNull; |
| 8 | import java.io.Serializable; | 10 | import java.io.Serializable; |
| 11 | +import java.util.Map; | ||
| 9 | 12 | ||
| 10 | /** | 13 | /** |
| 11 | * 支付单提交 Request DTO | 14 | * 支付单提交 Request DTO |
| @@ -38,4 +41,10 @@ public class PayOrderSubmitReqDTO implements Serializable { | @@ -38,4 +41,10 @@ public class PayOrderSubmitReqDTO implements Serializable { | ||
| 38 | @NotEmpty(message = "用户 IP 不能为空") | 41 | @NotEmpty(message = "用户 IP 不能为空") |
| 39 | private String userIp; | 42 | private String userIp; |
| 40 | 43 | ||
| 44 | + /** | ||
| 45 | + * 支付渠道的额外参数 | ||
| 46 | + */ | ||
| 47 | + @TableField(typeHandler = JacksonTypeHandler.class) | ||
| 48 | + private Map<String, String> channelExtras; | ||
| 49 | + | ||
| 41 | } | 50 | } |
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java
| @@ -9,6 +9,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; | @@ -9,6 +9,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; | ||
| 9 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; | 9 | import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; |
| 10 | import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; | 10 | import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; |
| 11 | import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderExtensionCoreMapper; | 11 | import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderExtensionCoreMapper; |
| 12 | +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum; | ||
| 12 | import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; | 13 | import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; |
| 13 | import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayAppCoreService; | 14 | import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayAppCoreService; |
| 14 | import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayChannelCoreService; | 15 | import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayChannelCoreService; |
| @@ -20,12 +21,14 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | @@ -20,12 +21,14 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 20 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 21 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 21 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; | 22 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; |
| 22 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; | 23 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 24 | +import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; | ||
| 23 | import lombok.extern.slf4j.Slf4j; | 25 | import lombok.extern.slf4j.Slf4j; |
| 24 | import org.springframework.stereotype.Service; | 26 | import org.springframework.stereotype.Service; |
| 27 | +import org.springframework.validation.annotation.Validated; | ||
| 25 | 28 | ||
| 26 | import javax.annotation.Resource; | 29 | import javax.annotation.Resource; |
| 27 | -import javax.validation.Valid; | ||
| 28 | import java.util.Date; | 30 | import java.util.Date; |
| 31 | +import java.util.Objects; | ||
| 29 | 32 | ||
| 30 | import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*; | 33 | import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*; |
| 31 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 34 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| @@ -36,7 +39,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU | @@ -36,7 +39,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU | ||
| 36 | * @author 芋道源码 | 39 | * @author 芋道源码 |
| 37 | */ | 40 | */ |
| 38 | @Service | 41 | @Service |
| 39 | -@Valid | 42 | +@Validated |
| 40 | @Slf4j | 43 | @Slf4j |
| 41 | public class PayOrderCoreServiceImpl implements PayOrderCoreService { | 44 | public class PayOrderCoreServiceImpl implements PayOrderCoreService { |
| 42 | 45 | ||
| @@ -68,10 +71,16 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { | @@ -68,10 +71,16 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { | ||
| 68 | } | 71 | } |
| 69 | 72 | ||
| 70 | // 创建支付交易单 | 73 | // 创建支付交易单 |
| 71 | - // TODO 芋艿:需要看看,还有啥要补全的字段 | ||
| 72 | order = PayOrderCoreConvert.INSTANCE.convert(reqDTO) | 74 | order = PayOrderCoreConvert.INSTANCE.convert(reqDTO) |
| 73 | - .setStatus(PayOrderStatusEnum.WAITING.getStatus()) | ||
| 74 | - .setNotifyUrl(app.getPayNotifyUrl()); | 75 | + .setMerchantId(app.getMerchantId()).setAppId(app.getId()); |
| 76 | + // 商户相关字段 | ||
| 77 | + order.setNotifyUrl(app.getPayNotifyUrl()) | ||
| 78 | + .setNotifyStatus(PayOrderNotifyStatusEnum.NO.getStatus()); | ||
| 79 | + // 订单相关字段 | ||
| 80 | + order.setStatus(PayOrderStatusEnum.WAITING.getStatus()); | ||
| 81 | + // 退款相关字段 | ||
| 82 | + order.setRefundStatus(PayOrderNotifyStatusEnum.NO.getStatus()) | ||
| 83 | + .setRefundTimes(0).setRefundAmount(0L); | ||
| 75 | payOrderCoreMapper.insert(order); | 84 | payOrderCoreMapper.insert(order); |
| 76 | // 最终返回 | 85 | // 最终返回 |
| 77 | return order.getId(); | 86 | return order.getId(); |
| @@ -80,9 +89,9 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { | @@ -80,9 +89,9 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { | ||
| 80 | @Override | 89 | @Override |
| 81 | public PayOrderSubmitRespDTO submitPayOrder(PayOrderSubmitReqDTO reqDTO) { | 90 | public PayOrderSubmitRespDTO submitPayOrder(PayOrderSubmitReqDTO reqDTO) { |
| 82 | // 校验 App | 91 | // 校验 App |
| 83 | - PayAppDO app = payAppCoreService.validPayApp(reqDTO.getId()); | 92 | + PayAppDO app = payAppCoreService.validPayApp(reqDTO.getAppId()); |
| 84 | // 校验支付渠道是否有效 | 93 | // 校验支付渠道是否有效 |
| 85 | - PayChannelDO channel = payChannelCoreService.validPayChannel(reqDTO.getId(), reqDTO.getChannelCode()); | 94 | + PayChannelDO channel = payChannelCoreService.validPayChannel(reqDTO.getAppId(), reqDTO.getChannelCode()); |
| 86 | // 校验支付客户端是否正确初始化 | 95 | // 校验支付客户端是否正确初始化 |
| 87 | PayClient client = payClientFactory.getPayClient(channel.getId()); | 96 | PayClient client = payClientFactory.getPayClient(channel.getId()); |
| 88 | if (client == null) { | 97 | if (client == null) { |
| @@ -92,7 +101,7 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { | @@ -92,7 +101,7 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { | ||
| 92 | 101 | ||
| 93 | // 获得 PayOrderDO ,并校验其是否存在 | 102 | // 获得 PayOrderDO ,并校验其是否存在 |
| 94 | PayOrderDO order = payOrderCoreMapper.selectById(reqDTO.getId()); | 103 | PayOrderDO order = payOrderCoreMapper.selectById(reqDTO.getId()); |
| 95 | - if (order == null || order.getAppId().equals(reqDTO.getAppId())) { // 是否存在 | 104 | + if (order == null || !Objects.equals(order.getAppId(), reqDTO.getAppId())) { // 是否存在 |
| 96 | throw exception(PAY_ORDER_NOT_FOUND); | 105 | throw exception(PAY_ORDER_NOT_FOUND); |
| 97 | } | 106 | } |
| 98 | if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 | 107 | if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 |
| @@ -102,18 +111,25 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { | @@ -102,18 +111,25 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { | ||
| 102 | // 插入 PayOrderExtensionDO | 111 | // 插入 PayOrderExtensionDO |
| 103 | PayOrderExtensionDO orderExtension = PayOrderCoreConvert.INSTANCE.convert(reqDTO) | 112 | PayOrderExtensionDO orderExtension = PayOrderCoreConvert.INSTANCE.convert(reqDTO) |
| 104 | .setOrderId(order.getId()).setNo(generateOrderExtensionNo()) | 113 | .setOrderId(order.getId()).setNo(generateOrderExtensionNo()) |
| 114 | + .setChannelId(channel.getId()).setChannelCode(channel.getCode()) | ||
| 105 | .setStatus(PayOrderStatusEnum.WAITING.getStatus()); | 115 | .setStatus(PayOrderStatusEnum.WAITING.getStatus()); |
| 106 | payOrderExtensionCoreMapper.insert(orderExtension); | 116 | payOrderExtensionCoreMapper.insert(orderExtension); |
| 107 | 117 | ||
| 108 | // 调用三方接口 | 118 | // 调用三方接口 |
| 109 | - // TODO 暂时传入 extra = null | ||
| 110 | - CommonResult<?> invokeResult = client.unifiedOrder(PayOrderCoreConvert.INSTANCE.convert2(reqDTO)); | ||
| 111 | - invokeResult.checkError(); | 119 | + PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderCoreConvert.INSTANCE.convert2(reqDTO); |
| 120 | + // 商户相关字段 | ||
| 121 | + unifiedOrderReqDTO.setMerchantOrderId(order.getMerchantOrderId()) | ||
| 122 | + .setSubject(order.getSubject()).setBody(order.getBody()) | ||
| 123 | + .setNotifyUrl(app.getPayNotifyUrl()); | ||
| 124 | + // 订单相关字段 | ||
| 125 | + unifiedOrderReqDTO.setAmount(order.getAmount()).setExpireTime(order.getExpireTime()); | ||
| 126 | + CommonResult<?> unifiedOrderResult = client.unifiedOrder(unifiedOrderReqDTO); | ||
| 127 | + unifiedOrderResult.checkError(); | ||
| 112 | 128 | ||
| 113 | // TODO 轮询三方接口,是否已经支付的任务 | 129 | // TODO 轮询三方接口,是否已经支付的任务 |
| 114 | // 返回成功 | 130 | // 返回成功 |
| 115 | return new PayOrderSubmitRespDTO().setExtensionId(orderExtension.getId()) | 131 | return new PayOrderSubmitRespDTO().setExtensionId(orderExtension.getId()) |
| 116 | - .setInvokeResponse(JsonUtils.toJsonString(invokeResult)); | 132 | + .setInvokeResponse(JsonUtils.toJsonString(unifiedOrderResult)); |
| 117 | } | 133 | } |
| 118 | 134 | ||
| 119 | private String generateOrderExtensionNo() { | 135 | private String generateOrderExtensionNo() { |
yudao-core-service/src/test-integration/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreServiceTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.coreservice.modules.pay.service.order; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.coreservice.BaseDbIntegrationTest; | ||
| 4 | +import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.impl.PayAppCoreServiceImpl; | ||
| 5 | +import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.impl.PayChannelCoreServiceImpl; | ||
| 6 | +import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderCreateReqDTO; | ||
| 7 | +import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitReqDTO; | ||
| 8 | +import cn.iocoder.yudao.coreservice.modules.pay.service.order.impl.PayOrderCoreServiceImpl; | ||
| 9 | +import cn.iocoder.yudao.framework.common.util.date.DateUtils; | ||
| 10 | +import cn.iocoder.yudao.framework.pay.config.YudaoPayAutoConfiguration; | ||
| 11 | +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; | ||
| 12 | +import org.junit.jupiter.api.Test; | ||
| 13 | +import org.springframework.context.annotation.Import; | ||
| 14 | + | ||
| 15 | +import javax.annotation.Resource; | ||
| 16 | +import java.time.Duration; | ||
| 17 | + | ||
| 18 | +@Import({PayOrderCoreServiceImpl.class, PayAppCoreServiceImpl.class, | ||
| 19 | + PayChannelCoreServiceImpl.class, YudaoPayAutoConfiguration.class}) | ||
| 20 | +public class PayOrderCoreServiceTest extends BaseDbIntegrationTest { | ||
| 21 | + | ||
| 22 | + @Resource | ||
| 23 | + private PayOrderCoreService payOrderCoreService; | ||
| 24 | + | ||
| 25 | + @Test | ||
| 26 | + public void testCreatePayOrder() { | ||
| 27 | + // 构造请求 | ||
| 28 | + PayOrderCreateReqDTO reqDTO = new PayOrderCreateReqDTO(); | ||
| 29 | + reqDTO.setAppId(6L); | ||
| 30 | + reqDTO.setUserIp("127.0.0.1"); | ||
| 31 | + reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis())); | ||
| 32 | + reqDTO.setSubject("标题"); | ||
| 33 | + reqDTO.setBody("内容"); | ||
| 34 | + reqDTO.setAmount(100); | ||
| 35 | + reqDTO.setExpireTime(DateUtils.addTime(Duration.ofDays(1))); | ||
| 36 | + // 发起请求 | ||
| 37 | + payOrderCoreService.createPayOrder(reqDTO); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + @Test | ||
| 41 | + public void testSubmitPayOrder() { | ||
| 42 | + // 构造请求 | ||
| 43 | + PayOrderSubmitReqDTO reqDTO = new PayOrderSubmitReqDTO(); | ||
| 44 | + reqDTO.setId(10L); | ||
| 45 | + reqDTO.setAppId(6L); | ||
| 46 | + reqDTO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); | ||
| 47 | + reqDTO.setUserIp("127.0.0.1"); | ||
| 48 | + // 发起请求 | ||
| 49 | + payOrderCoreService.submitPayOrder(reqDTO); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | +} |
yudao-core-service/src/test-integration/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.coreservice.modules.pay.service; |
yudao-core-service/src/test-integration/resources/application-integration-test.yaml
| @@ -60,7 +60,7 @@ mybatis-plus: | @@ -60,7 +60,7 @@ mybatis-plus: | ||
| 60 | logic-delete-value: 1 # 逻辑已删除值(默认为 1) | 60 | logic-delete-value: 1 # 逻辑已删除值(默认为 1) |
| 61 | logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) | 61 | logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) |
| 62 | mapper-locations: classpath*:mapper/*.xml | 62 | mapper-locations: classpath*:mapper/*.xml |
| 63 | - type-aliases-package: ${yudao.info.base-package}.modules.*.dal.dataobject, ${yudao.core-service.base-package}.modules.*.dal.dataobject | 63 | + type-aliases-package: ${yudao.core-service.base-package}.modules.*.dal.dataobject |
| 64 | 64 | ||
| 65 | --- #################### 定时任务相关配置 #################### | 65 | --- #################### 定时任务相关配置 #################### |
| 66 | 66 |
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/ObjectUtils.java
| @@ -29,4 +29,13 @@ public class ObjectUtils { | @@ -29,4 +29,13 @@ public class ObjectUtils { | ||
| 29 | return obj1.compareTo(obj2) > 0 ? obj1 : obj2; | 29 | return obj1.compareTo(obj2) > 0 ? obj1 : obj2; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | + public static <T> T defaultIfNull(T... array) { | ||
| 33 | + for (T item : array) { | ||
| 34 | + if (item != null) { | ||
| 35 | + return item; | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + return null; | ||
| 39 | + } | ||
| 40 | + | ||
| 32 | } | 41 | } |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java
| 1 | package cn.iocoder.yudao.framework.pay.core.client; | 1 | package cn.iocoder.yudao.framework.pay.core.client; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 4 | import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; | 3 | import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; |
| 5 | 4 | ||
| 6 | /** | 5 | /** |
| @@ -17,7 +16,12 @@ public interface PayClient { | @@ -17,7 +16,12 @@ public interface PayClient { | ||
| 17 | */ | 16 | */ |
| 18 | Long getId(); | 17 | Long getId(); |
| 19 | 18 | ||
| 20 | - // TODO 缺少注释 | ||
| 21 | - CommonResult<?> unifiedOrder(PayOrderUnifiedReqDTO reqDTO); | 19 | + /** |
| 20 | + * 调用支付渠道,统一下单 | ||
| 21 | + * | ||
| 22 | + * @param reqDTO 下单信息 | ||
| 23 | + * @return 各支付渠道的返回结果 | ||
| 24 | + */ | ||
| 25 | + PayCommonResult<?> unifiedOrder(PayOrderUnifiedReqDTO reqDTO); | ||
| 22 | 26 | ||
| 23 | } | 27 | } |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java
| @@ -54,7 +54,7 @@ public class PayOrderUnifiedReqDTO { | @@ -54,7 +54,7 @@ public class PayOrderUnifiedReqDTO { | ||
| 54 | */ | 54 | */ |
| 55 | @NotNull(message = "支付金额不能为空") | 55 | @NotNull(message = "支付金额不能为空") |
| 56 | @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") | 56 | @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") |
| 57 | - private Integer amount; | 57 | + private Long amount; |
| 58 | 58 | ||
| 59 | /** | 59 | /** |
| 60 | * 支付过期时间 | 60 | * 支付过期时间 |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java
| 1 | package cn.iocoder.yudao.framework.pay.core.client.impl; | 1 | package cn.iocoder.yudao.framework.pay.core.client.impl; |
| 2 | 2 | ||
| 3 | +import cn.hutool.extra.validation.ValidationUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping; | ||
| 3 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; |
| 4 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; | 6 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 5 | -import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping; | 7 | +import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; |
| 8 | +import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; | ||
| 6 | import lombok.extern.slf4j.Slf4j; | 9 | import lombok.extern.slf4j.Slf4j; |
| 7 | 10 | ||
| 11 | +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | ||
| 12 | + | ||
| 8 | /** | 13 | /** |
| 9 | * 支付客户端的抽象类,提供模板方法,减少子类的冗余代码 | 14 | * 支付客户端的抽象类,提供模板方法,减少子类的冗余代码 |
| 10 | * | 15 | * |
| @@ -30,7 +35,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen | @@ -30,7 +35,7 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen | ||
| 30 | */ | 35 | */ |
| 31 | protected Config config; | 36 | protected Config config; |
| 32 | 37 | ||
| 33 | - protected Double calculateAmount(Integer amount) { | 38 | + protected Double calculateAmount(Long amount) { |
| 34 | return amount / 100.0; | 39 | return amount / 100.0; |
| 35 | } | 40 | } |
| 36 | 41 | ||
| @@ -70,4 +75,23 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen | @@ -70,4 +75,23 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen | ||
| 70 | return channelId; | 75 | return channelId; |
| 71 | } | 76 | } |
| 72 | 77 | ||
| 78 | + @Override | ||
| 79 | + public final PayCommonResult<?> unifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | ||
| 80 | + ValidationUtil.validate(reqDTO); | ||
| 81 | + // 执行短信发送 | ||
| 82 | + PayCommonResult<?> result; | ||
| 83 | + try { | ||
| 84 | + result = doUnifiedOrder(reqDTO); | ||
| 85 | + } catch (Throwable ex) { | ||
| 86 | + // 打印异常日志 | ||
| 87 | + log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), ex); | ||
| 88 | + // 封装返回 | ||
| 89 | + return PayCommonResult.error(ex); | ||
| 90 | + } | ||
| 91 | + return result; | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + protected abstract PayCommonResult<?> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) | ||
| 95 | + throws Throwable; | ||
| 96 | + | ||
| 73 | } | 97 | } |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java
| 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; | 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.bean.BeanUtil; | 3 | import cn.hutool.core.bean.BeanUtil; |
| 4 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 5 | import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; | 4 | import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; |
| 6 | import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; | 5 | import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; |
| 7 | import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; | 6 | import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; |
| @@ -42,7 +41,7 @@ public class AlipayQrPayClient extends AbstractPayClient<AlipayPayClientConfig> | @@ -42,7 +41,7 @@ public class AlipayQrPayClient extends AbstractPayClient<AlipayPayClientConfig> | ||
| 42 | } | 41 | } |
| 43 | 42 | ||
| 44 | @Override | 43 | @Override |
| 45 | - public CommonResult<AlipayTradePrecreateResponse> unifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | 44 | + public PayCommonResult<AlipayTradePrecreateResponse> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { |
| 46 | // 构建 AlipayTradePrecreateModel 请求 | 45 | // 构建 AlipayTradePrecreateModel 请求 |
| 47 | AlipayTradePrecreateModel model = new AlipayTradePrecreateModel(); | 46 | AlipayTradePrecreateModel model = new AlipayTradePrecreateModel(); |
| 48 | model.setOutTradeNo(reqDTO.getMerchantOrderId()); | 47 | model.setOutTradeNo(reqDTO.getMerchantOrderId()); |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java
| 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; | 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.bean.BeanUtil; | 3 | import cn.hutool.core.bean.BeanUtil; |
| 4 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 5 | import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; | 4 | import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; |
| 6 | import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; | 5 | import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; |
| 7 | import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; | 6 | import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; |
| @@ -37,7 +36,7 @@ public class AlipayWapPayClient extends AbstractPayClient<AlipayPayClientConfig> | @@ -37,7 +36,7 @@ public class AlipayWapPayClient extends AbstractPayClient<AlipayPayClientConfig> | ||
| 37 | } | 36 | } |
| 38 | 37 | ||
| 39 | @Override | 38 | @Override |
| 40 | - public CommonResult<AlipayTradeWapPayResponse> unifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | 39 | + public PayCommonResult<AlipayTradeWapPayResponse> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { |
| 41 | // 构建 AlipayTradeWapPayModel 请求 | 40 | // 构建 AlipayTradeWapPayModel 请求 |
| 42 | AlipayTradeWapPayModel model = new AlipayTradeWapPayModel(); | 41 | AlipayTradeWapPayModel model = new AlipayTradeWapPayModel(); |
| 43 | model.setOutTradeNo(reqDTO.getMerchantOrderId()); | 42 | model.setOutTradeNo(reqDTO.getMerchantOrderId()); |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXCodeMapping.java
| 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.wx; | 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.wx; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.exception.ErrorCode; | 4 | import cn.iocoder.yudao.framework.common.exception.ErrorCode; |
| 4 | import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; | 5 | import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; |
| 5 | import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping; | 6 | import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping; |
| @@ -44,6 +45,11 @@ public class WXCodeMapping extends AbstractPayCodeMapping { | @@ -44,6 +45,11 @@ public class WXCodeMapping extends AbstractPayCodeMapping { | ||
| 44 | return PAY_OPENID_ERROR; | 45 | return PAY_OPENID_ERROR; |
| 45 | } | 46 | } |
| 46 | } | 47 | } |
| 48 | + if (Objects.equals(apiCode, "CustomErrorCode")) { | ||
| 49 | + if (StrUtil.contains(apiMsg, "必填字段")) { | ||
| 50 | + return PAY_PARAM_MISSING; | ||
| 51 | + } | ||
| 52 | + } | ||
| 47 | return null; | 53 | return null; |
| 48 | } | 54 | } |
| 49 | 55 |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java
| @@ -3,8 +3,8 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.wx; | @@ -3,8 +3,8 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.wx; | ||
| 3 | import cn.hutool.core.bean.BeanUtil; | 3 | import cn.hutool.core.bean.BeanUtil; |
| 4 | import cn.hutool.core.date.DateUtil; | 4 | import cn.hutool.core.date.DateUtil; |
| 5 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 7 | import cn.iocoder.yudao.framework.common.util.io.FileUtils; | 6 | import cn.iocoder.yudao.framework.common.util.io.FileUtils; |
| 7 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | ||
| 8 | import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; | 8 | import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; |
| 9 | import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; | 9 | import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; |
| 10 | import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; | 10 | import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; |
| @@ -21,7 +21,6 @@ import com.github.binarywang.wxpay.service.WxPayService; | @@ -21,7 +21,6 @@ import com.github.binarywang.wxpay.service.WxPayService; | ||
| 21 | import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; | 21 | import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; |
| 22 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
| 23 | 23 | ||
| 24 | -import static cn.hutool.core.util.ObjectUtil.defaultIfNull; | ||
| 25 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | 24 | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; |
| 26 | import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.CODE_SUCCESS; | 25 | import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.CODE_SUCCESS; |
| 27 | import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.MESSAGE_SUCCESS; | 26 | import static cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXCodeMapping.MESSAGE_SUCCESS; |
| @@ -62,7 +61,7 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> { | @@ -62,7 +61,7 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> { | ||
| 62 | } | 61 | } |
| 63 | 62 | ||
| 64 | @Override | 63 | @Override |
| 65 | - public CommonResult<WxPayMpOrderResult> unifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | 64 | + public PayCommonResult<WxPayMpOrderResult> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { |
| 66 | WxPayMpOrderResult response; | 65 | WxPayMpOrderResult response; |
| 67 | try { | 66 | try { |
| 68 | switch (config.getApiVersion()) { | 67 | switch (config.getApiVersion()) { |
| @@ -80,8 +79,8 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> { | @@ -80,8 +79,8 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> { | ||
| 80 | } | 79 | } |
| 81 | } catch (WxPayException e) { | 80 | } catch (WxPayException e) { |
| 82 | log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e); | 81 | log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e); |
| 83 | - return PayCommonResult.build(defaultIfNull(e.getErrCode(), e.getReturnCode()), | ||
| 84 | - defaultIfNull(e.getErrCodeDes(), e.getReturnMsg()),null, codeMapping); | 82 | + return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"), |
| 83 | + ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()),null, codeMapping); | ||
| 85 | } | 84 | } |
| 86 | return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping); | 85 | return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping); |
| 87 | } | 86 | } |
| @@ -92,9 +91,9 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> { | @@ -92,9 +91,9 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> { | ||
| 92 | .outTradeNo(reqDTO.getMerchantOrderId()) | 91 | .outTradeNo(reqDTO.getMerchantOrderId()) |
| 93 | // TODO 芋艿:貌似没 title? | 92 | // TODO 芋艿:貌似没 title? |
| 94 | .body(reqDTO.getBody()) | 93 | .body(reqDTO.getBody()) |
| 95 | - .totalFee(reqDTO.getAmount()) // 单位分 | 94 | + .totalFee(reqDTO.getAmount().intValue()) // 单位分 |
| 96 | .timeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyyMMddHHmmss")) | 95 | .timeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyyMMddHHmmss")) |
| 97 | - .spbillCreateIp(reqDTO.getClientIp()) | 96 | + .spbillCreateIp(reqDTO.getUserIp()) |
| 98 | .openid("ockUAwIZ-0OeMZl9ogcZ4ILrGba0") // TODO 芋艿:先随便写死 | 97 | .openid("ockUAwIZ-0OeMZl9ogcZ4ILrGba0") // TODO 芋艿:先随便写死 |
| 99 | .notifyUrl(reqDTO.getNotifyUrl()) | 98 | .notifyUrl(reqDTO.getNotifyUrl()) |
| 100 | .build(); | 99 | .build(); |
| @@ -108,10 +107,10 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> { | @@ -108,10 +107,10 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> { | ||
| 108 | request.setOutTradeNo(reqDTO.getMerchantOrderId()); | 107 | request.setOutTradeNo(reqDTO.getMerchantOrderId()); |
| 109 | // TODO 芋艿:貌似没 title? | 108 | // TODO 芋艿:貌似没 title? |
| 110 | request.setDescription(reqDTO.getBody()); | 109 | request.setDescription(reqDTO.getBody()); |
| 111 | - request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getAmount())); // 单位分 | 110 | + request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getAmount().intValue())); // 单位分 |
| 112 | request.setTimeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyyMMddHHmmss")); | 111 | request.setTimeExpire(DateUtil.format(reqDTO.getExpireTime(), "yyyyMMddHHmmss")); |
| 113 | request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid("ockUAwIZ-0OeMZl9ogcZ4ILrGba0")); // TODO 芋艿:先随便写死 | 112 | request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid("ockUAwIZ-0OeMZl9ogcZ4ILrGba0")); // TODO 芋艿:先随便写死 |
| 114 | - request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getClientIp())); | 113 | + request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp())); |
| 115 | request.setNotifyUrl(reqDTO.getNotifyUrl()); | 114 | request.setNotifyUrl(reqDTO.getNotifyUrl()); |
| 116 | // 执行请求 | 115 | // 执行请求 |
| 117 | return client.createOrderV3(TradeTypeEnum.JSAPI, request); | 116 | return client.createOrderV3(TradeTypeEnum.JSAPI, request); |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayFrameworkErrorCodeConstants.java
| @@ -20,6 +20,7 @@ public interface PayFrameworkErrorCodeConstants { | @@ -20,6 +20,7 @@ public interface PayFrameworkErrorCodeConstants { | ||
| 20 | 20 | ||
| 21 | // ========== 其它相关 2002000900 开头 ========== | 21 | // ========== 其它相关 2002000900 开头 ========== |
| 22 | ErrorCode PAY_OPENID_ERROR = new ErrorCode(2002000900, "无效的 openid"); // 例如说,微信 openid 未授权过 | 22 | ErrorCode PAY_OPENID_ERROR = new ErrorCode(2002000900, "无效的 openid"); // 例如说,微信 openid 未授权过 |
| 23 | + ErrorCode PAY_PARAM_MISSING = new ErrorCode(2002000901, "请求参数缺失"); // 例如说,支付少传了金额 | ||
| 23 | 24 | ||
| 24 | ErrorCode EXCEPTION = new ErrorCode(2002000999, "调用异常"); | 25 | ErrorCode EXCEPTION = new ErrorCode(2002000999, "调用异常"); |
| 25 | 26 |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/resources/META-INF/spring.factories
0 → 100644
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test-integration/java/cn/iocoder/yudao/framework/core/client/impl/PayClientFactoryImplTest.java
| @@ -117,11 +117,11 @@ public class PayClientFactoryImplTest { | @@ -117,11 +117,11 @@ public class PayClientFactoryImplTest { | ||
| 117 | 117 | ||
| 118 | private static PayOrderUnifiedReqDTO buildPayOrderUnifiedReqDTO() { | 118 | private static PayOrderUnifiedReqDTO buildPayOrderUnifiedReqDTO() { |
| 119 | PayOrderUnifiedReqDTO reqDTO = new PayOrderUnifiedReqDTO(); | 119 | PayOrderUnifiedReqDTO reqDTO = new PayOrderUnifiedReqDTO(); |
| 120 | - reqDTO.setAmount(123); | 120 | + reqDTO.setAmount(123L); |
| 121 | reqDTO.setSubject("IPhone 13"); | 121 | reqDTO.setSubject("IPhone 13"); |
| 122 | reqDTO.setBody("biubiubiu"); | 122 | reqDTO.setBody("biubiubiu"); |
| 123 | reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis())); | 123 | reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis())); |
| 124 | - reqDTO.setClientIp("127.0.0.1"); | 124 | + reqDTO.setUserIp("127.0.0.1"); |
| 125 | reqDTO.setNotifyUrl("http://127.0.0.1:8080"); | 125 | reqDTO.setNotifyUrl("http://127.0.0.1:8080"); |
| 126 | return reqDTO; | 126 | return reqDTO; |
| 127 | } | 127 | } |