境外支付寶接口對接--報關接口

剛剛把支付接口對接完成,原覺得報關是支付寶調用的,後來才發現也要本身掉支付寶的接口.啥也不說了看代碼:html

能夠下載demo,額.鏈接不知道怎麼添加,須要的能夠私信.api

我這裏是用httpclient發送請求的.首先獲取httpclient的實力,工廠類:數組

  1 public class HttpProtocolHandler {
  2 
  3     private static String              DEFAULT_CHARSET                     = "GBK";
  4 
  5     /** 鏈接超時時間,由bean factory設置,缺省爲8秒鐘 */
  6     private int                        defaultConnectionTimeout            = 8000;
  7 
  8     /** 迴應超時時間, 由bean factory設置,缺省爲30秒鐘 */
  9     private int                        defaultSoTimeout                    = 30000;
 10 
 11     /** 閒置鏈接超時時間, 由bean factory設置,缺省爲60秒鐘 */
 12     private int                        defaultIdleConnTimeout              = 60000;
 13 
 14     private int                        defaultMaxConnPerHost               = 30;
 15 
 16     private int                        defaultMaxTotalConn                 = 80;
 17 
 18     /** 默認等待HttpConnectionManager返回鏈接超時(只有在達到最大鏈接數時起做用):1秒*/
 19     private static final long          defaultHttpConnectionManagerTimeout = 3 * 1000;
 20 
 21     /**
 22      * HTTP鏈接管理器,該鏈接管理器必須是線程安全的.
 23      */
 24     private HttpConnectionManager      connectionManager;
 25 
 26     private static HttpProtocolHandler httpProtocolHandler                 = new HttpProtocolHandler();
 27 
 28     /**
 29      * 工廠方法
 30      * 
 31      * @return
 32      */
 33     public static HttpProtocolHandler getInstance() {
 34         return httpProtocolHandler;
 35     }
 36 
 37     /**
 38      * 私有的構造方法
 39      */
 40     private HttpProtocolHandler() {
 41         // 建立一個線程安全的HTTP鏈接池
 42         connectionManager = new MultiThreadedHttpConnectionManager();
 43         connectionManager.getParams().setDefaultMaxConnectionsPerHost(defaultMaxConnPerHost);
 44         connectionManager.getParams().setMaxTotalConnections(defaultMaxTotalConn);
 45 
 46         IdleConnectionTimeoutThread ict = new IdleConnectionTimeoutThread();
 47         ict.addConnectionManager(connectionManager);
 48         ict.setConnectionTimeout(defaultIdleConnTimeout);
 49 
 50         ict.start();
 51     }
 52 
 53     /**
 54      * 執行Http請求
 55      * 
 56      * @param request 請求數據
 57      * @param strParaFileName 文件類型的參數名
 58      * @param strFilePath 文件路徑
 59      * @return 
 60      * @throws HttpException, IOException 
 61      */
 62     public HttpResponse execute(HttpRequest request, String strParaFileName, String strFilePath) throws HttpException, IOException {
 63         HttpClient httpclient = new HttpClient(connectionManager);
 64 
 65         // 設置鏈接超時
 66         int connectionTimeout = defaultConnectionTimeout;
 67         if (request.getConnectionTimeout() > 0) {
 68             connectionTimeout = request.getConnectionTimeout();
 69         }
 70         httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);
 71 
 72         // 設置迴應超時
 73         int soTimeout = defaultSoTimeout;
 74         if (request.getTimeout() > 0) {
 75             soTimeout = request.getTimeout();
 76         }
 77         httpclient.getHttpConnectionManager().getParams().setSoTimeout(soTimeout);
 78 
 79         // 設置等待ConnectionManager釋放connection的時間
 80         httpclient.getParams().setConnectionManagerTimeout(defaultHttpConnectionManagerTimeout);
 81 
 82         String charset = request.getCharset();
 83         charset = charset == null ? DEFAULT_CHARSET : charset;
 84         HttpMethod method = null;
 85 
 86         //get模式且不帶上傳文件
 87         if (request.getMethod().equals(HttpRequest.METHOD_GET)) {
 88             method = new GetMethod(request.getUrl());
 89             method.getParams().setCredentialCharset(charset);
 90 
 91             // parseNotifyConfig會保證使用GET方法時,request必定使用QueryString
 92             method.setQueryString(request.getQueryString());
 93         } else if(strParaFileName.equals("") && strFilePath.equals("")) {
 94             //post模式且不帶上傳文件
 95             method = new PostMethod(request.getUrl());
 96             ((PostMethod) method).addParameters(request.getParameters());
 97             method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; text/html; charset=" + charset);
 98         }
 99         else {
100             //post模式且帶上傳文件
101             method = new PostMethod(request.getUrl());
102             List<Part> parts = new ArrayList<Part>();
103             for (int i = 0; i < request.getParameters().length; i++) {
104                 parts.add(new StringPart(request.getParameters()[i].getName(), request.getParameters()[i].getValue(), charset));
105             }
106             //增長文件參數,strParaFileName是參數名,使用本地文件
107             parts.add(new FilePart(strParaFileName, new FilePartSource(new File(strFilePath))));
108             
109             // 設置請求體
110             ((PostMethod) method).setRequestEntity(new MultipartRequestEntity(parts.toArray(new Part[0]), new HttpMethodParams()));
111         }
112 
113         // 設置Http Header中的User-Agent屬性
114         method.addRequestHeader("User-Agent", "Mozilla/4.0");
115         HttpResponse response = new HttpResponse();
116 
117         try {
118             httpclient.executeMethod(method);
119             if (request.getResultType().equals(HttpResultType.STRING)) {
120                 response.setStringResult(method.getResponseBodyAsString());
121             } else if (request.getResultType().equals(HttpResultType.BYTES)) {
122                 response.setByteResult(method.getResponseBody());
123             }
124             response.setResponseHeaders(method.getResponseHeaders());
125         } catch (UnknownHostException ex) {
126 
127             return null;
128         } catch (IOException ex) {
129 
130             return null;
131         } catch (Exception ex) {
132 
133             return null;
134         } finally {
135             method.releaseConnection();
136         }
137         return response;
138     }
139 
140     /**
141      * 將NameValuePairs數組轉變爲字符串
142      * 
143      * @param nameValues
144      * @return
145      */
146     protected String toString(NameValuePair[] nameValues) {
147         if (nameValues == null || nameValues.length == 0) {
148             return "null";
149         }
150 
151         StringBuffer buffer = new StringBuffer();
152 
153         for (int i = 0; i < nameValues.length; i++) {
154             NameValuePair nameValue = nameValues[i];
155 
156             if (i == 0) {
157                 buffer.append(nameValue.getName() + "=" + nameValue.getValue());
158             } else {
159                 buffer.append("&" + nameValue.getName() + "=" + nameValue.getValue());
160             }
161         }
162 
163         return buffer.toString();
164     }
165 }

