zoukankan      html  css  js  c++  java
  • 调用微信Js-SDK支付

    $(document).ready(function(){
    	var url = location.href.split('#')[0];
    	$.get(rootPath + "/wechat/member/user/getWechatConfig?url=" + url,"",function(data){
    		wx.config({
    			debug: false,
    			appId: data.appId,
    			nonceStr: data.nonceStr,
    			signature: data.signature,
    			timestamp: parseInt(data.timestamp),
    			jsApiList: [
    	            'checkJsApi',
    	            'onMenuShareTimeline',
    	            'onMenuShareAppMessage',
    	            'onMenuShareQQ',
    	            'onMenuShareWeibo',
    	            'hideMenuItems',
    	            'showMenuItems',
    	            'hideAllNonBaseMenuItem',
    	            'showAllNonBaseMenuItem',
    	            'translateVoice',
    	            'startRecord',
    	            'stopRecord',
    	            'onRecordEnd',
    	            'playVoice',
    	            'pauseVoice',
    	            'stopVoice',
    	            'uploadVoice',
    	            'downloadVoice',
    	            'chooseImage',
    	            'previewImage',
    	            'uploadImage',
    	            'downloadImage',
    	            'getNetworkType',
    	            'openLocation',
    	            'getLocation',
    	            'hideOptionMenu',
    	            'showOptionMenu',
    	            'closeWindow',
    	            'scanQRCode',
    	            'chooseWXPay',
    	            'openProductSpecificView',
    	            'addCard',
    	            'chooseCard',
    	            'openCard'
    	        ]
    		});
    	});
    
    	document.querySelector('#wxpay').onclick = function () {
    		$.get(rootPath + "/wechat/member/user/getWechatPayConfig","",function(data){
    			if(data != null){
    			    wx.chooseWXPay({
    			    	 timestamp: data.timestamp,
    			    	 nonceStr: data.nonceStr,
    			    	 package: data.pkg,
    			    	 signType: 'MD5',
    			    	 paySign: data.paySign,
    			    	 success: function (res) {
    			    		 // 支付成功后的回调函数
    			    		 alert(res.err_msg);
    			    	 }
    			    });
    			}else{
    				alert("支付异常");
    			}
    		});
    	};
    
    	wx.error(function (res) {
    		alert(res.errMsg);
    	});
    });
    

      获取页签参考调用微信Js-SDK上传、预览图片,下面是后台获取支付签名等参数:

    public static WechatPayConfig getWechatPayConfig(String openId)
                throws Exception {
            WechatPayConfig config = new WechatPayConfig();
            config.setAppId(APPID);
            String timestamp = Long.toString(System.currentTimeMillis() / 1000);
            config.setTimestamp(timestamp);
            String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");
            config.setNonceStr(nonceStr);
    
            PayInfo payInfo = new PayInfo();
            payInfo.setAppid(APPID);
            payInfo.setMch_id(WEIXIN_MCH_ID);// 商户号
            payInfo.setDevice_info("WEB");// 设备号
            payInfo.setNonce_str(nonceStr);// 随机字符串
            payInfo.setBody("这是商品描述");// 商品描述
            payInfo.setOut_trade_no(nonceStr);// 商户订单号
            payInfo.setTotal_fee("1");// 支付金额
            payInfo.setSpbill_create_ip(InetAddress.getLocalHost().getHostAddress());// 终端IP
            payInfo.setNotify_url(PAY_CALL_BACK);// 接收微信支付异步通知回调地址
            payInfo.setTrade_type("JSAPI");// 交易类型
            payInfo.setOpenid(openId);// 用户标识
            payInfo.setSign(getSign(payInfo));// 签名
            logger.info(JsonMapper.toJsonString(payInfo));
            
            String paramesValue = MessageUtil.payInfoToXML(payInfo)
                    .replace("__", "_").replace("<![CDATA[", "").replace("]]>", "");
            Map<String, String> map = httpsRequestToXML(paramesValue);
            if (!map.get("return_code").equals("SUCCESS")) {
                logger.info("调用微信统一下单接口失败:" + map.get("return_msg"));
                return null;
            }
            logger.info("调用微信统一下单接口成功:");
            logger.info(map.toString());
            String pkg = "prepay_id=" + map.get("prepay_id");
            config.setPkg(pkg);
    
            String str = "appId=" + APPID + "&nonceStr=" + nonceStr + "&package="
                    + config.getPkg() + "&signType=MD5" + "&timeStamp=" + timestamp
                    + "&key=" + WEIXIN_KEY;
            logger.info("str:" + str);
    
            String paySign = MD5Util.MD5Encode(str, "UTF-8").toUpperCase();
            logger.info("paySign:" + paySign);
            config.setPaySign(paySign);
    
            return config;
    }
    public static String getSign(PayInfo payInfo) throws Exception {
            String signTemp = "appid=" + payInfo.getAppid() + "&body="
                    + payInfo.getBody() + "&device_info="
                    + payInfo.getDevice_info() + "&mch_id=" + payInfo.getMch_id()
                    + "&nonce_str=" + payInfo.getNonce_str() + "&notify_url="
                    + payInfo.getNotify_url() + "&openid=" + payInfo.getOpenid()
                    + "&out_trade_no=" + payInfo.getOut_trade_no()
                    + "&spbill_create_ip=" + payInfo.getSpbill_create_ip()
                    + "&total_fee=" + payInfo.getTotal_fee() + "&trade_type="
                    + payInfo.getTrade_type()
                    + "&key=" + WEIXIN_KEY; // 商户号API安全的API密钥
            String sign = MD5Util.MD5Encode(signTemp, "UTF-8").toUpperCase();
            return sign;
    }
    public static String payInfoToXML(PayInfo pi) {
            XStream xstream = new XStream();
            xstream.alias("xml", pi.getClass());
            return xstream.toXML(pi);
    }
    public static Map<String, String> httpsRequestToXML(String outputStr) {
            Map<String, String> result = new HashMap<>();
            try {
                StringBuffer buffer = httpsRequest(WeixinUtil.WEIXIN_UNIFIED_ORDER,
                        "POST", outputStr);
                result = MessageUtil.parseXml(buffer.toString());
            } catch (ConnectException ce) {
                logger.error("连接超时:" + ce.getMessage());
            } catch (Exception e) {
                logger.error("https请求异常:" + e.getMessage());
            }
            return result;
    }
    
    
    public static StringBuffer httpsRequest(String requestUrl,
                String requestMethod, String output) throws Exception {
            StringBuffer buffer = new StringBuffer();
            try {
                URL url = new URL(requestUrl);
                HttpsURLConnection connection = (HttpsURLConnection) url
                        .openConnection();
                connection.setConnectTimeout(30000); // 设置连接主机超时(单位:毫秒)
                connection.setReadTimeout(30000); // 设置从主机读取数据超时(单位:毫秒)
                connection.setDoOutput(true); // post请求参数要放在http正文内,顾设置成true,默认是false
                connection.setDoInput(true); // 设置是否从httpUrlConnection读入,默认情况下是true
                connection.setUseCaches(false); // Post 请求不能使用缓存
                // 设定传送的内容类型是可序列化的java对象(如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
                connection.setRequestProperty("Content-Type",
                        "application/x-www-form-urlencoded");
                connection.setRequestMethod(requestMethod);// 设定请求的方法为"POST",默认是GET
                connection.setRequestProperty("Content-Length", requestUrl.length()
                        + "");
                String encode = "utf-8";
                if (null != output) {
                    OutputStream outputStream = connection.getOutputStream();
                    outputStream.write(output.getBytes("UTF-8"));
                    outputStream.flush();
                    outputStream.close();
                }
                // 从输入流读取返回内容
                InputStream inputStream = connection.getInputStream();
                InputStreamReader inputStreamReader = new InputStreamReader(
                        inputStream, "utf-8");
                BufferedReader bufferedReader = new BufferedReader(
                        inputStreamReader);
                String str = null;
                while ((str = bufferedReader.readLine()) != null) {
                    buffer.append(str);
                }
                bufferedReader.close();
                inputStreamReader.close();
                inputStream.close();
                inputStream = null;
                connection.disconnect();
            } catch (Exception e) {
                logger.info("post请求调用统一下单接口异常" + e);
            }
            return buffer;
    }
    
    public static Map<String, String> parseXml(String xml) throws Exception {
             Map<String, String> map = new HashMap<String, String>();
             Document document = DocumentHelper.parseText(xml);
             Element root = document.getRootElement();
             List<Element> elementList = root.elements();
             for (Element e : elementList)
             map.put(e.getName(), e.getText());
             return map;
    }
    import java.security.MessageDigest;
    
    public class MD5Util {
    
        private static String byteArrayToHexString(byte b[]) {
            StringBuffer resultSb = new StringBuffer();
            for (int i = 0; i < b.length; i++)
                resultSb.append(byteToHexString(b[i]));
            return resultSb.toString();
        }
    
        private static String byteToHexString(byte b) {
            int n = b;
            if (n < 0)
                n += 256;
            int d1 = n / 16;
            int d2 = n % 16;
            return hexDigits[d1] + hexDigits[d2];
        }
    
        public static String MD5Encode(String origin, String charsetname) {
            String resultString = null;
            try {
                resultString = new String(origin);
                MessageDigest md = MessageDigest.getInstance("MD5");
                if (charsetname == null || "".equals(charsetname))
                    resultString = byteArrayToHexString(md.digest(resultString
                            .getBytes()));
                else
                    resultString = byteArrayToHexString(md.digest(resultString
                            .getBytes(charsetname)));
            } catch (Exception exception) {
            }
            return resultString;
        }
    
        private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
                "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
    
    }

    步骤:

    1.获取页签,只有成功获取了页签,才能调微信Js-SDK下的API

    2.调统一支付也叫统一下单接口,出入都是一个xml,成功会返回:

    {
      result_code=SUCCESS,
      sign=3E5062C1CCBBF020628280A9E6CDE9E9,
      mch_id=10022311,
      prepay_id=wx201511170958368f617c0d5f0988190603,
      return_msg=OK,
      appid=wx3d407f02f5d3dd63,
      nonce_str=Fl2ViAVbdwQdZSQz,
      return_code=SUCCESS,
      device_info=WEB,
      trade_type=JSAPI
    }

    其中prepay_id=wx201511181358442e0bc083190380094951就是package的值

    3.最后用appId、nonceStr、package、signType、timeStamp、key 6个参数得到paySign的值

  • 相关阅读:
    事务的特性(ACID)
    网络代理
    防止SpringMVC拦截器拦截js等静态资源文件
    Tomcat配置虚拟目录
    SpringMVC总结(SSM)
    Spring声明式事务总结
    Linux中MySQL忽略表中字段大小写
    MySQL之sql文件的导入导出
    MyBatis总结
    Linux网络
  • 原文地址:https://www.cnblogs.com/linying/p/4974559.html
Copyright © 2011-2022 走看看