微信支付APP端以及服务端(JavaEE)可以直接使用

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zdd199401/article/details/80941161

最近在集成微信支付,不得不说微信文档就是坑,说的不明不白,还是支付宝简单,

流程:

1、客户端提交订单——》到(自己平台的)服务器,参数与服务端协商

2、服务端拿到请求订单信息——》参考微信统一下单接口——》把必须传的参数进行加密转XML传到微信服务器

统一下单链接

3、如果签名正确,微信服务端会返回成功信息 ——》XML格式——》解析XML——》

拿到预支付交易会话标识(prepay_id)这个是关键

4、拿到交易会话ID后,进行二次签名 把下表数据按照第一次签名规范进行签名——》传到客户端


5、(注意)二次签名的随机字符串(noncestr)不要再次生成新的字符串,一定要是第一次签名传

微信服务器那个保持一至。(这点微信文档没有找到)

6、二次签名的数据就可以传到客户端——》客户端调用拿到数据就可以调用微信支付了

7、一定要是正式打包的apk才会有效果,否则不能调起微信支付,

8、微信开发平台设置好包名,以及应用签名就可以了

应用签名获取工具





直接上代码


上面是调起微信支付关键代码,当然调用微信支付前一定要先注册到微信 建议放到onCreate中

再说下服务端 简单写的测试下,直接复制就能用,

/**
 * Servlet implementation class PayHttpServlet
 */
