从零玩转系列之微信支付实战PC端支付微信取消接口搭建1

简介: 从零玩转系列之微信支付实战PC端支付微信取消接口搭建

一、前言

作者: 杨不易呀

halo各位大佬很久没更新了最近在搞微信支付,因商户号审核了我半个月和小程序认证也找了资料并且将商户号和小程序进行关联,至此微信支付Native支付完成.此篇文章过长我将分几个阶段的文章发布(项目源码都有,小程序和PC端)

在此之前已经更新了微信支付开篇、微信支付安全、微信实战基础框架搭建、本次更新为微信支付实战PC端接口搭建,实战篇分为几个章节因为代码量确实有点多哈.

  • 第一章从零玩转系列之微信支付开篇
  • 第二章从零玩转系列之微信支付安全
  • 第三章从零玩转系列之微信支付实战基础框架搭建
  • 第四章从零玩转系列之微信支付实战PC端支付下单接口搭建
  • 第五章从零玩转系列之微信支付实战PC端支付微信回调接口搭建
  • 第六章从零玩转系列之微信支付实战PC端支付微信取消订单接口搭建
  • 第七章从零玩转系列之微信支付实战PC端支付微信退款订单接口搭建
  • 第八章从零玩转系列之微信支付实战PC端项目构建Vue3+Vite+页面基础搭建
  • 第九章从零玩转系列之微信支付实战PC端装修下单页面
  • 第十章从零玩转系列之微信支付实战PC端装修我的订单下单页面
  • 第十一章从零玩转系列之微信支付实战PC端我的订单接入退款取消接口
  • 第十二章从零玩转系列之微信支付实战Uni—App基础项目搭建

a6875a95223c5902d9f4a9b18741b15.png

本次项目使用技术栈

后端: SpringBoot3.1.x、Mysql8.0、MybatisPlus

前端: Vue3、Vite、ElementPlus

小程序: Uniapp、Uview

一、取消订单接口

场景

  1. 用户下单完毕后未支付 可进行取消订单
  2. 订单超时支付系统自动取消订单

修改 WechatNativeController

/**
     * 用户取消订单
     */
    @PostMapping("/cancel/{orderNo}")
    public R<String> cancel(@PathVariable String orderNo) {
        log.info("取消订单");
        wxPayService.cancelOrder(orderNo);
        return R.ok("订单已取消");
    }

修改 wxPayService

/**
     * 关闭订单
     */
    @SneakyThrows
    public void cancelOrder(String orderNo) {
        // ...../
      // 
        // 
        // 
        // 
        // step 2 还未支付才能取消订单
    }

逻辑分析

在工作中我们逻辑可能是这样子的

step 1 查询该订单状态是否需要关闭订单,如果订单已经关闭则不需要再次关闭

思考: 我们应该去哪里查询订单的状态?

c4ba60f6_5151444.png

假如我们去数据库查询记录的话,如果数据库因为什么原因导致状态可能不对呢?

所以我们直接去微信服务器查最新的直接更新关闭状态到数据库当中

306cc813_5151444.png

你看微信也要我们这样子玩那就万无一失直接干

================================================================

好既然我们要去调用微信查询接口我们是不是可以封装一个通用的 后续肯定有其他地方也会调用查询支付信息的情况

文档(商户): https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_2.shtml

有两种查询方式第二种方便就这么简单

代码很好理解传递商户订单号和直连商户号mchid

/**
     * 抽出公共获取微信订单信息
     */
    private WeChartOrderInfo selectOrderInfo(String orderNo) throws IOException {
        log.info("查询订单,直连商户号:{} , 微信支付订单号: {}", orderNo, wxPayConfig.getMchId());
        String url = wxPayConfig.getDomain().concat(String.format(WxApiType.ORDER_QUERY_BY_NO.getType(), orderNo)).concat("?mchid=").concat(wxPayConfig.getMchId());
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("Accept", "application/json");
        CloseableHttpResponse response = wxPayClient.execute(httpGet);
        WeChartOrderInfo weChartOrderInfo = buildBodyParams(response, WeChartOrderInfo.class);
        log.info("查询订单响应, {}", weChartOrderInfo);
        response.close();
        return weChartOrderInfo;
    }

