苍穹外卖学习-day08-day10(跳过微信支付,订单取消,来电提醒问题解决)

day08-跳过微信支付

由于微信支付需要商家认证才能开通,个人开发者只能模拟支付的流程,完成后续项目的学习。

方法:

1.修改 orderServiceImpl下的payment方法

注释原有调用微信支付接口的代码,生成空JSON替换原接口生成预支付交易单

直接替换下面代码:

    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();
        User user = userMapper.getById(userId);

//        //调用微信支付接口,生成预支付交易单
//        JSONObject jsonObject = weChatPayUtil.pay(
//                ordersPaymentDTO.getOrderNumber(), //商户订单号
//                new BigDecimal(0.01), //支付金额,单位 元
//                "苍穹外卖订单", //商品描述
//                user.getOpenid() //微信用户的openid
//        );

        //生成空JSON,跳过微信支付流程
        JSONObject jsonObject = new JSONObject();

        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
            throw new OrderBusinessException("该订单已支付");
        }

        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
        vo.setPackageStr(jsonObject.getString("package"));
/*      // 模拟支付成功,更新数据库订单状态
        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        // 根据订单号查询订单
        Orders ordersDB = orderMapper.getByNumberAndUserId(ordersPaymentDTO.getOrderNumber(), userId);
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .status(Orders.TO_BE_CONFIRMED)
                .payStatus(Orders.PAID)
                .checkoutTime(LocalDateTime.now())
                .build();
        orderMapper.update(orders);*/

        return vo;
    }

2.修改OrderController

调用orderService.paySuccess方法,传入订单号ordersPaymentDTO.getOrderNumber(),直接更新数据库订单状态,模拟支付成功

直接替换下面代码:

    @PutMapping("/payment")
    @ApiOperation("订单支付")
    public Result<OrderPaymentVO> payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {
        log.info("订单支付:{}", ordersPaymentDTO);
        OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO);
        log.info("生成预支付交易单:{}", orderPaymentVO);
        // 模拟支付成功,更新数据库订单状态 -此时没有回调
        orderService.paySuccess(ordersPaymentDTO.getOrderNumber());
        return Result.success(orderPaymentVO);
    }

3.修改微信小程序代码

修改 pages.pay.index.js 文件

打开index.js文件,在大概221行左右地方修改,把箭头所指的代码放开

订单支付效果:

day09-取消订单

1.用户端

