Java微信支付之服务号支付实现

来源:互联网 发布:mac book切换输入法 编辑:程序博客网 时间:2024/05/07 13:03

网上的java微信支付sdk和Demo基本上是水的,看着头疼所以我决心自己开始写Java微信支付之公众号支付,多的不说见下面源码,为了方便使用我分别用了两个Servlet,一个是统一下单UnifiedorderServlet,一个是支付回调PayCallBackServlet,你们可以自己封装。

官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1

一是统一下单UnifiedorderServlet:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;import java.net.HttpURLConnection;import java.net.URL;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Random;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.http.ParseException;import org.apache.http.client.ClientProtocolException;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONML;import org.json.JSONObject;public class UnifiedorderServlet extends HttpServlet {private static final long serialVersionUID = 1L;private static final String appid = "";// 找微信private static final String mch_id = "";// 找微信public static final String api_key = "";// 找微信private static final String trade_type = "JSAPI";// 写死public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html; charset=utf-8");PrintWriter out = response.getWriter();JSONObject jso = new JSONObject();double money = 0.01;String openId = "", out_trade_no = "", body = "测试", ip = "";try {out.print(execute(out_trade_no, body, openId, money, ip, jso).toString());} catch (JSONException e) {e.printStackTrace();}out.flush();out.close();}/** * 微信服务号统一下单支付 *  * @param out_trade_no *            订单号 * @param body *            标题 * @param openId *            用户的openId * @param money *            支付金额 * @param ip *            客户端ip * @param request *            HttpServletRequest * @return * @throws JSONException */public JSONObject execute(String out_trade_no, String body, String openId, double money, String ip, JSONObject jso) throws JSONException {StringBuilder xml = new StringBuilder();String notify_url = "http://test.com/payCallBack";// 支付回调地址String prepay_id = "", sign = "", charset = "UTF-8", nonce_str = "";try {String weixinMoney = new java.text.DecimalFormat("#").format(money * 100);// 微信是以分为单位的所以要乘以100nonce_str = getRandomString(32);xml.append("appid=").append(appid).append("&body=").append(new String(body.getBytes(charset), charset));// 处理中文xml.append("&mch_id=").append(mch_id).append("&nonce_str=").append(nonce_str);xml.append("¬ify_url=").append(notify_url).append("&openid=").append(openId);xml.append("&out_trade_no=").append(out_trade_no).append("&spbill_create_ip=").append(ip);xml.append("&total_fee=").append(weixinMoney).append("&trade_type=").append(trade_type).append("&key=").append(api_key);sign = MD5Purity(xml.toString());// System.out.println(xml);xml.delete(0, xml.length());xml.append("<xml>");xml.append("   <appid>").append(appid).append("</appid>");xml.append("   <body>").append(body).append("</body>");xml.append("   <mch_id>").append(mch_id).append("</mch_id>");xml.append("   <nonce_str>").append(nonce_str).append("</nonce_str>");xml.append("   <openid>").append(openId).append("</openid>");xml.append("   <notify_url>").append(notify_url).append("</notify_url>");xml.append("   <out_trade_no>").append(out_trade_no).append("</out_trade_no>");xml.append("   <spbill_create_ip>").append(ip).append("</spbill_create_ip>");xml.append("   <total_fee>").append(weixinMoney).append("</total_fee>");xml.append("   <trade_type>").append(trade_type).append("</trade_type>");xml.append("   <sign>").append(sign).append("</sign>");xml.append("</xml>");HttpURLConnection conn = (HttpURLConnection) new URL("https://api.mch.weixin.qq.com/pay/unifiedorder").openConnection();conn.setDoOutput(true);conn.setRequestMethod("POST");conn.setRequestProperty("Content-Type", "text/xml");conn.setRequestProperty("Charset", charset);OutputStream os = conn.getOutputStream();os.write(xml.toString().getBytes(charset));xml.delete(0, xml.length());os.close();int responseCode = conn.getResponseCode();InputStreamReader in = null;BufferedReader br = null;if (responseCode == 200) {in = new InputStreamReader(conn.getInputStream(), charset);br = new BufferedReader(in);String retData = null;while ((retData = br.readLine()) != null)xml.append(retData);JSONArray childNodes = JSONML.toJSONObject(xml.toString()).getJSONArray("childNodes");int len = childNodes.length() - 1;for (int i = len; i > -1; i--) {JSONObject js = childNodes.getJSONObject(i);if (js.get("tagName").equals("prepay_id")) {prepay_id = js.getJSONArray("childNodes").getString(0);break;}}}if (in != null)in.close();if (br != null)br.close();conn.disconnect();// ----------------------------------给h5返回的数据String timeStamp = System.currentTimeMillis() + "";timeStamp = timeStamp.substring(0, 10);// 微信只要精确到秒nonce_str = getRandomString(32);jso.put("appId", appid);jso.put("nonceStr", nonce_str);jso.put("package", "prepay_id=" + prepay_id);jso.put("signType", "MD5");jso.put("timeStamp", timeStamp);xml.delete(0, xml.length());xml.append("appId=").append(appid);xml.append("&nonceStr=").append(nonce_str);xml.append("&package=").append(jso.getString("package"));xml.append("&signType=").append(jso.getString("signType"));xml.append("&timeStamp=").append(timeStamp);xml.append("&key=").append(api_key);sign = MD5Purity(new String(xml.toString().getBytes(charset), charset));jso.put("paySign", sign);//返回的数据主要用在这地方 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6// ----------------------------------给h5返回的数据} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (ParseException e) {e.printStackTrace();} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return jso;}/** * MD5 *  * @param plainText * @return */public String MD5Purity(String plainText) {try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(plainText.getBytes("utf-8"));byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0)i += 256;if (i < 16)buf.append("0");buf.append(Integer.toHexString(i));}plainText = buf.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}return plainText.toUpperCase();}/** * 生成一个随机字符串 *  * @param length *            表示生成字符串的长度 * @return */private String getRandomString(int length) {String base = "abcdefghijklmnopqrstuvwxyz0123456789";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();}}


二是支付回调PayCallBackServlet:

import java.io.BufferedReader;import java.io.IOException;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONML;import org.json.JSONObject;public class PayCallBackServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html; charset=utf-8");PrintWriter out = response.getWriter();out.print(doWxServer(request));out.flush();out.close();}/** * 处理微信回调 *  * @param request * @return * @throws ServletException * @throws IOException */public String doWxServer(HttpServletRequest request) {System.out.println("微信服务号支付回调");String inputLine;StringBuilder notityXml = new StringBuilder();BufferedReader bufferedReader = null;try {bufferedReader = request.getReader();while ((inputLine = bufferedReader.readLine()) != null)notityXml.append(inputLine);if (bufferedReader != null)bufferedReader.close();if (notityXml.length() < 10) {return "fail";}String appid = "", total_fee = "", bank_type = "", cash_fee = "", fee_type = "", is_subscribe = "", mch_id = "", nonce_str = "";String out_trade_no = "", transaction_id = "", openid = "", sign = "", result_code = "", return_code = "", time_end = "", trade_type = "";JSONArray result = JSONML.toJSONObject(notityXml.toString()).getJSONArray("childNodes");int len = result.length();for (int i = 0; i < len; i++) {JSONObject js = result.getJSONObject(i);Object tagName = js.get("tagName");if (tagName.equals("appid")) {appid = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("bank_type")) {bank_type = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("cash_fee")) {cash_fee = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("fee_type")) {fee_type = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("is_subscribe")) {is_subscribe = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("mch_id")) {mch_id = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("nonce_str")) {nonce_str = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("openid")) {openid = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("out_trade_no")) {out_trade_no = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("result_code")) {result_code = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("return_code")) {return_code = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("time_end")) {time_end = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("total_fee")) {total_fee = js.getJSONArray("childNodes").getInt(0) + "";} else if (tagName.equals("trade_type")) {trade_type = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("transaction_id")) {transaction_id = js.getJSONArray("childNodes").getString(0);} else if (tagName.equals("sign")) {sign = js.getJSONArray("childNodes").getString(0);}}StringBuilder str = new StringBuilder();str.append("appid=").append(appid).append("&bank_type=").append(bank_type).append("&cash_fee=").append(cash_fee).append("&fee_type=");str.append(fee_type).append("&is_subscribe=").append(is_subscribe).append("&mch_id=").append(mch_id).append("&nonce_str=");str.append(nonce_str).append("&openid=").append(openid).append("&out_trade_no=").append(out_trade_no).append("&result_code=").append(result_code).append("&return_code=").append(return_code).append("&time_end=").append(time_end).append("&total_fee=").append(total_fee);str.append("&trade_type=").append(trade_type).append("&transaction_id=").append(transaction_id).append("&key=").append(UnifiedorderServlet.api_key);if (!MD5Purity(str.toString()).equals(sign)) {// 验证签名System.out.println("微信服务号支付回调签名异常sign=" + sign);System.out.println(str);System.out.println(result);return "fail";}total_fee = new java.text.DecimalFormat("#0.00").format(Double.parseDouble(total_fee) / 100);// 支付金额以分为单位return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";//成功后给微信返回数据} catch (JSONException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return "fail";}/** * MD5 *  * @param plainText * @return */public String MD5Purity(String plainText) {try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(plainText.getBytes("utf-8"));byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0)i += 256;if (i < 16)buf.append("0");buf.append(Integer.toHexString(i));}plainText = buf.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}return plainText.toUpperCase();}}


大功告成有么么哒。

1 0
原创粉丝点击