境外支付宝接口对接--报关接口

刚刚把支付接口对接完成,原以为报关是支付宝调用的,后来才发现也要自己掉支付宝的接口.啥也不说了看代码:

可以下载demo,额.连接不知道怎么添加,需要的可以私信.

我这里是用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 }

分别编写一个请求和相应对象:

请求对象

  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 }

响应对象:

 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:

 /**
     * 生成请求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;

    }

测试:

 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>
原文地址:https://www.cnblogs.com/cunkouzh/p/5640633.html