当前位置: 移动技术网 > IT编程>开发语言>Java > Java编程调用微信支付功能的方法详解

Java编程调用微信支付功能的方法详解

2019年07月19日  | 移动技术网IT编程  | 我要评论

本文实例讲述了java编程调用微信支付功能的方法。分享给大家供大家参考,具体如下:

微信开发文档地址:

从调用处开始

我的流程: 1.点击“支付”按钮,去后台 —-> 2.后台生成支付所需数据返回页面 —-> 3.页面点击“确认支付”调用微信支付js。完成支付功能

支付按钮

<div class="button" id="pay" onclick="paybox()">支付</div>

支付按钮js

function paybox(){
    //获得支付的钱数
    var money = $(".money input").val();
    //后台路径,加上参数
    location.href = "/xxx/xxx/xxxx/xxxx?money ="+money;
}

后台方法(例:index())

注释:

getpara( ) == request.getparameter(name);
setattr( ) == request.setattribute(name, value);
render() == 我现在所用框架返回页面的一种方法。

首先得openid;下面是具体方法。

public string getopenid(){
  string code = getpara("code");
  string openid = "";
    if (stringutils.isempty(openid) && !stringutils.isempty(code)) {
      snsaccesstoken token = snsaccesstokenapi.getsnsaccesstoken("你的appid","你的appsecret密码",
          code);
      openid = token.getopenid();
    }
    getsession().setattribute("openandid",openid);
    return openid;
}
public void index() throws exception{
    string openid = getopenid();
    //得到金额
    string money= getpara("money");
    map<string ,string > map=new hashmap<string,string>();
    //获取随机串
    string noncestr=uuid.randomuuid().tostring().substring(0, 32);
    //可以是支付物品的订单号。一个号码,看自己怎么给
    string out_trade_no="123456789";
    //支付金额。微信默认支付是(1=0.01)的比例,下面是将金额换算成微信可识别的
    bigdecimal re1=new bigdecimal(expresscharge);
    bigdecimal re2=new bigdecimal(float.tostring(100.00f));
    float aa = re1.multiply(re2).floatvalue();
    string total_fee = string.valueof(aa);
    string[] smill = total_fee.split("\\.");
    total_fee = smill[0];
    //微信的appid
    string appid="xxxxxxxxxxxxxxxxx";
    string mch_id="xxxxxxxxx";//商户号
    string body="xxxxxxx";//商品信息,可以自己起最好写英文
    //密匙,商户平台的支付api密匙,注意是商户平台,不是微信平台
    string key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    long timestamp = system.currenttimemillis() / 1000;
    map.put("appid", appid );
    map.put("mch_id", mch_id);
    map.put("nonce_str",noncestr);
    map.put("body", body);
    map.put("out_trade_no", out_trade_no);
    map.put("total_fee", total_fee);
    map.put("spbill_create_ip",getrequest().getremoteaddr());
    //这里是支付成功后返回的地址,微信会以xml形式放回数据,就是本篇文章的下一类(例:wxxml())方法名。
    map.put("notify_url", "http://www.xxxx.com/xxxx/xxxx/xxxx/wxxml");
    map.put("trade_type", "jsapi");
    map.put("openid", openid);//传入openid
    //这里传入map集合和key商户支付密匙
    string paysign=getpaycustomsign(map,key);
    map.put("sign",paysign);
    //将map转为xml格式
    string xml= arraytoxml(map);
    //统一下单,这里不用改
    string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    string xmlstr = httpkit.post(url, xml);
    //prepayid由微信返回的 。
    string prepayid = "";
    if (xmlstr.indexof("success") != -1) {
      map<string, string> map2 = doxmlparse(xmlstr);
      prepayid = (string) map2.get("prepay_id");
    }
    string paysign2=getpaycustomsign(signmap,key);
    setattr("model", model);
    setattr("appid", appid);
    setattr("paytimestamp", string.valueof(timestamp));
    setattr("paynoncestr", noncestr);
    setattr("paypackage", "prepay_id="+prepayid);
    setattr("paysigntype","md5");
    setattr("paysign", paysign2);
    //去到确认支付页面,返回页面方式不同,(例:pay.html页面),下面
    render("/xxxx/pay.html");
}
/**
* 获取支付所需签名
* @param ticket
* @param timestamp
* @param card_id
* @param code
* @return
* @throws exception
*/
public static string getpaycustomsign(map<string, string> bizobj,string key) throws exception {
    string bizstring = formatbizqueryparamap(bizobj, false);
    return sign(bizstring, key);
}
/**
* 字典排序
* @param paramap
* @param urlencode
* @return
* @throws exception
*/
public static string formatbizqueryparamap(map<string, string> paramap,
  boolean urlencode) throws exception {
    string buff = "";
    try {
      list<map.entry<string, string>> infoids = new arraylist<map.entry<string, string>>(paramap.entryset());
      collections.sort(infoids,
          new comparator<map.entry<string, string>>() {
      public int compare(map.entry<string, string> o1,
         map.entry<string, string> o2) {
         return (o1.getkey()).tostring().compareto(
                  o2.getkey());
            }
          });
      for (int i = 0; i < infoids.size(); i++) {
        map.entry<string, string> item = infoids.get(i);
        //system.out.println(item.getkey());
        if (item.getkey() != "") {
          string key = item.getkey();
          string val = item.getvalue();
          if (urlencode) {
            val = urlencoder.encode(val, "utf-8");
          }
          buff += key + "=" + val + "&";
        }
      }
      if (buff.isempty() == false) {
        buff = buff.substring(0, buff.length() - 1);
      }
    } catch (exception e) {
      throw new exception(e.getmessage());
    }
    return buff;
}
//支付所需签名处调用此方法
public static string sign(string content, string key)
  throws exception{
    string signstr = "";
    signstr = content + "&key=" + key;
    return md5(signstr).touppercase();
}
//上一方法,md5加密处理
public final static string md5(string s) {
    char hexdigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
    try {
      byte[] btinput = s.getbytes();
      messagedigest mdinst = messagedigest.getinstance("md5");
      mdinst.update(btinput);
      byte[] md = mdinst.digest();
      int j = md.length;
      char str[] = new char[j * 2];
      int k = 0;
      for (int i = 0; i < j; i++) {
        byte byte0 = md[i];
        str[k++] = hexdigits[byte0 >>> 4 & 0xf];
        str[k++] = hexdigits[byte0 & 0xf];
      }
      return new string(str);
    } catch (exception e) {
      e.printstacktrace();
      return null;
    }
}
//转为xml格式
public static string arraytoxml(map<string, string> arr) {
    string xml = "<xml>";
    iterator<entry<string, string>> iter = arr.entryset().iterator();
    while (iter.hasnext()) {
      entry<string, string> entry = iter.next();
      string key = entry.getkey();
      string val = entry.getvalue();
      if (isnumeric(val)) {
        xml += "<" + key + ">" + val + "</" + key + ">";
      } else
        xml += "<" + key + "><![cdata[" + val + "]]></" + key + ">";
    }
    xml += "</xml>";
    return xml;
}
public static boolean isnumeric(string str) {
    if (str.matches("\\d *")) {
      return true;
    } else {
      return false;
    }
}
//解析xml
private map<string, string> doxmlparse(string xml)
    throws xmlpullparserexception, ioexception {
      inputstream inputstream = new bytearrayinputstream(xml.getbytes());
      map<string, string> map = null;
      xmlpullparser pullparser = xmlpullparserfactory.newinstance()
          .newpullparser();
      pullparser.setinput(inputstream, "utf-8");// 为xml设置要解析的xml数据
      int eventtype = pullparser.geteventtype();
      while (eventtype != xmlpullparser.end_document) {
        switch (eventtype) {
        case xmlpullparser.start_document:
          map = new hashmap<string, string>();
          break;
        case xmlpullparser.start_tag:
          string key = pullparser.getname();
          if (key.equals("xml"))
            break;
          string value = pullparser.nexttext();
          map.put(key, value);
          break;
        case xmlpullparser.end_tag:
          break;
        }
        eventtype = pullparser.next();
      }
      return map;
}

