Просмотр исходного кода

1. 引入 IJPay 组件
2. 增加创建支付单的 Service 实现

YunaiV 3 лет назад
Родитель
Сommit
81126b2b4b
36 измененных файлов с 586 добавлено и 84 удалено
  1. 2 2
      yudao-admin-server/pom.xml
  2. 0 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/package-info.java
  3. 4 0
      yudao-core-service/pom.xml
  4. 1 1
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/infra/dal/dataobject/config/InfConfigDO.java
  5. 15 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreServiceConvert.java
  6. 6 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/package-info.java
  7. 1 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md
  8. 9 6
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayAppDO.java
  9. 2 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayChannelDO.java
  10. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayMerchantDO.java
  11. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayNotifyDO.java
  12. 28 21
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayOrderDO.java
  13. 54 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java
  14. 12 7
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayRefundDO.java
  15. 1 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/package-info.java
  16. 9 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayAppCoreMapper.java
  17. 16 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderCoreMapper.java
  18. 16 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeConstants.java
  19. 28 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/merchant/PayChannelCodeEnum.java
  20. 29 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderStatusEnum.java
  21. 7 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/package-info.java
  22. 23 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayAppCoreService.java
  23. 43 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java
  24. 33 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java
  25. 64 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java
  26. 41 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java
  27. 23 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitRespDTO.java
  28. 89 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java
  29. 1 0
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java
  30. 13 0
      yudao-dependencies/pom.xml
  31. 10 9
      yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
  32. 0 8
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/merchant/package-info.java
  33. 0 8
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/package-info.java
  34. 0 8
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/pay/package-info.java
  35. 0 8
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/refund/package-info.java
  36. 4 1
      更新日志.md

+ 2 - 2
yudao-admin-server/pom.xml

@@ -122,11 +122,11 @@
             <artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
         </dependency>
 
-        <!-- TODO 后续看情况,进行调整 -->
+        <!-- 三方云服务相关 -->
+
         <dependency>
             <groupId>com.xkcoding.justauth</groupId>
             <artifactId>justauth-spring-boot-starter</artifactId>
-            <version>1.4.0</version>
         </dependency>
     </dependencies>
 

+ 0 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/package-info.java

@@ -1 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject;

+ 4 - 0
yudao-core-service/pom.xml

@@ -32,6 +32,10 @@
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-biz-sms</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-biz-pay</artifactId>
+        </dependency>
 
         <!-- Web 相关 -->
         <dependency>

+ 1 - 1
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/infra/dal/dataobject/config/InfConfigDO.java

@@ -11,7 +11,7 @@ import lombok.ToString;
 /**
  * 参数配置表
  *
- * @author ruoyi
+ * @author 芋道源码
  */
 @TableName("inf_config")
 @Data

+ 15 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreServiceConvert.java

@@ -0,0 +1,15 @@
+package cn.iocoder.yudao.coreservice.modules.pay.convert.order;
+
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
+import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderCreateReqDTO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface PayOrderCoreServiceConvert {
+
+    PayOrderCoreServiceConvert INSTANCE = Mappers.getMapper(PayOrderCoreServiceConvert.class);
+
+    PayOrderDO convert(PayOrderCreateReqDTO bean);
+
+}

+ 6 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/package-info.java

@@ -0,0 +1,6 @@
+/**
+ * 提供 POJO 类的实体转换
+ *
+ * 目前使用 MapStruct 框架
+ */
+package cn.iocoder.yudao.coreservice.modules.pay.convert;

+ 1 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md

@@ -0,0 +1 @@
+<http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao>

