微信小店订单回调处理的实现

1.背景

我们公司有线上的saas服务,售卖虚拟服务,用户在系统上面进行下单就可以获取到相应的权益。后来,公司增加了小程序直播,在直播中挂载相关的商品供用户购买,也就是微信小店。因为微信小店的订单跟我们系统的订单还没有打通,需要人工手动去处理小店里的每笔订单,要在我们系统里一笔一笔地去录入,效率较低。因此需要实现订单的自动化处理。

2.主要流程

需要打通微信小店的回调消息推送,小店的消息推送类型有很多种,商品、订单、支付等很多模块都有消息推送,我们这里只处理订单支付成功的回调就行了。

2.1 开通支付回调

  1. 登录微信小店管理系统: 小店地址
    进入服务市场/经验工具

在这里插入图片描述

  1. 我的服务/自研
    在这里插入图片描述
    3.初次设置的话需要设置小店密钥,按提示设置即可。

4.设置报文相关的信息
注意只支持80,443端口,直接填写回调的url,如http://10.10.10.410/callback
消息加解密方式:视频号小店只允许安全模式,不可选择,使用消息加解密,纯密文,安全系数高。
数据格式:视频号小店只允许为JSON,不可选择。
在这里插入图片描述
5. 设置完成后可以按技术文档那样来进行编码,接收微信的回调信息
文档见:技术文档,腾讯也提供了相关的工具和demo demo下载
主要是在自己的服务里需要提供两个同样路径的回调地址,一个支持GET(用于校验服务器地址接口),一个支持POST请求(携带回调信息)

我这里因为使用了密文,所以需要进行解密:
get 类型的回调方法

    //get请求用于微信小店后台绑定路由验证
    @GetMapping("/callback")
    @LoginIgnore
    public void callback(HttpServletRequest request, HttpServletResponse response) throws IOException, AesException {
        String echoStr = request.getParameter("echostr");
        String result = null;
        try {
            this.checkRequest(request);
            result = echoStr;
        } catch (AesException e) {
            log.error("微信小店:回调异常", e);
        }
        response.getWriter().print(result);
        response.getWriter().close();
    }
   //校验请求是否微信给过来的
    private void checkRequest(HttpServletRequest request) throws AesException {
        String msgSignature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        echostr = echostr.replace(" ", "+");
        log.info("微信小店收到回调消息: msgSignature={}, timestamp={}, nonce={},echostr={}", msgSignature, timestamp, nonce, echostr);
        WXBizMsgCrypt pc = new WXBizMsgCrypt(wechatStoreConfig.getWechatStoreToken(), wechatStoreConfig.getWechatStoreEncodingAesKey(), wechatStoreConfig.getWechatStoreId());
        pc.verifyUrl(msgSignature, timestamp, nonce, wechatStoreConfig.getWechatStoreToken());
    }

POST方法接收处理回调,如果是配置了接收明文的话就按文档说的返回"success"就行了,密文的话需要返回json内容给微信那边

    @PostMapping(value = "/callback")
    @LoginIgnore
    public String callBack(HttpServletRequest request) throws IOException {
        String returnTemplate = "{" + " \"Encrypt\": \"%s\",\n" +
                "    \"MsgSignature\": \"%s\",\n" +
                "    \"TimeStamp\": %s,\n" +
                "    \"Nonce\": \"%s\"\n" + "}";
        String result = "";
        String token = wechatStoreConfig.getWechatStoreToken();
        String storeId = wechatStoreConfig.getWechatStoreId();
        String wechatStoreEncodingAesKey = wechatStoreConfig.getWechatStoreEncodingAesKey();
        try {
            String sMsgSignature = request.getParameter("msg_signature");
            // 时间戳
            String sTimestamp = request.getParameter("timestamp");
            // 随机数
            String sNonce = request.getParameter("nonce");
            log.info("微信小店收到回调消息: msg_signature={}, timestamp={}, sNonce={}", sMsgSignature, sTimestamp, sNonce);

            InputStream inputStream = request.getInputStream();
            String sPostData = IOUtils.toString(inputStream, StandardCharsets.UTF_8);

            org.json.JSONObject json = new org.json.JSONObject(sPostData);
            String encrypt = json.getString("Encrypt");

            //验证是否微信请求:
            // 将 token、timestamp、nonce 进行字典序排序
            String signature = SHA1.getSHA1(token, sTimestamp, sNonce, encrypt);

            if (!sMsgSignature.equals(signature)) {
                throw new AesException(AesException.ValidateSignatureError);
            }
            WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(token, wechatStoreEncodingAesKey, storeId);
            String sMsg = wxBizMsgCrypt.decrypt(encrypt);
            String encryptedMsg = wxBizMsgCrypt.encrypt(WXBizMsgCrypt.getRandomStr(), "{\"demo_resp\":\"good luck\"}");

            String timeStamp =  (System.currentTimeMillis() / 1000) + "";
            signature = SHA1.getSHA1(token, timeStamp, sNonce, encryptedMsg);
            log.info("微信小店,解析后的消息体信息:\n{}", sMsg);
            //处理消息

            result = String.format(returnTemplate, encryptedMsg, signature, timeStamp, sNonce);
        } catch (Exception e) {
            log.error("微信小店:回调异常", e);
        }
        return result;
    }

消息体内容可以参考文档说明:回调通知接口说明
6. 可以用微信提供的工具进行测试
在线调试

2. 小店订单与原系统融合

在微信小店里的商品管理里可以配置商品的sku,我这里配置的是跟我们原系统同样的sku编码,有了sku,两边的订单就能对齐。

在这里插入图片描述

主要流程

  1. 用户完成订单支付时,触发回调;
  2. 系统获取到小店的订单信息(订单id),通过订单详情API接口获取到订单信息(包括商品的sku,数量,用户手机号等)
  3. 为客户创建系统订单,并记录小店与系统订单的关联关系,处理进度等。
  4. 完成订单处理。。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值