Android微信支付预处理订单一系列参数的生成方法

直接进入正题,在做微信支付时候,如果写后台的人比较懒,各种参数要Android端自己生成怎么办?其实也是有办法的,就是比较麻烦,而且会有点问题(这是小概率事件了)


微信支付的官方文档说的很清楚了,这一步的参数是要后台生成的。现在我们在Android端生成。直接上代码

微信支付的文档链接:戳这里

/**
	 * 
	 * @Title: getOrderHttp 
	 * @Description: TODO(拿到订单ID) 
	 * @param  参数 @param money
	 * @param  参数 @param uid
	 * @return 返回类型  void    
	 * @throws
	 */
	private void getOrderHttp(String money,String uid){
		String url="http://webui.430.com.cn:81/AppPay/PayWeixin.aspx";
		List<NameValuePair> parameters = new ArrayList<NameValuePair>();  
		parameters.add(new BasicNameValuePair("uid", uid));  
		parameters.add(new BasicNameValuePair("money", money));  
		JSONObject json = HttpUtils.getHttp(url, parameters);
		if(null != json){
			String orderID = json.optString("orderID");
			getWXHttp(orderID,money);
		}else {
			Log.e("PAY_GET","处理结果异常");
		}

	} 
这里先从后台服务器拿到订单号和金额。然后调用getWXHttp();这个方法。

/**
	 * 
	* @Title: getWXHttp 
	* @Description: TODO(得到微信支付预处理的一些参数并跳转到微信支付) 
	* @param  参数 @param orderID
	* @param  参数 @param money
	* @return 返回类型  void    
	* @throws
	 */
	private void getWXHttp(String orderID,String money){
		Map<String,String> xml=new HashMap<String,String>();  
		String url="https://api.mch.weixin.qq.com/pay/unifiedorder"; //这个地址就是微信支付文档中请求的地址
		String entity = genProductArgs(orderID,money);  
		byte[] buf = HttpUtils.httpPost(url, entity);  
		if(buf != null){  
			String content = new String(buf);  
			try {  
				Document doc = (Document)DocumentHelper.parseText(content);  
				Element root = doc.getRootElement();  
				List<Element> list = root.elements();  
				for (Element e : list) {  
					xml.put(e.getName(), e.getText());  
				}  
			} catch (DocumentException e) {  
				e.printStackTrace();  
			}  
			if(xml != null){  
				PayReq req = new PayReq();
				req.appId			= xml.get("appid");
		    	req.partnerId       = xml.get("mch_id");
		        req.prepayId        = xml.get("prepay_id");  
		        req.packageValue    = "Sign=WXPay";  
		        req.nonceStr        = xml.get("nonce_str"); 
		        req.timeStamp = String.valueOf(StringUtils.genTimeStamp());
		        List<NameValuePair> signParams = new LinkedList<NameValuePair>();  
		        signParams.add(new BasicNameValuePair("appid", req.appId));  
		        signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));  
		        signParams.add(new BasicNameValuePair("package",req.packageValue));  
		        signParams.add(new BasicNameValuePair("partnerid",req.partnerId));  
		        signParams.add(new BasicNameValuePair("prepayid",req.prepayId));  
		        signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
		        req.sign =StringUtils.genAppSign(signParams);
		        m_IWxAPI.sendReq(req);
			}  
		}  

	}  


	/**
	 *  
	* @Title: genProductArgs 
	* @Description: TODO(拼接参数) 
	* @param  参数 @param orderID
	* @param  参数 @param money
	* @param  参数 @return
	* @return 返回类型  String    
	* @throws
	 */
	private static String genProductArgs(String orderID,String money) {  
		StringBuffer xml = new StringBuffer();  
		try {  
			xml.append("</xml>");  
			List<NameValuePair> packageParams = new LinkedList<NameValuePair>();  
            packageParams.add(new BasicNameValuePair("appid", ""));  
            packageParams.add(new BasicNameValuePair("body", ""));//商品描述,商品或支付单简要描述,必填  
            packageParams.add(new BasicNameValuePair("mch_id", ""));   //商户ID
            packageParams.add(new BasicNameValuePair("nonce_str", StringUtils.genNonceStr()));//随机字符串,不长于32位。必填  
            packageParams.add(new BasicNameValuePair("notify_url", ""));//接收微信支付异步通知回调地址.必填  
            packageParams.add(new BasicNameValuePair("out_trade_no",));//商户系统内部的订单号,32个字符内、可包含字母,必填  
            packageParams.add(new BasicNameValuePair("spbill_create_ip",StringUtils.getLocalIpAddress(AppActivity.getContext())));//APP和网页支付提交用户端ip.必填  
            packageParams.add(new BasicNameValuePair("total_fee", (Integer.parseInt(money)*100)+""));//订单总金额,只能为整数.必填  
            packageParams.add(new BasicNameValuePair("trade_type", "APP"));//取值如下:JSAPI,NATIVE,APP,WAP,必填  
			String sign = StringUtils.genPackageSign(packageParams);
			packageParams.add(new BasicNameValuePair("sign",sign));  //签名
			String xmlstring =toXml(packageParams);  
			xmlstring = new String(xmlstring.getBytes("UTF-8"), "ISO-8859-1");  
			return xmlstring;  
		} catch (Exception e) {  
			Log.e("e", "genProductArgs fail, 异常: " + e.getMessage());  
			return null;  
		}  
	}  
	/**
	 *   
	* @Title: toXml 
	* @Description: TODO(转换成String格式的xml) 
	* @param  参数 @param params
	* @param  参数 @return
	* @return 返回类型  String    
	* @throws
	 */
	private static String toXml(List<NameValuePair> params) {  
		StringBuilder sb = new StringBuilder();  
		sb.append("<xml>");  
		for (int i = 0; i < params.size(); i++) {  
			sb.append("<"+params.get(i).getName()+">");  
			sb.append(params.get(i).getValue());  
			sb.append("</"+params.get(i).getName()+">");  
		}  
		sb.append("</xml>");  
		return sb.toString();  
	} 

