java微信刷卡支付demo,微信刷卡支付API详解
場景:
*對于一些必選參數,即使沒什么用,也一定要傳。
map.put('appid','你的公眾號appid');map.put('mch_id', '微信支付商戶號');map.put('sub_mch_id', '微信支付分配的子商戶號,服務商必填');map.put('device_info', '終端設備號'));map.put('body', '商品名稱');map.put('detail', '單品優惠功能字段');map.put('attach','附加數據');map.put('out_trade_no', '訂單號,要求32個字符內');map.put('total_fee','支付金額'));map.put('fee_type','默認人民幣:CNY');map.put('spbill_create_ip',InetAddress.getLocalHost().getHostAddress().toString());//獲取調用支付接口的機器終端ipmap.put('goods_tag', '');map.put('limit_pay', '');map.put('time_start', '');map.put('auth_code','付款碼' );map.put('scene_info','');map.put('nonce_str', '');sign = APIUtil.createSign(map, apikey, 'utf-8');logger.info('sign:'+sign);map.put('sign',sign);xml = APIUtil.buildXML(map);try { if(visitUrl!=''||visitUrl!=null) { reStr= APIUtil.post(visitUrl, xml); System.out.println('reStr:'+reStr); if (reStr != null ) { xmlMap = APIUtil.reqMsg2Map(reStr); String reSign = APIUtil.createSign(xmlMap, apikey, 'utf-8'); logger.info(xmlMap.toString()); if (reSign.toLowerCase().equals(xmlMap.get('sign').toString().toLowerCase())) { logger.info('reSign', true); } } } logger.info('接口返回數據=' + reStr);} catch (Exception e) { // TODO Auto-generated catch block logger.error(e.getMessage());}return xmlMap;
1.首先要明確微信支付是使用MD5進行簽名的,這個是進行兩次驗簽的,一次支付前進行驗簽,一次接收微信返回數據后進行驗簽,目的是確保這是一次交易。驗簽我們必須明確:
當然按ASCII排序直接一個TreeMap搞定(不熟悉TreeMap的孩紙們自行查閱資料)。
2. 我們要知道你發過去的數據是個XML,所以必須用把你的參數構造成XML形式。
3. 返回給你的數據也是XML,所以你得轉兩次。
4. 發送數據了,你發現返回給你簽名錯誤,這時候從哪兒找問題呢?
(1)你的那些參數中有沒有中文,有的話進行編碼設置,可能你的數據已經亂碼
(2)你的商戶號和子商戶號有沒有寫對(首先要明確一點,你是服務商還是特約客戶,特約客戶就是子商戶,如果你是服務商,這兩個參數你都應該有,如果沒有請登陸商戶平臺進行查詢)
(3) 你的密鑰是否正確,加密的時候是拼接key的,所以確保你的key正確無誤,如果不確定key,可以登陸商戶平臺(pay.weixin.qq.com)-->賬戶設置-->API安全-->密鑰設置
(4)還有一種,這個就是我說的坑(話說微信的接口文檔真叫一個爛),如果你確定你的密鑰、商戶號、子商戶號、appid這些都正確的話,還報簽名錯誤,那么你可以去他們官方的簽名校驗工具(https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=20_1)檢驗下你的簽名算法是否正確,如果計算出來的簽名和你的簽名算法算出來一樣,那么恭喜你,踩坑了,重置你的密鑰再試試(有可能會重置好幾次哦,做好準備)。
(5) 如果很幸運,你成功調用了接口,這時候你高興的遞交了代碼,靜等測試給你反饋了,你覺得沒問題,很完美。好了,夢醒了,繼續測吧,bug很多:
① 你發現錢扣了,但是返回失敗,為什么呢?
明確一個很重要的點,return_code是通信表示,他返回成功知識說明你接口調通了,不能說明業務成功,業務成功看result_code。
② 你的用戶有可能開通了免密支付,如果免密支付,那你這個代碼很成功,no bug。如果你的用戶設置了非免密支付,那么bug來了。這時候result_code也是FAIL,但是錢扣了,怎么辦?如果你用debug調試,你會發現 err_code是USERPAYING,這就表明用戶在輸入密碼,所以你得調查詢訂單接口,去查詢訂單,不要立即去查,每隔10秒。
如果這個時候result_code和rade_state都返回成功,這才表示用戶支付成功了。
下來就是你根據自己的業務進行的一些操作,就不表述了,下來咋們看微信退款,支付是不需要證書的,但是退款需要雙向證書。你先要想一想你把證書放哪兒,兩個建議,第一種放數據庫(以二進制的形式存在BLOB類型),第二種放在resource里面單獨建一個文件夾。
我是以第二種形式存放的。
但是記得在pom.xml中配置。
微信退款和支付傳參、加密等一摸一樣,就不多說了,我只說重點,怎么加載呢?明確一下,咋們是不需要解析證書的!而且證書默認密碼是你的商戶號。
加載:KeyStore keyStore = KeyStore.getInstance('PKCS12');FileInputStream instream = new FileInputStream(new File('文件目錄'));//P12文件目錄try { keyStore.load(instream, '商戶號'.toCharArray());//這里寫密碼..默認是你的MCHID} finally { instream.close();}SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, '商戶號'.toCharArray())//這里也是寫密碼的 .build();// Allow TLSv1 protocol onlySSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[] { 'TLSv1' }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf) .build();
這樣你發現,加載成功了,但是你還是沒有調用成功,因為你沒設置響應頭信息,傳過去是亂碼!!!!相信我,你需要它,在你加載證書的工具類里把這些東西加上就完美了:
try { HttpPost httpost = new HttpPost(url); // 設置響應頭信息 httpost.addHeader('Connection', 'keep-alive'); httpost.addHeader('Accept', '*/*'); httpost.addHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); httpost.addHeader('Host', 'api.mch.weixin.qq.com'); httpost.addHeader('X-Requested-With', 'XMLHttpRequest'); httpost.addHeader('Cache-Control', 'max-age=0'); httpost.addHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) '); httpost.setEntity(new StringEntity(data, 'UTF-8')); CloseableHttpResponse response = httpclient.execute(httpost); try { HttpEntity entity = response.getEntity(); String jsonStr = EntityUtils.toString(response.getEntity(), 'UTF-8'); EntityUtils.consume(entity); return jsonStr; } finally { response.close(); }} finally { httpclient.close();}
這樣微信支付就完了,建議不要用撤銷接口,沒必要。
總結
以上是生活随笔為你收集整理的java微信刷卡支付demo,微信刷卡支付API详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vba批量合并指定的sheet_Exce
- 下一篇: 【笔记】蒙特卡洛树搜素(MCTS)与三子