微信支付(三) - 异步通知并且查询支付结果

要知道,app调用支付后,微信会发送一个异步通知给后台,同时后台需要调用查询微信后台这笔订单的支付结果以及金额,这是一个并行操作,需要注意的是微信后台收到的金额和订单金额需要进行比对,为了防止钓鱼,所以这个查询是有必要的,必须匹配:收到的到账金额 >= 订单金额(我有一哥们他们的app是没有这步操作的,支付了不论是否成功订单直接往下走,这样是不对滴...)

好吧,来看一下代码,异步通知地址需要自己配置好,在生成预付单的时候就得传过去

// TODO 通知回调地址
    @Value("${WXPAY_NOTIFYURL}")
    private String notifyUrl;

这个地址就是自己的webservice,也就是你的某个rest-controller

@RequestMapping("/notice")
    public void notice(HttpServletRequest request, HttpServletResponse response) throws IOException {
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inStream.close();
        String result = new String(outSteam.toByteArray(), "utf-8");
        Map<String, String> map = null;
        try {
            map = XMLUtil.doXMLParse(result);
        } catch (JDOMException e) {
            e.printStackTrace();
        }

        // 此处调用订单查询接口验证是否交易成功
        WXOrderQuery wxpayResult = reqOrderQueryResult(map);
        boolean isSucc = wxpayResult.isSuccess();

        // 支付成功,商户处理后同步返回给微信参数
        PrintWriter writer = response.getWriter();
        if (!isSucc) {
            // 支付失败, 记录流水失败
            System.out.println("===============支付失败==============");
        } else {
            orderService.doWXPayNotice(wxpayResult);
            System.out.println("===============付款成功,业务处理完毕==============");

            // 通知微信已经收到消息,不要再给我发消息了,否则微信会8连击调用本接口
            String noticeStr = setXML("SUCCESS", "");
            writer.write(noticeStr);
            writer.flush();
        }

        String noticeStr = setXML("FAIL", "");
        writer.write(noticeStr);
        writer.flush();
    }

    public static String setXML(String return_code, String return_msg) {
        return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
    }
/**
     * 目前用的这个接口
     * @Description: 查询通知的结果bean
     * @param map
     * @return
     *
     * @author leechenxiang
     * @date 2016年12月8日 上午11:04:52
     */
    public WXOrderQuery reqOrderQueryResult(Map<String, String> map) {
        WXOrderQuery orderQuery = new WXOrderQuery();
        orderQuery.setAppid(map.get("appid"));
        orderQuery.setMch_id(map.get("mch_id"));
        orderQuery.setTransaction_id(map.get("transaction_id"));
        orderQuery.setOut_trade_no(map.get("out_trade_no"));
        orderQuery.setNonce_str(map.get("nonce_str"));
        String payFlowId = map.get("attach");
        orderQuery.setAttach(payFlowId);

        //此处需要密钥PartnerKey,此处直接写死,自己的业务需要从持久化中获取此密钥,否则会报签名错误
        orderQuery.setPartnerKey(WXPayContants.partnerKey);

        Map<String, String> orderMap = orderQuery.reqOrderquery();
        //此处添加支付成功后,支付金额和实际订单金额是否等价,防止钓鱼
        if (orderMap.get("return_code") != null && orderMap.get("return_code").equalsIgnoreCase("SUCCESS")) {
            if (orderMap.get("trade_state") != null && orderMap.get("trade_state").equalsIgnoreCase("SUCCESS")) {
                // 查询订单(交易流水的实际金额),判断微信收到的钱和订单中的钱是否等额
                SpPayFlowCargoSource payFlow = spPayFlowCargoSourceService.getPayFlowById(payFlowId);
                String total_fee = map.get("total_fee");
                orderQuery.setPayFlow(payFlow);
                Integer db_fee = payFlow.getFee().multiply(new BigDecimal(100)).intValue();
                if (Integer.parseInt(total_fee) == db_fee) {
                    orderQuery.setSuccess(true);
                    return orderQuery;
                }
            }
        }
        orderQuery.setSuccess(false);
        return orderQuery;
    }

到这一步,就能判断金额到底对不对,对了那么久成功支付,订单进行下一步流程~

再次强调,一定要防止钓鱼,另外异步调用的时候需要去查看你的订单或者交易流水是否已经成功了,成功就没有必要继续走,直接return就行,因为微信

会多次异步通知,主要还是看你的接口怎么设计了

 (附:微信异步通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒)

 

时间: 2025-01-31 03:56:02

微信支付(三) - 异步通知并且查询支付结果的相关文章

关于支付系统异步通知的功能实现

问题描述 现在想做一个中间层去管理支付系统的异步通知~有可参考的例子或经验分享吗? 解决方案 参考支付宝文档吧. 之前用过它的集成 文档挺全的解决方案二:你是想管理所有的网上支付异步通知么?与各种银行的接口上面提到如果异步通知,需要提供通知的callback的url,然后银行会自动调用这个url,把信息发送过来.如果想做个中间层来管理这个异步通知,可以定义一个dispather,然后根据各个银行标识,由定义好的各个银行的handler来处理,如果增加一个支付接口,只需要增加handler即可.

