麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

Java實現JsApi方式的微信支付

2019-11-15 00:59:17
字體:
來源:轉載
供稿:網友
java實現JsApi方式的微信支付

要使用JsApi進行微信支付,首先要從微信獲得一個PRepay_id,然后通過調用微信的jsapi完成支付,JS API的返回結果get_brand_wcpay_request:ok僅在用戶成功完成支付時返回。由于前端交互復雜,get_brand_wcpay_request:cancel或者get_brand_wcpay_request:fail可以統一處理為用戶遇到錯誤或者主動放棄,不必細化區分。示例代碼如下:

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詳細文檔見:https://pay.weixin.QQ.com/wiki/doc/api/jsapi.php?chapter=7_7

下面講的是獲得參數來調用jsapi我們調用JSAPI時,必須獲得用戶的openid,(trade_type=JSAPI,openid為必填參數。)首先定義一個請求的對象:

package com.unstoppedable.protocol;import com.thoughtworks.xstream.annotations.XStreamAlias;import com.unstoppedable.common.Configure;import com.unstoppedable.common.RandomStringGenerator;import com.unstoppedable.common.Signature;import java.lang.reflect.Field;import java.util.HashMap;import java.util.Map;@XStreamAlias("xml")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 String getAppid() {        return appid;    }    public String getMch_id() {        return mch_id;    }    public String getDevice_info() {        return device_info;    }    public String getNonce_str() {        return nonce_str;    }    public String getSign() {        return sign;    }    public String getBody() {        return body;    }    public String getDetail() {        return detail;    }    public String getAttach() {        return attach;    }    public String getOut_trade_no() {        return out_trade_no;    }    public String getFee_type() {        return fee_type;    }    public int getTotal_fee() {        return total_fee;    }    public String getSpbill_create_ip() {        return spbill_create_ip;    }    public String getTime_start() {        return time_start;    }    public String getTime_expire() {        return time_expire;    }    public String getGoods_tag() {        return goods_tag;    }    public String getNotify_url() {        return notify_url;    }    public String getTrade_type() {        return trade_type;    }    public String getProduct_id() {        return product_id;    }    public String getLimit_pay() {        return limit_pay;    }    public String getOpenid() {        return 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;        /**         * 使用配置中的 appid 和  mch_id         *         * @param body         * @param out_trade_no         * @param total_fee         * @param spbill_create_ip         * @param notify_url         * @param trade_type         */        public UnifiedOrderReqDataBuilder(String body, String out_trade_no, Integer total_fee,                                          String spbill_create_ip, String notify_url, String trade_type) {            this(Configure.getAppid(), Configure.getMchid(), body, out_trade_no, total_fee,                    spbill_create_ip, notify_url, trade_type);        }        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模式。關于每個參數的定義,參考說明文檔https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

我們選用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中使用他就可以了。。

代碼托管在https://github.com/hupengcool/wxpay_jsapi ,歡迎指正


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产一区二区三区黄 | 男人午夜小视频 | 久久精品国产久精国产 | 九九热在线免费观看视频 | 斗破苍穹在线免费 | 成人午夜视频在线观看免费 | 美女黄网站免费观看 | 欧美亚成人 | 香蕉黄色网 | 99视频在线观看视频 | 国产精品爱久久久久久久 | 欧美成人做爰高潮片免费视频 | 成年免费视频黄网站在线观看 | 免费观看视频网站 | 中国黄色一级生活片 | 欧美成人黄色 | 久久吊 | 国产精品一区二区视频 | 久久人添人人爽人人爽人人片av | 成年免费视频黄网站在线观看 | 一色桃子av大全在线播放 | 黄色毛片一级视频 | 日韩黄网站 | 亚洲一区在线观看视频 | 永久免费黄色片 | 国产影院在线观看 | 北原夏美av | 91色一区二区三区 | 福利在线影院 | 免费男女视频 | 欧美性生活网站 | 久久精品视频1 | 欧美三级短视频 | 成人在线视频黄色 | 国产精品999在线观看 | asian附近女人裸体pics | 久久久久久久久久综合 | av在线在线| 久久久久一本一区二区青青蜜月 | 亚洲码无人客一区二区三区 | 色视频在线观看 |