1. 引入 IJPay 组件

2. 增加创建支付单的 Service 实现
This commit is contained in:
YunaiV 2021-10-18 09:41:38 +08:00
parent 711a074059
commit 81126b2b4b
36 changed files with 587 additions and 85 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
}

View File

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

View File

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

View File

@ -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.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@ -22,11 +22,6 @@ public class PayAppDO extends BaseDO {
*/ */
@TableId @TableId
private Long id; private Long id;
/**
* 应用号
* 例如说60cc81e0e4b06afc4d3f0cfq
*/
private String no;
/** /**
* 应用名 * 应用名
*/ */
@ -46,6 +41,14 @@ public class PayAppDO extends BaseDO {
* TODO 芋艿用途 * TODO 芋艿用途
*/ */
private String secret; private String secret;
/**
* 支付结果的回调地址
*/
private String payNotifyUrl;
/**
* 退款结果的回调地址
*/
private String refundNotifyUrl;
/** /**
* 商户编号 * 商户编号

View File

@ -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.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import lombok.Data; import lombok.Data;

View File

@ -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.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;

View File

@ -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 cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import lombok.Data; import lombok.Data;

View File

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

View File

@ -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;
}

View File

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

View File

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

View File

@ -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> {
}

View File

@ -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));
}
}

View File

@ -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 已经被禁用");
}

View File

@ -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;
}

View File

@ -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];
}
}

View File

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

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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());
}
}

View File

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

View File

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

View File

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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

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