diff --git a/yudao-admin-server/pom.xml b/yudao-admin-server/pom.xml index 120d3e926..9200eb771 100644 --- a/yudao-admin-server/pom.xml +++ b/yudao-admin-server/pom.xml @@ -122,11 +122,11 @@ screw-core - + + com.xkcoding.justauth justauth-spring-boot-starter - 1.4.0 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/package-info.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/package-info.java deleted file mode 100644 index b89b77f7e..000000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject; diff --git a/yudao-core-service/pom.xml b/yudao-core-service/pom.xml index 3ce350b54..278c33fc7 100644 --- a/yudao-core-service/pom.xml +++ b/yudao-core-service/pom.xml @@ -32,6 +32,10 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-sms + + cn.iocoder.boot + yudao-spring-boot-starter-biz-pay + diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/infra/dal/dataobject/config/InfConfigDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/infra/dal/dataobject/config/InfConfigDO.java index 5955fe18c..c8d58196e 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/infra/dal/dataobject/config/InfConfigDO.java +++ b/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 diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreServiceConvert.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreServiceConvert.java new file mode 100644 index 000000000..dd6084b11 --- /dev/null +++ b/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); + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/package-info.java new file mode 100644 index 000000000..b10c09029 --- /dev/null +++ b/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; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md new file mode 100644 index 000000000..8153487b7 --- /dev/null +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md @@ -0,0 +1 @@ + diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayAppDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayAppDO.java similarity index 82% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayAppDO.java rename to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayAppDO.java index eefdca682..859e490a5 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayAppDO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/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; @@ -22,11 +22,6 @@ public class PayAppDO extends BaseDO { */ @TableId private Long id; - /** - * 应用号 - * 例如说,60cc81e0e4b06afc4d3f0cfq - */ - private String no; /** * 应用名 */ @@ -46,6 +41,14 @@ public class PayAppDO extends BaseDO { * TODO 芋艿:用途 */ private String secret; + /** + * 支付结果的回调地址 + */ + private String payNotifyUrl; + /** + * 退款结果的回调地址 + */ + private String refundNotifyUrl; /** * 商户编号 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayChannelDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayChannelDO.java similarity index 87% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayChannelDO.java rename to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayChannelDO.java index 190debdab..0fa866696 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayChannelDO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/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; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayMerchantDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java similarity index 93% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayMerchantDO.java rename to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java index 0d64d4c3a..81a3710d5 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/merchant/PayMerchantDO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/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; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayNotifyDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayNotifyDO.java similarity index 85% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayNotifyDO.java rename to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayNotifyDO.java index 110e1a082..b9e948f5e 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayNotifyDO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/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; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayOrderDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderDO.java similarity index 76% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayOrderDO.java rename to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderDO.java index 88c0012a9..273078ac1 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayOrderDO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/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,9 +98,14 @@ public class PayOrderDO extends BaseDO { /** * 支付状态 * - * TODO 芋艿:状态枚举 + * 枚举 {@link PayOrderStatusEnum} */ private Integer status; + /** + * 通知商户支付结果的回调状态 + * TODO 芋艿:0 未发送 1 已发送 + */ + private Integer notifyStatus; /** * 客户端 IP */ @@ -110,7 +117,7 @@ public class PayOrderDO extends BaseDO { /** * 订单失效时间 */ - private Date expiredTime; + private Date expireTime; /** * 支付渠道的额外参数 * diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java new file mode 100644 index 000000000..6dce032c8 --- /dev/null +++ b/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; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayRefundDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java similarity index 82% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayRefundDO.java rename to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java index 375fee5b4..6f9ce7060 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/dataobject/order/PayRefundDO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/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; /** @@ -79,6 +79,11 @@ public class PayRefundDO extends BaseDO { * TODO 芋艿:状态枚举 */ private Integer status; + /** + * 通知商户退款结果的回调状态 + * TODO 芋艿:0 未发送 1 已发送 + */ + private Integer notifyStatus; /** * 客户端 IP */ @@ -98,7 +103,7 @@ public class PayRefundDO extends BaseDO { /** * 退款失效时间 */ - private Date expiredTime; + private Date expireTime; /** * 支付渠道的额外参数 * diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/package-info.java new file mode 100644 index 000000000..8fe90e379 --- /dev/null +++ b/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; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayAppCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayAppCoreMapper.java new file mode 100644 index 000000000..603ff4609 --- /dev/null +++ b/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 { +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderCoreMapper.java new file mode 100644 index 000000000..a2879741b --- /dev/null +++ b/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 { + + default PayOrderDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) { + return selectOne(new QueryWrapper().eq("app_id", appId) + .eq("merchant_order_id", merchantOrderId)); + } + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeConstants.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeConstants.java new file mode 100644 index 000000000..affb3ddeb --- /dev/null +++ b/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 已经被禁用"); + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/merchant/PayChannelCodeEnum.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/merchant/PayChannelCodeEnum.java new file mode 100644 index 000000000..9e8f7eba1 --- /dev/null +++ b/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; + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderStatusEnum.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderStatusEnum.java new file mode 100644 index 000000000..b61c0400c --- /dev/null +++ b/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]; + } + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/package-info.java new file mode 100644 index 000000000..8f5ba6ac3 --- /dev/null +++ b/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; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayAppCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayAppCoreService.java new file mode 100644 index 000000000..ab6f3f27f --- /dev/null +++ b/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); + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java new file mode 100644 index 000000000..784a213a3 --- /dev/null +++ b/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; + } + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java new file mode 100644 index 000000000..329f28bab --- /dev/null +++ b/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); + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java new file mode 100644 index 000000000..17a27fcfa --- /dev/null +++ b/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; + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java new file mode 100644 index 000000000..c2d155865 --- /dev/null +++ b/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; + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitRespDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitRespDTO.java new file mode 100644 index 000000000..b1a5d2e10 --- /dev/null +++ b/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; + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java new file mode 100644 index 000000000..60b2877a8 --- /dev/null +++ b/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 invokeResult = thirdPayClient.submitTransaction(payTransaction, payTransactionExtensionDO, null); // TODO 暂时传入 extra = null + invokeResult.checkError(); + + // TODO 轮询三方接口,是否已经支付的任务 + // 返回成功 + return new PayTransactionSubmitRespDTO().setId(payTransactionExtensionDO.getId()).setInvokeResponse(invokeResult.getData()); + } + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java new file mode 100644 index 000000000..13b4863a5 --- /dev/null +++ b/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; diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 125d3bdaf..43dfea757 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -52,6 +52,7 @@ 4.5.25 2.1.0 1.2.7 + 1.4.0 @@ -92,6 +93,11 @@ yudao-spring-boot-starter-biz-sms ${revision} + + cn.iocoder.boot + yudao-spring-boot-starter-biz-pay + ${revision} + @@ -421,6 +427,13 @@ ${aliyun-java-sdk-dysmsapi.version} + + + com.xkcoding.justauth + justauth-spring-boot-starter + ${justauth.version} + + diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml index 606a435d7..4cc0eed0b 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml @@ -11,23 +11,24 @@ yudao-spring-boot-starter-biz-pay ${artifactId} - 支付核心业务 + 支付拓展,基于 IJPay 简单封装,支持微信、支付宝等常见支付渠道 - - cn.iocoder.boot - yudao-spring-boot-starter-extension - ${revision} - - cn.iocoder.boot yudao-common + - cn.iocoder.boot - yudao-spring-boot-starter-biz-operatelog + com.github.javen205 + IJPay-AliPay + 2.7.8 + + + com.github.javen205 + IJPay-WxPay + 2.7.8 - \ No newline at end of file + diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/merchant/package-info.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/merchant/package-info.java deleted file mode 100644 index fb2b3a848..000000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/merchant/package-info.java +++ /dev/null @@ -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; \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/package-info.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/package-info.java deleted file mode 100644 index d01b48c17..000000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/package-info.java +++ /dev/null @@ -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; \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/pay/package-info.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/pay/package-info.java deleted file mode 100644 index f0b0ee10c..000000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/pay/package-info.java +++ /dev/null @@ -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; \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/refund/package-info.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/refund/package-info.java deleted file mode 100644 index 860421c4c..000000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/domain/refund/package-info.java +++ /dev/null @@ -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; \ No newline at end of file diff --git a/更新日志.md b/更新日志.md index 206599b25..4b631772a 100644 --- a/更新日志.md +++ b/更新日志.md @@ -7,10 +7,13 @@ * 工作流 +## [v1.1.2] 待定 + +* 用户前台的社交登陆 + ## [v1.1.1] 待定 * 支付 -* 用户前台的社交登陆 ## [v1.1.0] 进行中