订单处于待接单状态下取消,需要进行退款,由于前面模拟微信支付,直接调用了支付成功的接口,实际上并未支付,此时用户端取消订单,需要跳过微信支付退款接口,直接修改数据库订单状态,直接替换下面代码(OrderController中)


    /**
     * 用户取消订单
     *
     * @param id
     */
    public void userCancelById(Long id) throws Exception {
        // 根据id查询订单
        Orders ordersDB = orderMapper.getById(id);

        // 校验订单是否存在
        if (ordersDB == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        //订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消
        if (ordersDB.getStatus() > 2) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        Orders orders = new Orders();
        orders.setId(ordersDB.getId());

        // 订单处于待接单状态下取消,需要进行退款
        if (ordersDB.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
            //调用微信支付退款接口
//            weChatPayUtil.refund(
//                    ordersDB.getNumber(), //商户订单号
//                    ordersDB.getNumber(), //商户退款单号
//                    new BigDecimal(0.01),//退款金额,单位 元
//                    new BigDecimal(0.01));//原订单金额

            //支付状态修改为 退款
            orders.setPayStatus(Orders.REFUND);
        }

        // 更新订单状态、取消原因、取消时间
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelReason("用户取消");
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.update(orders);
    }

功能效果:

2.管理端

拒单功能:

涉及到退款部分:跳过 weChatPayUtil.refund调用,模拟给用户退款,直接更新数据库订单支付状态为 ”已退款 “,直接替换下面代码:


     /**
     * 拒单
     *
     * @param ordersRejectionDTO
     */
    public void rejection(OrdersRejectionDTO ordersRejectionDTO) throws Exception {
        // 根据id查询订单
        Orders ordersDB = orderMapper.getById(ordersRejectionDTO.getId());

        // 订单只有存在且状态为2(待接单)才可以拒单
        if (ordersDB == null || !ordersDB.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //支付状态
        Integer payStatus = ordersDB.getPayStatus();
        if (payStatus == Orders.PAID) {
            //跳过 weChatPayUtil.refund调用,模拟给用户退款,直接更新数据库订单支付状态为 ”已退款 “
            //用户已支付,需要退款
//            String refund = weChatPayUtil.refund(
//                    ordersDB.getNumber(),
//                    ordersDB.getNumber(),
//                    new BigDecimal(0.01),
//                    new BigDecimal(0.01));
//            log.info("申请退款:{}", refund);
            log.info("给订单{}退款", ordersDB.getNumber());
        }

        // 拒单需要退款,根据订单id更新订单状态、拒单原因、取消时间
        Orders orders = new Orders();
        orders.setPayStatus(Orders.REFUND);//修改订单支付状态为 ”已退款 “

        orders.setId(ordersDB.getId());
        orders.setStatus(Orders.CANCELLED);
        orders.setRejectionReason(ordersRejectionDTO.getRejectionReason());
        orders.setCancelTime(LocalDateTime.now());

        orderMapper.update(orders);
    }

功能效果:

取消订单:

同上,注释 weChatPayUtil,直接更新数据库订单支付状态为 ”已退款 “

直接替换下面代码:

    public void cancel(OrdersCancelDTO ordersCancelDTO) throws Exception {
        // 根据id查询订单
        Orders ordersDB = orderMapper.getById(ordersCancelDTO.getId());

        //支付状态
        Integer payStatus = ordersDB.getPayStatus();
        if (payStatus == 1) {
            //跳过 weChatPayUtil.refund调用,模拟给用户退款,直接更新数据库订单支付状态为 ”已退款 “
            //用户已支付,需要退款
//            String refund = weChatPayUtil.refund(
//                    ordersDB.getNumber(),
//                    ordersDB.getNumber(),
//                    new BigDecimal(0.01),
//                    new BigDecimal(0.01));
//            log.info("申请退款:{}", refund);
            log.info("给订单{}退款", ordersDB.getNumber());
        }

        // 管理端取消订单需要退款,根据订单id更新订单状态、取消原因、取消时间
        Orders orders = new Orders();
        orders.setPayStatus(Orders.REFUND);//修改订单支付状态为 ”已退款 “

        orders.setId(ordersCancelDTO.getId());
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelReason(ordersCancelDTO.getCancelReason());
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.update(orders);
    }

功能效果:

day10-来电提醒业务

由于前面模拟微信支付,直接调用了支付成功的接口,所以可以直接跳过内网穿透工具配置微信支付回调的相关配置:在yml文件中仅配置appid和secret即可,其余均可注释掉

直接修改OrderServiceImpl中的paySuccess代码:

    public void paySuccess(String outTradeNo) {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();

        // 根据订单号查询当前用户的订单
        Orders ordersDB = orderMapper.getByNumberAndUserId(outTradeNo, userId);

        // 根据订单号查询订单
//        Orders ordersDB = orderMapper.getByNumber(outTradeNo);

        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .status(Orders.TO_BE_CONFIRMED)
                .payStatus(Orders.PAID)
                .checkoutTime(LocalDateTime.now())
                .build();
        orderMapper.update(orders);

        //通过WebSocket实现来单提醒  type orderId content
        Map map = new HashMap<>();
        map.put("type", 1);//消息类型,1表示来单提醒 2表示客户催单
        map.put("orderID", ordersDB.getId());//订单id
        map.put("content", "订单号:" + outTradeNo);
        //通过websocket向客户端浏览器推送消息
        String json = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(json);

    }

功能效果:

支付成功后,后台收到来单提醒,并有语音播报

若没用来电提醒,去浏览器设置中打开媒体自动播放权限,或者重新登录一下,或者换个浏览器

至此所有与微信支付有关的代码均已修改完成!

### 苍穹外卖项目 Day09 支付功能实现 #### 接口设计 支付模块作为苍穹外卖系统中的重要组成部分,其接口设计需确保安全性和可靠性。对于支付请求的处理,通常会涉及到订单状态更新、交易记录保存以及与第三方支付平台(如微信支付)交互等功能[^1]。 #### 数据库设计 为了支持支付操作,在数据库层面至少应包含如下表结构: - `orders` 表用于存储订单详情; - `transactions` 表负责记录每笔交易的信息,包括但不限于金额、时间戳、支付方式等字段; - 另外还需考虑加入一些辅助性的表格来满足特定业务逻辑的需求,比如退款申请表单等。 #### 代码开发 以下是简化版的支付服务类 (`PaymentService`) 的部分方法实现示例,该类主要用于发起并完成一次完整的在线付款流程: ```java @Service public class PaymentServiceImpl implements PaymentService { private final OrderRepository orderRepo; private final TransactionRepository transRepo; public PaymentServiceImpl(OrderRepository orderRepo, TransactionRepository transRepo){ this.orderRepo = orderRepo; this.transRepo = transRepo; } /** * 发起支付请求至第三方支付网关. */ @Override public String initiatePayment(Long orderId) throws Exception { Optional<Order> optOrder = orderRepo.findById(orderId); if (!optOrder.isPresent()) throw new ResourceNotFoundException("找不到指定ID的订单"); Order order = optOrder.get(); // 构建支付参数... Map<String, Object> payParams = buildPayParamMap(order); // 调用微信支付API... WeChatPayResponse response = wechatPayApi.sendRequest(payParams); // 创建本地事务条目关联此订单 Transaction transaction = createTransactionEntity(response.getTransactionId(), order.getId()); transRepo.save(transaction); return "https://example.com/pay?transaction_id=" + response.getTransactionId(); // 返回预支付链接给前端 } } ``` 此外,针对批量插入购物车数据的功能也进行了扩展,以便更好地服务于后续可能产生的促销活动或其他场景下的快速结算需求[^2]: ```java @Repository public interface ShoppingCartMapper extends BaseMapper<ShoppingCart> { /** * 批量插入购物车数据 * * @param shoppingCartList 列表形式的商品项集合 */ void insertBatch(@Param("shoppingCartList") List<ShoppingCart> shoppingCartList); } ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值