响应结果

{
 "amount": {
  "currency": "CNY",
  "payer_currency": "CNY",
  "payer_total": 1,
  "total": 1
 },
 "appid": "wxdace645e0bc2cXXX",
 "attach": "",
 "bank_type": "OTHERS",
 "mchid": "1900006XXX",
 "out_trade_no": "44_2126281063_5504",
 "payer": {
  "openid": "o4GgauJP_mgWEWictzA15WT15XXX"
 },
 "promotion_detail": [],
 "success_time": "2021-03-22T10:29:05+08:00",
 "trade_state": "SUCCESS",
 "trade_state_desc": "支付成功",
 "trade_type": "JSAPI",
 "transaction_id": "4200000891202103228088184743"
}

完善逻辑

/**
     * 关闭订单
     */
    @SneakyThrows
    public void cancelOrder(String orderNo) {
     // step 1 查询该订单状态是否需要关闭订单
       WeChartOrderInfo state = selectOrderInfo(orderNo);
    // 判断如果订单已经关闭则不需要再次关闭 更新数据库
        if (null == state || state.getTrade_state() == null) {
            // 更新本地订单状态超时关闭订单
            orderInfoService.lambdaUpdate().eq(OrderInfo::getOrderNo, orderNo).set(OrderInfo::getOrderStatus, OrderStatus.CLOSED.getType()).update();
            return;
        }
        // step 2 还未支付才能取消订单
        if (state.getTrade_state().equals(OrderStatus.NOTPAY.name())) {
            // step 2 进行调用微信关闭订单接口
            sendCloseRequest(orderNo);
            // step 2 更新商户端的订单状态用户取消订单
            this.orderInfoService.lambdaUpdate().eq(OrderInfo::getOrderNo, orderNo).set(OrderInfo::getOrderStatus, OrderStatus.CANCEL.getType()).update();
        }
    }

抽出通用订单关闭代码

文档: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_3.shtml