关于支付系统中的同步通知和异步通知电商的区别,为什么需要通知

问题描述 关于支付系统中的同步通知和异步通知电商的区别,为什么需要通知 在电商对应的支付系统中当支付完成之后需要做相关的同步通知和异步通知操作,请大神解释一下什么是同步通知和异步通知,为什么需要同步通知和异步通知. 解决方案 同步用于即时通知支付完成 异步用于防止信息漏发漏收 解决方案二: 可以这样理解, 1.用户(买家)支付完成后,电商平台需要实时的给用户一个通知,如支付已经处理等待订单确认. 2.电商平台,这块就需要考虑系统技术方面的各个环节,考虑应对复杂多变的并发用户量.业务.流量.网络环

同步通知 电商-关于支付系统中同步通知和异步通知时什么为什么需要同步通知和异步通知

问题描述 关于支付系统中同步通知和异步通知时什么为什么需要同步通知和异步通知 在电商发起订单支付中到支付系统支付完成之后 为什么需要发送同步通知或者异步通知,什么是同步通知什么又是异步通知,请大神赐教! 解决方案 同步用于即时通知支付完成 异步用于防止信息漏发漏收 解决方案二: http://ask.csdn.net/questions/200584 解决方案三: 异步通知与同步互斥异步通知fasync异步通知fasync

微信支付开发告警通知实例_php实例

一.告警通知 为了及时通知商户异常,提高商户在微信平台的服务质量.微信后台会向商户推送告警通知,包括发货延迟.调用失败.通知失败等情况,通知的地址是商户在申请支付时填写的告警通知URL,在"公众平台-服务-服务中心-商户功能-商户基本资料-告警通知URL"可以查看.商户接收到告警通知后需要尽快修复其中提到的问题,以免影响线上经营. 告警通知URL接收的postData中还将含xml数据,格式如下: <xml> <AppId><![CDATA[wxf8b4f

微信支付开发交易通知实例_php实例

一.交易通知 用户在成功完成支付后,微信后台通知(POST)商户服务器(notify_url)支付结果.商户可以使用notify_url的通知结果进行个性化页面的展示. 对后台通知交互时,如果微信收到商户的应答不是success或超时,微信不为通知失败,微信会通过一定的策略(如30分钟共8次)定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功. 后台通知通过请求中的 notify_url 迚行,采用 POST 机制. 同时,在postData中还将包含xml数据. 二.交易结果

微信支付开发告警通知实例

一.告警通知 为了及时通知商户异常,提高商户在微信平台的服务质量.微信后台会向商户推送告警通知,包括发货延迟.调用失败.通知失败等情况,通知的地址是商户在申请支付时填写的告警通知URL,在"公众平台-服务-服务中心-商户功能-商户基本资料-告警通知URL"可以查看.商户接收到告警通知后需要尽快修复其中提到的问题,以免影响线上经营. 告警通知URL接收的postData中还将含xml数据,格式如下: <xml> <AppId><![CDATA[wxf8b4f

微信支付开发交易通知实例

一.交易通知 用户在成功完成支付后,微信后台通知(POST)商户服务器(notify_url)支付结果.商户可以使用notify_url的通知结果进行个性化页面的展示. 对后台通知交互时,如果微信收到商户的应答不是success或超时,微信不为通知失败,微信会通过一定的策略(如30分钟共8次)定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功. 后台通知通过请求中的 notify_url 迚行,采用 POST 机制. 同时,在postData中还将包含xml数据. 二.交易结果

Android App支付系列(一):微信支付接入详细指南(附官方支付demo)_Android

写在前面 一家移动互联网公司,说到底,要盈利总是需要付费用户的,自己开发支付系统显然是不明智的,国内已经有多家成熟的移动支付提供商,腾讯就是其中之一.梳理了下微信支付的接入,今天给大家分享下腾讯旗下的微信支付SDK的接入流程. 接入流程 1.申请开发者资质 地址:https://open.weixin.qq.com/ 使用公司管理者/高层帐号登录微信开放平台,进入"账号中心",进行开发者资质认证,需要填写公司资料,包括但不限于,公司注册号,公司营业执照,公司对外办公电话,公司对公银行卡

C# MVC 微信支付教程系列之扫码支付代码实例_C#教程

今天,我们来一起探讨一下这个微信扫码支付.何为扫码支付呢?这里面,扫的码就是二维码了,就是我们经常扫一扫的那种二维码图片,例如,我们自己添加好友的时候,可以通过输入对方的微信号,也可以扫一扫对方的二维码.扫码支付,作为,微信支付里面,不可或缺的一个功能,对商品的支付提供了极为方便的体验,用途也非常的多. 例如我们在地铁.公交站常见的那些自动售货机(不错,就是那种投硬币,就可以自动出货的那种机器)中都用到.微信(支付宝)的扫码支付的出现,大大的减少了这方面的风险,近些年来,二维码的应用越来越广,甚