微信小程序的java支付開發(fā)一直是一塊坑,網(wǎng)上的教程也是琳瑯滿目。筆者六月的時候接觸到了微信的小程序開發(fā)摸到了微信支付方面的東西,騰訊的官方文檔也是一言難盡很多地方看不懂,而且官方也沒有提供java的示范導致java做微信支付不得不自己踩坑。現(xiàn)在我把自己微信支付開發(fā)的步驟和代碼都在下面展示出來,希望有沒有做出來的朋友不要心急跟著我的步驟走就沒問題。
第一步:首先微信支付的話只能是企業(yè)的開發(fā)賬戶才能使用的如果你是個人開發(fā)者是無法開通微信支付的。我們首先拿到賬號,然后拿到微信支付相關的商戶號和商戶支付密鑰,這些東西公司都會提供。有了這些以后就可以進行開發(fā)了。
1
2
3
4
5
6
7
8
9
|
public class configure { //商戶支付密鑰 private static string key = "****************************" ; //小程序id private static string appid = "***************" ; //商戶號 private static string mch_id = "*********" ; //小程序密鑰 private static string secret = "********************" ; |
我把開發(fā)者賬號和商戶號都放在了一個工具類方便在后面的調(diào)用。
第二步:做支付要先獲取到用戶的openid這是一個很重要的參數(shù)你必須要拿到的東西不然就無法完成支付。下面是我獲取用戶的openid的代碼。
1
2
3
4
5
6
7
8
9
10
|
protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { string code = request.getparameter( "code" ); httpget httpget = new httpget( "https://api.weixin.qq.com/sns/jscode2session?appid=" +configure.getappid()+ "&secret=" +configure.getsecret()+ "&js_code=" +code+ "&grant_type=authorization_code" ); //設置請求器的配置 httpclient httpclient = httpclients.createdefault(); httpresponse res = httpclient.execute(httpget); httpentity entity = res.getentity(); string result = entityutils.tostring(entity, "utf-8" ); response.getwriter().append(result); } |
第三步:獲取到用戶的openid之后我們就要進行下單。簡單來說要把微信支付所需要的參數(shù)都準備好然后給到官方提供的api。這些東西在官方的文檔里面各位可以去查閱。下面是我傳遞參數(shù)的代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
string openid = request.getparameter( "openid" ); int totalfee=integer.parseint(request.getparameter( "totalfee" )); //獲取支付金額 string out_trade_no=randomstringgenerator.getrandomstringbylength( 32 ); //商戶訂單號 orderinfo order = new orderinfo(); order.setappid(configure.getappid()); order.setmch_id(configure.getmch_id()); order.setnonce_str(randomstringgenerator.getrandomstringbylength( 32 )); order.setbody( "測試" ); order.setout_trade_no(out_trade_no); order.settotal_fee(totalfee); order.setspbill_create_ip( "***.***.***.**" ); order.setnotify_url( "https://www.see-source.com/weixinpay/payresult" ); order.settrade_type( "jsapi" ); order.setopenid(openid); order.setsign_type( "md5" ); |
可以看到上面的傳遞的參數(shù)中有需要支付的金額、和隨機生成的32位商戶訂單號、以及開發(fā)者的appid和支付說明支付的ip地址這些參數(shù)我們想辦法都拿到之后是否就能丟給官方api呢?當然還不是,往下看第四步。
第四步:我們拿到了參數(shù)之后能否直接給到api呢?微信支付出于安全考慮參數(shù)需要進行加密之后發(fā)送給微信支付api。我們得把剛剛拿到的參數(shù)進行簽名加密,我這里用到的是md5的加密方式,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
try { string repay_id = request.getparameter( "repay_id" ); signinfo signinfo = new signinfo(); signinfo.setappid(configure.getappid()); long time = system.currenttimemillis()/ 1000 ; signinfo.settimestamp(string.valueof(time)); signinfo.setnoncestr(randomstringgenerator.getrandomstringbylength( 32 )); signinfo.setrepay_id( "prepay_id=" +repay_id); signinfo.setsigntype( "md5" ); //生成簽名 string sign = signature.getsign(signinfo); jsonobject json = new jsonobject(); json.put( "timestamp" , signinfo.gettimestamp()); json.put( "noncestr" , signinfo.getnoncestr()); json.put( "package" , signinfo.getrepay_id()); json.put( "signtype" , signinfo.getsigntype()); json.put( "paysign" , sign); l.info( "-------再簽名:" +json.tojsonstring()); response.getwriter().append(json.tojsonstring()); } catch (exception e) { // todo auto-generated catch block e.printstacktrace(); l.error( "-------" , e); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public static string getsign(object o) throws illegalaccessexception { arraylist<string> list = new arraylist<string>(); @suppresswarnings ( "rawtypes" ) class cls = o.getclass(); field[] fields = cls.getdeclaredfields(); for (field f : fields) { f.setaccessible( true ); if (f.get(o) != null && f.get(o) != "" ) { string name = f.getname(); xstreamalias anno = f.getannotation(xstreamalias. class ); if (anno != null ) name = anno.value(); list.add(name + "=" + f.get(o) + "&" ); } } int size = list.size(); string [] arraytosort = list.toarray( new string[size]); arrays.sort(arraytosort, string.case_insensitive_order); stringbuilder sb = new stringbuilder(); for ( int i = 0 ; i < size; i ++) { sb.append(arraytosort[i]); } string result = sb.tostring(); result += "key=" + configure.getkey(); system.out.println( "簽名數(shù)據(jù):" +result); result = md5util.md5encode(result, "utf-8" ).touppercase(); return result; } |
到這一步就已經(jīng)支付完成了。
通過官方api返回的回調(diào)類型來判斷支付是否成功。
只要大家按照步驟來就可以實現(xiàn),以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.51cto.com/13981400/2309067