微信公众号开发之微信支付

微信公众号开发之微信支付

1、简要思路图

微信公众号开发之微信支付_第1张图片

2、添加支付授权目录

微信公众号开发之微信支付_第2张图片

3、页面调用

function onBridgeReady(){
	var params={};
	params["appId"]=$("#appId").val();
	params["timeStamp"]=$("#timeStamp").val();
	params["nonceStr"]=$("#nonceStr").val();
	params["package"]=$("#package").val();
	params["signType"]=$("#signType").val();
	params["paySign"]=$("#paySign").val();
   WeixinJSBridge.invoke(
       'getBrandWCPayRequest', params,
       function(res){     
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {
           	// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
          	var outtradeno = $("#out_trade_no").val();//返回自己的订单号
           }     
       }
   ); 
}

 if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
} 

 

4、统一下单

 

统一下单文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

 

       /**
	 * 
	 * @description 统一下订单接口(微信公众号)
	 * @author csh
	 * @param orderNo 订单号
	 * @param money 金额
	 * @param openid 用户 openId
	 * @param attach 该字段主要用于商户携带订单的自定义数据
	 * @param request
	 * @return
	 * @throws Exception
	 * @date : 2017-7-3 下午3:21:16
	 */
	public static Map addDeltaData(String orderNo, String money, String openid,
			String attach, HttpServletRequest request)
			throws Exception { 
		String mch_id = IConstants.wxMCHID.trim();//商户id
		String body = "福豆工社";
		String nonce = create_timestamp();
		String ip = IPProject.getIpAddr(request);
		String path = "https://api.mch.weixin.qq.com/pay/unifiedorder";//统一下单接口
		String para = "appid=" + IConstants.wxgzAppID;//公众号ID
		para += "&attach=" + attach;//自定义参数
		para += "&body=" + body;// 商品描述
		para += "&mch_id=" + mch_id;// 商户号
		para += "&nonce_str=" + nonce;// 随机字符串
		para += "¬ify_url=" + IConstants.wxNotifyUrl;// 接收微信支付异步通知回调地址
		para += "&openid=" + openid;// 用户标识
		para += "&out_trade_no=" + orderNo;// 商户订单号
		para += "&spbill_create_ip=" + ip;// 终端IP
		para += "&total_fee=" + money;// 总金额
		para += "&trade_type=JSAPI";// 交易类型
		para += "&key=" + IConstants.wxMCHSecret;//商户号secret
		String signature = MD5WeiXin.encode(para).toUpperCase();

		// 组织xml数据
		StringBuffer xml = new StringBuffer("");
		xml.append("").append(IConstants.wxgzAppID).append("");
		xml.append("").append(attach).append("");
		xml.append("").append(body).append("");
		xml.append("").append(mch_id).append("");
		xml.append("").append(nonce).append("");
		xml.append("").append(IConstants.wxNotifyUrl).append("");
		xml.append("").append(openid).append("");
		xml.append("").append(orderNo).append("");
		xml.append("").append(ip).append("");
		xml.append("").append(money).append("");
		xml.append("JSAPI");
		xml.append("").append(signature).append("");
		xml.append("");
		
		Map maData = new HashMap();
		// 请求连接
		String str = HttpUtil.request(path, xml.toString());
		Document document = DocumentHelper.parseText(str);
		Element root = document.getRootElement();
		String code = root.elementText("return_code");
		if ("SUCCESS".equals(code)) {
			// 创建微信订单成功
			String resultCode = root.elementText("result_code");
			if ("SUCCESS".equals(resultCode)) {
				String prepayId = root.elementText("prepay_id");
				maData.put("code", "succ");
				maData.put("preId", prepayId);
			} else {
				maData.put("code", "fail");
			}
		} else {
			// 创建微信订单失败
			maData.put("code", "fail");
		}
		return maData;
	}
        /**
	 * @description 生成JSSDK支付签名,并生成微信订单 
	 * @param orderNo 订单号
	 * @param money 金额
	 * @param openid 用户openid
	 * @param attach  该字段主要用于商户携带订单的自定义数据
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public static Map ddQm(String orderNo, String money, String openid, String attach, HttpServletRequest request)
			throws Exception {
		
		int nwmoney = (int) (Double.valueOf(money) * 100);
		// 调用微信统一下单
		Map maData = addDeltaData(orderNo, nwmoney + "", openid, "1", request);
		String code = (String) maData.get("code");
		if ("succ".equals(code)) {
			String preId = (String) maData.get("preId");
			String times = WeixinJsSdk.create_timestamp();
			String nonce = StringCommon.randomCharactersInt(32);
			// 进行签名
			String para = "appId=" + IConstants.wxgzAppID + "&nonceStr=" + nonce;// 随机字符串
			para += "&package=prepay_id=" + preId;
			para += "&signType=MD5";
			para += "&timeStamp=" + times;
			para += "&key=" + IConstants.wxMCHSecret;//商户密钥
			String paySign = MD5WeiXin.encode(para).toUpperCase();
			Map qmData = new HashMap();
			qmData.put("appId", IConstants.wxgzAppID);
			qmData.put("nonceStr", nonce);
			qmData.put("packages", "prepay_id=" + preId);
			qmData.put("signType", "MD5");
			qmData.put("timeStamp", times);
			qmData.put("paySign", paySign);
			return qmData;
		} else {
			return null;
		}
	}
public static String create_timestamp() {
		return Long.toString(System.currentTimeMillis() / 1000);
}

 

	/**
	 * 随机获取字符(字母+数字)
	 * 
	 * @param size
	 *            字符位数
	 * @return
	 */
	public static String randomCharactersInt(int size) {
		StringBuffer sb = new StringBuffer();
		Random random = new Random();
		for (int i = 0; i < size; i++) {
			int j = random.nextInt(35) + 1;// 获得随机数
			if (j > 26) {
				sb.append(35 - j);
				continue;
			}
			sb.append(getChar(j));
		}
		return sb.toString();
	}

