欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-04-01 23:32:58
java微信支付之服务号支付实现,网上的java微信支付sdk和demo基本上是水的,看着头疼所以我决心自己开始写java微信支付之公众号支付,多的不说见下面源码,为了方便...

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编程接口调用的作用及代码分享、等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!