您好,登錄后才能下訂單哦!
Java微信支付之服務號支付實現,網上的java微信支付sdk和Demo基本上是水的,看著頭疼所以我決心自己開始寫Java微信支付之公眾號支付,多的不說見下面源碼,為了方便使用我分別用了兩個Servlet,一個是統一下單UnifiedorderServlet,一個是支付回調PayCallBackServlet,你們可以自己封裝。
一是統一下單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 = "https://test.com/payCallBack";// 支付回調地址 String prepay_id = "", sign = "", charset = "UTF-8", nonce_str = ""; try { String weixinMoney = new java.text.DecimalFormat("#").format(money * 100);// 微信是以分為單位的所以要乘以100 nonce_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(" ").append(appid).append("</appid>"); xml.append("").append(body).append(""); 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(); // ----------------------------------給h6返回的數據 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 // ----------------------------------給h6返回的數據 } 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(); } }
大功告成
總結
以上就是本文關于Java微信支付之服務號支付代碼示例的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站:快速理解Java設計模式中的組合模式、Java編程接口調用的作用及代碼分享、淺談java中字符串數組、字符串、整形之間的轉換等,有什么問題可以隨時留言,小編會及時回復大家的。感謝朋友們對本站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。