zoukankan      html  css  js  c++  java
  • 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);
                        }
                    })
                });
            });
        }
  • 相关阅读:
    开发细节
    html
    java学习
    Promise对象
    强制转换和隐式转换
    借助防抖解决输入框的非空校验
    setTimeout
    Symbol类型
    js API
    vue 使用mixin
  • 原文地址:https://www.cnblogs.com/xcggdd/p/9157447.html
Copyright © 2011-2022 走看看