频道栏目
首页 > 资讯 > 微信公众平台开发 > 正文

微信公众号、APP微信支付

16-08-12        来源:[db:作者]  
收藏   我要投稿

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 respMap = new HashMap();
				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 = getParams("openId");
				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×tamp=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 parameters) throws SDKRuntimeException {
    
    		String buff = "";
    		try {
    			List<>> infoIds = new ArrayList<>>(parameters.entrySet());
    
    			Collections.sort(infoIds, new Comparator<>>() {
    				public int compare(Map.Entry o1, Map.Entry o2) {
    					return (o1.getKey()).toString().compareTo(o2.getKey());
    				}
    			});
    
    			for (int i = 0; i < infoIds.size(); i++) {
    				Map.Entry 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 paraMap, boolean urlencode)
    			throws SDKRuntimeException {
    
    		String buff = "";
    		try {
    			List<>> infoIds = new ArrayList<>>(paraMap.entrySet());
    
    			Collections.sort(infoIds, new Comparator<>>() {
    				public int compare(Map.Entry o1, Map.Entry o2) {
    					return (o1.getKey()).toString().compareTo(o2.getKey().toString());
    				}
    			});
    
    			for (int i = 0; i < infoIds.size(); i++) {
    				Map.Entry 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 arr) {
    		String xml = "&quot;;
    		Iterator<>> iter = arr.entrySet().iterator();
    		while (iter.hasNext()) {
    			Entry entry = iter.next();
    			String key = entry.getKey();
    			String val = entry.getValue();
    			if (IsNumeric(val)) {
    				xml += &quot;<" else="" key="" public="" return="" static="" string="" val="" xml=""> map) {
    		Document doc = DocumentHelper.createDocument();
    		Element root = doc.addElement(&quot;xml&quot;);
    		Set set = map.keySet();
    		for (String s : set) {
    			Element e = root.addElement(s);
    			e.addCDATA(map.get(s));
    		}
    		try {
    			//return new String(doc.asXML().getBytes(), &quot;utf-8&quot;);
    			return new String(doc.asXML().getBytes(), &quot;ISO8859-1&quot;);
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    		}
    		// return doc.asXML();
    		return null;
    		/*return doc.asXML();*/
    	}
    
    	public static String GetBizSign(Map bizObj, String key) throws SDKRuntimeException {
    		HashMap bizParameters = new HashMap();
    
    		List<>> infoIds = new ArrayList<>>(bizObj.entrySet());
    
    		Collections.sort(infoIds, new Comparator<>>() {
    			public int compare(Map.Entry o1, Map.Entry o2) {
    				return (o1.getKey()).toString().compareTo(o2.getKey());
    			}
    		});
    		for (int i = 0; i < infoIds.size(); i++) {
    			Map.Entry item = infoIds.get(i);
    			if (!&quot;&quot;.equals(item.getKey())) {
    				bizParameters.put(item.getKey().toLowerCase(), item.getValue());
    			}
    		}
    		if (key == &quot;&quot;) {
    			throw new SDKRuntimeException(&quot;key为空!&quot;);
    		}
    		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 = &quot;appId=&quot;+appId+&quot;&nonceStr=&quot;+noncestr+&quot;&package=&quot;+packagestr+&quot;&signType=&quot;+singType+&quot;&timeStamp=&quot;+timestamp;
    		log.info(&quot;公众号支付签名串:&quot; + 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 = &quot;appId=&quot;+appId+&quot;&nonceStr=&quot;+noncestr+&quot;&package=&quot;+packagestr+&quot;&partnerId=&quot;+partnerId+&quot;&prepayId=&quot;+prepayId+&quot;&timeStamp=&quot; + timestamp;
    		String payString = &quot;appid=&quot;+appId+&quot;&noncestr=&quot;+noncestr+&quot;&package=&quot;+packagestr+&quot;&partnerid=&quot;+partnerId+&quot;&prepayid=&quot;+prepayId+&quot;&times;tamp=&quot; + timestamp;
    		log.info(&quot;APP支付签名串:&quot; + 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 map = new HashMap();
    		map.put(&quot;return_code&quot;, resultCode);
    		map.put(&quot;return_msg&quot;, 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 map) {
    		// Pattern pattern = Pattern.compile(&quot;^[0-9.]$&quot;);
    		StringBuffer sb = new StringBuffer();
    		sb.append(&quot;&quot;);
    		// String sign = map.get(&quot;sign&quot;);
    		if (map != null && !map.isEmpty()) {
    			Iterator it = map.keySet().iterator();
    			while (it.hasNext()) {
    				String key = it.next();
    				String value = map.get(key);
    				// if(!pattern.matcher(value).matches()){
    				sb.append(&quot;<" 11:18:45="" author="" catch="" date="" ershuai="" exception="" key="" new="" param="" public="" request="" return="" static="" string="" throws="" try="" unsupportedencodingexception="" v1.0="" version="" xmlstr="sb.toString();"> parseXml(HttpServletRequest request) throws Exception {
    		// 将解析结果存储在HashMap中
    		Map map = new HashMap();
    
    		// 从request中取得输入流
    		InputStream inputStream = request.getInputStream();
    		// 读取输入流
    		SAXReader reader = new SAXReader();
    		Document document = reader.read(inputStream);
    		// 得到xml根元素
    		Element root = document.getRootElement();
    		// 得到根元素的所有子节点
    		@SuppressWarnings(&quot;unchecked&quot;)
    		List elementList = root.elements();
    
    		// 遍历所有子节点
    		for (Element e : elementList) {
    			map.put(e.getName(), e.getText());
    			log.info(&quot;e.getName():&quot;+e.getName());
    			log.info(&quot;e.getText():&quot;+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 params = new HashMap();
    		String noncestr = CreateNoncestr();
    		
    		params.put(&quot;appid&quot;, appId);
    		params.put(&quot;mch_id&quot;, mchId);
    		params.put(&quot;nonce_str&quot;, noncestr);
    		params.put(&quot;body&quot;, body);
    		params.put(&quot;input_charset&quot;, &quot;UTF-8&quot;);
    		params.put(&quot;out_trade_no&quot;, outTradeNo);
    		params.put(&quot;total_fee&quot;, NumberUtil.formatNumber(totalFee * 100, NumberUtil.NUMBER_IN));
    		
    		params.put(&quot;spbill_create_ip&quot;, createIp);
    		//params.put(&quot;notify_url&quot;, !CommonUtil.isNull(notifyUrl) ? notifyUrl : notifyUrl);
    		params.put(&quot;notify_url&quot;, notifyUrl);
    		params.put(&quot;trade_type&quot;, tradeType);
    		params.put(&quot;fee_type&quot;, &quot;CNY&quot;);
    		if (!CommonUtil.isNull(openId)) {
    			params.put(&quot;openid&quot;, openId);
    		}
    		String sign = GetBizSign(params, key);
    		params.put(&quot;sign&quot;, sign);
    		log.info(&quot;微信预订单参数:&quot; + params);
    		
    		String xmlStr = toXml(params);
    		String result = HttpClientUtil.httpsRequest(Constants.unified_order_url_v3, xmlStr);
    		
    		log.info(&quot;\n wechat getPayElement json \n:&quot; + result + &quot; \n&quot;);
    		Document document = DocumentHelper.parseText(result);
    		Element res = document.getRootElement().element(&quot;prepay_id&quot;);
    		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 (&quot;pay&quot;.equals(initType)) {
    				initVo.setPackagestr(&quot;prepay_id=&quot; + initVo.getPrepayId());
    				//获取签名
    				paySign = GetPaySignForGzh(appId, noncestr, initVo.getPackagestr(), initVo.getSignType(), initVo.getTimestamp(), key);
    			} else if (&quot;appPay&quot;.equals(initType)) {//app微信支付,需要返回mchId和appId
    				initVo.setAppId(appId);
    				initVo.setMchId(mchId);
    				initVo.setPackagestr(&quot;Sign=WXPay&quot;);//APP微信支付是写死的;
    				
    				//获取签名
    				paySign = GetPaySignForApp(appId, noncestr, initVo.getPackagestr(), initVo.getMchId(), initVo.getPrepayId(), initVo.getTimestamp(), key);
    			}
    			initVo.setPaySign(paySign);
    			log.info(&quot;返回内容:&quot; + 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 {
    			byte[] btInput = s.getBytes();
    			// 获得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;
    		}
    	}
    
    	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" };
    }
    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<><><><><><><><" else="" key="" public="" return="" static="" string="" val="" xml=""><><><><" 11:18:45="" author="" catch="" date="" ershuai="" exception="" key="" new="" param="" public="" request="" return="" static="" string="" throws="" try="" unsupportedencodingexception="" v1.0="" version="" xmlstr="sb.toString();"> requestParams = WxPayUtil.parseXml(request);
    			//return_code
    			String return_code =  requestParams.get(&quot;return_code&quot;);
    			//result_code
    			String result_code =  requestParams.get(&quot;result_code&quot;);
    			log.info(&quot;return_code:&quot; + return_code);
    			log.info(&quot;result_code:&quot; + result_code);
    			if (&quot;SUCCESS&quot;.equals(result_code)&&&quot;SUCCESS&quot;.equals(return_code)) {//成功回调
    				log.info(&quot;SUCCESS&quot;);
    			} else {//错误回调
    				log.info(&quot;FAIL&quot;);
    			}
    		} catch (Exception e) {
    			log.error(&quot;notifyInsurancePay 微信支付 服务订单 回调 异常:&quot;, e);
    		}
    		if (&quot;SUCCESS&quot;.equals(resultCode)) {
    			log.info(&quot;**************************** 服务订单 回调成功  &quot;+(new Timestamp(System.currentTimeMillis()))+&quot; **********************&quot;);
    		} else {
    			log.info(&quot;**************************** 服务订单 回调失败  &quot;+(new Timestamp(System.currentTimeMillis()))+&quot; **********************&quot;);
    		}
    		log.info(&quot;resultCode:&quot; + resultCode);
    		log.info(&quot;resultMsg:&quot; + resultMsg);
    		Map map = new HashMap();
    		map.put(&quot;return_code&quot;, resultCode);
    		map.put(&quot;return_msg&quot;, resultMsg);
    		String notifyXml = WxPayUtil.toXml(map);
    		log.info(&quot;notifyXml after:&quot; + notifyXml);
    		try {
    			notifyXml = new String(notifyXml.getBytes(), &quot;ISO8859-1&quot;);
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    			log.error(&quot;notifyInsurancePay 微信支付 服务订单 回调 返回编码 异常:&quot;, e);
    		}
    		log.info(&quot;notifyXml:&quot; + notifyXml);
    		writeSuccMsg(response, notifyXml);
    	}


     

     

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

    接下来写网页

    1、wxpay_test.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;
    			}
    		}
    	});
    }
相关TAG标签
上一篇:微信开发束缚了你的思想
下一篇:致内容创业者:你期待的内容付费,目前还与你无关
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站