微信公众号、APP微信支付

微信公众号微信支付(需具备微信支付权限 - https://mp.weixin.qq.com申请)

1、【基本配置】配置开发者服务器

2、右上角点击公众号名称,【功能设置】业务域名、JS接口安全域名

3、【接口权限】-【网页账号】设置域名

4、【微信支付】-【开发配置】-【支付授权目录】,配置你支付页面所在路径

比如我的路径是 http://XXXX/third_pay/weixin/wxpay_test.html;需要在此处配置 http://XXXX/third_pay/weixin

(如果是配置测试授权目录,还需要配置测试白名单,就是你要进行微信支付测试的帐号)


APP微信支付(需具备微信支付权限 - https://open.weixin.qq.com申请)


以下内容复制完,应该就能行了~


1、服务端方法

Controller

@RequestMapping("/initWechatConfig.xhtml")
	public void initWechatConfig(HttpServletRequest request, HttpServletResponse response) throws Exception {
		try {
			String initType = getParams("initType");//request.getParameter("initType");
			if (CommonUtil.isNull(initType)) {
				throw new BizException(ErrorMsg.PARAMS_NULL);
			}
			if ("jsapi".equals(initType)) {//只有公众号微信支付才会调用该类型
				HashMap<String, Object> respMap = new HashMap<String, Object>();
				String initUrl = getParams("initUrl");//当前网页地址
				if (CommonUtil.isNull(initUrl)) {
					throw new BizException(ErrorMsg.PARAMS_NULL);
				}
				String noncestr = WxPayUtil.CreateNoncestr();
				String timestamp = DateUtil.getTimestampWx();
				String signature = null;
				//获取
				String appId = Constants.GZH_APPID;
				Ticket ticket = getJsapiTicket(appId);
				signature = SHA1Util.signForJsapiTicket(ticket.getTicket(), noncestr, timestamp, initUrl);
				respMap.put("appId", appId);
				respMap.put("timestamp", timestamp);
				respMap.put("nonceStr", noncestr);
				respMap.put("signature", signature);
				writeSuccMsg(response, respMap);
			} else if ("pay".equals(initType) || "appPay".equals(initType)) {//pay 网页端;appPay app端
				//校验必要参数
				String outTradeNo = getParams("outTradeNo");
				//根据outTradeNo获取订单信息
				//...
				Double totalFee = 0.01;
				String body = "body";
				//校验必要参数
				
				//根据支付类型生成预订单
				String openId = <span style="font-family: Arial, Helvetica, sans-serif;">getParams</span><span style="font-family: Arial, Helvetica, sans-serif;">("openId");</span>
				if ("pay".equals(initType) && CommonUtil.isNull(openId)) {//网页端微信支付,必定有openId
					throw new BizException(ErrorMsg.PARAMS_NULL);
				}
				String createIp = null//获取IP地址;
				
				//封装信息后,初始化微信预订单
				log.info("********************************************************************");
				
				String appId = null;
				String mchId = null;
				String key = null;
				String tradeType = null;
				if ("pay".equals(initType)) {
					tradeType = "JSAPI";
					appId = Constants.GZH_APPID;
					mchId = Constants.GZH_PAY_MCHID;
					key = Constants.GZH_PAY_KEY;
				} else if ("appPay".equals(initType)) {
					tradeType = "APP";
					appId = Constants.APP_APPID;
					mchId = Constants.APP_PAY_MCHID;
					key = Constants.APP_PAY_KEY;
				}
				String notify_url = Constants.UNIFIED_THIRD_PAY_NOTIFY_BROKER;
				log.info("微信支付 - 回调地址:" + notify_url);
				ThirdPayVo payVo = WxPayUtil.getPayElement(initType, appId, mchId, key, tradeType, outTradeNo, body, createIp, openId, totalFee, notify_url);
				if (CommonUtil.isNull(payVo)) {
					throw new BizException(ErrorMsg.PAY_INIT_FAIL);
				}
				writeSuccMsg(response, payVo);
			} else {
				throw new BizException(ErrorMsg.PARAMS_NULL);
			}
		} catch (Exception e) {
			log.error("初始化微信配置 异常:", e);
			writeErrorMsg(response, e.getMessage());
		}
	}
获取access_token、jsapi_ticket等就自己去看API了,很简单~

(获取access_token需要注意区分全局access_token和绑定openid的access_token)

writeSuccMsg

response.setCharacterEncoding("utf-8");
		response.setContentType("text/json");
		PrintWriter out = null;
		try {
			out = response.getWriter();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		String jsonstr = JSON.toJSONString(jsonEntity);
		out.print(jsonstr);


-----------------------------------------------util包----------------------------------------------------

1、SHA1Util方法

public class SHA1Util {
	public static String signForJsapiTicket(String jsapiTicket, String noncestr, String timestamp, String initUrl) {
		String signature = null;
		// 注意这里参数名必须全部小写,且必须有序  jsapi_ticket=JSAPI_TICKET&noncestr=NONCESTR&timestamp=TIMESTAMP&url=INIT_URL
		String signatureStr = Constants.ticket_url_params;
		signatureStr = signatureStr.replace("JSAPI_TICKET", jsapiTicket);
		signatureStr = signatureStr.replace("NONCESTR", noncestr);
		signatureStr = signatureStr.replace("TIMESTAMP", timestamp);
		signatureStr = signatureStr.replace("INIT_URL", initUrl);
		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(signatureStr.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return signature;
	}

	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}
}
3、WxPayUtil

public class WxPayUtil {

	/**
	 * 
	 */
	protected final static Logger log = LoggerFactory.getLogger(WxPayUtil.class);

	public static String CreateNoncestr(int length) {
		String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		String res = "";
		for (int i = 0; i < length; i++) {
			Random rd = new Random();
			res += chars.indexOf(rd.nextInt(chars.length() - 1));
		}
		return res;
	}

	public static String CreateNoncestr() {
		String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		String res = "";
		for (int i = 0; i < 16; i++) {
			Random rd = new Random();
			res += chars.charAt(rd.nextInt(chars.length() - 1));
		}
		return res;
	}

	public static String FormatQueryParaMap(HashMap<String, String> parameters) throws SDKRuntimeException {

		String buff = "";
		try {
			List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(parameters.entrySet());

			Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
				public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
					return (o1.getKey()).toString().compareTo(o2.getKey());
				}
			});

			for (int i = 0; i < infoIds.size(); i++) {
				Map.Entry<String, String> item = infoIds.get(i);
				if (item.getKey() != "") {
					buff += item.getKey() + "=" + URLEncoder.encode(item.getValue(), "utf-8") + "&";
				}
			}
			if (buff.isEmpty() == false) {
				buff = buff.substring(0, buff.length() - 1);
			}
		} catch (Exception e) {
			throw new SDKRuntimeException(e.getMessage());
		}

		return buff;
	}

	public static String FormatBizQueryParaMap(HashMap<String, String> paraMap, boolean urlencode)
			throws SDKRuntimeException {

		String buff = "";
		try {
			List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(paraMap.entrySet());

			Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
				public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
					return (o1.getKey()).toString().compareTo(o2.getKey().toString());
				}
			});

			for (int i = 0; i < infoIds.size(); i++) {
				Map.Entry<String, String> item = infoIds.get(i);
				// System.out.println(item.getKey());
				if (item.getKey() != "") {

					String key = item.getKey();
					String val = item.getValue();
					if (urlencode) {
						val = URLEncoder.encode(val, "utf-8");

					}
					buff += key.toLowerCase() + "=" + val + "&";

				}
			}

			if (buff.isEmpty() == false) {
				buff = buff.substring(0, buff.length() - 1);
			}
		} catch (Exception e) {
			throw new SDKRuntimeException(e.getMessage());
		}
		return buff;
	}

	public static boolean IsNumeric(String str) {
		if (str.matches("\\d *")) {
			return true;
		} else {
			return false;
		}
	}

	public static String toXml(Map<String, String> arr) {
		String xml = "<xml>";
		Iterator<Entry<String, String>> iter = arr.entrySet().iterator();
		while (iter.hasNext()) {
			Entry<String, String> entry = iter.next();
			String key = entry.getKey();
			String val = entry.getValue();
			if (IsNumeric(val)) {
				xml += "<" + key + ">" + val + "</" + key + ">";

			} else
				xml += "<" + key + "><![CDATA[" + val + "]]></" + key + ">";
		}
		xml += "</xml>";
		return xml;
	}
	
	public static String mapToXMl(Map<String, String> map) {
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement("xml");
		Set<String> set = map.keySet();
		for (String s : set) {
			Element e = root.addElement(s);
			e.addCDATA(map.get(s));
		}
		try {
			//return new String(doc.asXML().getBytes(), "utf-8");
			return new String(doc.asXML().getBytes(), "ISO8859-1");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		// return doc.asXML();
		return null;
		/*return doc.asXML();*/
	}

	public static String GetBizSign(Map<String, String> bizObj, String key) throws SDKRuntimeException {
		HashMap<String, String> bizParameters = new HashMap<String, String>();

		List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(bizObj.entrySet());

		Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
			public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
				return (o1.getKey()).toString().compareTo(o2.getKey());
			}
		});
		for (int i = 0; i < infoIds.size(); i++) {
			Map.Entry<String, String> item = infoIds.get(i);
			if (!"".equals(item.getKey())) {
				bizParameters.put(item.getKey().toLowerCase(), item.getValue());
			}
		}
		if (key == "") {
			throw new SDKRuntimeException("key为空!");
		}
		String bizString = FormatBizQueryParaMap(bizParameters, false);
		return MD5SignUtil.Sign(bizString, key);
	}

	/**
	 * 公众号微信支付
	 * @author ershuai
	 * @date 2016年7月18日 下午3:53:52 
	 * @version V1.0 
	 * @param appId
	 * @param noncestr
	 * @param packagestr
	 * @param singType
	 * @param timestamp
	 * @param key
	 * @return
	 * @throws SDKRuntimeException
	 */
	public static String GetPaySignForGzh(String appId, String noncestr, String packagestr, String singType, String timestamp, String key) throws SDKRuntimeException {
		String payString = "appId="+appId+"&nonceStr="+noncestr+"&package="+packagestr+"&signType="+singType+"&timeStamp="+timestamp;
		log.info("公众号支付签名串:" + payString);
		return MD5SignUtil.Sign(payString, key);
	}
	
	/**
	 * APP微信支付
	 * @author ershuai
	 * @date 2016年7月18日 下午3:55:21 
	 * @version V1.0 
	 * @param appId
	 * @param noncestr
	 * @param packagestr
	 * @param partnerId
	 * @param prepayId
	 * @param timestamp
	 * @param key
	 * @return
	 * @throws SDKRuntimeException
	 */
	public static String GetPaySignForApp(String appId, String noncestr, String packagestr, String partnerId, String prepayId, String timestamp, String key) throws SDKRuntimeException {
		//String payString = "appId="+appId+"&nonceStr="+noncestr+"&package="+packagestr+"&partnerId="+partnerId+"&prepayId="+prepayId+"&timeStamp=" + timestamp;
		String payString = "appid="+appId+"&noncestr="+noncestr+"&package="+packagestr+"&partnerid="+partnerId+"&prepayid="+prepayId+"×tamp=" + timestamp;
		log.info("APP支付签名串:" + payString);
		return MD5SignUtil.Sign(payString, key);
	}
	
	/**
	 * 
	 * @author ershuai
	 * @date 2016年7月5日 上午11:22:24 
	 * @version V1.0 
	 * @param resultCode
	 * @param returnMsg
	 * @return
	 */
	public static String getXMLString(String resultCode, String returnMsg) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("return_code", resultCode);
		map.put("return_msg", returnMsg);
		return getXMLString(map);
	}
	
	/**
	 * map转xml
	 * @author ershuai
	 * @date 2016年7月5日 上午11:21:55 
	 * @version V1.0 
	 * @param map
	 * @return
	 */
	public static String getXMLString(Map<String, String> map) {
		// Pattern pattern = Pattern.compile("^[0-9.]$");
		StringBuffer sb = new StringBuffer();
		sb.append("<xml version=\"1.0\" encoding=\"utf-8\">");
		// String sign = map.get("sign");
		if (map != null && !map.isEmpty()) {
			Iterator<String> it = map.keySet().iterator();
			while (it.hasNext()) {
				String key = it.next();
				String value = map.get(key);
				// if(!pattern.matcher(value).matches()){
				sb.append("<" + key + ">").append(value).append("</" + key + ">");
				// }else{
				// sb.append("<" + key +
				// ">").append("<![CDATA["+value+"]]>").append("</" + key +
				// ">");
				// }
			}
		}
		// sb.append("<sign>").append(sign).append("</sign>");
		sb.append("</xml>");
		try {
			return new String(sb.toString().getBytes(), "utf-8");
		} catch (UnsupportedEncodingException e) {
		}
		String xmlStr = sb.toString();
		log.info("getXMLString:" + xmlStr);
		return xmlStr;
	}
	
	/**
	 * 统一xml解析
	 * @author ershuai
	 * @date 2016年7月5日 上午11:18:45 
	 * @version V1.0 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
		// 将解析结果存储在HashMap中
		Map<String, String> map = new HashMap<String, String>();

		// 从request中取得输入流
		InputStream inputStream = request.getInputStream();
		// 读取输入流
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		// 得到xml根元素
		Element root = document.getRootElement();
		// 得到根元素的所有子节点
		@SuppressWarnings("unchecked")
		List<Element> elementList = root.elements();

		// 遍历所有子节点
		for (Element e : elementList) {
			map.put(e.getName(), e.getText());
			log.info("e.getName():"+e.getName());
			log.info("e.getText():"+e.getText());
		}
		
		// 释放资源
		inputStream.close();
		inputStream = null;

		return map;
	}
	
	/**
	 * 生成预订单
	 * @author ershuai
	 * @date 2016年7月20日 下午4:07:09 
	 * @version V1.0 
	 * @param initType
	 * @param appId
	 * @param mchId
	 * @param key
	 * @param tradeType
	 * @param outTradeNo
	 * @param body
	 * @param createIp
	 * @param openId
	 * @param totalFee
	 * @param notifyUrl
	 * @return
	 * @throws Exception
	 */
	public static ThirdPayVo getPayElement(String initType, String appId, String mchId, String key, String tradeType, String outTradeNo, String body, String createIp, String openId, Double totalFee, String notifyUrl) throws Exception {
		
		Map<String,String> params = new HashMap<String, String>();
		String noncestr = CreateNoncestr();
		
		params.put("appid", appId);
		params.put("mch_id", mchId);
		params.put("nonce_str", noncestr);
		params.put("body", body);
		params.put("input_charset", "UTF-8");
		params.put("out_trade_no", outTradeNo);
		params.put("total_fee", NumberUtil.formatNumber(totalFee * 100, NumberUtil.NUMBER_IN));
		
		params.put("spbill_create_ip", createIp);
		//params.put("notify_url", !CommonUtil.isNull(notifyUrl) ? notifyUrl : notifyUrl);
		params.put("notify_url", notifyUrl);
		params.put("trade_type", tradeType);
		params.put("fee_type", "CNY");
		if (!CommonUtil.isNull(openId)) {
			params.put("openid", openId);
		}
		String sign = GetBizSign(params, key);
		params.put("sign", sign);
		log.info("微信预订单参数:" + params);
		
		String xmlStr = toXml(params);
		String result = HttpClientUtil.httpsRequest(Constants.unified_order_url_v3, xmlStr);
		
		log.info("\n wechat getPayElement json \n:" + result + " \n");
		Document document = DocumentHelper.parseText(result);
		Element res = document.getRootElement().element("prepay_id");
		ThirdPayVo initVo = null;
		if (!CommonUtil.isNull(res)) {
			initVo = new ThirdPayVo();
			initVo.setPrepayId(res.getText());
			initVo.setOutTradeNo(outTradeNo);
			initVo.setTimestamp(DateUtil.getTimestampWx());//Long.toString(System.currentTimeMillis() / 1000)
			initVo.setNonceStr(noncestr);
			initVo.setSignType(Constants.SING_TYPE);//MD5
			
			String paySign = null;
			if ("pay".equals(initType)) {
				initVo.setPackagestr("prepay_id=" + initVo.getPrepayId());
				//获取签名
				paySign = GetPaySignForGzh(appId, noncestr, initVo.getPackagestr(), initVo.getSignType(), initVo.getTimestamp(), key);
			} else if ("appPay".equals(initType)) {//app微信支付,需要返回mchId和appId
				initVo.setAppId(appId);
				initVo.setMchId(mchId);
				initVo.setPackagestr("Sign=WXPay");//<span style="font-family: Arial, Helvetica, sans-serif;">APP微信支付是写死的;</span>
				
				//获取签名
				paySign = GetPaySignForApp(appId, noncestr, initVo.getPackagestr(), initVo.getMchId(), initVo.getPrepayId(), initVo.getTimestamp(), key);
			}
			initVo.setPaySign(paySign);
			log.info("返回内容:" + JSON.toJSONString(initVo));
		}
		return initVo;
	}
}
2、MD5SignUtil