@WebServlet("/PayHttpServlet")
public class PayHttpServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private String urlWx = "https://api.mch.weixin.qq.com/pay/unifiedorder";

	private String postType = "POST";

	private String result;

	private int price100 = -1;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public PayHttpServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		// response.getWriter().append("Served at: ").append(request.getContextPath());
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		// 设置编码
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		String price = request.getParameter("price");

		if (price == null || "".equals(price)) {
			// 返回客户端数据
			System.out.print("参数有误,金额不能为0");
			return;
		} else {
			price100 = new BigDecimal(price).multiply(new BigDecimal(100)).intValue();
			doconfig(request, response);
		}

	}

	private void doconfig(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		Map<String, Object> resultMap = new HashMap<String, Object>();
		SortedMap<String, Object> map = new TreeMap<>();
		map.put("appid", PayCommonUtil.APPID);
		map.put("mch_id", PayCommonUtil.MCH_ID);
		map.put("nonce_str", PayCommonUtil.getRandomString(30));
		// map.put("sign", value);
		map.put("trade_type", "APP");
		map.put("body", "APP测试支付");
		map.put("out_trade_no", PayCommonUtil.getRandomString(15));
		map.put("total_fee", String.valueOf(price100));
		map.put("spbill_create_ip", "113.113.157.124");//ip地址
		map.put("notify_url", "http://www.baidu.com");//异步通知地址
		// 签名
		String singA = PayCommonUtil.createSign("utf-8", map);
		map.put("sign", singA);
		// 请求封装
		String urlData = PayCommonUtil.getRequestXml(map);
		System.out.println("xml=" + "\n" + urlData);
		// 调用下单接口,得到prepay_id预支付码,重新签名返回给app
		String result = PayCommonUtil.httpsRequest(urlWx, postType, urlData);
		// System.out.println("xml="+urlData);
		System.out.println("resultXML=" + "\n" + result);
		// 得到数据返回给app
		try {
			Map<String, Object> map2 = PayCommonUtil.doXMLParse(result);

			SortedMap<String, Object> mapApp = new TreeMap<>();
			mapApp.put("appid", PayCommonUtil.APPID);
			mapApp.put("partnerid", PayCommonUtil.MCH_ID);
			mapApp.put("prepayid", map2.get("prepay_id"));
			mapApp.put("package", "Sign=WXPay");
			mapApp.put("noncestr", map.get("nonce_str"));
			System.out.println("nonce_str=="+map.get("nonce_str"));
			// 时间戳
			mapApp.put("timestamp",
					String.valueOf(Long.parseLong(String.valueOf(System.currentTimeMillis()).substring(0, 10))));
			String signAPP = PayCommonUtil.createSign("utf-8", mapApp);
			mapApp.put("sign", signAPP);
			mapApp.put("status", "1");

			try {
				String object = new Gson().toJson(mapApp);
				JSONObject object2 = new JSONObject(object);
				System.out.println("json=" + "\n" + object2);
				// 返回客户端数据
				PrintWriter out = response.getWriter();
				out.write(object2.toString());

				out.flush();
				out.close();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			System.out.println("mapApp" + "\n" + mapApp);

		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
public class PayCommonUtil {
	// 微信参数配置
	public static String API_KEY = "";
	public static String APPID = "";
	public static String MCH_ID = "";

	// 随机字符串生成
	public static String getRandomString(int length) { // length表示生成字符串的长度
		String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	// 请求xml组装
	public static String getRequestXml(SortedMap<String, Object> parameters) {
		StringBuffer sb = new StringBuffer();
		sb.append("<xml>");
		Set es = parameters.entrySet();
		Iterator it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String key = (String) entry.getKey();
			String value = (String) entry.getValue();
			if ("attach".equalsIgnoreCase(key) || "body".equalsIgnoreCase(key) || "sign".equalsIgnoreCase(key)) {
				sb.append("<" + key + ">" + "<![CDATA[" + value + "]]></" + key + ">");
			} else {
				sb.append("<" + key + ">" + value + "</" + key + ">");
			}
		}
		sb.append("</xml>");
		return sb.toString();
	}

	/**
	 * 所有参数除sign外,按照ASCII码排序,
	 */
	public static String buildASCiiParams(Map<String, Object> params) {
		StringBuffer stringBuffer = new StringBuffer();// 存放数据
		// 按照ASCII码进行排序
		Map<String, Object> sortMap = new TreeMap<String, Object>(params);
		// 便利字典,拼接"key=value&key=value"
		for (Map.Entry<String, Object> m : sortMap.entrySet()) {
			if (stringBuffer.length() > 0) {
				stringBuffer.append("&");
			}
			stringBuffer.append(m.getKey()).append("=").append(m.getValue());
		}
		return stringBuffer.toString();
	}

	// 生成签名
	public static String createSign(String characterEncoding, SortedMap<String, Object> parameters) {
		StringBuffer sb = new StringBuffer();
		Set es = parameters.entrySet();
		Iterator it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			Object v = entry.getValue();
			if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
				sb.append(k + "=" + v + "&");
			}
		}
		sb.append("key=" + API_KEY);
		String sign = MD5Utils.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
		return sign;
	}

	// 请求方法
	public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
		try {

			URL url = new URL(requestUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();

			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式(GET/POST)
			conn.setRequestMethod(requestMethod);
			conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
			// 当outputStr不为null时向输出流写数据
			if (null != outputStr) {
				OutputStream outputStream = (OutputStream) conn.getOutputStream();
				// 注意编码格式
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}
			// 从输入流读取返回内容
			InputStream inputStream = (InputStream) conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			return buffer.toString();
		} catch (ConnectException ce) {
			System.out.println("连接超时:{}" + ce);
		} catch (Exception e) {
			System.out.println("https请求异常:{}" + e);
		}
		return null;
	}

	// xml解析
	public static Map doXMLParse(String strxml) throws JDOMException, IOException {
		strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

		if (null == strxml || "".equals(strxml)) {
			return null;
		}

		Map m = new HashMap();

		InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
		SAXBuilder builder = new SAXBuilder();
		Document doc = builder.build(in);
		Element root = doc.getRootElement();
		List list = root.getChildren();
		Iterator it = list.iterator();
		while (it.hasNext()) {
			Element e = (Element) it.next();
			String k = e.getName();
			String v = "";
			List children = e.getChildren();
			if (children.isEmpty()) {
				v = e.getTextNormalize();
			} else {
				v = getChildrenText(children);
			}

			m.put(k, v);
		}

		// 关闭流
		in.close();

		return m;
	}

	public static String getChildrenText(List children) {
		StringBuffer sb = new StringBuffer();
		if (!children.isEmpty()) {
			Iterator it = children.iterator();
			while (it.hasNext()) {
				Element e = (Element) it.next();
				String name = e.getName();
				String value = e.getTextNormalize();
				List list = e.getChildren();
				sb.append("<" + name + ">");
				if (!list.isEmpty()) {
					sb.append(getChildrenText(list));
				}
				sb.append(value);
				sb.append("</" + name + ">");
			}
		}

		return sb.toString();
	}

}

demo下载



展开阅读全文

没有更多推荐了,返回首页