• 支付宝报关接口开发


    1,开通海关报关产品 ,不能登录账号,登陆账号是看不到产品的

    地址:https://b.alipay.com/order/productDetail.htm?productId=2015112418944074
    在这里插入图片描述

    2,产品开通成功后,查看报关的开发文档

    地址:https://docs.open.alipay.com/155/104778/
    在这里插入图片描述

    3,官方提供了项目demo,支持三种语言

    在这里插入图片描述

    4,整合到springboot 项目,使用MD5加密方式

    (1),application.yml里面添加,根据自己的参数修改里面值

    alipay:
      #合作身份者ID
      partnerId: 2088***********
      #商户的私钥 根据加密类型,填写:MD5 ,RSA
      privateKey: ***********
      #字符编码格式
      inputCharset: utf-8
      #签名方式
      ignType: MD5
      #广州总署海关
      customs: ZONGSHU
      #商户海关备案号
      mchCustomsNo: ***********
      #商户海关备案名称
      mchCustomsName: ***********
      #接口名称
      service: alipay.acquire.customs
      #接口地址
      payGateWay: https://mapi.alipay.com/gateway.do?
    

    (2)下面代码是工具类,httpclient的一些代码

    package io.renren.utils.alipay;
    
    import org.apache.commons.codec.digest.DigestUtils;
    import org.apache.commons.lang.StringUtils;
    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    
    public class AlipayUtil {
        /**
         * 生成请求url
         * @param params
         * @param key
         * @param paygateway
         * @param input_charset
         * @return
         */
        public static String createUrl( Map<String,String> params ,String key, String paygateway,String input_charset,String sign_type) {
            String prestr = "";
            prestr = prestr + key;
            String sign = DigestUtils.md5Hex(getContent(params, key));
            String parameter = "";
            parameter = parameter + paygateway;
    
            List<String> keys = new ArrayList<>(params.keySet());
            for (int i = 0; i < keys.size(); i++) {
                try {
                    parameter = parameter + keys.get(i) + "="
                            + URLEncoder.encode(params.get(keys.get(i)), input_charset) + "&";
                } catch (UnsupportedEncodingException e) {
    
                    e.printStackTrace();
                }
            }
    
            parameter = parameter + "sign=" + sign + "&sign_type="+sign_type;
    
            return parameter;
    
        }
        /**
         * 拼接请求参数
         * @param params
         * @param privateKey
         * @return
         */
        private static String getContent(Map params, String privateKey) {
            Map map = params;
            List keys = new ArrayList(map.keySet());
            Collections.sort(keys);
    
            String prestr = "";
    
            for (int i = 0; i < keys.size(); i++) {
                String key = (String) keys.get(i);
                String value = (String) map.get(key);
    
                if (i == keys.size() - 1) {
                    prestr = prestr + key + "=" + value;
                } else {
                    prestr = prestr + key + "=" + value + "&";
                }
            }
            String p = "";
            if(StringUtils.isNotBlank(privateKey)){
                p = prestr+privateKey;
    
            } else {
                p = prestr;
            }
            return p;
        }
    }
    
    package io.renren.utils.alipay.httpClient;
    
    import org.apache.commons.httpclient.*;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.methods.PostMethod;
    import org.apache.commons.httpclient.methods.multipart.*;
    import org.apache.commons.httpclient.params.HttpMethodParams;
    import org.apache.commons.httpclient.util.IdleConnectionTimeoutThread;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.UnknownHostException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class HttpProtocolHandler {
    
        private static String              DEFAULT_CHARSET                     = "GBK";
    
        /** 连接超时时间,由bean factory设置,缺省为8秒钟 */
        private int                        defaultConnectionTimeout            = 8000;
    
        /** 回应超时时间, 由bean factory设置,缺省为30秒钟 */
        private int                        defaultSoTimeout                    = 30000;
    
        /** 闲置连接超时时间, 由bean factory设置,缺省为60秒钟 */
        private int                        defaultIdleConnTimeout              = 60000;
    
        private int                        defaultMaxConnPerHost               = 30;
    
        private int                        defaultMaxTotalConn                 = 80;
    
        /** 默认等待HttpConnectionManager返回连接超时(只有在达到最大连接数时起作用):1秒*/
        private static final long          defaultHttpConnectionManagerTimeout = 3 * 1000;
    
        /**
         * HTTP连接管理器,该连接管理器必须是线程安全的.
         */
        private HttpConnectionManager connectionManager;
    
        private static HttpProtocolHandler httpProtocolHandler                 = new HttpProtocolHandler();
    
        /**
         * 工厂方法
         *
         * @return
         */
        public static HttpProtocolHandler getInstance() {
            return httpProtocolHandler;
        }
    
        /**
         * 私有的构造方法
         */
        private HttpProtocolHandler() {
            // 创建一个线程安全的HTTP连接池
            connectionManager = new MultiThreadedHttpConnectionManager();
            connectionManager.getParams().setDefaultMaxConnectionsPerHost(defaultMaxConnPerHost);
            connectionManager.getParams().setMaxTotalConnections(defaultMaxTotalConn);
    
            IdleConnectionTimeoutThread ict = new IdleConnectionTimeoutThread();
            ict.addConnectionManager(connectionManager);
            ict.setConnectionTimeout(defaultIdleConnTimeout);
    
            ict.start();
        }
    
        /**
         * 执行Http请求
         *
         * @param request 请求数据
         * @param strParaFileName 文件类型的参数名
         * @param strFilePath 文件路径
         * @return
         * @throws HttpException, IOException
         */
        public HttpResponse execute(HttpRequest request, String strParaFileName, String strFilePath) throws HttpException, IOException {
            HttpClient httpclient = new HttpClient(connectionManager);
    
            // 设置连接超时
            int connectionTimeout = defaultConnectionTimeout;
            if (request.getConnectionTimeout() > 0) {
                connectionTimeout = request.getConnectionTimeout();
            }
            httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);
    
            // 设置回应超时
            int soTimeout = defaultSoTimeout;
            if (request.getTimeout() > 0) {
                soTimeout = request.getTimeout();
            }
            httpclient.getHttpConnectionManager().getParams().setSoTimeout(soTimeout);
    
            // 设置等待ConnectionManager释放connection的时间
            httpclient.getParams().setConnectionManagerTimeout(defaultHttpConnectionManagerTimeout);
    
            String charset = request.getCharset();
            charset = charset == null ? DEFAULT_CHARSET : charset;
            HttpMethod method = null;
    
            //get模式且不带上传文件
            if (request.getMethod().equals(HttpRequest.METHOD_GET)) {
                method = new GetMethod(request.getUrl());
                method.getParams().setCredentialCharset(charset);
    
                // parseNotifyConfig会保证使用GET方法时,request一定使用QueryString
                method.setQueryString(request.getQueryString());
            } else if(strParaFileName.equals("") && strFilePath.equals("")) {
                //post模式且不带上传文件
                method = new PostMethod(request.getUrl());
                ((PostMethod) method).addParameters(request.getParameters());
                method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; text/html; charset=" + charset);
            }
            else {
                //post模式且带上传文件
                method = new PostMethod(request.getUrl());
                List<Part> parts = new ArrayList<Part>();
                for (int i = 0; i < request.getParameters().length; i++) {
                    parts.add(new StringPart(request.getParameters()[i].getName(), request.getParameters()[i].getValue(), charset));
                }
                //增加文件参数,strParaFileName是参数名,使用本地文件
                parts.add(new FilePart(strParaFileName, new FilePartSource(new File(strFilePath))));
    
                // 设置请求体
                ((PostMethod) method).setRequestEntity(new MultipartRequestEntity(parts.toArray(new Part[0]), new HttpMethodParams()));
            }
    
            // 设置Http Header中的User-Agent属性
            method.addRequestHeader("User-Agent", "Mozilla/4.0");
            HttpResponse response = new HttpResponse();
    
            try {
                httpclient.executeMethod(method);
                if (request.getResultType().equals(HttpResultType.STRING)) {
                    response.setStringResult(method.getResponseBodyAsString());
                } else if (request.getResultType().equals(HttpResultType.BYTES)) {
                    response.setByteResult(method.getResponseBody());
                }
                response.setResponseHeaders(method.getResponseHeaders());
            } catch (UnknownHostException ex) {
    
                return null;
            } catch (IOException ex) {
    
                return null;
            } catch (Exception ex) {
    
                return null;
            } finally {
                method.releaseConnection();
            }
            return response;
        }
    
        /**
         * 将NameValuePairs数组转变为字符串
         *
         * @param nameValues
         * @return
         */
        protected String toString(NameValuePair[] nameValues) {
            if (nameValues == null || nameValues.length == 0) {
                return "null";
            }
    
            StringBuffer buffer = new StringBuffer();
    
            for (int i = 0; i < nameValues.length; i++) {
                NameValuePair nameValue = nameValues[i];
    
                if (i == 0) {
                    buffer.append(nameValue.getName() + "=" + nameValue.getValue());
                } else {
                    buffer.append("&" + nameValue.getName() + "=" + nameValue.getValue());
                }
            }
    
            return buffer.toString();
        }
    }
    
    package io.renren.utils.alipay.httpClient;
    
    import org.apache.commons.httpclient.NameValuePair;
    
    /* *
     *类名:HttpRequest
     *功能:Http请求对象的封装
     *详细:封装Http请求
     *版本:3.3
     *日期:2011-08-17
     *说明:
     *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
     *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
     */
    
    public class HttpRequest {
    
        /** HTTP GET method */
        public static final String METHOD_GET        = "GET";
    
        /** HTTP POST method */
        public static final String METHOD_POST       = "POST";
    
        /**
         * 待请求的url
         */
        private String             url               = null;
    
        /**
         * 默认的请求方式
         */
        private String             method            = METHOD_POST;
    
        private int                timeout           = 0;
    
        private int                connectionTimeout = 0;
    
        /**
         * Post方式请求时组装好的参数值对
         */
        private NameValuePair[]    parameters        = null;
    
        /**
         * Get方式请求时对应的参数
         */
        private String             queryString       = null;
    
        /**
         * 默认的请求编码方式
         */
        private String             charset           = "GBK";
    
        /**
         * 请求发起方的ip地址
         */
        private String             clientIp;
    
        /**
         * 请求返回的方式
         */
        private HttpResultType     resultType        = HttpResultType.BYTES;
    
        public HttpRequest(HttpResultType resultType) {
            super();
            this.resultType = resultType;
        }
    
        /**
         * @return Returns the clientIp.
         */
        public String getClientIp() {
            return clientIp;
        }
    
        /**
         * @param clientIp The clientIp to set.
         */
        public void setClientIp(String clientIp) {
            this.clientIp = clientIp;
        }
    
        public NameValuePair[] getParameters() {
            return parameters;
        }
    
        public void setParameters(NameValuePair[] parameters) {
            this.parameters = parameters;
        }
    
        public String getQueryString() {
            return queryString;
        }
    
        public void setQueryString(String queryString) {
            this.queryString = queryString;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public String getMethod() {
            return method;
        }
    
        public void setMethod(String method) {
            this.method = method;
        }
    
        public int getConnectionTimeout() {
            return connectionTimeout;
        }
    
        public void setConnectionTimeout(int connectionTimeout) {
            this.connectionTimeout = connectionTimeout;
        }
    
        public int getTimeout() {
            return timeout;
        }
    
        public void setTimeout(int timeout) {
            this.timeout = timeout;
        }
    
        /**
         * @return Returns the charset.
         */
        public String getCharset() {
            return charset;
        }
    
        /**
         * @param charset The charset to set.
         */
        public void setCharset(String charset) {
            this.charset = charset;
        }
    
        public HttpResultType getResultType() {
            return resultType;
        }
    
        public void setResultType(HttpResultType resultType) {
            this.resultType = resultType;
        }
    
    }
    
    
    package io.renren.utils.alipay.httpClient;
    
    import io.renren.config.AlipayConfig;
    import org.apache.commons.httpclient.Header;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import java.io.UnsupportedEncodingException;
    
    /* *
     *类名:HttpResponse
     *功能:Http返回对象的封装
     *详细:封装Http返回信息
     *版本:3.3
     *日期:2011-08-17
     *说明:
     *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
     *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
     */
    public class HttpResponse {
        @Autowired
        private AlipayConfig alipayConfig;
        /**
         * 返回中的Header信息
         */
        private Header[] responseHeaders;
    
        /**
         * String类型的result
         */
        private String   stringResult;
    
        /**
         * btye类型的result
         */
        private byte[]   byteResult;
    
        public Header[] getResponseHeaders() {
            return responseHeaders;
        }
    
        public void setResponseHeaders(Header[] responseHeaders) {
            this.responseHeaders = responseHeaders;
        }
    
        public byte[] getByteResult() {
            if (byteResult != null) {
                return byteResult;
            }
            if (stringResult != null) {
                return stringResult.getBytes();
            }
            return null;
        }
    
        public void setByteResult(byte[] byteResult) {
            this.byteResult = byteResult;
        }
    
        public String getStringResult() throws UnsupportedEncodingException {
            if (stringResult != null) {
                return stringResult;
            }
            if (byteResult != null) {
                return new String(byteResult, alipayConfig.getInputCharset());
            }
            return null;
        }
    
        public void setStringResult(String stringResult) {
            this.stringResult = stringResult;
        }
    
    }
    
    
    /*
     * Alipay.com Inc.
     * Copyright (c) 2004-2005 All Rights Reserved.
     */
    package io.renren.utils.alipay.httpClient;
    
    /* *
     *类名:HttpResultType
     *功能:表示Http返回的结果字符方式
     *详细:表示Http返回的结果字符方式
     *版本:3.3
     *日期:2012-08-17
     *说明:
     *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
     *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
     */
    public enum HttpResultType {
        /**
         * 字符串方式
         */
        STRING,
    
        /**
         * 字节数组方式
         */
        BYTES
    }
    
    

    (3)下面是serviceImpl调用接口,发送请求,测试的话可以写个main方法传参数即可

    /*支付宝海关报文*/
        @Override
        public Result alipayOffical(Map<String, String> params) throws Exception {
            Map<String, String> sParaTemp = new HashMap<>();
            sParaTemp.put("service", alipayConfig.getService());
            sParaTemp.put("partner", alipayConfig.getPartnerId());
            sParaTemp.put("_input_charset", alipayConfig.getInputCharset());
            sParaTemp.put("out_request_no", params.get("out_request_no"));
            sParaTemp.put("trade_no", params.get("trade_no"));
            sParaTemp.put("merchant_customs_code", alipayConfig.getMchCustomsNo());
            sParaTemp.put("merchant_customs_name", alipayConfig.getMchCustomsName());
            sParaTemp.put("amount", params.get("amount"));
            sParaTemp.put("customs_place", alipayConfig.getCustoms());
    
            String createUrl = AlipayUtil.createUrl(sParaTemp, alipayConfig.getPrivateKey(),
                    alipayConfig.getPayGateWay(), alipayConfig.getInputCharset(), alipayConfig.getIgnType());
            HttpProtocolHandler httpProtocolHandler = HttpProtocolHandler.getInstance();
            HttpRequest request = new HttpRequest(HttpResultType.STRING);
            //设置编码集
            request.setCharset(alipayConfig.getInputCharset());
            request.setUrl(createUrl);
            System.out.println(request.getUrl());
            HttpResponse response = httpProtocolHandler.execute(request, "", "");
            String param = response.getStringResult();
            System.out.println("支付宝报关响应数据----" + param);
    
            int isSuccessBegin = param.indexOf("<is_success>");
            int isSuccessEnd = param.indexOf("</is_success>");
            String isSuccess = param.substring(isSuccessBegin + 12, isSuccessEnd);
    
            if ("T".equals(isSuccess)) {
                int resultCodeBegin = param.indexOf("<result_code>");
                int resultCodeEnd = param.indexOf("</result_code>");
                String resultCode = param.substring(resultCodeBegin + 13, resultCodeEnd);
                if ("SUCCESS".equals(resultCode)) {
                    System.out.println("支付宝海关支付报关成功!");
                    return new Result().ok("SUCCESS");
                } else {
                    System.out.println("支付宝海关支付报关失败!---请求成功---业务处理失败");
                    return new Result().error("FAIL");
                }
            } else {
                System.out.println("支付宝海关支付报关失败!---请求失败");
                return new Result().error("FAIL");
            }
        }
    

    (4)业务正常受理并报关成功返回样例

    <?xml version="1.0" encoding="utf-8"?>
    <alipay>
        <is_success>T</is_success>
        <request>
            <param name="trade_no">2015051446800462</param>
            <param name="merchant_customs_code">hanguo</param>
            <param name="sign_type">MD5</param>
            <param name="merchant_customs_name">jwyhanguo_card</param>
            <param name="sign">2118ac8fad6bc1d9e88a6cd017c18d37</param>
            <param name="amount">2</param>
            <param name="_input_charset">UTF-8</param>
            <param name="customs_place">HANGZHOU</param>
            <param name="service">alipay.acquire.customs</param>
            <param name="out_request_no">9193457120563834</param>
            <param name="partner">2088101142878662</param>
        </request>
        <response>
            <alipay>
                <result_code>SUCCESS</result_code>
                <trade_no>2013111511001004390000105126</trade_no>
                <alipay_declare_no>2013112611001004680073956707</alipay_declare_no>
            </alipay>
        </response>
        <sign>3afc92ac4708425ab74ecb2c4e58ef56</sign>
        <sign_type>MD5</sign_type>
    </alipay>
    
  • 相关阅读:
    神奇的HTML5画图应用
    Eclipse REST 库使用
    在应用中使用Ext Loader
    新浪微博XSS攻击事件
    数字图像处理空间变换
    安装制作不用愁—Wise installation入门教程
    ExtJS 4中自定义Grid列标题的对齐方式
    页面的兼容性从认识<!DOCTYPE>开始
    ExtJS 4.1有什么值得期待?
    ExtJS应用架构设计(二)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13300585.html
Copyright © 2020-2023  润新知