分別編寫一個請求和相應對象:安全

請求對象app

  1 public class HttpRequest {
  2 
  3     /** HTTP GET method */
  4     public static final String METHOD_GET        = "GET";
  5 
  6     /** HTTP POST method */
  7     public static final String METHOD_POST       = "POST";
  8 
  9     /**
 10      * 待請求的url
 11      */
 12     private String             url               = null;
 13 
 14     /**
 15      * 默認的請求方式
 16      */
 17     private String             method            = METHOD_POST;
 18 
 19     private int                timeout           = 0;
 20 
 21     private int                connectionTimeout = 0;
 22 
 23     /**
 24      * Post方式請求時組裝好的參數值對
 25      */
 26     private NameValuePair[]    parameters        = null;
 27 
 28     /**
 29      * Get方式請求時對應的參數
 30      */
 31     private String             queryString       = null;
 32 
 33     /**
 34      * 默認的請求編碼方式
 35      */
 36     private String             charset           = "GBK";
 37 
 38     /**
 39      * 請求發起方的ip地址
 40      */
 41     private String             clientIp;
 42 
 43     /**
 44      * 請求返回的方式
 45      */
 46     private HttpResultType     resultType        = HttpResultType.BYTES;
 47 
 48     public HttpRequest(HttpResultType resultType) {
 49         super();
 50         this.resultType = resultType;
 51     }
 52 
 53     /**
 54      * @return Returns the clientIp.
 55      */
 56     public String getClientIp() {
 57         return clientIp;
 58     }
 59 
 60     /**
 61      * @param clientIp The clientIp to set.
 62      */
 63     public void setClientIp(String clientIp) {
 64         this.clientIp = clientIp;
 65     }
 66 
 67     public NameValuePair[] getParameters() {
 68         return parameters;
 69     }
 70 
 71     public void setParameters(NameValuePair[] parameters) {
 72         this.parameters = parameters;
 73     }
 74 
 75     public String getQueryString() {
 76         return queryString;
 77     }
 78 
 79     public void setQueryString(String queryString) {
 80         this.queryString = queryString;
 81     }
 82 
 83     public String getUrl() {
 84         return url;
 85     }
 86 
 87     public void setUrl(String url) {
 88         this.url = url;
 89     }
 90 
 91     public String getMethod() {
 92         return method;
 93     }
 94 
 95     public void setMethod(String method) {
 96         this.method = method;
 97     }
 98 
 99     public int getConnectionTimeout() {
100         return connectionTimeout;
101     }
102 
103     public void setConnectionTimeout(int connectionTimeout) {
104         this.connectionTimeout = connectionTimeout;
105     }
106 
107     public int getTimeout() {
108         return timeout;
109     }
110 
111     public void setTimeout(int timeout) {
112         this.timeout = timeout;
113     }
114 
115     /**
116      * @return Returns the charset.
117      */
118     public String getCharset() {
119         return charset;
120     }
121 
122     /**
123      * @param charset The charset to set.
124      */
125     public void setCharset(String charset) {
126         this.charset = charset;
127     }
128 
129     public HttpResultType getResultType() {
130         return resultType;
131     }
132 
133     public void setResultType(HttpResultType resultType) {
134         this.resultType = resultType;
135     }
136 
137 }

