微信小店下单,发货,订单查询接入流程

328 阅读3分钟

首先是需要定义两个请求接口: 一个是get请求用于微信小店后台绑定服务器对应的路由 一个是post请求用于接受微信小店不同的事件回调

微信小店的话回调数据主要是相关json数据回传过来 相比于之前接入的企微回调的相关内容是xml类型,需要避免xss拦截,以及对应官网工具类转一层;

消息推送:developers.weixin.qq.com/doc/store/s…

相关代码内容示例:

@Autowired
WechatStoreConfig wechatStoreConfig;


//get请求用于微信小店后台绑定路由验证    
@GetMapping("/callback")
    public void callback(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String msgSignature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr").trim();
        echostr = echostr.replace(" ", "+");
       log.info("微信小店收到回调消息: msgSignature={}, timestamp={}, nonce={},echostr={}", msgSignature, timestamp, nonce,echostr);

        String token = wechatStoreConfig.getWechatStoreToken();

        // 将 token、timestamp、nonce 进行字典序排序
        List<String> params = Arrays.asList(nonce, timestamp, token);
        // 将排序后的参数字符串拼接成一个字符串
        Collections.sort(params);
        StringBuilder paramStr = new StringBuilder();
        for (String param : params) {
            paramStr.append(param);
        }
        String calculatedSignature = sha1(paramStr.toString());

        String result =null;
        if (msgSignature.equals(calculatedSignature)) {
            // 相等说明请求来自微信服务器,合法,回包消息体内容为 echostr
            result = echostr;
        }
        log.info("密文: calculatedSignature={}", calculatedSignature);

        response.getWriter().print(result);
        response.getWriter().close();
    }


//post请求接受订阅:
@PostMapping(value = "/callback")
    public String callBack() {

        String result = "success";
        String token = wechatStoreConfig.getWechatStoreToken();
        String storeId = wechatStoreConfig.getWechatStoreId();
        String appSecret = wechatStoreConfig.getWechatStoreAppSecret();
        String wechatStoreEncodingAesKey = wechatStoreConfig.getWechatStoreEncodingAesKey();

        ServletRequestAttributes servletRequestAttributes = null;
        try {
            if (RequestContextHolder.getRequestAttributes() != null) {
                servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                if (servletRequestAttributes != null) {
                    HttpServletRequest request = servletRequestAttributes.getRequest();

                    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 进行字典序排序
                    List<String> params = Arrays.asList(token, sTimestamp, sNonce,encrypt);
                    // 将排序后的参数字符串拼接成一个字符串
                    Collections.sort(params);
                    StringBuilder paramStr = new StringBuilder();
                    for (String param : params) {
                        paramStr.append(param);
                    }
                    //sha1--官方引入https://wximg.gtimg.com/shake_tv/mpwiki/cryptoDemo.zip
                    String calculatedSignature = sha1(paramStr.toString());
                    if (!sMsgSignature.equals(calculatedSignature)) {
                        log.warn("微信小店请求不合法: sMsgSignature={}, calculatedSignature={}", sMsgSignature, calculatedSignature);
                        // 相等说明请求来自微信服务器,合法,回包消息体内容为 echostr
                        return result;
                    }

                    //WXBizMsgCrypt--官方引入https://wximg.gtimg.com/shake_tv/mpwiki/cryptoDemo.zip
                  
                    WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(token, wechatStoreEncodingAesKey, storeId);
                    String sMsg = wxBizMsgCrypt.decrypt(encrypt);
                    log.info("微信小店,解析后的消息体信息:\n{}",sMsg);
                    ObjectMapper objectMapper = new ObjectMapper();
                    WecahtStoreMsg wechatMessage = objectMapper.readValue(sMsg, WecahtStoreMsg.class);

                    // 打印解析后的消息体
                    String event = wechatMessage.getEvent();
                    log.info("微信小店,序列化后的消息体:\n{},event{}", wechatMessage,event);
                    //event类型区分不同的事件: 
                    //成功支付:channels_ec_order_pay
                    //退款同意:channels_ec_order_cancel cancel_type=3
                    //同时上述事件过来基本都有product_order_status_update事件回调


                }
            }
        }catch (Exception e){
            log.error("微信小店:回调异常",e);
        }
        return result;
    }
    //accessToken获取:常用:https://developers.weixin.qq.com/doc/store/shop/API/basics/getaccesstoken.html

1. 常用的事件:

成功支付事件:channels_ec_order_pay

退款事件相关事件:

1:channels_ec_order_cancel 对应的cancel_type为3,全部售后事件已完成,比如说用户买了两件,然后这两件都退掉:

WecahtStoreMsg(toUserName=XXX,fromUserName=XXX,createTime=1747221305,msgType=event,event=channels_ec_order_cancel,productOrderStatusUpdate=null,orderInfo=WecahtStoreMsg.OrderInfo(orderId=3728110005492004096,cancelType=3,payTime=0,finishDelivery=0),finderShopAftersaleStatusUpdate=null),eventchannels_ec_order_cancel

2:如果说用户一次性买了三件,然后只退了一件则会有对应的channels_ec_aftersale_update事件推送:

{"ToUserName":"XXX","FromUserName":"XXX","CreateTime":1747221304,"MsgType":"event","Event":"channels_ec_aftersale_update","finder_shop_aftersale_status_update":{"after_sale_order_id":"XXX","status":"MERCHANT_REFUND_SUCCESS","order_id":"XXX"}}

3:小店后台的话同意,拒绝退款,还有有协商退款,协商相关金额,具体退款金额可以根据after_sale_order_id 查询售后单,查询相关退款详情金额amount数据api:

developers.weixin.qq.com/doc/store/s…

4:可以同时买多笔订单,需要批处理下

5:虚拟商品相关信息:订单详情的:RechargeInfo中

2. 后台相关配置:

相关api配置:

点击服务市场经营工具,右上角的自研,配置相关消息推送的路由

2:微信小店后台可以配置自定义商品id进行关联起来:

3:一些api:

获取订单详情:developers.weixin.qq.com/doc/store/s… developers.weixin.qq.com/doc/store/s…