详解Java通过JsApi方式实现微信支付方法

互联网 17-3-27
本文讲解了Java如何实现JsApi方式的微信支付,代码内容详细,文章思路清晰,需要的朋友可以参考下
function onBridgeReady(){   WeixinJSBridge.invoke(   'getBrandWCPayRequest', {    "appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入     "timeStamp":" 1395712654",  //时间戳,自1970年以来的秒数     "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串     "package" : "u802345jgfjsdfgsdg888",     "signType" : "MD5",  //微信签名方式:     "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名    },   function(res){     if(res.err_msg == "get_brand_wcpay_request:ok" ) {} // 使用以上方式判断前端返回,微信团队郑重提示: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();  }

以上传入的参数package,即为prepay_id

下面讲的是获得参数来调用jsapi我们调用JSAPI时,必须获得用户的openid,(trade_type=JSAPI,openid为必填参数。)首先定义一个请求的对象:

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 Map<String, Object> toMap() {   Map<String, Object> map = new HashMap<String, Object>();   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("传入参数appid不能为null");    }    if (mch_id == null) {    throw new IllegalArgumentException("传入参数mch_id不能为null");    }    if (body == null) {    throw new IllegalArgumentException("传入参数body不能为null");    }    if (out_trade_no == null) {    throw new IllegalArgumentException("传入参数out_trade_no不能为null");    }    if (total_fee == null) {    throw new IllegalArgumentException("传入参数total_fee不能为null");    }    if (spbill_create_ip == null) {    throw new IllegalArgumentException("传入参数spbill_create_ip不能为null");    }    if (notify_url == null) {    throw new IllegalArgumentException("传入参数notify_url不能为null");    }    if (trade_type == null) {    throw new IllegalArgumentException("传入参数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("当传入trade_type为JSAPI时,openid为必填参数");    }    if("NATIVE".equals(this.trade_type) && this.product_id == null) {    throw new IllegalArgumentException("当传入trade_type为NATIVE时,product_id为必填参数");    }    return new UnifiedOrderReqData(this);   }   }  }

因为有些参数为必填,有些参数为选填。而且sign要等所有参数传入之后才能计算的出,所以这里用了builder模式。关于builder模式。

我们选用httpclient进行网络传输。

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();   //连接超时时间,默认10秒   private static int socketTimeout = 5000;   //传输超时时间,默认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()));//加载本地的证书进行https加密传输    try {    keyStore.load(instream, Configure.getCertPassword().toCharArray());//设置证书密码    } 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    ResponseHandler<String> responseHandler = new ResponseHandler<String>() {    @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对出现双下划线的bug   XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));   //将要提交给API的数据对象转换成XML格式数据Post给API   String postDataXML = xStreamForRequestPostData.toXML(object2Xml);   logger.info("API,POST过去的数据是:");   logger.info(postDataXML);   //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别   StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");   httpPost.addHeader("Content-Type", "text/xml");   httpPost.setEntity(postEntity);   //设置请求器的配置   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;   }  }

然后是我们的总入口:

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 Map<String,Object> UnifiedOrder(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为:

<xml>   <return_code><![CDATA[SUCCESS]]></return_code>   <return_msg><![CDATA[OK]]></return_msg>   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>   <mch_id><![CDATA[10000100]]></mch_id>   <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>   <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>   <result_code><![CDATA[SUCCESS]]></result_code>   <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>   <trade_type><![CDATA[JSAPI]]></trade_type>  </xml>

return_code 和result_code都为SUCCESS的时候会返回我们需要的prepay_id。。。,然后在jsapi中使用他就可以了。。

以上就是详解Java通过JsApi方式实现微信支付方法的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:Android 高仿微信支付数字键盘功能

相关资讯