響應對象:post

 1 public class HttpResponse {
 2 
 3     /**
 4      * 返回中的Header信息
 5      */
 6     private Header[] responseHeaders;
 7 
 8     /**
 9      * String類型的result
10      */
11     private String   stringResult;
12 
13     /**
14      * btye類型的result
15      */
16     private byte[]   byteResult;
17 
18     public Header[] getResponseHeaders() {
19         return responseHeaders;
20     }
21 
22     public void setResponseHeaders(Header[] responseHeaders) {
23         this.responseHeaders = responseHeaders;
24     }
25 
26     public byte[] getByteResult() {
27         if (byteResult != null) {
28             return byteResult;
29         }
30         if (stringResult != null) {
31             return stringResult.getBytes();
32         }
33         return null;
34     }
35 
36     public void setByteResult(byte[] byteResult) {
37         this.byteResult = byteResult;
38     }
39 
40     public String getStringResult() throws UnsupportedEncodingException {
41         if (stringResult != null) {
42             return stringResult;
43         }
44         if (byteResult != null) {
45             return new String(byteResult, AlipayConfig.input_charset);
46         }
47         return null;
48     }
49 
50     public void setStringResult(String stringResult) {
51         this.stringResult = stringResult;
52     }
53 
54 }

分別一個生產url和轉換參數的方法:
拼接參數:測試

 1 /**
 2      * 拼接請求參數
 3      * @param params
 4      * @param privateKey
 5      * @return
 6      */
 7     private static String getContent(Map params, String privateKey) {
 8         Map map = params;
 9         List keys = new ArrayList(map.keySet());
10         Collections.sort(keys);
11 
12         String prestr = "";
13 
14         for (int i = 0; i < keys.size(); i++) {
15             String key = (String) keys.get(i);
16             String value = (String) map.get(key);
17 
18             if (i == keys.size() - 1) {
19                 prestr = prestr + key + "=" + value;
20             } else {
21                 prestr = prestr + key + "=" + value + "&";
22             }
23         }
24 //        String p = prestr + privateKe+"&forex_biz=\"FP\"";
25         String p = "";
26         if(StringUtils.isNotBlank(privateKey)){
27              p = prestr+privateKey;
28             
29         } else {
30             p = prestr;
31         }
32         return p;
33     }