public class MD5WeiXin {
	/*
	 * MD5加密(32位)
	 */
	public static String encode(String context) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			try {
				md.update(context.getBytes("utf-8"));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			byte[] encryContext = md.digest();

			int i;
			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < encryContext.length; offset++) {
				i = encryContext[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
			return buf.toString();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return context;
		}
	}
}
public class IPProject {
	/**
	 * 获得IP地址
	 * @param request
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {  
		String ipAddress = request.getHeader("x-forwarded-for");
		if (ipAddress == null || ipAddress.length() == 0
				|| "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0
				|| "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0
				|| "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getRemoteAddr();
			if (ipAddress.equals("127.0.0.1")
					|| ipAddress.equals("0:0:0:0:0:0:0:1")) {
				// 根据网卡取本机配置的IP
				InetAddress inet = null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
				ipAddress = inet.getHostAddress();
			}
		}
		// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
		if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
			// = 15
			if (ipAddress.indexOf(",") > 0) {
				ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
			}
		}
		return ipAddress;  
	}
}
public class HttpUtil {
	
    public static String request(String path,String param) {
        try {
            URL url = new URL(path.toString());
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setRequestMethod("POST");
            conn.setConnectTimeout(10000);
			conn.setReadTimeout(60000);
            conn.setDoInput(true);  
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            if(param != null && !"".equals(param)){
	            DataOutputStream out = new DataOutputStream(conn.getOutputStream()); 
	            out.write(param.getBytes("UTF-8"));
				out.flush();
				out.close();
            }
			byte[] data = readStream(conn.getResponseCode() == 200 ? conn.getInputStream() : conn.getErrorStream());
			String json = new String(data,"UTF-8");
            return json;
        } catch (Exception e) {
            return "";
        }
    }
    
    
    public static String GETRequest(String path) {
    	  try {
              URL url = new URL(path.toString());
              URLConnection conn = url.openConnection();
              BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
              String l = "";
              StringBuilder sb = new StringBuilder();
              while ((l = br.readLine()) != null) {
                  sb.append(l);
              }
              br.close();
              
              return sb.toString();
          } catch (Exception e) {
              return "";
          }
    }
    
    public static byte[] readStream(InputStream inputStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inputStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		outStream.close();
		inputStream.close();
		return outStream.toByteArray();
	}
    
    /**
	 * 执行url请求数据
	 * 
	 * @param urlStr
	 * @return
	 * @throws Exception
	 * @throws IOException
	 */
	public static String getUrlData(String urlStr) throws Exception {
		URL url = new URL(urlStr);
		URLConnection connection = url.openConnection();
		// 一旦发送成功,用以下方法就可以得到服务器的回应:
		String sCurrentLine = "";
		StringBuffer sTotalString = new StringBuffer();
		InputStream l_urlStream = connection.getInputStream();
		// 三层包装
		BufferedReader l_reader = new BufferedReader(new InputStreamReader(
				l_urlStream, "UTF-8"));
		while ((sCurrentLine = l_reader.readLine()) != null) {
			sTotalString.append(sCurrentLine);
		}
		return sTotalString.toString();
	}

	/**
	 * 执行url请求数据
	 * 
	 * @param urlStr
	 * @return
	 * @throws Exception
	 * @throws IOException
	 */
	public static String postUrlData(String urlStr, String data)
			throws Exception {
		URL url = new URL(urlStr);
		HttpURLConnection http = (HttpURLConnection) url.openConnection();
		http.setRequestMethod("POST");
		http.setRequestProperty("Content-Type",
				"application/x-www-form-urlencoded");
		http.setDoOutput(true);
		http.setDoInput(true);
		System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒28
		System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒29
																			// 30
		OutputStream os = http.getOutputStream();
		os.write(data.getBytes("UTF-8"));// 传入参数
		os.flush();
		os.close();
		// 一旦发送成功,用以下方法就可以得到服务器的回应:
		String sCurrentLine = "";
		String sTotalString = "";
		InputStream l_urlStream = http.getInputStream();
		// 传说中的三层包装阿!
		BufferedReader l_reader = new BufferedReader(new InputStreamReader(
				l_urlStream, "UTF-8"));
		while ((sCurrentLine = l_reader.readLine()) != null) {
			sTotalString += sCurrentLine;
		}
		return sTotalString;
	}
	
	public static void main(String[] args) {
		String url="http://localhost:8080/wap/changeposition.do?coords=114.21892734521,29.575429778924&from=1&to=5&ak=826e806b86676d155282de3d37188137";
		try {
			System.out.println(getUrlData(url));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(项目实战笔记)