parent
711a074059
commit
81126b2b4b
@ -1 +0,0 @@
|
|||||||
package cn.iocoder.yudao.adminserver.modules.pay.dal.dataobject;
|
|
||||||
@ -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,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;
|
||||||
@ -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;
|
||||||
@ -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;
|
||||||
@ -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,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,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,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;
|
||||||
@ -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