生產url:ui

 /**
     * 生成請求url
     * @param params
     * @param key
     * @param paygateway
     * @param input_charset
     * @return
     */
    public static String createUrl( Map<String,Object> params ,String key, String paygateway,String input_charset,String sign_type) {
        String prestr = "";
        prestr = prestr + key;
        //System.out.println("prestr=" + prestr);

        String sign = DigestUtils.md5Hex(getContent(params, key));
        String parameter = "";
        parameter = parameter + paygateway;

        List<Object> keys = new ArrayList<Object>(params.keySet());
        for (int i = 0; i < keys.size(); i++) {
            try {
                parameter = parameter + keys.get(i) + "="
                            + URLEncoder.encode((String) params.get(keys.get(i)), input_charset) + "&";
            } catch (UnsupportedEncodingException e) {

                e.printStackTrace();
            }
        }

        parameter = parameter + "sign=" + sign + "&sign_type="+sign_type;

        return parameter;

    }

測試:this

 1 public static void main(String[] args) {
 2         //報關
 3         Map<String, Object> params = new HashMap<String, Object>();
 4         //一下的參數參考pdf裏面的必填參數
 5         params.put("service", "alipay.acquire.customs");
 6         params.put("partner", AlipayConfig.partner);
 7         params.put("_input_charset", AlipayConfig.input_charset);
 8         params.put("trade_no", "2016070421001003100000009481");//這個是支付成功後,支付寶返回的支付流水號,若是你在支付的時候沒有保存,那麼就搞大了
 9         params.put("out_request_no", StringUtil.timeStamp("BG"));///報關的流水號,用系統時間幾號,方法不貼了
10 //        params.put("is_split","T");
11 //        params.put("merchant_customs_code", "hanguo");
12         params.put("merchant_customs_code", "ZF14021901");//注意,這裏是你商品所在倉庫的備案號,並非支付寶備案號.用支付寶的備案號會致使:申報數據中電商平臺不一致(看我的緣由)
13         params.put("customs_place", "HANGZHOU");//海關編號
14         params.put("merchant_customs_name", "jwyhanguo_card");//商戶海關備案編號名稱
15         params.put("amount","1");
16         String createUrl = createUrl(params, AlipayConfig.key, "https://openapi.alipaydev.com/gateway.do?", "utf-8",AlipayConfig.sign_type);
17         System.out.println("請求url:"+createUrl);
18         try {
19             HttpProtocolHandler httpProtocolHandler = HttpProtocolHandler.getInstance();
20             HttpRequest request = new HttpRequest(HttpResultType.STRING);
21             //設置編碼集
22             request.setCharset(AlipayConfig.input_charset);
23             request.setUrl(createUrl);//支付寶測試環境
24             System.out.println(request.getUrl());
25             HttpResponse response = httpProtocolHandler.execute(request,"","");
26             String stringResult = response.getStringResult();
27         } catch (Exception e) {
28             e.printStackTrace();
29         }
30     }

返回成功信息--案例:編碼

 1 <alipay>
 2 <is_success>T</is_success>
 3 <request>
 4 <param name="sign">0b69f5e1fd796b944c9749e832979ffb</param>
 5 <param name="amount">1</param>
 6 <param name="merchant_customs_code">hanguo</param>
 7 <param name="trade_no">2016052500001000100000599501</param>
 8 <param name="_input_charset">utf-8</param>
 9 <param name="customs_place">HANGZHOU</param>
10 <param name="sign_type">MD5</param>
11 <param name="service">alipay.acquire.customs</param>
12 <param name="out_request_no">201505252210</param>
13 <param name="partner">2088101122136241</param>
14 <param name="merchant_customs_name">jwyhanguo_card</param>
15 </request>
16 <response>
17 <alipay>
18 <alipay_declare_no>2016052511082107300001603</alipay_declare_no>
19 <out_request_no>201505252210</out_request_no>
20 <result_code>SUCCESS</result_code>
21 <trade_no>2016052500001000100000599501</trade_no>
22 </alipay>
23 </response>
24 <sign>ad6d244175cda04a3736af16d9f2da1e</sign>
25 <sign_type>MD5</sign_type>
26 </alipay>
相關文章
相關標籤/搜索