parent
711a074059
commit
81126b2b4b
|
@ -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>
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject;
|
|
@ -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>
|
||||
|
|
|
@ -11,7 +11,7 @@ import lombok.ToString;
|
|||
/**
|
||||
* 参数配置表
|
||||
*
|
||||
* @author ruoyi
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("inf_config")
|
||||
@Data
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
/**
|
||||
* 提供 POJO 类的实体转换
|
||||
*
|
||||
* 目前使用 MapStruct 框架
|
||||
*/
|
||||
package cn.iocoder.yudao.coreservice.modules.pay.convert;
|
|
@ -0,0 +1 @@
|
|||
<http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao>
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 商户编号
|
|
@ -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,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,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;
|
|
@ -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;
|
||||
/**
|
||||
* 支付渠道的额外参数
|
||||
*
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
/**
|
||||
* 支付渠道的额外参数
|
||||
*
|
|
@ -0,0 +1 @@
|
|||
package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject;
|
|
@ -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> {
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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 已经被禁用");
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* pay 包下,我们放支付业务,提供业务的支付能力。
|
||||
* 例如说:商户、应用、支付、退款等等
|
||||
*
|
||||
* 缩写:pay
|
||||
*/
|
||||
package cn.iocoder.yudao.coreservice.modules.pay;
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package cn.iocoder.yudao.coreservice.modules.pay.service;
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 三方云服务相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
|
||||
<groupId>com.github.javen205</groupId>
|
||||
<artifactId>IJPay-AliPay</artifactId>
|
||||
<version>2.7.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.javen205</groupId>
|
||||
<artifactId>IJPay-WxPay</artifactId>
|
||||
<version>2.7.8</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
Loading…
Reference in New Issue