pay:前端收银台接入支付宝扫码
This commit is contained in:
parent
84e9c0bba0
commit
4d2ebcd898
|
@ -64,8 +64,8 @@ public class PayNotifyController {
|
||||||
@PermitAll
|
@PermitAll
|
||||||
@OperateLog(enable = false) // 回调地址,无需记录操作日志
|
@OperateLog(enable = false) // 回调地址,无需记录操作日志
|
||||||
public String notifyCallback(@PathVariable("channelId") Long channelId,
|
public String notifyCallback(@PathVariable("channelId") Long channelId,
|
||||||
@RequestParam Map<String, String> params,
|
@RequestParam(required = false) Map<String, String> params,
|
||||||
@RequestBody String body) throws Exception {
|
@RequestBody(required = false) String body) throws Exception {
|
||||||
// 校验支付渠道是否存在
|
// 校验支付渠道是否存在
|
||||||
PayClient payClient = payClientFactory.getPayClient(channelId);
|
PayClient payClient = payClientFactory.getPayClient(channelId);
|
||||||
if (payClient == null) {
|
if (payClient == null) {
|
||||||
|
@ -87,5 +87,4 @@ public class PayNotifyController {
|
||||||
return "success";
|
return "success";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.pay.controller.admin.order;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
|
import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO;
|
||||||
|
@ -18,15 +20,13 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
||||||
|
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -37,6 +37,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||||
|
|
||||||
@Tag(name = "管理后台 - 支付订单")
|
@Tag(name = "管理后台 - 支付订单")
|
||||||
|
@ -91,6 +92,14 @@ public class PayOrderController {
|
||||||
return success(respVO);
|
return success(respVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/submit")
|
||||||
|
@Operation(summary = "提交支付订单")
|
||||||
|
public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) {
|
||||||
|
PayOrderSubmitRespBO respDTO = payOrderService.submitPayOrder(
|
||||||
|
PayOrderConvert.INSTANCE.convert(reqVO, getClientIP()));
|
||||||
|
return success(new AppPayOrderSubmitRespVO(respDTO.getInvokeResponse()));
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
@Operation(summary = "获得支付订单分页")
|
@Operation(summary = "获得支付订单分页")
|
||||||
@PreAuthorize("@ss.hasPermission('pay:order:query')")
|
@PreAuthorize("@ss.hasPermission('pay:order:query')")
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package cn.iocoder.yudao.module.pay.controller.admin.order.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 支付订单提交 Request VO")
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class PayOrderSubmitReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "支付单编号", required = true, example = "1024")
|
||||||
|
@NotNull(message = "支付单编号不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "支付渠道", required = true, example = "wx_pub")
|
||||||
|
@NotEmpty(message = "支付渠道不能为空")
|
||||||
|
private String channelCode;
|
||||||
|
|
||||||
|
@Schema(description = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数")
|
||||||
|
private Map<String, String> channelExtras;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package cn.iocoder.yudao.module.pay.controller.admin.order.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 支付订单提交 Response VO")
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PayOrderSubmitRespVO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用支付渠道的响应结果
|
||||||
|
*/
|
||||||
|
private Object invokeResponse;
|
||||||
|
|
||||||
|
}
|
|
@ -1,15 +1,13 @@
|
||||||
package cn.iocoder.yudao.module.pay.controller.app.order;
|
package cn.iocoder.yudao.module.pay.controller.app.order;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
|
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitReqDTO;
|
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitRespDTO;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
@ -34,20 +32,10 @@ public class AppPayOrderController {
|
||||||
|
|
||||||
@PostMapping("/submit")
|
@PostMapping("/submit")
|
||||||
@Operation(summary = "提交支付订单")
|
@Operation(summary = "提交支付订单")
|
||||||
// @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好
|
|
||||||
public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) {
|
public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) {
|
||||||
// 获得订单
|
PayOrderSubmitRespBO respDTO = orderService.submitPayOrder(
|
||||||
PayOrderDO payOrder = orderService.getOrder(reqVO.getId());
|
PayOrderConvert.INSTANCE.convert(reqVO, getClientIP()));
|
||||||
|
return success(new AppPayOrderSubmitRespVO(respDTO.getInvokeResponse()));
|
||||||
// 提交支付
|
|
||||||
PayOrderSubmitReqDTO reqDTO = new PayOrderSubmitReqDTO();
|
|
||||||
BeanUtil.copyProperties(reqVO, reqDTO, false);
|
|
||||||
reqDTO.setUserIp(getClientIP());
|
|
||||||
reqDTO.setAppId(payOrder.getAppId());
|
|
||||||
PayOrderSubmitRespDTO respDTO = orderService.submitPayOrder(reqDTO);
|
|
||||||
|
|
||||||
// 拼接返回
|
|
||||||
return success(AppPayOrderSubmitRespVO.builder().invokeResponse(respDTO.getInvokeResponse()).build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
|
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderDetailsRespVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExcelVO;
|
import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageItemRespVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitReqDTO;
|
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitReqBO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
@ -92,10 +90,14 @@ public interface PayOrderConvert {
|
||||||
PayOrderDO convert(PayOrderCreateReqDTO bean);
|
PayOrderDO convert(PayOrderCreateReqDTO bean);
|
||||||
|
|
||||||
@Mapping(target = "id", ignore = true)
|
@Mapping(target = "id", ignore = true)
|
||||||
PayOrderExtensionDO convert(PayOrderSubmitReqDTO bean);
|
PayOrderExtensionDO convert(PayOrderSubmitReqBO bean);
|
||||||
|
|
||||||
PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqDTO bean);
|
PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqBO bean);
|
||||||
|
|
||||||
PayOrderRespDTO convert2(PayOrderDO bean);
|
PayOrderRespDTO convert2(PayOrderDO bean);
|
||||||
|
|
||||||
|
PayOrderSubmitReqBO convert(AppPayOrderSubmitReqVO bean, String userIp);
|
||||||
|
|
||||||
|
PayOrderSubmitReqBO convert(PayOrderSubmitReqVO bean, String userIp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
|
||||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitReqDTO;
|
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitReqBO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitRespDTO;
|
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -84,7 +84,7 @@ public interface PayOrderService {
|
||||||
* @param reqDTO 提交请求
|
* @param reqDTO 提交请求
|
||||||
* @return 提交结果
|
* @return 提交结果
|
||||||
*/
|
*/
|
||||||
PayOrderSubmitRespDTO submitPayOrder(@Valid PayOrderSubmitReqDTO reqDTO);
|
PayOrderSubmitRespBO submitPayOrder(@Valid PayOrderSubmitReqBO reqDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知支付单成功
|
* 通知支付单成功
|
||||||
|
|
|
@ -31,8 +31,8 @@ import cn.iocoder.yudao.module.pay.service.merchant.PayAppService;
|
||||||
import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService;
|
import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService;
|
||||||
import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
|
import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
|
||||||
import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitReqDTO;
|
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitReqBO;
|
||||||
import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitRespDTO;
|
import cn.iocoder.yudao.module.pay.service.order.bo.PayOrderSubmitRespBO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
@ -127,53 +127,64 @@ public class PayOrderServiceImpl implements PayOrderService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayOrderSubmitRespDTO submitPayOrder(PayOrderSubmitReqDTO reqDTO) {
|
public PayOrderSubmitRespBO submitPayOrder(PayOrderSubmitReqBO reqBO) {
|
||||||
// 校验 App
|
// 1. 获得 PayOrderDO ,并校验其是否存在
|
||||||
appService.validPayApp(reqDTO.getAppId());
|
PayOrderDO order = validatePayOrderCanSubmit(reqBO.getId());
|
||||||
// 校验支付渠道是否有效
|
// 1.2 校验支付渠道是否有效
|
||||||
PayChannelDO channel = channelService.validPayChannel(reqDTO.getAppId(), reqDTO.getChannelCode());
|
PayChannelDO channel = validatePayChannelCanSubmit(order.getAppId(), reqBO.getChannelCode());
|
||||||
// 校验支付客户端是否正确初始化
|
|
||||||
PayClient client = payClientFactory.getPayClient(channel.getId());
|
PayClient client = payClientFactory.getPayClient(channel.getId());
|
||||||
if (client == null) {
|
|
||||||
log.error("[submitPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId());
|
|
||||||
throw exception(ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获得 PayOrderDO ,并校验其是否存在
|
// 2. 插入 PayOrderExtensionDO
|
||||||
PayOrderDO order = orderMapper.selectById(reqDTO.getId());
|
PayOrderExtensionDO orderExtension = PayOrderConvert.INSTANCE.convert(reqBO)
|
||||||
if (order == null || !Objects.equals(order.getAppId(), reqDTO.getAppId())) { // 是否存在
|
|
||||||
throw exception(ErrorCodeConstants.PAY_ORDER_NOT_FOUND);
|
|
||||||
}
|
|
||||||
if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付
|
|
||||||
throw exception(ErrorCodeConstants.PAY_ORDER_STATUS_IS_NOT_WAITING);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 插入 PayOrderExtensionDO
|
|
||||||
PayOrderExtensionDO orderExtension = PayOrderConvert.INSTANCE.convert(reqDTO)
|
|
||||||
.setOrderId(order.getId()).setNo(generateOrderExtensionNo())
|
.setOrderId(order.getId()).setNo(generateOrderExtensionNo())
|
||||||
.setChannelId(channel.getId()).setChannelCode(channel.getCode())
|
.setChannelId(channel.getId()).setChannelCode(channel.getCode())
|
||||||
.setStatus(PayOrderStatusEnum.WAITING.getStatus());
|
.setStatus(PayOrderStatusEnum.WAITING.getStatus());
|
||||||
orderExtensionMapper.insert(orderExtension);
|
orderExtensionMapper.insert(orderExtension);
|
||||||
|
|
||||||
// 调用三方接口
|
// 3. 调用三方接口
|
||||||
PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqDTO);
|
PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqBO)
|
||||||
// 商户相关字段
|
// 商户相关的字段
|
||||||
//TODO jason @芋艿 是否加一个属性 如tradeNo 支付订单号, 用这个merchantOrderId让人迷糊
|
.setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性!
|
||||||
unifiedOrderReqDTO.setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性!
|
|
||||||
.setSubject(order.getSubject()).setBody(order.getBody())
|
.setSubject(order.getSubject()).setBody(order.getBody())
|
||||||
.setNotifyUrl(genChannelPayNotifyUrl(channel))
|
.setNotifyUrl(genChannelPayNotifyUrl(channel))
|
||||||
.setReturnUrl(genChannelReturnUrl(channel));
|
.setReturnUrl(genChannelReturnUrl(channel))
|
||||||
// 订单相关字段
|
// 订单相关字段
|
||||||
unifiedOrderReqDTO.setAmount(order.getAmount()).setExpireTime(order.getExpireTime());
|
.setAmount(order.getAmount()).setExpireTime(order.getExpireTime());
|
||||||
CommonResult<?> unifiedOrderResult = client.unifiedOrder(unifiedOrderReqDTO);
|
CommonResult<?> unifiedOrderResult = client.unifiedOrder(unifiedOrderReqDTO);
|
||||||
unifiedOrderResult.checkError();
|
unifiedOrderResult.checkError();
|
||||||
|
|
||||||
// TODO 轮询三方接口,是否已经支付的任务
|
// TODO 轮询三方接口,是否已经支付的任务
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return new PayOrderSubmitRespDTO().setExtensionId(orderExtension.getId())
|
return new PayOrderSubmitRespBO().setExtensionId(orderExtension.getId())
|
||||||
.setInvokeResponse(unifiedOrderResult.getData());
|
.setInvokeResponse(unifiedOrderResult.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PayOrderDO validatePayOrderCanSubmit(Long id) {
|
||||||
|
PayOrderDO order = orderMapper.selectById(id);
|
||||||
|
if (order == null) { // 是否存在
|
||||||
|
throw exception(ErrorCodeConstants.PAY_ORDER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付
|
||||||
|
throw exception(ErrorCodeConstants.PAY_ORDER_STATUS_IS_NOT_WAITING);
|
||||||
|
}
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PayChannelDO validatePayChannelCanSubmit(Long appId, String channelCode) {
|
||||||
|
// 校验 App
|
||||||
|
appService.validPayApp(appId);
|
||||||
|
|
||||||
|
// 校验支付渠道是否有效
|
||||||
|
PayChannelDO channel = channelService.validPayChannel(appId, channelCode);
|
||||||
|
// 校验支付客户端是否正确初始化
|
||||||
|
PayClient client = payClientFactory.getPayClient(channel.getId());
|
||||||
|
if (client == null) {
|
||||||
|
log.error("[validatePayChannelCanSubmit][渠道编号({}) 找不到对应的支付客户端]", channel.getId());
|
||||||
|
throw exception(ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND);
|
||||||
|
}
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据支付渠道的编码,生成支付渠道的返回地址
|
* 根据支付渠道的编码,生成支付渠道的返回地址
|
||||||
* @param channel 支付渠道
|
* @param channel 支付渠道
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.pay.service.order.dto;
|
package cn.iocoder.yudao.module.pay.service.order.bo;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
@ -9,17 +9,11 @@ import java.io.Serializable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付单提交 Request DTO
|
* 支付单提交 Request BO
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class PayOrderSubmitReqDTO implements Serializable {
|
public class PayOrderSubmitReqBO implements Serializable {
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用编号
|
|
||||||
*/
|
|
||||||
@NotNull(message = "应用编号不能为空")
|
|
||||||
private Long appId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付单编号
|
* 支付单编号
|
|
@ -1,14 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.pay.service.order.dto;
|
package cn.iocoder.yudao.module.pay.service.order.bo;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付单提交 Response DTO
|
* 支付单提交 Response BO
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class PayOrderSubmitRespDTO implements Serializable {
|
public class PayOrderSubmitRespBO implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付拓展单的编号
|
* 支付拓展单的编号
|
|
@ -10,6 +10,8 @@ import javax.validation.constraints.DecimalMin;
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
// TODO 芋艿:可能需要改造
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退款申请单 Request DTO
|
* 退款申请单 Request DTO
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
"jsencrypt": "3.3.1",
|
"jsencrypt": "3.3.1",
|
||||||
"min-dash": "3.5.2",
|
"min-dash": "3.5.2",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
|
"qrcode.vue": "^1.7.0",
|
||||||
"quill": "1.3.7",
|
"quill": "1.3.7",
|
||||||
"screenfull": "5.0.2",
|
"screenfull": "5.0.2",
|
||||||
"sortablejs": "1.10.2",
|
"sortablejs": "1.10.2",
|
||||||
|
|
|
@ -1,23 +1,5 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
// 创建支付订单
|
|
||||||
export function createOrder(data) {
|
|
||||||
return request({
|
|
||||||
url: '/pay/order/create',
|
|
||||||
method: 'post',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新支付订单
|
|
||||||
export function updateOrder(data) {
|
|
||||||
return request({
|
|
||||||
url: '/pay/order/update',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除支付订单
|
// 删除支付订单
|
||||||
export function deleteOrder(id) {
|
export function deleteOrder(id) {
|
||||||
return request({
|
return request({
|
||||||
|
@ -42,6 +24,15 @@ export function getOrderDetail(id) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提交支付订单
|
||||||
|
export function submitOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/pay/order/submit',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 获得支付订单分页
|
// 获得支付订单分页
|
||||||
export function getOrderPage(query) {
|
export function getOrderPage(query) {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
@ -12,13 +12,13 @@
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 微信支付 -->
|
<!-- 支付选择框 -->
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 10px">
|
||||||
<!-- 支付宝 -->
|
<!-- 支付宝 -->
|
||||||
<el-descriptions title="选择支付宝支付">
|
<el-descriptions title="选择支付宝支付">
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
<div class="pay-channel-container">
|
<div class="pay-channel-container">
|
||||||
<div class="box" v-for="channel in aliPayChannels" :key="channel.code">
|
<div class="box" v-for="channel in aliPayChannels" :key="channel.code" @click="submit(channel.code)">
|
||||||
<img :src="icons[channel.code]">
|
<img :src="icons[channel.code]">
|
||||||
<div class="title">{{ channel.name }}</div>
|
<div class="title">{{ channel.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,16 +40,24 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 支付二维码 -->
|
||||||
|
<el-dialog :title="qrCode.title" :visible.sync="qrCode.visible" width="350px" append-to-body
|
||||||
|
:close-on-press-escape="false">
|
||||||
|
<qrcode-vue :value="qrCode.url" size="310" level="H" />
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import QrcodeVue from 'qrcode.vue'
|
||||||
import { DICT_TYPE, getDictDatas } from "@/utils/dict";
|
import { DICT_TYPE, getDictDatas } from "@/utils/dict";
|
||||||
import { getOrder } from '@/api/pay/order';
|
import { getOrder, submitOrder } from '@/api/pay/order';
|
||||||
import { PayOrderStatusEnum } from "@/utils/constants";
|
import { PayChannelEnum, PayOrderStatusEnum } from "@/utils/constants";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PayOrderSubmit",
|
name: "PayOrderSubmit",
|
||||||
components: {
|
components: {
|
||||||
|
QrcodeVue,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -69,6 +77,12 @@ export default {
|
||||||
wx_pub: require("@/assets/images/pay/icon/wx_pub.svg"),
|
wx_pub: require("@/assets/images/pay/icon/wx_pub.svg"),
|
||||||
mock: require("@/assets/images/pay/icon/mock.svg"),
|
mock: require("@/assets/images/pay/icon/mock.svg"),
|
||||||
},
|
},
|
||||||
|
qrCode: { // 支付二维码
|
||||||
|
url: '',
|
||||||
|
title: '',
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
|
interval: undefined, // 定时任务,轮询是否完成支付
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -94,25 +108,25 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/** 获得请假信息 */
|
/** 获得支付信息 */
|
||||||
getDetail() {
|
getDetail() {
|
||||||
// 1.1 未传递订单编号
|
// 1.1 未传递订单编号
|
||||||
if (!this.id) {
|
if (!this.id) {
|
||||||
this.$message.error('未传递支付单号,无法查看对应的支付信息');
|
this.$message.error('未传递支付单号,无法查看对应的支付信息');
|
||||||
this.$router.go(-1);
|
this.goBackToList();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getOrder(this.id).then(response => {
|
getOrder(this.id).then(response => {
|
||||||
// 1.2 无法查询到支付信息
|
// 1.2 无法查询到支付信息
|
||||||
if (!response.data) {
|
if (!response.data) {
|
||||||
this.$message.error('支付订单不存在,请检查!');
|
this.$message.error('支付订单不存在,请检查!');
|
||||||
this.$router.go(-1);
|
this.goBackToList();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 1.3 订单已支付
|
// 1.3 订单已支付
|
||||||
if (response.data.status !== PayOrderStatusEnum.WAITING.status) {
|
if (response.data.status !== PayOrderStatusEnum.WAITING.status) {
|
||||||
this.$message.error('支付订单不处于待支付状态,请检查!');
|
this.$message.error('支付订单不处于待支付状态,请检查!');
|
||||||
this.$router.go(-1);
|
this.goBackToList();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +134,64 @@ export default {
|
||||||
this.payOrder = response.data;
|
this.payOrder = response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/** 提交支付 */
|
||||||
|
submit(channelCode) {
|
||||||
|
submitOrder({
|
||||||
|
id: this.id,
|
||||||
|
channelCode: channelCode
|
||||||
|
}).then(response => {
|
||||||
|
// 不同的支付,调用不同的策略
|
||||||
|
if (channelCode === PayChannelEnum.ALIPAY_QR.code) {
|
||||||
|
this.submitAfterAlipayQr(response.data.invokeResponse)
|
||||||
|
}
|
||||||
|
// 打开轮询任务
|
||||||
|
this.createQueryInterval()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 提交支付后(支付宝扫码支付) */
|
||||||
|
submitAfterAlipayQr(invokeResponse) {
|
||||||
|
this.qrCode = {
|
||||||
|
title: '请使用支付宝“扫一扫”扫码支付',
|
||||||
|
url: invokeResponse.qrCode,
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 轮询查询任务 */
|
||||||
|
createQueryInterval() {
|
||||||
|
this.interval = setInterval(() => {
|
||||||
|
getOrder(this.id).then(response => {
|
||||||
|
// 已支付
|
||||||
|
if (response.data.status === PayOrderStatusEnum.SUCCESS.status) {
|
||||||
|
this.clearQueryInterval();
|
||||||
|
this.$message.success('支付成功!');
|
||||||
|
this.goBackToList();
|
||||||
|
}
|
||||||
|
// 已取消
|
||||||
|
if (response.data.status === PayOrderStatusEnum.CLOSED.status) {
|
||||||
|
this.clearQueryInterval();
|
||||||
|
this.$message.error('支付已关闭!');
|
||||||
|
this.goBackToList();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, 1000 * 2)
|
||||||
|
},
|
||||||
|
/** 清空查询任务 */
|
||||||
|
clearQueryInterval() {
|
||||||
|
// 清空各种弹窗
|
||||||
|
this.qrCode = {
|
||||||
|
title: '',
|
||||||
|
url: '',
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
// 清空任务
|
||||||
|
clearInterval(this.interval)
|
||||||
|
this.interval = undefined
|
||||||
|
},
|
||||||
|
/** 回到列表 **/
|
||||||
|
goBackToList() {
|
||||||
|
this.$tab.closePage();
|
||||||
|
this.$router.go(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
16878
yudao-ui-admin/yarn.lock
16878
yudao-ui-admin/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue