Java编程调用微信支付功能的方法详解
程序员文章站
2024-02-20 20:41:35
本文实例讲述了java编程调用微信支付功能的方法。分享给大家供大家参考,具体如下:
微信开发文档地址:
从调用处开始
我的流程: 1.点击“支付”按钮,去后台 —-&...
本文实例讲述了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程序设计有所帮助。