public class MD5SignUtil {
	
	public static String Sign(String content, String key)
			throws SDKRuntimeException {
		String signStr = "";

		if ("".equals(key)) {
			throw new SDKRuntimeException("签名key不能为空!");
		}
		if ("".equals(content)) {
			throw new SDKRuntimeException("签名内容不能为空!");
		}
		signStr = content + "&key=" + key;
		return MD5Util.MD5(signStr).toUpperCase();

	}
	
	public static boolean VerifySignature(String content, String sign, String md5Key) {
		String signStr = content + "&key=" + md5Key;
		String calculateSign = MD5Util.MD5(signStr).toUpperCase();
		String tenpaySign = sign.toUpperCase();
		return (calculateSign == tenpaySign);
	}
}
3、MD5Util

public class MD5Util {

	public final static String MD5(String s) {
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		try {
			//中文md5不一致
			//byte[] btInput = s.getBytes();
			//中文md5不一致
			
			//中文md5一致
			byte[] btInput=null;
	        try {
	        	btInput = s.getBytes("utf-8");
	        } catch (UnsupportedEncodingException e) {
	            e.printStackTrace();
	        }
			//中文md5一致
	        
			// 获得MD5摘要算法的 MessageDigest 对象
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			// 使用指定的字节更新摘要
			mdInst.update(btInput);
			// 获得密文
			byte[] md = mdInst.digest();
			// 把密文转换成十六进制的字符串形式
			int j = md.length;
			char str[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(str);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static void main(String[] args) {
		String md5Str = MD5Util.MD5("中文-我长得帅");
		System.out.println("加密:" + md5Str);
	}
}


4、SDKRuntimeException

public class SDKRuntimeException extends Exception {
	
	private static final long serialVersionUID = 1L;

	public SDKRuntimeException(String str) {
	        super(str);
	 }
}

-----------------------------------------------util包----------------------------------------------------


微信支付回调

@RequestMapping(value = "/notifyWxPay.xhtml")
	public void notifyWxPay(final HttpServletRequest request,final HttpServletResponse response) {
		String resultCode = "FAIL";
		String resultMsg = "this's error";
		try {
			log.info("**************************** 微信 服务订单 回调 开始 "+(new Timestamp(System.currentTimeMillis()))+" ************************************");
			//获取微信回调信息
			Map<String, String> requestParams = WxPayUtil.parseXml(request);
			//return_code
			String return_code =  requestParams.get("return_code");
			//result_code
			String result_code =  requestParams.get("result_code");
			log.info("return_code:" + return_code);
			log.info("result_code:" + result_code);
			if ("SUCCESS".equals(result_code)&&"SUCCESS".equals(return_code)) {//成功回调
				log.info("SUCCESS");
			} else {//错误回调
				log.info("FAIL");
			}
		} catch (Exception e) {
			log.error("notifyInsurancePay 微信支付 服务订单 回调 异常:", e);
		}
		if ("SUCCESS".equals(resultCode)) {
			log.info("**************************** 服务订单 回调成功  "+(new Timestamp(System.currentTimeMillis()))+" **********************");
		} else {
			log.info("**************************** 服务订单 回调失败  "+(new Timestamp(System.currentTimeMillis()))+" **********************");
		}
		log.info("resultCode:" + resultCode);
		log.info("resultMsg:" + resultMsg);
		Map<String, String> map = new HashMap<String, String>();
		map.put("return_code", resultCode);
		map.put("return_msg", resultMsg);
		String notifyXml = WxPayUtil.toXml(map);
		log.info("notifyXml after:" + notifyXml);
		try {
			notifyXml = new String(notifyXml.getBytes(), "ISO8859-1");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			log.error("notifyInsurancePay 微信支付 服务订单 回调 返回编码 异常:", e);
		}
		log.info("notifyXml:" + notifyXml);
		writeSuccMsg(response, notifyXml);
	}



上面的搞完了,服务端就完事了

接下来写网页

1、wxpay_test.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<meta name="author" content="ershuai" />
<link rel="shortcut icon" href="../../images/zds.ico" type="image/x-icon">

<title>二帅</title>

<script type="text/javascript" src="../../scripts/common/common.js"></script>
<script type="text/javascript" src="../../scripts/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script><!-- 必须引入的JS文件 -->
<script type="text/javascript" src="../../scripts/common/weixin/weixin_common.js"></script>

<link type="text/css" href="../../styles/common/common_phone.css" rel="stylesheet" />

</head>
<body>
	<input type="button" id="test_pay" value="微信支付测试" />
</body>
<script type="text/javascript">
	$("#test_pay").on("click", function() {
		console.log('微信支付测试…begin…');
		var initUrl = window.location.href;
		initOrder(initUrl, '测试订单ID');
	});
</script>
</html>

2、common.js

/**
 * 获取参数
 * @param paramsName
 * @returns
 */
function GetParams(paramsName) {
	var addr = window.location;
	if (addr != null && addr != '') {
		var reg = new RegExp("(^|&)" + paramsName + "=([^&]*)(&|$)");
		var r = addr.search.substr(1).match(reg);
		if (r != null && r != '') {
			return decodeURI(r[2]);
		} else {
			null;
		}
	} else {
		return null;
	}
}

/**
 * 判断是否微信浏览器
 * @returns {Boolean}
 */
function isWeiXin() {
	var ua = window.navigator.userAgent.toLowerCase();
	if(ua.match(/MicroMessenger/i) == 'micromessenger'){
		return true;
	} else {
		return false;
	}
}
3、weixin_common.js
/**
 * 初始化	微信支付	jsapi
 * @param initUrl		当前初始化网页地址
 * @param outTradeNo	需要支付订单ID
 */
function initOrder(initUrl, outTradeNo) {
	if (!isWeiXin()) {
		hintDiv(null, '请在微信浏览器中打开');
		return false;
	}
	//弹起遮盖
	loading('正在初始化,请稍后…');
	$.ajax({
		async: false,
		type : "post",
		url : weixin_conf_url,
		data : {
			"initUrl" : initUrl,
			"initType" : "jsapi"
		},
		dataType : "json",
		error : function(request) {
			alert('初始化失败');
		},
		success : function(ajaxRes) {
			closeAllIndex();
			var state = ajaxRes.state;
			if (state == 1) {
				var data = ajaxRes.data;
				//初始化微信配置
				wxPayConfig(data.appId, data.timestamp, data.nonceStr, data.signature);
				//支付准备
				return wxPayReady(outTradeNo);
			} else {
				hintDiv(null, ajaxRes.msg);
				return false;
			}
		}
	});
};

/**
 * 初始化微信配置
 * @param appId
 * @param timestamp
 * @param nonceStr
 * @param signature
 */
function wxPayConfig(appId, timestamp, nonceStr, signature) {
	wx.config({
		debug: true,
		appId: appId,
		timestamp: timestamp,
		nonceStr: nonceStr,
		signature: signature,
		jsApiList: [
			'checkJsApi',
	        'chooseWXPay',
		]
	});
	
	wx.error(function (res) {
		alert(res.errMsg);
	});
}

/**
 * 支付准备
 * @param data
 */
function wxPayReady(outTradeNo) {
	var openId = GetParams("openId");
	if (openId == null || openId == '') {
		hintDiv(null, '校验错误,请在微信端打开');
		return;
	}
	//弹起遮盖
	loading('正在生成预订单,请稍后…');
	$.ajax({
		async: false,
		type : "post",
		url : weixin_conf_url,
		data : {
			"outTradeNo" : outTradeNo,
			"initType" : "pay",
			"payWay" : "jsapi",
			"openId": openId
		},
		dataType : "json",
		error : function(request) {
			hintDiv(null, '生成预订单失败');
			return;
		},
		success : function(ajaxRes) {
			closeAllIndex();
			if (ajaxRes.state == 1) {
				var data = ajaxRes.data;
				wx.chooseWXPay({
				    timestamp: data.timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
				    nonceStr: data.nonceStr, // 支付签名随机串,不长于 32 位
				    package: data.packagestr, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
				    signType: data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
				    paySign: data.paySign, // 支付签名
			    	success: function (res) {
                        if(res.errMsg == "chooseWXPay:ok" ) {
                        	//hintDiv(null, '支付成功');
                        	return true;
                        } else {
                        	//hintDiv(null, '支付错误:'  + res.errMsg);
                        	return false;
                        }
			        }
				});
			} else {
				hintDiv(null, ajaxRes.msg);
            	return false;
			}
		}
	});
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值