java微信支付--------公众号内H5调起支付

谨以此做记录,方便下次实现,不适合新手拷贝,如有指教,欢迎留言讨论!

新手请参考博文:https://blog.csdn.net/javaYouCome/article/details/79473743,致谢该博主!

微信支付官方文档:https://pay.weixin.qq.com/wiki/doc/api/index.html

记录几个容易出问题的点:

1、参与签名的参数名大小写保持与官方文档一致,

2、在商户平台配置支付目录,类似配置js安全接口域名

3、调用统一下单接口获取prepay_id=参数(参数签名浪费了很多时间,注意参数名保持一致)

主要代码:

后台调用统一下单接口:参数签名工具类来自微信官方支付demo

/**
     * 统一下单接口,获取prepay_id
     * @param request
     * @return
     */
    @RequestMapping(value = "/unifiedOrder", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, String> unifiedOrder(HttpServletRequest request,String openId,String totalFee) {
        try {
            // 不带properties扩展名的文件名
            ResourceBundle wx = ResourceBundle.getBundle("wx"); 
            // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder  
            String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";  
            //拼接统一下单地址参数  
            Map<String, String> paraMap = new HashMap<String, String>();  
            //获取请求ip地址  
            String ip = request.getHeader("x-forwarded-for");  
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){  
                ip = request.getHeader("Proxy-Client-IP");  
            }  
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){  
                ip = request.getHeader("WL-Proxy-Client-IP");  
            }  
            if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){  
                ip = request.getRemoteAddr();  
            }  
            if(ip.indexOf(",")!=-1){  
                String[] ips = ip.split(",");  
                ip = ips[0].trim();  
            }  
            String appid = wx.getString("wx_appid");
            paraMap.put("appid", appid);    
            paraMap.put("body", "********");    
            paraMap.put("mch_id", "****");    
            paraMap.put("nonce_str", WXPayUtil.generateNonceStr());    
            paraMap.put("openid", openId);  
            paraMap.put("out_trade_no", new Date().getTime()+"");//订单号  
            paraMap.put("spbill_create_ip", ip);    
            paraMap.put("total_fee",totalFee);    
            paraMap.put("trade_type", "JSAPI");    
            paraMap.put("notify_url",wx.getString("red_url") + "/callback.do");// 此路径是微信服务器调用支付结果通知路径随意写  
            String sign = WXPayUtil.generateSignature(paraMap, "********");  
            paraMap.put("sign", sign);  
            String xml = WXPayUtil.mapToXml(paraMap);//将所有参数(map)转xml格式  
            System.out.println(xml);
            String xmlStr = wxMpService.post(unifiedorder_url, xml); //发送post请求"统一下单接口"返回预支付id:prepay_id  
              
            //以下内容是返回前端页面的json数据  
            String prepay_id = "";//预支付id  
            if (xmlStr.indexOf("SUCCESS") != -1) {    
                Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);    
                prepay_id = (String) map.get("prepay_id");    
            }  
            Map<String, String> payMap = new HashMap<String, String>();  
            payMap.put("appId", appid);    
            payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp()+"");    
            payMap.put("nonceStr", WXPayUtil.generateNonceStr());    
            payMap.put("signType", "MD5");    
            payMap.put("package", "prepay_id=" + prepay_id);    
            String paySign = WXPayUtil.generateSignature(payMap, "*******");
            payMap.put("paySign", paySign);  
            String xml2 = WXPayUtil.mapToXml(payMap);//将所有参数(map)转xml格式  
            System.out.println(xml2);
            return payMap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }  
    }
    
    @RequestMapping(value="/callback",method=RequestMethod.GET)  
    public String callBack(HttpServletRequest request,HttpServletResponse response){  
        //System.out.println("微信支付成功,微信发送的callback信息,请注意修改订单信息");  
        InputStream is = null;  
        try {  
            is = request.getInputStream();//获取请求的流信息(这里是微信发的xml格式所有只能使用流来读)  
            String xml = WXPayUtil.inputStream2String(is, "UTF-8");  
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);//将微信发的xml转map  
                          
            if(notifyMap.get("return_code").equals("SUCCESS")){    
                //支付成功
            }  
              
            //告诉微信服务器收到信息了,不要在调用回调action了========这里很重要回复微信服务器信息用流发送一个xml即可  
            response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");    
            is.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return null;  
    }

前台jssdk接收配置参数,调起支付:

//支付
    function pay(price){
        $.get("${basePath}/pay/unifiedOrder.do",{"openId":"${sessionScope.openId }","totalFee":price},function(data,status){
            wx.ready(function() { 
                wx.chooseWXPay({
                    timestamp: data.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
                    nonceStr: data.nonceStr, // 支付签名随机串,不长于 32 位
                    package: data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
                    signType: data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
                    paySign: data.paySign, // 支付签名
                    success: function (res) {
                        // 支付成功后的回调函数
                        alert(1);
                    }
                })
            });
        });
    }

 

posted @ 2018-06-08 20:09  九三x  阅读(2321)  评论(0编辑  收藏  举报