小編給大家分享一下Java通過JsApi方式如何實現(xiàn)微信支付,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:主機(jī)域名、雅安服務(wù)器托管、營銷軟件、網(wǎng)站建設(shè)、大慶網(wǎng)站維護(hù)、網(wǎng)站推廣。
要使用JsApi進(jìn)行微信支付,首先要從微信獲得一個prepay_id,然后通過調(diào)用微信的jsapi完成支付,JS API的返回結(jié)果get_brand_wcpay_request:ok僅在用戶成功完成支付時返回。由于前端交互復(fù)雜,get_brand_wcpay_request:cancel或者get_brand_wcpay_request:fail可以統(tǒng)一處理為用戶遇到錯誤或者主動放棄,不必細(xì)化區(qū)分。
示例代碼如下:
function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId" : "wx2421b1c4370ec43b", //公眾號名稱,由商戶傳入 "timeStamp":" 1395712654", //時間戳,自1970年以來的秒數(shù) "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //隨機(jī)串 "package" : "u802345jgfjsdfgsdg888", "signType" : "MD5", //微信簽名方式: "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信簽名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ) {} // 使用以上方式判斷前端返回,微信團(tuán)隊鄭重提示:res.err_msg將在用戶支付成功后返回 ok,但并不保證它絕對可靠。 } ); } 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{ onBridgeReady(); }
以上傳入的參數(shù)package,即為prepay_id
下面講的是獲得參數(shù)來調(diào)用jsapi
我們調(diào)用JSAPI時,必須獲得用戶的openid,(trade_type=JSAPI,openid為必填參數(shù)。)
首先定義一個請求的對象:
package com.unstoppedable.protocol; import com.unstoppedable.common.Configure; import com.unstoppedable.common.HttpService; import com.unstoppedable.common.RandomStringGenerator; import com.unstoppedable.common.Signature; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; public class UnifiedOrderReqData { private String appid; private String mch_id; private String device_info; private String nonce_str; private String sign; private String body; private String detail; private String attach; private String out_trade_no; private String fee_type; private int total_fee; private String spbill_create_ip; private String time_start; private String time_expire; private String goods_tag; private String notify_url; private String trade_type; private String product_id; private String limit_pay; private String openid; private UnifiedOrderReqData(UnifiedOrderReqDataBuilder builder) { this.appid = builder.appid; this.mch_id = builder.mch_id; this.device_info = builder.device_info; this.nonce_str = RandomStringGenerator.getRandomStringByLength(32); this.body = builder.body; this.detail = builder.detail; this.attach = builder.attach; this.out_trade_no = builder.out_trade_no; this.fee_type = builder.fee_type; this.total_fee = builder.total_fee; this.spbill_create_ip = builder.spbill_create_ip; this.time_start = builder.time_start; this.time_expire = builder.time_expire; this.goods_tag = builder.goods_tag; this.notify_url = builder.notify_url; this.trade_type = builder.trade_type; this.product_id = builder.product_id; this.limit_pay = builder.limit_pay; this.openid = builder.openid; this.sign = Signature.getSign(toMap()); } public void setAppid(String appid) { this.appid = appid; } public void setMch_id(String mch_id) { this.mch_id = mch_id; } public void setDevice_info(String device_info) { this.device_info = device_info; } public void setNonce_str(String nonce_str) { this.nonce_str = nonce_str; } public void setSign(String sign) { this.sign = sign; } public void setBody(String body) { this.body = body; } public void setDetail(String detail) { this.detail = detail; } public void setAttach(String attach) { this.attach = attach; } public void setOut_trade_no(String out_trade_no) { this.out_trade_no = out_trade_no; } public void setFee_type(String fee_type) { this.fee_type = fee_type; } public void setTotal_fee(int total_fee) { this.total_fee = total_fee; } public void setSpbill_create_ip(String spbill_create_ip) { this.spbill_create_ip = spbill_create_ip; } public void setTime_start(String time_start) { this.time_start = time_start; } public void setTime_expire(String time_expire) { this.time_expire = time_expire; } public void setGoods_tag(String goods_tag) { this.goods_tag = goods_tag; } public void setNotify_url(String notify_url) { this.notify_url = notify_url; } public void setTrade_type(String trade_type) { this.trade_type = trade_type; } public void setProduct_id(String product_id) { this.product_id = product_id; } public void setLimit_pay(String limit_pay) { this.limit_pay = limit_pay; } public void setOpenid(String openid) { this.openid = openid; } public MaptoMap() { Map map = new HashMap (); Field[] fields = this.getClass().getDeclaredFields(); for (Field field : fields) { Object obj; try { obj = field.get(this); if (obj != null) { map.put(field.getName(), obj); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return map; } public static class UnifiedOrderReqDataBuilder { private String appid; private String mch_id; private String device_info; private String body; private String detail; private String attach; private String out_trade_no; private String fee_type; private int total_fee; private String spbill_create_ip; private String time_start; private String time_expire; private String goods_tag; private String notify_url; private String trade_type; private String product_id; private String limit_pay; private String openid; public UnifiedOrderReqDataBuilder(String appid, String mch_id, String body, String out_trade_no, Integer total_fee, String spbill_create_ip, String notify_url, String trade_type) { if (appid == null) { throw new IllegalArgumentException("傳入?yún)?shù)appid不能為null"); } if (mch_id == null) { throw new IllegalArgumentException("傳入?yún)?shù)mch_id不能為null"); } if (body == null) { throw new IllegalArgumentException("傳入?yún)?shù)body不能為null"); } if (out_trade_no == null) { throw new IllegalArgumentException("傳入?yún)?shù)out_trade_no不能為null"); } if (total_fee == null) { throw new IllegalArgumentException("傳入?yún)?shù)total_fee不能為null"); } if (spbill_create_ip == null) { throw new IllegalArgumentException("傳入?yún)?shù)spbill_create_ip不能為null"); } if (notify_url == null) { throw new IllegalArgumentException("傳入?yún)?shù)notify_url不能為null"); } if (trade_type == null) { throw new IllegalArgumentException("傳入?yún)?shù)trade_type不能為null"); } this.appid = appid; this.mch_id = mch_id; this.body = body; this.out_trade_no = out_trade_no; this.total_fee = total_fee; this.spbill_create_ip = spbill_create_ip; this.notify_url = notify_url; this.trade_type = trade_type; } public UnifiedOrderReqDataBuilder setDevice_info(String device_info) { this.device_info = device_info; return this; } public UnifiedOrderReqDataBuilder setDetail(String detail) { this.detail = detail; return this; } public UnifiedOrderReqDataBuilder setAttach(String attach) { this.attach = attach; return this; } public UnifiedOrderReqDataBuilder setFee_type(String fee_type) { this.fee_type = fee_type; return this; } public UnifiedOrderReqDataBuilder setTime_start(String time_start) { this.time_start = time_start; return this; } public UnifiedOrderReqDataBuilder setTime_expire(String time_expire) { this.time_expire = time_expire; return this; } public UnifiedOrderReqDataBuilder setGoods_tag(String goods_tag) { this.goods_tag = goods_tag; return this; } public UnifiedOrderReqDataBuilder setProduct_id(String product_id) { this.product_id = product_id; return this; } public UnifiedOrderReqDataBuilder setLimit_pay(String limit_pay) { this.limit_pay = limit_pay; return this; } public UnifiedOrderReqDataBuilder setOpenid(String openid) { this.openid = openid; return this; } public UnifiedOrderReqData build() { if("JSAPI".equals(this.trade_type) && this.openid == null) { throw new IllegalArgumentException("當(dāng)傳入trade_type為JSAPI時,openid為必填參數(shù)"); } if("NATIVE".equals(this.trade_type) && this.product_id == null) { throw new IllegalArgumentException("當(dāng)傳入trade_type為NATIVE時,product_id為必填參數(shù)"); } return new UnifiedOrderReqData(this); } } }
因為有些參數(shù)為必填,有些參數(shù)為選填。而且sign要等所有參數(shù)傳入之后才能計算的出,所以這里用了builder模式。關(guān)于builder模式。
我們選用httpclient進(jìn)行網(wǎng)絡(luò)傳輸。
package com.unstoppedable.common; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.SocketTimeoutException; import java.security.KeyStore; /** * Created by hupeng on 2015/7/28. */ public class HttpService { private static Log logger = LogFactory.getLog(HttpService.class); private static CloseableHttpClient httpClient = buildHttpClient(); //連接超時時間,默認(rèn)10秒 private static int socketTimeout = 5000; //傳輸超時時間,默認(rèn)30秒 private static int connectTimeout = 5000; private static int requestTimeout = 5000; public static CloseableHttpClient buildHttpClient() { try { KeyStore keyStore = KeyStore.getInstance("PKCS12"); FileInputStream instream = new FileInputStream(new File(Configure.getCertLocalPath()));//加載本地的證書進(jìn)行https加密傳輸 try { keyStore.load(instream, Configure.getCertPassword().toCharArray());//設(shè)置證書密碼 } finally { instream.close(); } // Trust own CA and all self-signed certs SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, Configure.getCertPassword().toCharArray()) .build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(connectTimeout) .setConnectionRequestTimeout(requestTimeout) .setSocketTimeout(socketTimeout).build(); httpClient = HttpClients.custom() .setDefaultRequestConfig(requestConfig) .setSSLSocketFactory(sslsf) .build(); return httpClient; } catch (Exception e) { throw new RuntimeException("error create httpclient......", e); } } public static String doGet(String requestUrl) throws Exception { HttpGet httpget = new HttpGet(requestUrl); try { logger.debug("Executing request " + httpget.getRequestLine()); // Create a custom response handler ResponseHandlerresponseHandler = new ResponseHandler () { @Override public String handleResponse( final HttpResponse response) throws ClientProtocolException, IOException { int status = response.getStatusLine().getStatusCode(); if (status >= 200 && status < 300) { HttpEntity entity = response.getEntity(); return entity != null ? EntityUtils.toString(entity) : null; } else { throw new ClientProtocolException("Unexpected response status: " + status); } } }; return httpClient.execute(httpget, responseHandler); } finally { httpget.releaseConnection(); } } public static String doPost(String url, Object object2Xml) { String result = null; HttpPost httpPost = new HttpPost(url); //解決XStream對出現(xiàn)雙下劃線的bug XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_"))); //將要提交給API的數(shù)據(jù)對象轉(zhuǎn)換成XML格式數(shù)據(jù)Post給API String postDataXML = xStreamForRequestPostData.toXML(object2Xml); logger.info("API,POST過去的數(shù)據(jù)是:"); logger.info(postDataXML); //得指明使用UTF-8編碼,否則到API服務(wù)器XML的中文不能被成功識別 StringEntity postEntity = new StringEntity(postDataXML, "UTF-8"); httpPost.addHeader("Content-Type", "text/xml"); httpPost.setEntity(postEntity); //設(shè)置請求器的配置 logger.info("executing request" + httpPost.getRequestLine()); try { HttpResponse response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); result = EntityUtils.toString(entity, "UTF-8"); } catch (ConnectionPoolTimeoutException e) { logger.error("http get throw ConnectionPoolTimeoutException(wait time out)", e); } catch (ConnectTimeoutException e) { logger.error("http get throw ConnectTimeoutException", e); } catch (SocketTimeoutException e) { logger.error("http get throw SocketTimeoutException", e); } catch (Exception e) { logger.error("http get throw Exception", e); } finally { httpPost.abort(); } return result; } }
然后是我們的總?cè)肟冢?/p>
package com.unstoppedable.service; import com.unstoppedable.common.Configure; import com.unstoppedable.common.HttpService; import com.unstoppedable.common.XMLParser; import com.unstoppedable.protocol.UnifiedOrderReqData; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.util.Map; /** * Created by hupeng on 2015/7/28. */ public class WxPayApi { public static MapUnifiedOrder(UnifiedOrderReqData reqData) throws IOException, SAXException, ParserConfigurationException { String res = HttpService.doPost(Configure.UNIFIED_ORDER_API, reqData); return XMLParser.getMapFromXML(res); } public static void main(String[] args) throws Exception { UnifiedOrderReqData reqData = new UnifiedOrderReqData.UnifiedOrderReqDataBuilder("appid", "mch_id", "body", "out_trade_no", 1, "spbill_create_ip", "notify_url", "JSAPI").setOpenid("openid").build(); System.out.println(UnifiedOrder(reqData)); } }
返回的xml為:
return_code 和result_code都為SUCCESS的時候會返回我們需要的prepay_id。。。,然后在jsapi中使用他就可以了。。
以上是“Java通過JsApi方式如何實現(xiàn)微信支付”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!