上面需要转成xml格式的参数,这是微信文档规定的,大家可以去看看。主要步骤就是上面的代码了。


public static byte[] httpPost(String url, String entity) {  
		if (url == null || url.length() == 0) {  
			//Log.e(TAG, "httpPost, url is null");  
			return null;  
		}  
		HttpClient httpClient = getNewHttpClient();  
		HttpPost httpPost = new HttpPost(url);  
		try {  
			httpPost.setEntity(new StringEntity(entity));  
			httpPost.setHeader("Accept", "application/json");  
			httpPost.setHeader("Content-type", "application/json");  
			HttpResponse resp = httpClient.execute(httpPost);  
			if (resp.getStatusLine().getStatusCode() != 200) {  
				//Log.e(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode());  
//				return null;  
				return EntityUtils.toByteArray(resp.getEntity());  
			}  
			return EntityUtils.toByteArray(resp.getEntity());  
		} catch (Exception e) {  
			e.printStackTrace();  
			return null;  
		}  
	} 

	private static HttpClient getNewHttpClient() {   
		try {   
			KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());   
			trustStore.load(null, null);   
			SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore);   
			sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);   
			HttpParams params = new BasicHttpParams();   
			HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);   
			HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);   
			SchemeRegistry registry = new SchemeRegistry();   
			registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));  
			registry.register(new Scheme("https", sf, 443));  
			ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);  
			return new DefaultHttpClient(ccm, params);   
		} catch (Exception e) {   
			return new DefaultHttpClient();   
		}   
	}  

	private static class SSLSocketFactoryEx extends SSLSocketFactory {        
		SSLContext sslContext = SSLContext.getInstance("TLS");        
		public SSLSocketFactoryEx(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {        
			super(truststore);        
			TrustManager tm = new X509TrustManager() {        
				public X509Certificate[] getAcceptedIssuers() {        
					return null;        
				}        
				public void checkClientTrusted(X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {  
				}  
				public void checkServerTrusted(X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {  
				}    
			};        
			sslContext.init(null, new TrustManager[] { tm }, null);        
		}        
		@Override  
		public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {  
			return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);  
		}  

		@Override  
		public Socket createSocket() throws IOException {  
			return sslContext.getSocketFactory().createSocket();  
		}   
	}    

public class StringUtils {

	/**
	 *   
	 * @Title: int2ip 
	 * @Description: TODO(将ip的整数形式转换成ip形式 ) 
	 * @param  参数 @param ipInt
	 * @param  参数 @return
	 * @return 返回类型  String    
	 * @throws
	 */
	public static String int2ip(int ipInt) {  
		StringBuilder sb = new StringBuilder();  
		sb.append(ipInt & 0xFF).append(".");  
		sb.append((ipInt >> 8) & 0xFF).append(".");  
		sb.append((ipInt >> 16) & 0xFF).append(".");  
		sb.append((ipInt >> 24) & 0xFF);  
		return sb.toString();  
	}  

	/**
	 *   
	 * @Title: getLocalIpAddress 
	 * @Description: TODO(获取当前ip地址 ) 
	 * @param  参数 @param context
	 * @param  参数 @return
	 * @return 返回类型  String    
	 * @throws
	 */
	public static String getLocalIpAddress(Context context) {  
		try {  
			WifiManager wifiManager = (WifiManager) context  
					.getSystemService(Context.WIFI_SERVICE);  
			WifiInfo wifiInfo = wifiManager.getConnectionInfo();  
			int i = wifiInfo.getIpAddress();  
			return int2ip(i);  
		} catch (Exception ex) {  
			return " 获取IP出错鸟!!!!请保证是WIFI,或者请重新打开网络!\n" + ex.getMessage();  
		}  
		// return null;  
	} 

	/**
	 * 
	 * @Title: genTimeStamp 
	 * @Description: TODO(生成时间戳) 
	 * @param  参数 @return
	 * @return 返回类型  long    
	 * @throws
	 */
	public static long genTimeStamp() {
		return System.currentTimeMillis() / 1000;
	}

	/**
	 * 
	 * @Title: genAppSign 
	 * @Description: TODO(生成签名) 
	 * @param  参数 @param params
	 * @param  参数 @return
	 * @return 返回类型  String    
	 * @throws
	 */
	public static String genAppSign(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append("换成自己的");

		String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		return appSign;
	}


	/**
	 * 
	 * @Title: genPackageSign 
	 * @Description: TODO(生成签名) 
	 * @param  参数 @param params
	 * @param  参数 @return
	 * @return 返回类型  String    
	 * @throws
	 */
	public static String genPackageSign(List<NameValuePair> params) {  
		StringBuilder sb = new StringBuilder();  

		for (int i = 0; i < params.size(); i++) {  
			sb.append(params.get(i).getName());  
			sb.append('=');  
			sb.append(params.get(i).getValue());  
			sb.append('&');  
		}  
		sb.append("key=");  
		sb.append("换成自己的");  
		String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();  
		return packageSign;  
	}  




	/**
	 *   
	 * @Title: genNonceStr 
	 * @Description: TODO(随机字符串) 
	 * @param  参数 @return
	 * @return 返回类型  String    
	 * @throws
	 */
	public static  String genNonceStr() {  
		Random random = new Random();  
		return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());  
	}  
}
public class MD5 {

	private MD5() {}
	
	public final static String getMessageDigest(byte[] buffer) {
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		try {
			MessageDigest mdTemp = MessageDigest.getInstance("MD5");
			mdTemp.update(buffer);
			byte[] md = mdTemp.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) {
			return null;
		}
	}
}

上面就是一些用到的帮助类。里面请求方式可以根据自己的网络请求去改写。


最后吐槽一句:该让后台做的事不要拿在Android端来做。


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值