/**
     * 发送关闭订单请求
     *
     * @param orderNo 订单编号
     */
    @SneakyThrows
    private void sendCloseRequest(String orderNo) {
        log.info("关闭订单, 订单号:{}", orderNo);
        String url = String.format(wxPayConfig.getDomain().concat(WxApiType.CLOSE_ORDER_BY_NO.getType()), orderNo);
        HttpPost httpPost = new HttpPost(url);
        Map<String, Object> paramsMap = new HashMap<>(1);
        paramsMap.put("mchid", wxPayConfig.getMchId());
        String jsonParams = JSONUtil.toJsonStr(paramsMap);
        log.info("请求参数 ===> {}", jsonParams);
        StringEntity entity = new StringEntity(jsonParams, "utf-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        httpPost.setHeader("Accept", "application/json");
        try (CloseableHttpResponse response = wxPayClient.execute(httpPost)) {
            log.info("关单响应: {}", response.getEntity());
            log.info("解析body {}", buildBodyParams(response, Map.class));
        }
    }

到这里订单取消就完毕了

二、查询订单接口接口

根据上面编写的查询订单方法完善一下

修改 WechatNativeController

/**
 * 查询订单
 */
@PostMapping("/query/{orderNo}")
public R<WeChartOrderInfo> query(@PathVariable String orderNo) {
    log.info("查询订单");
    return R.ok(wxPayService.queryOrder(orderNo));
}

修改 WxPayService

/**
 * 查询订单信息
 *
 * @param orderNo 订单号
 * @return 订单信息
 */
@SneakyThrows
public WeChartOrderInfo queryOrder(String orderNo) {
    return this.selectOrderInfo(orderNo);
}

好了查询接口也写完了so easy to happy !

我们来测试看看是什么效果咯~


b718f7e7_5151444.png



相关文章
|
4天前
|
算法 iOS开发 CDN
“企业微信iPad协议”第 0x04 天:当朋友圈接口在凌晨 2:14 突然返回 404
新品上线紧急任务:300位经销商朋友圈同步海报。突破官方限制,利用企业微信iPad协议私有接口,自动化上传发布。凌晨遭遇404,迅速定位并修复算法版本问题,最终高效完成推送,点赞超4200。技术在文档之外,也在边界之内。
43 0
|
8天前
|
缓存 小程序 前端开发
商城/点餐/家政类小程序源码合集_微信抖音小程序源码开发从入门到精通实战
本文系统讲解如何利用现有源码快速开发商城、点餐、家政类微信/抖音小程序,涵盖环境搭建、核心功能实现、多平台部署与优化,提供完整技术方案。实战导向,助力开发者高效入门与落地。
|
8天前
|
小程序 PHP 图形学
热门小游戏源码(Python+PHP)下载-微信小程序游戏源码Unity发实战指南​
本文详解如何结合Python、PHP与Unity开发并部署小游戏至微信小程序。涵盖技术选型、Pygame实战、PHP后端对接、Unity转换适配及性能优化,提供从原型到发布的完整指南,助力开发者快速上手并发布游戏。
|
7月前
|
自然语言处理 搜索推荐 小程序
微信公众号接口:解锁公众号开发的无限可能
微信公众号接口是微信官方提供的API,支持开发者通过编程与公众号交互,实现自动回复、消息管理、用户管理和数据分析等功能。本文深入探讨接口的定义、类型、优势及应用场景,如智能客服、内容分发、电商闭环等,并介绍开发流程和工具,帮助运营者提升用户体验和效率。未来,随着微信生态的发展,公众号接口将带来更多机遇,如小程序融合、AI应用等。
|
2月前
|
移动开发 小程序 开发工具
揭秘微信/支付宝6大支付方式:从扫码到刷脸,谁在偷偷赚你的手续费?优雅草卓伊凡
揭秘微信/支付宝6大支付方式:从扫码到刷脸,谁在偷偷赚你的手续费?优雅草卓伊凡
396 0
揭秘微信/支付宝6大支付方式:从扫码到刷脸,谁在偷偷赚你的手续费?优雅草卓伊凡
|
4月前
|
JSON 监控 小程序
微信百度字节小程序包过大解决方案(实战经验总结)-优雅草卓伊凡|果果|小无
微信百度字节小程序包过大解决方案(实战经验总结)-优雅草卓伊凡|果果|小无
282 14
微信百度字节小程序包过大解决方案(实战经验总结)-优雅草卓伊凡|果果|小无
|
7月前
|
小程序 测试技术 数据安全/隐私保护
微信公众号接口测试实战指南
微信公众号接口测试是确保系统稳定性和功能完整性的重要环节。本文详细介绍了测试全流程,包括准备、工具选择(如Postman、JMeter)、用例设计与执行,以及常见问题的解决方法。通过全面测试,可以提前发现潜在问题,优化用户体验,确保公众号上线后稳定运行。内容涵盖基础接口、高级接口、微信支付和数据统计接口的测试,强调了功能验证、性能优化、安全保护及用户体验的重要性。未来,随着微信生态的发展,接口测试将面临更多挑战和机遇,如小程序融合、AI应用和国际化拓展。
|
10天前
|
消息中间件 人工智能 Java
抖音微信爆款小游戏大全:免费休闲/竞技/益智/PHP+Java全筏开源开发
本文基于2025年最新行业数据,深入解析抖音/微信爆款小游戏的开发逻辑,重点讲解PHP+Java双引擎架构实战,涵盖技术选型、架构设计、性能优化与开源生态,提供完整开源工具链,助力开发者从理论到落地打造高留存、高并发的小游戏产品。
|
1月前
|
小程序 JavaScript API
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
这篇文章介绍了使用uni-halo框架进行微信小程序开发的过程,包括选择该框架的原因、开发目标以及项目配置和部署的步骤。
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
|
4月前
|
小程序 前端开发 Android开发
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
1037 29
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡

热门文章

最新文章