+ 9 - 6
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayAppDO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.merchant;
+package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant;
 
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@@ -23,11 +23,6 @@ public class PayAppDO extends BaseDO {
     @TableId
     private Long id;
     /**
-     * 应用号
-     * 例如说,60cc81e0e4b06afc4d3f0cfq
-     */
-    private String no;
-    /**
      * 应用名
      */
     private String name;
@@ -46,6 +41,14 @@ public class PayAppDO extends BaseDO {
      * TODO 芋艿:用途
      */
     private String secret;
+    /**
+     * 支付结果的回调地址
+     */
+    private String payNotifyUrl;
+    /**
+     * 退款结果的回调地址
+     */
+    private String refundNotifyUrl;
 
     /**
      * 商户编号

+ 2 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayChannelDO.java

@@ -1,6 +1,6 @@
-package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.merchant;
+package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant;
 
-import cn.iocoder.yudao.adminserver.modules.pay.enums.PayChannelCodeEnum;
+import cn.iocoder.yudao.coreservice.modules.pay.enums.merchant.PayChannelCodeEnum;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import lombok.Data;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayMerchantDO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.merchant;
+package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant;
 
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayNotifyDO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.order;
+package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import lombok.Data;

+ 28 - 21
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayOrderDO.java

@@ -1,11 +1,15 @@
-package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.order;
+package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order;
 
-import cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.merchant.PayAppDO;
-import cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.merchant.PayChannelDO;
-import cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.merchant.PayMerchantDO;
-import cn.iocoder.yudao.adminserver.modules.pay.enums.PayChannelCodeEnum;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
+import cn.iocoder.yudao.coreservice.modules.pay.enums.merchant.PayChannelCodeEnum;
+import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
 
 import java.util.Date;
 
@@ -14,19 +18,22 @@ import java.util.Date;
  *
  * @author 芋道源码
  */
+@TableName("pay_order")
 @Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
 public class PayOrderDO extends BaseDO {
 
     /**
      * 订单编号,数据库自增
      */
     private Long id;
-    /**
-     * 订单号,根据规则生成
-     *
-     * 例如说,P202110132239124200055
-     */
-    private String no;
+//    /**
+//     * 订单号,根据规则生成
+//     *
+//     * 例如说,P202110132239124200055
+//     */
+//    private String no;
     /**
      * 商户编号
      *
@@ -42,7 +49,7 @@ public class PayOrderDO extends BaseDO {
     /**
      * 渠道编号
      *
-     * 关联 {@link PayChannelDO#getMerchantId()}
+     * 关联 {@link PayChannelDO#getId()}
      */
     private Long channelId;
     /**
@@ -55,10 +62,10 @@ public class PayOrderDO extends BaseDO {
     // ========== 商户相关字段 ==========
 
     /**
-     * 商户订单号
+     * 商户订单
      * 例如说,内部系统 A 的订单号。需要保证每个 PayMerchantDO 唯一 TODO 芋艿:需要在测试下
      */
-    private String merchantOrderNo;
+    private String merchantOrderId;
     /**
      * 商品标题
      */
@@ -71,11 +78,6 @@ public class PayOrderDO extends BaseDO {
      * 商户拓展参数
      */
     private String merchantExtra;
-    /**
-     * 通知商户支付结果的回调状态
-     * TODO 芋艿:0 未发送 1 已发送
-     */
-    private Integer notifyStatus;
 
     // ========== 订单相关字段 ==========
 
@@ -96,10 +98,15 @@ public class PayOrderDO extends BaseDO {
     /**
      * 支付状态
      *
-     * TODO 芋艿:状态枚举
+     * 枚举 {@link PayOrderStatusEnum}
      */
     private Integer status;
     /**
+     * 通知商户支付结果的回调状态
+     * TODO 芋艿:0 未发送 1 已发送
+     */
+    private Integer notifyStatus;
+    /**
      * 客户端 IP
      */
     private String clientIp;
@@ -110,7 +117,7 @@ public class PayOrderDO extends BaseDO {
     /**
      * 订单失效时间
      */
-    private Date expiredTime;
+    private Date expireTime;
     /**
      * 支付渠道的额外参数
      *

+ 54 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java

@@ -0,0 +1,54 @@
+package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 交易扩展表
+ */
+@TableName("pay_transaction_extension")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+public class PayOrderExtensionDO extends BaseDO {
+
+    /**
+     * 编号,自增
+     */
+    private Integer id;
+    /**
+     * 交易编号 {@link PayTransactionDO#getId()}
+     */
+    private Integer transactionId;
+    /**
+     * 选择的支付渠道
+     */
+    private Integer payChannel;
+    /**
+     * 生成传输给第三方的订单号
+     *
+     * 唯一索引
+     */
+    private String transactionCode;
+    /**
+     * 扩展内容
+     *
+     * 异步通知的时候填充回调的数据
+     */
+    private String extensionData;
+    /**
+     * 发起交易的 IP
+     */
+    private String createIp;
+    /**
+     * 状态
+     *
+     * @see cn.iocoder.mall.payservice.enums.transaction.PayTransactionStatusEnum
+     * 注意,只包含上述枚举的 WAITING 和 SUCCESS
+     */
+    private Integer status;
+
+}

+ 12 - 7
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayRefundDO.java

@@ -1,9 +1,9 @@
-package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.order;
+package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order;
 
-import cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.merchant.PayAppDO;
-import cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.merchant.PayChannelDO;
-import cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject.merchant.PayMerchantDO;
-import cn.iocoder.yudao.adminserver.modules.pay.enums.PayChannelCodeEnum;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
+import cn.iocoder.yudao.coreservice.modules.pay.enums.merchant.PayChannelCodeEnum;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import lombok.Data;
 
@@ -45,7 +45,7 @@ public class PayRefundDO extends BaseDO {
     /**
      * 渠道编号
      *
-     * 关联 {@link PayChannelDO#getMerchantId()}
+     * 关联 {@link PayChannelDO#getId()}
      */
     private Long channelId;
     /**
@@ -80,6 +80,11 @@ public class PayRefundDO extends BaseDO {
      */
     private Integer status;
     /**
+     * 通知商户退款结果的回调状态
+     * TODO 芋艿:0 未发送 1 已发送
+     */
+    private Integer notifyStatus;
+    /**
      * 客户端 IP
      */
     private String clientIp;
@@ -98,7 +103,7 @@ public class PayRefundDO extends BaseDO {
     /**
      * 退款失效时间
      */
-    private Date expiredTime;
+    private Date expireTime;
     /**
      * 支付渠道的额外参数
      *

+ 1 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject;

+ 9 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayAppCoreMapper.java

@@ -0,0 +1,9 @@
+package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant;
+
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface PayAppCoreMapper extends BaseMapperX<PayAppDO> {
+}

+ 16 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderCoreMapper.java

@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order;
+
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface PayOrderCoreMapper extends BaseMapperX<PayOrderDO> {
+
+    default PayOrderDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) {
+        return selectOne(new QueryWrapper<PayOrderDO>().eq("app_id", appId)
+                .eq("merchant_order_id", merchantOrderId));
+    }
+
+}

+ 16 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeConstants.java

@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.coreservice.modules.pay.enums;
+
+import cn.iocoder.yudao.framework.common.exception.ErrorCode;
+
+/**
+ * Pay 错误码枚举类
+ *
+ * pay 系统,使用 1-007-000-000 段
+ */
+public interface PayErrorCodeConstants {
+
+    // ========== APP 模块 1-007-000-000 ==========
+    ErrorCode PAY_APP_NOT_FOUND = new ErrorCode(1007000000, "App 不存在");
+    ErrorCode PAY_APP_IS_DISABLE = new ErrorCode(1007000002, "App 已经被禁用");
+
+}

+ 28 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/merchant/PayChannelCodeEnum.java

@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.coreservice.modules.pay.enums.merchant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 支付渠道的编码的枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum PayChannelCodeEnum {
+
+    wx_pub("wx_pub", "微信 JSAPI 支付");
+
+    /**
+     * 编码
+     *
+     * 参考 https://www.pingxx.com/api/支付渠道属性值.html
+     */
+    private String code;
+    /**
+     * 名字
+     */
+    private String name;
+
+}

+ 29 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderStatusEnum.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.coreservice.modules.pay.enums.order;
+
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 支付订单的状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum PayOrderStatusEnum implements IntArrayValuable {
+
+    WAITING(0, "未支付"),
+    SUCCESS(10, "支付成功"),
+    CLOSED(20, "支付关闭"), // 未付款交易超时关闭,或支付完成后全额退款 TODO 芋艿:需要优化下
+    ;
+
+    private final Integer status;
+    private final String name;
+
+    @Override
+    public int[] array() {
+        return new int[0];
+    }
+
+}

+ 7 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/package-info.java

@@ -0,0 +1,7 @@
+/**
+ * pay 包下,我们放支付业务,提供业务的支付能力。
+ * 例如说:商户、应用、支付、退款等等
+ *
+ * 缩写:pay
+ */
+package cn.iocoder.yudao.coreservice.modules.pay;

+ 23 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayAppCoreService.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.coreservice.modules.pay.service.merchant;
+
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
+
+/**
+ * 支付应用 Core Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface PayAppCoreService {
+
+    /**
+     * 支付应用的合法性
+     *
+     * 如果不合法,抛出 {@link ServiceException} 业务异常
+     *
+     * @param id 应用编号
+     * @return 应用信息
+     */
+    PayAppDO validPayApp(Long id);
+
+}

+ 43 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java

@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.coreservice.modules.pay.service.merchant.impl;
+
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant.PayAppCoreMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayAppCoreService;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeConstants.*;
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+
+/**
+ * 支付应用 Core Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Valid
+@Slf4j
+public class PayAppCoreServiceImpl implements PayAppCoreService {
+
+    @Resource
+    private PayAppCoreMapper payAppCoreMapper;
+
+    @Override
+    public PayAppDO validPayApp(Long id) {
+        PayAppDO app = payAppCoreMapper.selectById(id);
+        // 校验是否存在
+        if (app == null) {
+            throw exception(PAY_APP_NOT_FOUND);
+        }
+        // 校验是否禁用
+        if (CommonStatusEnum.DISABLE.getStatus().equals(app.getStatus())) {
+            throw exception(PAY_APP_IS_DISABLE);
+        }
+        return app;
+    }
+
+}

+ 33 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java

@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.coreservice.modules.pay.service.order;
+
+import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderCreateReqDTO;
+import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitReqDTO;
+import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitRespDTO;
+
+import javax.validation.Valid;
+
+/**
+ * 支付订单 Core Service
+ *
+ * @author 芋道源码
+ */
+public interface PayOrderCoreService {
+
+   /**
+    * 创建支付单
+    *
+    * @param reqDTO 创建请求
+    * @return 支付单编号
+    */
+   Long createPayOrder(@Valid PayOrderCreateReqDTO reqDTO);
+
+   /**
+    * 提交支付
+    * 此时,会发起支付渠道的调用
+    *
+    * @param reqDTO 提交请求
+    * @return 提交结果
+    */
+   PayOrderSubmitRespDTO submitPayOrder(PayOrderSubmitReqDTO reqDTO);
+
+}

+ 64 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java

@@ -0,0 +1,64 @@
+package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto;
+
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 支付单创建 Request DTO
+ */
+@Data
+public class PayOrderCreateReqDTO implements Serializable {
+
+    /**
+     * 应用编号
+     */
+    @NotEmpty(message = "应用编号不能为空")
+    private Long appId;
+    /**
+     * 客户端 IP
+     */
+    @NotEmpty(message = "客户端 IP 不能为空")
+    private String clientIp;
+
+    // ========== 商户相关字段 ==========
+
+    /**
+     * 商户订单编号
+     */
+    @NotEmpty(message = "商户订单编号不能为空")
+    private String merchantOrderId;
+    /**
+     * 商品标题
+     */
+    @NotEmpty(message = "商品标题不能为空")
+    @Length(max = 32, message = "商品标题不能超过 32")
+    private String subject;
+    /**
+     * 商品描述信息
+     */
+    @NotEmpty(message = "商品描述信息不能为空")
+    @Length(max = 128, message = "商品描述信息长度不能超过128")
+    private String body;
+
+    // ========== 订单相关字段 ==========
+
+    /**
+     * 支付金额,单位:分
+     */
+    @NotNull(message = "支付金额不能为空")
+    @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
+    private Integer amount;
+
+    /**
+     * 支付过期时间
+     */
+    @NotNull(message = "支付过期时间不能为空")
+    private Date expireTime;
+
+}

+ 41 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java

@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 支付单提交 Request DTO
+ */
+@Data
+@Accessors(chain = true)
+public class PayOrderSubmitReqDTO implements Serializable {
+
+    /**
+     * 应用编号
+     */
+    @NotEmpty(message = "应用编号不能为空")
+    private String appId;
+
+    /**
+     * 支付单编号
+     */
+    @NotNull(message = "支付单编号不能为空")
+    private Long id;
+
+    /**
+     * 支付渠道
+     */
+    @NotNull(message = "支付渠道")
+    private String channelCode;
+
+    /**
+     * 客户端 IP
+     */
+    @NotEmpty(message = "客户端 IP 不能为空")
+    private String clientIp;
+
+}

+ 23 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitRespDTO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 支付单提交 Response DTO
+ */
+@Data
+public class PayOrderSubmitRespDTO implements Serializable {
+
+    /**
+     * 支付拓展单的编号
+     */
+    private Long extensionId;
+
+    /**
+     * 调用支付渠道的响应结果
+     */
+    private String invokeResponse;
+
+}

+ 89 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java

@@ -0,0 +1,89 @@
+package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl;
+
+import cn.iocoder.yudao.coreservice.modules.pay.convert.order.PayOrderCoreServiceConvert;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum;
+import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayAppCoreService;
+import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayOrderCoreService;
+import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderCreateReqDTO;
+import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitReqDTO;
+import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitRespDTO;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+/**
+ * 支付订单 Core Service 实现类
+ */
+@Service
+@Valid
+@Slf4j
+public class PayOrderCoreServiceImpl implements PayOrderCoreService {
+
+    @Resource
+    private PayAppCoreService payAppCoreService;
+
+    @Resource
+    private PayOrderCoreMapper payOrderCoreMapper;
+
+    @Override
+    public Long createPayOrder(PayOrderCreateReqDTO reqDTO) {
+        // 校验 App
+        PayAppDO app = payAppCoreService.validPayApp(reqDTO.getAppId());
+
+        // 查询对应的支付交易单是否已经存在。如果是,则直接返回
+        PayOrderDO order = payOrderCoreMapper.selectByAppIdAndMerchantOrderId(
+                reqDTO.getAppId(), reqDTO.getMerchantOrderId());
+        if (order != null) {
+            log.warn("[createPayOrder][appId({}) merchantOrderId({}) 已经存在对应的支付单({})]", order.getAppId(),
+                    order.getMerchantOrderId(), JsonUtils.toJsonString(order)); // 理论来说,不会出现这个情况
+            return app.getId();
+        }
+
+        // 创建支付交易单
+        order = PayOrderCoreServiceConvert.INSTANCE.convert(reqDTO)
+                .setStatus(PayOrderStatusEnum.WAITING.getStatus())
+                .setNotifyUrl(app.getPayNotifyUrl());
+        payOrderCoreMapper.insert(order);
+        // 最终返回
+        return order.getId();
+    }
+
+    @Override
+    public PayOrderSubmitRespDTO submitPayOrder(PayOrderSubmitReqDTO reqDTO) {
+        // 校验 App
+        PayAppDO app = payAppCoreService.validPayApp(reqDTO.getId());
+        // TODO 校验支付渠道是否有效
+
+        // 获得 PayOrderDO ,并校验其是否存在
+        PayOrderDO order = payOrderCoreMapper.selectById(reqDTO.getId());
+        if (order == null) { // 是否存在
+            throw exception(PAY_TRANSACTION_NOT_FOUND);
+        }
+        if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付
+            throw exception(PAY_TRANSACTION_STATUS_IS_NOT_WAITING);
+        }
+
+        // 插入 PayTransactionExtensionDO
+        PayTransactionExtensionDO payTransactionExtensionDO = PayTransactionConvert.INSTANCE.convert(submitReqDTO)
+                .setTransactionId(payTransaction.getId()).setTransactionCode(generateTransactionCode())
+                .setStatus(PayTransactionStatusEnum.WAITING.getStatus());
+        payTransactionExtensionMapper.insert(payTransactionExtensionDO);
+
+        // 调用三方接口
+        AbstractThirdPayClient thirdPayClient = ThirdPayClientFactory.getThirdPayClient(submitReqDTO.getPayChannel());
+        CommonResult<String> invokeResult = thirdPayClient.submitTransaction(payTransaction, payTransactionExtensionDO, null); // TODO 暂时传入 extra = null
+        invokeResult.checkError();
+
+        // TODO 轮询三方接口,是否已经支付的任务
+        // 返回成功
+        return new PayTransactionSubmitRespDTO().setId(payTransactionExtensionDO.getId()).setInvokeResponse(invokeResult.getData());
+    }
+
+}

+ 1 - 0
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.yudao.coreservice.modules.pay.service;

+ 13 - 0
yudao-dependencies/pom.xml

@@ -52,6 +52,7 @@
         <aliyun-java-sdk-core.version>4.5.25</aliyun-java-sdk-core.version>
         <aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version>
         <yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version>
+        <justauth.version>1.4.0</justauth.version>
     </properties>
 
     <dependencyManagement>
@@ -92,6 +93,11 @@
                 <artifactId>yudao-spring-boot-starter-biz-sms</artifactId>
                 <version>${revision}</version>
             </dependency>
+            <dependency>
+                <groupId>cn.iocoder.boot</groupId>
+                <artifactId>yudao-spring-boot-starter-biz-pay</artifactId>
+                <version>${revision}</version>
+            </dependency>
 
             <!-- Spring 核心 -->
             <dependency>
@@ -421,6 +427,13 @@
                 <version>${aliyun-java-sdk-dysmsapi.version}</version>
             </dependency>
             <!-- SMS SDK end -->
+
+            <dependency>
+                <groupId>com.xkcoding.justauth</groupId>
+                <artifactId>justauth-spring-boot-starter</artifactId>
+                <version>${justauth.version}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 

+ 10 - 9
yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml

@@ -11,23 +11,24 @@
 
     <artifactId>yudao-spring-boot-starter-biz-pay</artifactId>
     <name>${artifactId}</name>
-    <description>支付核心业务</description>
+    <description>支付拓展,基于 IJPay 简单封装,支持微信、支付宝等常见支付渠道</description>
 
     <dependencies>
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-extension</artifactId>
-            <version>${revision}</version>
+            <artifactId>yudao-common</artifactId>
         </dependency>
 
+        <!-- 三方云服务相关 -->
         <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-common</artifactId>
+            <groupId>com.github.javen205</groupId>
+            <artifactId>IJPay-AliPay</artifactId>
+            <version>2.7.8</version>
         </dependency>
-
         <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
+            <groupId>com.github.javen205</groupId>
+            <artifactId>IJPay-WxPay</artifactId>
+            <version>2.7.8</version>
         </dependency>
     </dependencies>
-</project>
+</project>

+ 0 - 8
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/merchant/package-info.java

@@ -1,8 +0,0 @@
-/**
- * @description
- * @author Qingchen
- * @version 1.0.0
- * @date 2021-10-12 10:42
- * @class cn.iocoder.yudao.framework.pay.core.domain.merchant.package-info.java
- */
-package cn.iocoder.yudao.framework.pay.core.domain.merchant;

+ 0 - 8
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/package-info.java

@@ -1,8 +0,0 @@
-/**
- * @description
- * @author Qingchen
- * @version 1.0.0
- * @date 2021-09-29 14:44
- * @class cn.iocoder.yudao.framework.pay.core.domain.package-info.java
- */
-package cn.iocoder.yudao.framework.pay.core.domain;

+ 0 - 8
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/pay/package-info.java

@@ -1,8 +0,0 @@
-/**
- * @description
- * @author Qingchen
- * @version 1.0.0
- * @date 2021-10-12 10:42
- * @class cn.iocoder.yudao.framework.pay.core.domain.pay.package-info.java
- */
-package cn.iocoder.yudao.framework.pay.core.domain.pay;

+ 0 - 8
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/refund/package-info.java

@@ -1,8 +0,0 @@
-/**
- * @description
- * @author Qingchen
- * @version 1.0.0
- * @date 2021-10-12 10:42
- * @class cn.iocoder.yudao.framework.pay.core.domain.refund.package-info.java
- */
-package cn.iocoder.yudao.framework.pay.core.domain.refund;

+ 4 - 1
更新日志.md

@@ -7,10 +7,13 @@
 
 * 工作流
 
+## [v1.1.2] 待定
+
+* 用户前台的社交登陆
+
 ## [v1.1.1] 待定
 
 * 支付
-* 用户前台的社交登陆
 
 ## [v1.1.0] 进行中