微信APP支付Java服务端

微信APP支付Java服务端,爬出一半坑,记录下心得。

同样,对于微信APP支付申请和配置在这里就不做说明了,拿到APPID和partnerid,在商户平台设置好自己的key之后再说。

微信对比支付宝而言,确实比较坑,官方文档不清晰,稍不留神就掉坑里了,而且没有客服,和客户端的小伙伴试了好多次终于在今天调起微信支付,再次在此记录下微信支付服务端的心得,给后面需要用的小伙伴做下参考,共同学习。。

首先,因为官方没有给出服务端的demo,所以我也是在网上找别人的demo 看着,然后自己调试,和微信交互就不细说了,我参考的是这个大神的demo ,把其中的appid等等参数更换成自己申请的ID 然后调用执行之后拿到这个结果 http://blog.csdn.net/seven_cm/article/details/41559301
我下载大神demo之后,把其中的appid等等参数更换成自己申请的ID  然后调用执行之后拿到这个结果
这里的流程是:后台生成订单之后,把参数信息打包签名,通过post发送给微信,微信返回xml格式的数据,返回的数据里边有个很重要的prepayid—预支付交易会话ID。这个数据需要传递给前端 所以我们需要解析这个微信传过来的xml数据

生成签名规则:

    /** 
         * 微信支付签名算法sign 
         * @param characterEncoding 
         * @param parameters 
         * @return 
         */  
        @SuppressWarnings("rawtypes")  
        public static String createSign(String characterEncoding,SortedMap<Object,Object> parameters){  
            StringBuffer sb = new StringBuffer();  
            Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)  
            Iterator it = es.iterator();  
            while(it.hasNext()) {  
                Map.Entry entry = (Map.Entry)it.next();  
                String k = (String)entry.getKey();  
                Object v = entry.getValue();  
                if(null != v && !"".equals(v)   
                        && !"sign".equals(k) && !"key".equals(k)) {  
                    sb.append(k + "=" + v + "&");  
                }  
            }  
            sb.append("key=" + Key);  
            System.out.println("字符串拼接后是:"+sb.toString());  
            String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();  
            return sign;  
        }  

第一次签名,即订单内容

//参数:开始生成签名
        SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
        parameters.put("appid", appid);
        parameters.put("mch_id", mch_id);
        parameters.put("nonce_str", nonce_str);
        parameters.put("body", body);
        parameters.put("nonce_str", nonce_str);
        parameters.put("detail", detail);
        parameters.put("attach", attach);
        parameters.put("out_trade_no", out_trade_no);
        parameters.put("total_fee", total_fee);
        parameters.put("time_start", time_start);
        parameters.put("time_expire", time_expire);
        parameters.put("notify_url", notify_url);
        parameters.put("trade_type", trade_type);
        parameters.put("spbill_create_ip", spbill_create_ip);

        String sign = WXSignUtils.createSign("UTF-8", parameters);
        System.out.println("签名是:"+sign);

生成的xml参数,解析prepayid

//构造xml参数
        String xmlInfo = HttpXmlUtils.xmlInfo(unifiedorder);

        String wxUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";

        String method = "POST";

        String weixinPost = HttpXmlUtils.httpsRequest(wxUrl, method, xmlInfo).toString();

        System.out.println(weixinPost);

        ParseXMLUtils.jdomParseXml(weixinPost);//解析key值

到这里准备工作就完成了,然后我们需要把参数传递给客户端

客户端需要的参数,官方文档是这样说的:
只是说明了需要的参数根本没说参数从哪来  怎么传递

这里的
appid 就是我们微信支付申请的ID
partnerid 就是申请的商户平台的账号
prepayid 预支付ID 就是上面说的解析xml数据之后拿到的值
package 官方说,暂填写固定值Sign=WXPay
noncestr 随机生成的16为字符串
timestamp 注意:这里是个巨坑,这里的时间戳指的是1970年到发起支付的秒数,并且是十位,,Calendar.getInstance().getTimeInMillis()这个获取的是13位,正确的是:Calendar.getInstance().getTimeInMillis()/1000 拿到十位秒数

sign 返回给客户端的二次签名,巨巨坑,下面细说:

服务端一共需要两次签名,第一次生成签名是返回给微信服务端,签名的内容是订单信息,参考上面大神demo

第二次的签名,即服务端返回给客户端的签名,方法与第一次签名相同,签名的内容就是上面的六位参数外加商户平台申请的key

拿到签名之后,把以上参数和签名通过json返回给客户端就OK了,剩下的就是客户端解析json数据调起微信支付。

服务端把数据传递正确之后前端很快就可以调起支付,主要是微信官方文档说的太简略,我也是和前端小伙伴一次一次调整数据试出来,微信只要不正确就只报-1非常无奈,这样比起来支付宝开发文档简直太好了。

猜你喜欢

转载自blog.csdn.net/ms___/article/details/78777440