pay页面(上面步骤执行完后去的页面)

此处是页面js代码,接受后台代码传回来的参数。现在用的是bsl模板引擎,参数可以以el表达式方式接收。可先将后台传会的参数,放在几个input类型type=”hidden”标签标签中。

<input type="hidden" name="appid" value="${appid}" id="appid" />

js中得到值

var appid = $("#appid").val();

js引用

<script type="text/javascript" src="${staticpath}/front/js/weixin.js"></script>

下面是js代码,由于是bsl,自己看着传参数吧,反正都是后台来的。

<div class="button" id="onlinepaynow">确认支付</div>

//先写一个点击事件,当点击id为onlinepaynow的按钮时,触发该事件。
$("#onlinepaynow").click(function getpay(){
  if (typeof weixinjsbridge=="undefined") {
    if (document.addeventlistener) {document.addeventlistener('weixinjsbridgeready',onbridgeready,false);
    }else if(document.attachevent){document.attachevent('weixinjsbridgeready',onbridgeready);document.attachevent('onweixinjsbridgeready',onbridgeready);
    }
  }else{
    //如果报错,可用下面方法看看是不是参数缺少。
    /* alert('${appid}');
    alert('${paytimestamp}');
    alert('${paynoncestr}');
    alert('${paypackage}');
    alert('${paysigntype}');
    alert('${paysign}'); */
    //调用下面方法。开启微信支付。
    onbridgeready();
  }
})
function onbridgeready(){
  weixinjsbridge.invoke('getbrandwcpayrequest', {
    "appid" : '${appid}', //公众号名称,由商户传入
    "timestamp" : '${paytimestamp}', //时间戳,自1970年以来的秒数
    "noncestr" : '${paynoncestr}', //随机串
    "package" : '${paypackage}',
    "signtype" : '${paysigntype}', //微信签名方式:
    "paysign" : '${paysign}' //微信签名
  }, function(res) {
    //alert(res.err_msg); // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返
    if(res.err_msg == "get_brand_wcpay_request:ok"){
    //支付成功,完成后去到哪个页面。
    window.location.href="/xxxx/xxxx.html" rel="external nofollow" ;
    }
  });
}

在微信公众平台配置,支付授权目录。

授权目录建议:

http://www.xxxx.com/xxxx/xxx/index/

我觉得最好写后台是action地址就写action地址,controller就写controller地址,如果有spring注解,就写注解后名称。

我所导入的包(java后台,就是index方法。)

import java.io.bytearrayinputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.math.bigdecimal;
import java.net.urlencoder;
import java.security.messagedigest;
import java.util.arraylist;
import java.util.collections;
import java.util.comparator;
import java.util.hashmap;
import java.util.iterator;
import java.util.list;
import java.util.map;
import java.util.map.entry;
import java.util.uuid;
import org.xmlpull.v1.xmlpullparser;
import org.xmlpull.v1.xmlpullparserexception;
import org.xmlpull.v1.xmlpullparserfactory;
import com.jfinal.kit.httpkit;
import com.uitrs.express.common.constants;

更多关于java算法相关内容感兴趣的读者可查看本站专题:《java字符与字符串操作技巧总结》、《java数组操作技巧总结》、《java数学运算技巧总结》、《java编码操作技巧总结》和《java数据结构与算法教程

希望本文所述对大家java程序设计有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网