首页 > 编程 > Java > 正文

Java微信支付之服务号支付代码示例

2019-11-26 10:58:34
字体:
来源:转载
供稿:网友

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();      // ----------------------------------给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();  }}

大功告成

总结

以上就是本文关于Java微信支付之服务号支付代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:快速理解Java设计模式中的组合模式Java编程接口调用的作用及代码分享浅谈java中字符串数组、字符串、整形之间的转换等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表