Skip to content

Latest commit

 

History

History
117 lines (102 loc) · 5.19 KB

订单接口-3.md

File metadata and controls

117 lines (102 loc) · 5.19 KB

订单接口-3

确认订单-提交订单之后,就是支付了。

用户点击提交订单之后,选择确定付款,此时进入支付界面

前端调用接口为/mall4cloud_payment/pay/order,根据订单号进行支付,上一步提交订单返回的便是订单id列表

接口详情:

@PostMapping("/order")
@ApiOperation(value = "根据订单号进行支付", notes = "根据订单号进行支付")
public ServerResponseEntity<?> pay(HttpServletRequest request, @Valid @RequestBody PayInfoDTO payParam) {
    // 这里的地址是网关通过转发过来的时候,获取到当前服务器的地址,测试环境要用测试环境的uri
    String gatewayUri = "http://192.168.1.17:8126/mall4cloud_payment";
    UserInfoInTokenBO userInfoInTokenBO = AuthUserContext.get();
    Long userId = userInfoInTokenBO.getUserId();
    PayInfoBO payInfo = payInfoService.pay(userId, payParam);
    payInfo.setBizUserId(userInfoInTokenBO.getBizUserId());
    ...
}

这里关键的是调用了payInfoService.pay(userId, payParam)

该方法由于涉及多个表库的增改,故此加了事务注解来保证一致性。

@Override
@Transactional(rollbackFor = Exception.class)
public PayInfoBO pay(Long userId, PayInfoDTO payParam) {
    // 支付单号
    ServerResponseEntity<Long> segmentIdResponse = segmentFeignClient.getSegmentId(PayInfo.DISTRIBUTED_ID_KEY);
    if (!segmentIdResponse.isSuccess()) {
        throw new mall4cloudException(ResponseEnum.EXCEPTION);
    }
    Long payId = segmentIdResponse.getData();
    List<Long> orderIds = payParam.getOrderIds();
    // 如果订单没有被取消的话,获取订单金额,否之会获取失败
    ServerResponseEntity<OrderAmountVO> ordersAmountAndIfNoCancelResponse = 					                                                                                                  orderFeignClient.getOrdersAmountAndIfNoCancel(orderIds);
    // 如果订单已经关闭了,此时不能够支付了
    if (!ordersAmountAndIfNoCancelResponse.isSuccess()) {
        throw new mall4cloudException(ordersAmountAndIfNoCancelResponse.getMsg());
    }
    //将数据存到数据库中
    OrderAmountVO orderAmount = ordersAmountAndIfNoCancelResponse.getData();
    PayInfo payInfo = new PayInfo();
    payInfo.setPayId(payId);
    payInfo.setUserId(userId);
    //支付的金额是从数据库查询的,并非前端传过来的值
    payInfo.setPayAmount(orderAmount.getPayAmount());
    payInfo.setPayStatus(PayStatus.UNPAY.value());
    payInfo.setSysType(AuthUserContext.get().getSysType());
    payInfo.setVersion(0);
    // 保存多个支付订单号
    payInfo.setOrderIds(StrUtil.join(StrUtil.COMMA, orderIds));
    // 保存预支付信息
    payInfoMapper.save(payInfo);
    PayInfoBO payInfoDto = new PayInfoBO();
    payInfoDto.setBody("商城订单");
    payInfoDto.setPayAmount(orderAmount.getPayAmount());
    payInfoDto.setPayId(payId);
    //返回支付信息
    return payInfoDto;
}

controller方法剩下的便是支付回调了,前面的gatewayUri便有用了

// 回调地址
    payInfo.setApiNoticeUrl(gatewayUri + "/notice/pay/order");
    payInfo.setReturnUrl(payParam.getReturnUrl());
    payNoticeController.submit(payInfo.getPayId());
    return ServerResponseEntity.success(payInfo.getPayId());

执行完pay方法后,由于没有对接微信和支付宝接口,故直接调用submit中payInfoService.paySuccess(payInfoResult,orderIdList);使其支付成功

@Override
@Transactional(rollbackFor = Exception.class)
public void paySuccess(PayInfoResultBO payInfoResult, List<Long> orderIds) {
    // 标记为支付成功状态
    PayInfo payInfo = new PayInfo();
    payInfo.setPayId(payInfoResult.getPayId());
    payInfo.setBizPayNo(payInfoResult.getBizPayNo());
    payInfo.setCallbackContent(payInfoResult.getCallbackContent());
    payInfo.setCallbackTime(new Date());
    payInfo.setPayStatus(PayStatus.PAYED.value());
    payInfoMapper.update(payInfo);
    // 发送消息,订单支付成功
    SendStatus sendStatus = orderNotifyTemplate.syncSend(RocketMqConstant.ORDER_NOTIFY_TOPIC, new GenericMessage<>(new PayNotifyBO(orderIds))).getSendStatus();
    if (!Objects.equals(sendStatus, SendStatus.SEND_OK)) {
        // 消息发不出去就抛异常,因为订单回调会有多次,几乎不可能每次都无法发送出去,发的出去无所谓因为接口是幂等的
        throw new mall4cloudException(ResponseEnum.EXCEPTION);
    }
}

使用rocketMq来发送支付成功的消息,OrderNotifyConsumer进行订单回调,此时将订单改为已支付状态,并且发送消息通知库存可以扣减了

@Override
public void onMessage(PayNotifyBO message) {
    LOG.info("订单回调开始... message: " + Json.toJsonString(message));
    orderService.updateByToPaySuccess(message.getOrderIds());
    // 发送消息,订单支付成功,通知库存扣减
    SendStatus sendStockStatus = orderNotifyStockTemplate.syncSend(RocketMqConstant.ORDER_NOTIFY_STOCK_TOPIC, new GenericMessage<>(message)).getSendStatus();
    if (!Objects.equals(sendStockStatus,SendStatus.SEND_OK)) {
        throw new mall4cloudException(ResponseEnum.EXCEPTION);
    }
}

将支付单号返回给前端即可。