调用招商银行接口(手把手教程,附调用接口工具类)

一、下载示例代码

首先到招商银行的文档中心下载示例代码:
https://openbiz.cmbchina.com/developer/UI/Business/CloudDirectConnect/Public/DocumentCenter/DocDetail.aspx?bizkey=DCCT20201215143758097&fabizkey=1&treeID=100034594

在这里插入图片描述
在这里插入图片描述
这个下载下来是一个压缩包,打开压缩包,里面有一个,java文件这个文件就是示例代码了。

二、申请测试环境、或者生产环境加入到示例代码

在这里插入图片描述
这里面的公钥、私钥等环境参数是不能直接用的(红框框住的那些就是),需要企业事先跟招商银行申请测试环境,申请成功后将申请环境中的参数与示例代码的参数一一替换。

三、调用招商银行接口参数拼装

在这里插入图片描述
这个data参数里面的就是招商银行的接口参数,这样看有点费劲,格式一下json
在这里插入图片描述

注意,reqid是有格式要求的

在这里插入图片描述

这个接口的funcode是“NTDMAADD”,在文档中找到对应的接口详情
在这里插入图片描述
会有接口的使用说明,请求和响应的参数介绍,往下拉还会有调用示例和响应示例
在这里插入图片描述

四、调用接口测试

在调用接口前记得找管理网银的同事添加一下本机ip的白名单,否则会出现白名单错误,出现这个错误说明接口传参没问题了,就差白名单了。
在这里插入图片描述
添加了白名单之后,如果响应体中参数“resultcode”的值为“SUC0000”,说明接口调用成功,保存下需要的返回信息即可。

当然也可以用postman测试
在这里插入图片描述
但是“DATA”参数还是需要用示例代码中的方法加密,个人觉得意义不大。

五、最后,贴上我自己改造过的工具类

这个不是调用接口必要的,只是觉得经过我改动后调用接口方便一点

1、这是获取银行环境参数的工具类

import lombok.Data;

/**
 * 银行配置dto
 *
 * @author:user
 * @date: 2022-03-25 10:51
 */
@Data
public class BankConfigDto {

    //公钥
    private String pubkeyStr;

    //私钥
    private String prikeyStr;

    //AESKEY
    private String AESKEY;

    //用户id
    private String UID;

    //访问地址
    private String URL;

    //=============以下参数并不是所有的银行接口都需要,所以是非必填的

    //付方账号
    private String payacc;

    //模式编号
    private String busmod;

    //网银审批标志    可选;Y 直连经办,客户端审批
    private String grtflg;

    //分行号
    private String bbknbr;

}

2、新增记账子单元 NTDMAADD-参数dto

这只是这个接口的dto,后面要调用其他接口再增加对应的参数dto。


import lombok.Data;

/**
 * 新增记账子单元 NTDMAADD-参数dto
 *
 * @author:user
 * @date: 2022-03-25 18:14
 */
@Data
public class NTDMAADDParam {

    //账号
    private String accnbr;

    //记账子单元编号
    // 不超过 10 位
    private String dmanbr;

    //记账子单元名称
    private String dmanam;

    //=================以下字段为非必填

    //额度控制标志
    //空:默认 Y,Y:允许透支 N:不允许透支
    private String ovrctl;

    //退票处理方式
    //空:默认 N,Y: 退回原记账子单元 N:退回结算户
    private String bcktyp;

    //余额非零时是否可关闭
    //Y:可关闭, N:不可关闭 空:默认 Y
    private String clstyp;
}

3、这是调用银行接口的工具类,一般就用“commonRequestMethod”方法


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.jeecg.common.util.ReflectHelper;
import org.jeecg.modules.cmb.dto.*;
import org.jeecg.modules.cmb.entity.CMBBase64;
import org.jeecg.modules.cmb.entity.CMBRequest;
import org.jeecg.modules.cmb.entity.CMBRestBuilder;
import org.jeecg.modules.cmb.enums.CMBTransAction;

/**
 * 调用银行接口工具类
 *
 * @author:user
 * @date: 2022-03-24 11:50
 */
public class CMBUtils {

    static String pubkeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5Ec7viMyQC5SShRz1jP0IQRLLVGDQ4f1rgZwtxT4ZOgnWxUoAHquj2yIrgFjNpWVnt/1dJGtXWkpp2UN3jMI5ubjVQkL0OFD+8r0IFXYAARsCLAwVLF0LE487KvVRaQC7A7rPlFfBtE/v++KajzMuDauNlIASYobcFKYdZ89vIfE/xMg/44QJqQ2XBkoMnJ7ul0kMdh4YWOQnO0qqvXD2eK3KPaXMRtxieGsVBgsvtETprw98bTl9tPUBUrneyirrccS8/Z6raV6nioyx2RzrMld8YnjlnV2YTJpNAlG+y/wLoKY55Rkjcvg9wSe8qbI/VtYVQfQz8gfeUzFQTKKCwIDAQAB";
    static String prikeyStr = "MIIEowIBAAKCAQEAwN7xTseqQs1pNA/+gTgXRqcxCYfkxDTsckfqf3O2ndsvJS5T" + "8Fb0oHTyjy0HjrKLASWWUKfhQGXPHbo1FQd+0TyHxSza55+HtXquUq7QsAITHCu3"
            + "U7aslvC7xe6/2E7nhu1TausF1nSyB1o4xVEjZyjrdQpTID0JvG8BtA5Yem9YDBCM" + "ZHBxvarQHVqdBsqo2G3M09qeUDbY3DuBgdiVAw0ApIM8mKGj4jsWmRSnypuxl40B"
            + "jWAr6Xgk44MpSGHndhiFXGvfMRRYEd8Z30w32QlB+Gjk8rQwXnvxG8YCBPYqXVkq" + "wld81bHFFz5zHQ0qekPhD8RrFimPn+RaD9VNfwIDAQABAoIBAQCxUUZQw0hJOkgq"
            + "UToO2t6rWjK/LGyp5m4rcuqoWl3eKxDhAgKxx4AHtPz7nM6B5qvdVg0oAfAZIICW" + "OAdtWgLBowC/yklHAWfm9O8nnQjHiGDBWX+mOx/ZdWFsy98cow5BAhfbCE/Jpme2"
            + "UsA2yC3gPcKbS+64iOVWlEfgnf/CLte/dE0eAMfsp5wXpwv3ygA4wtyd2X2P+y6s" + "+WYBKSvNMS08W4dsxwU9Q3AG3hS0Uab09qIPNS8tEMZ2L1tl0/VvkrAYjayM1CcK"
            + "CrSnwtH6eJVi4WQxL1K3QxyxDKucsOlqSHg++4VMpGZNpvstn3IsY3PyCgfsODvH" + "aoygvDBhAoGBAPxxdcI9stK9bIGSms0FqbVXYj8WmAjE/M9B7ECToWRQg65Gf8MY"
            + "PyUSkY2mbDHwf+yPsUb5Oli+a2GW8BwmJWeXEIy0lQxa1TS2b7CN6XJtZVnjEgiZ" + "d7bXy/j69r/C4CMlfbrRWnUGftKr/U7ynaGs10/bISeW12E7WdLV5+kDAoGBAMOW"
            + "nEzAFMPFzG9p/GtYpWU5jMNSiakzfm6n9Nwr7dFGnLhVGtO6act1bm/WB26NAgIE" + "ArhcitoKrI346nfkoZLXBpzzyJgFx4r31d1RN9Vsrt6AEywlwnLwHk2HXtCwmqre"
            + "hZ4I741S2rHlaT8ifNwLyjW2sbw9QnpC3RL7R3rVAoGAOI/Dbs4cLxO6KB4NCTrn" + "l3YI0VHiprRcYKPIp39sfel8V6P8JF5eZ5QNgMt1GotkXkCj298jr5aawLbs/aGe"
            + "Z+N1FdGwQ6BmfPUTeV+SmszgFI/IDp00MYeQcCzq9HRZfAZ+cUlPF0FpURKwIuxB" + "XWQ4qe/TMeeeQm7l5VOALrkCgYAljLa5LW9PHpxfD3P8j+pBAsl5flEbgN1XFTu3"
            + "QV/I+8t+wCgEWheRjhwDsI2AteWayXZUOsAVmFMEdrNdDTHP5SRJ4auzM/jZPzd5" + "4+vaN6Fi6ifEJAOu2VaX/9M+MYmgIFR6wLBs62k9GhQYoOBjxoetxENfJkuq+UdE"
            + "K6XPeQKBgFvf+SUrg7hFpRRyCq+DehdMQk1TJnEPTNLOalfrA/319KA8LGa0Q+ay" + "5c2mDc9F//yAJEAT1WTEqHnvKBQvjofFAGRntoCT8anAnskSytwwpltKqDcpoKx/"
            + "hVK+eVL47wuFroCBLGj0Zm3I7S+saGGmVllEky4jceE7IMTN7i6W";

    private static PrivateKey privateKey;
    private static PublicKey publicKey;
    static String UID = "N002985759";

    static String URL = "http://99.12.250.6:9080/cdcserver/api/v2";
    static String AESKEY = "YSqdwE8vAQ1BcfYCpESUsnVzOOMA2ZSd";

    public static void main(String[] args) throws Exception {

        // TODO Auto-generated method stub
        try {
            BankConfigDto bankConfigDto = new BankConfigDto();
            bankConfigDto.setPubkeyStr(pubkeyStr);
            bankConfigDto.setPrikeyStr(prikeyStr);
            bankConfigDto.setAESKEY(AESKEY);
            bankConfigDto.setUID(UID);
            bankConfigDto.setURL(URL);

//            //============================新增记账子单元 接口测试================================
            NTDMAADDParam ntdmaaddParam = new NTDMAADDParam();
            ntdmaaddParam.setAccnbr("769900019310827");
            ntdmaaddParam.setDmanbr("10101");
            ntdmaaddParam.setDmanam("测试嘿嘿");

            List<NTDMAADDParam> ntdmaaddx = new ArrayList<>();
            ntdmaaddx.add(ntdmaaddParam);

            //拼接银行请求body里面的参数
            Map<String, Object> body = new HashMap<>();
            body.put("ntdmaaddx", ntdmaaddx);

            //接口funcode参数
            String funcode = "NTDMAADD";

            List<String> requestEmptyFiledList = Arrays.asList("ovrctl", "bcktyp", "clstyp");
            JSONObject jsonObject4 = commonRequestMethod(bankConfigDto, funcode, body, requestEmptyFiledList, "参数【body】");
            System.out.println("jsonObject4 " + jsonObject4);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 银行接口公共请求方法
     * @param bankConfigDto  银行相关配置
     * @param funcode  银行接口的funcode
     * @param body  银行接口的body属性值,目前只有Object和Map<String, Object>两种类型
     * @param emptyFiledList  body属性中可以为空的属性值,没有传null
     * @param message  在为空的基础上,前面添加的提示信息,没有传null
     * @return
     * @throws Exception
     */
    public static <T> JSONObject commonRequestMethod(BankConfigDto bankConfigDto, String funcode, T body, List<String> emptyFiledList, String message) throws Exception {

        //校验body参数
        checkBody(body, emptyFiledList, message);

        return DoProcessMyself(bankConfigDto, funcode, body);
    }

    //15位真实账号+10位记账子单元编号(长度可小于10位)=25位交易识别账号,可用于对外收款,并实现自动记账功能。(交易识别不支持外币)。
    public static void modifySubAcc( SubAccUpdateDto updateDto) throws Exception {
        init();
        JSONObject jsonObject = new JSONObject();
        CMBRequest<SubAccUpdateDto> request =  new CMBRestBuilder().of(updateDto).build(CMBTransAction.AccMgt_UPDATE, UID);
        jsonObject.put("request", request);
        DoProcess(JSONObject.parseObject(jsonObject.toJSONString()), privateKey);
    }

    /**
     * 获取主账号15位
     * @param accno25
     * @return
     */
    public static String getMainAcc2Accnbr(String accno25){
        return accno25.substring(0,15);
    }

    public static String getYurrefNoByReceiptName(String receiptName){

        return receiptName.substring(receiptName.lastIndexOf("_")+1,receiptName.lastIndexOf("."));

    }

    //etytim 的格式是一个把是时分秒连起来的格式 但是数据库要求有时分秒,所以这里做一下转化
    public static String getDateStr(String dateStr){
        return dateStr.substring(0,4)+"-"+dateStr.substring(4,6)+"-"+dateStr.substring(6,8);
    }


    public  static String getEtytime(String etytim){
        return etytim.substring(0,2)+":"+etytim.substring(2,4)+":"+etytim.substring(4,6);
    }

    /**
     * 获取账号编号主账号后半部分数据10位后的数据
     * @param accno25
     * @return
     */
    public static String getSubAccUtil2Manbr(String accno25){
        return accno25.substring(15);
    }

    /**
     * 判断银行调用结果是否成功
     * @param responseJson 银行响应结果json
     * @return
     */
    public static Boolean isSuccess(JSONObject responseJson) {
        return "SUC0000".equals(getCmbResponseParam(responseJson, "head", "resultcode"));
    }

    /**
     * 获取调用银行接口的响应参数值,不能通过该方法获取signature参数下的值
     * @param responseJson 银行响应结果json
     * @param param1 要获取的结果参数名 (一级或者二级)
     * @param param2 要获取的结果参数名 (三级,没有可以为空,如果是body下的参数则一定要写正确)
     * @return
     */
    public static String getCmbResponseParam(JSONObject responseJson, String param1, String param2) {

        JSONObject response = (JSONObject) responseJson.get("response");
        checkParam(response, "返回结果中【response】为空或传入param1有误!");

        JSONObject head = (JSONObject) response.get("head");
        checkParam(head, "返回结果中【head】为空或传入param1有误!");

        JSONObject body = (JSONObject) response.get("body");
        checkParam(body, "返回结果中【body】为空或传入param1有误!");

        //head下的参数
        List<String> param2List = Arrays.asList("bizcode", "funcode", "reqid", "resultcode", "resultmsg", "rspid", "userid");

        JSONObject result = null;
        if ("response".equals(param1)) {
            result = response;
        } else if ("head".equals(param1)) {
            result = StringUtils.isNotBlank(param2) && param2List.contains(param2) ? (JSONObject) head.get(param2) : head;
        } else if ("body".equals(param1)) {
            result = StringUtils.isNotBlank(param2) && param2List.contains(param2) ? (JSONObject) body.get(param2) : body;
        } else {
            throw new RuntimeException("传入param2时param1不能为空!");
        }

        return result.toString();
    }

    /**
     * 获取请求参数json
     * @param bankConfigDto  银行接口参数,这里用来校验是否为空,这个方法只使用到了UID
     * @param funcode 接口code
     * @param body  请求json中的参数body,泛型类型
     * @return
     */
    public static <T> JSONObject getRequestJson(BankConfigDto bankConfigDto, String funcode, T body) {
        checkBankConfig(bankConfigDto);

        checkParam(funcode, "funcode不能为空!");

        String data = "{\"request\":{\"body\":" + JSON.toJSONString(body) + ",\"head\":{\"funcode\":\"" + funcode + "\",\"reqid\":\"" + getTimestamp() + "\",\"userid\":\"" + bankConfigDto.getUID() + "\"}}}";

        return JSONObject.parseObject(data);
    }

    /**
     * 校验银行body参数
     * @param body  body参数
     * @param emptyFiledList  可以为空的属性集合,为JavaBean的属性,没有可以为空的传null
     * @param message  在为空的基础上,前面添加的提示信息,没有传null
     */
    public static <T> void checkBody(T body, List<String> emptyFiledList, String message) {
        if (body instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) body;
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();

                List list = null;
                if (value instanceof List) {
                    list = (List) value;
                } else {
                    throw new RuntimeException("map集合中key为【" + key + "】的value值非法!应为List!");
                }

                checkList(list, emptyFiledList, message);
            }
        } else {
            checkBean(body, emptyFiledList, message);
        }
    }

    /**
     * 校验参数集合
     * @param list  参数集合
     * @param emptyFiledList  可以为空的属性集合,为JavaBean的属性,没有可以为空的传null
     * @param message  在为空的基础上,前面添加的提示信息,没有传null
     */
    public static <T> void checkList(List<T> list, List<String> emptyFiledList, String message) {
        checkParam(list, (StringUtils.isBlank(message) ? "集合" : message) + "为空!");

        for (int i = 0; i < list.size(); i++) {
            T t = list.get(i);

            checkBean(t, emptyFiledList, (StringUtils.isBlank(message) ? "集合的" : message + "的") + "第【" + i + "】条记录");
        }
    }

    /**
     * 校验参数集合
     * @param list  参数集合
     */
    public static <T> void checkList(List<T> list) {
        checkList(list, null, null);
    }

    /**
     * 校验参数集合
     * @param list  参数集合
     * @param emptyFiledList  可以为空的属性集合,没有传null
     */
    public static <T> void checkList(List<T> list, List<String> emptyFiledList) {
        checkList(list, emptyFiledList, null);
    }

    /**
     * 校验参数集合
     * @param list  参数集合
     * @param message  在为空的基础上,前面添加的提示信息,没有传null
     */
    public static <T> void checkList(List<T> list, String message) {
        checkList(list, null, message);
    }

    /**
     * 校验javabean,传其他类型的对象可能会报错
     * @param obj  校验的javabean
     * @param emptyFiledList 可以为空的属性集合,没有传null
     * @param message  在为空的基础上,前面添加的提示信息,没有传null
     */
    public static void checkBean(Object obj, List<String> emptyFiledList, String message) {
        checkParam(obj, (StringUtils.isBlank(message) ? "对象" : message) + "为空!");

        //传入为空属性集合为null表示当前集合所有属性都不能为空,但为了做校验,emptyFiledList也不能为null
        //在这里做校验可以减少http请求
        emptyFiledList = null != emptyFiledList ? emptyFiledList : new ArrayList<>();

        List<Map> objectInfoList = ReflectHelper.getFiledsInfo(obj);

        for (Map objectInfo : objectInfoList) {
            String name = (String) objectInfo.get("name"); //对象属性名,属性名都是字符串

            //可以为空的属性不做校验
            if (!emptyFiledList.contains(name)) {

                //校验对象属性值是否为空
                checkParam(objectInfo.get("value"), (StringUtils.isBlank(message) ? "对象的" : message + "的") + "【" + name + "】属性为空!");
            }
        }
    }

    /**
     * 校验javabean,传其他类型的对象可能会报错
     * @param obj  校验的javabean
     */
    public static void checkBean(Object obj) {
        checkBean(obj, null, null);
    }

    /**
     * 校验javabean,传其他类型的对象可能会报错
     * @param obj  校验的javabean
     * @param emptyFiledList  可以为空的属性集合
     */
    public static void checkBean(Object obj, List<String> emptyFiledList) {
        checkBean(obj, emptyFiledList, null);
    }

    /**
     * 校验javabean,传其他类型的对象可能会报错
     * @param obj  校验的javabean
     * @param message  在为空的基础上,前面添加的提示信息
     */
    public static void checkBean(Object obj, String message) {
        checkBean(obj, null, message);
    }

    /**
     * 校验参数是否为空
     * @param obj 参数
     * @param message 提示信息
     */
    public static void checkParam(Object obj, String message) {
        if (obj instanceof String) {
            if (StringUtils.isBlank((String) obj)) throw new RuntimeException(message);
        }
        Optional.ofNullable(obj).orElseThrow(() -> new RuntimeException(message));
    }

    /**
     * 校验银行配置是否为空
     * @param bankConfigDto 银行配置
     */
    public static void checkBankConfig(BankConfigDto bankConfigDto) {
        checkParam(bankConfigDto, "传入银行配置为空!");

        checkParam(bankConfigDto.getPubkeyStr(), "银行公钥为空!");
        checkParam(bankConfigDto.getPrikeyStr(), "银行私钥为空!");
        checkParam(bankConfigDto.getAESKEY(), "银行AESKEY为空!");
        checkParam(bankConfigDto.getAESKEY(), "银行UID为空!");
        checkParam(bankConfigDto.getURL(), "银行接口路径为空!");

//        Optional.ofNullable(bankConfigDto.getPayacc()).orElseThrow(() -> new RuntimeException("银行付方账号为空!"));
//        Optional.ofNullable(bankConfigDto.getBusmod()).orElseThrow(() -> new RuntimeException("银行模式编号为空!"));
//        Optional.ofNullable(bankConfigDto.getGrtflg()).orElseThrow(() -> new RuntimeException("银行网银审批标志为空!"));
//        Optional.ofNullable(bankConfigDto.getBbknbr()).orElseThrow(() -> new RuntimeException("银行分行号为空!"));
    }

    //这是用来获取时间戳的方法,用来生成唯一的银行接口参数reqid
    public static String getTimestamp() {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");//设置日期格式
        String date = df.format(new Date());// new Date()为获取当前系统时间,也可使用当前时间戳
        Random random = new Random();
        int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;
        // System.out.println(rannum);
        String rand = date + rannum;
        System.out.println(rand);

//        SimpleDateFormat df2 = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
//        String date2 = df2.format(new Date());// new Date()为获取当前系统时间,也可使用当前时间戳
//        System.out.println(date2);

        return rand;
    }








    //============================这里开始是银行的相关类

    public static void init() throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        publicKey = getPublicKeyFromBytes(pubkeyStr);
        privateKey = getPrivateKeyFromBytes(prikeyStr, "PKCS");
    }

    //这是经过自己加工的DoProcess方法
    public static <T> JSONObject DoProcessMyself(BankConfigDto bankConfigDto, String funcode, T body) throws Exception {

        //这个方法放在前面是为了校验参数
        JSONObject jObject = getRequestJson(bankConfigDto, funcode, body);

        //要先执行初始化的方法,不然调用银行接口会报错
        init();

        JSONObject object = new JSONObject();
        // 签名
        object.put("sigdat", "__signature_sigdat__");
        object.put("sigtim", GetTime());
        //object.put("sigtim", "20191023165900");
        jObject.put("signature", object);
        String source = serialJsonOrdered(jObject);
        System.out.println(source);
        String data = signRsa2048(source.getBytes(), getPrivateKeyFromBytes(bankConfigDto.getPrikeyStr(), "PKCS"));
        object.put("sigdat", data);
        jObject.put("signature", object);

        // AES加密
        //因为在前面校验过了,这里直接使用
        byte[] AESBytes = bankConfigDto.getAESKEY().getBytes();
        String AesPlainxt = serialJsonOrdered(jObject);
        System.out.println("加密前req:  " + AesPlainxt);
        String req = encryptAES256Str(AesPlainxt, AESBytes);
        System.out.println("加密后req:  " + req);

        //发送请求
        HashMap<String, String> map = new HashMap<>();
        map.put("UID", bankConfigDto.getUID());
        map.put("FUNCODE", funcode);  //银行最近新增的
        map.put("DATA", URLEncoder.encode(req, "utf-8"));
        String res = doPostForm(bankConfigDto.getURL(), map);
        System.out.println("请求结果 res:  " + res);

        //返回结果中包含这个两个字符,可能是没有白名单,也可能用户没有权限,或者其他错误
        if ((res.contains("CDCServer:") && res.contains("ErrMsg:"))) {
            throw new RuntimeException(res);
        }

        //解密请求
        String resplain = decryptAES256(res, AESBytes, true);
        System.out.println("res decrypt: " + resplain);
        JSONObject object2 =  JSONObject.parseObject(resplain);
        JSONObject object3 = object2.getJSONObject("signature");
        String resSign = object3.getString("sigdat");
        object3.put("sigdat", "__signature_sigdat__");
        object2.put("signature", object3);
        String resSignSource = serialJsonOrdered(object2);
        System.out.println("验签原文: " + resSignSource);
        System.out.println("验签签名值: " +resSign);
        Boolean verify = signRsa2048Verify(resSignSource.getBytes(), CMBBase64.decode(resSign), getPublicKeyFromBytes(bankConfigDto.getPubkeyStr()));
        System.out.println("验签结果: " + verify);
        return JSONObject.parseObject(resSignSource);
    }

    //这是原始的DoProcess
    public static String DoProcess(JSONObject jObject, PrivateKey prikey) throws Exception {
        JSONObject object = new JSONObject();
        // 签名
        object.put("sigdat", "__signature_sigdat__");
        object.put("sigtim", GetTime());
        //object.put("sigtim", "20191023165900");
        jObject.put("signature", object);
        String source = serialJsonOrdered(jObject);
        System.out.println(source);
        String data = signRsa2048(source.getBytes());
        object.put("sigdat", data);
        jObject.put("signature", object);

        // AES加密
        String AesPlainxt = serialJsonOrdered(jObject);
        System.out.println("加密前req:  " + AesPlainxt);
        String req = encryptAES256Str(AesPlainxt, AESKEY.getBytes());
        System.out.println("加密后req:  " + req);

        //发送请求
        HashMap<String, String> map = new HashMap<>();
        map.put("UID", UID);
        map.put("DATA", URLEncoder.encode(req, "utf-8"));
        String res = doPostForm(URL, map);
        System.out.println("发送请求 res:  " + res);

        //解密请求
        String resplain = decryptAES256(res, AESKEY.getBytes(), true);
        System.out.println("res decrypt: " + resplain);
        JSONObject object2 =  JSONObject.parseObject(resplain);
        JSONObject object3 = object2.getJSONObject("signature");
        String resSign = object3.getString("sigdat");
        object3.put("sigdat", "__signature_sigdat__");
        object2.put("signature", object3);
        String resSignSource = serialJsonOrdered(object2);
        System.out.println("验签原文: " + resSignSource);
        System.out.println("验签签名值: " +resSign);
        Boolean verify = signRsa2048Verify(resSignSource.getBytes(), CMBBase64.decode(resSign), publicKey);
        System.out.println("验签结果: " + verify);
        return resSignSource;
    }

    public static String GetTime() {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        return dateFormat.format(date);
    }

    public static String GetTime(String datePattern) {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
        return dateFormat.format(date);
    }

    public static String encryptAES256Str(String content, byte[] bytePassword) {
        return CMBBase64.encode(encryptAES256(content, bytePassword));
    }

    public static byte[] encryptAES256(String content, byte[] bytePassword) {
        try {
            Cipher cipherInstance = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
            SecretKeySpec key = new SecretKeySpec(bytePassword, "AES");
            cipherInstance.init(Cipher.ENCRYPT_MODE, key);
            byte[] byteContent = content.getBytes();
            byte[] cryptograph = cipherInstance.doFinal(byteContent);
            return cryptograph;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        return bytePassword;
    }

    public static String decryptAES256(String content, byte[] bytePassword, boolean logError) {
        if (content == null || content.length() == 0) {
            System.out.println("decryptAES256 param content is null or empty");
        }
        byte[] bContent = null;
        try {
            bContent = CMBBase64.decode(content);
        } catch (Exception e) {
            System.out.println("decryptAES256  appear error");
            e.printStackTrace();
        }
        try {
            Cipher cipherInstance = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
            SecretKeySpec key = new SecretKeySpec(bytePassword, "AES");
            cipherInstance.init(Cipher.DECRYPT_MODE, key);
            byte[] crypted = cipherInstance.doFinal(bContent);
            return new String(crypted, "utf-8");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return content;
    }

    public static String signRsa2048(byte[] baSource) throws Exception {
        try {
            Signature signature = Signature.getInstance("SHA256WithRSA");
            signature.initSign(privateKey);
            signature.update(baSource);
            return CMBBase64.encode(signature.sign());
        } catch (Exception e) {
            System.out.println("signRsa2048 appear error " + e.getMessage());
            throw new Exception("signRsa2048 appear error " + e.getMessage());
        }
    }

    public static String signRsa2048(byte[] baSource, PrivateKey prvKey) throws Exception {
        try {
            Signature signature = Signature.getInstance("SHA256WithRSA");
            signature.initSign(prvKey);
            signature.update(baSource);
            return CMBBase64.encode(signature.sign());
        } catch (Exception e) {
            System.out.println("signRsa2048 appear error" + e.getMessage());
            throw new Exception("signRsa2048 appear error " + e.getMessage());
        }
    }

    public static boolean signRsa2048Verify(byte[] baSource, byte[] baSignature, PublicKey pubKey) throws Exception {
        try {
            Signature signature = Signature.getInstance("SHA256WithRSA");
            signature.initVerify(pubKey);
            signature.update(baSource);
            return signature.verify(baSignature);
        } catch (Exception e) {
            System.out.println("验签失败 " + e.getMessage());
            throw new Exception("验签失败 " + e.getMessage());
        }
    }


    public static PrivateKey getPrivateKeyFromBytes(String crtBase64, String type) throws Exception {
        // type = PKCS,X509
        try {
            byte[] baKey = CMBBase64.decode(crtBase64);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey prvkey = keyFactory.generatePrivate(type.equals("PKCS") ? new PKCS8EncodedKeySpec(baKey) : new X509EncodedKeySpec(baKey));
            return prvkey;
        } catch (Exception e) {
            throw new Exception("getPrivateKeyFromBytes error" + e.getMessage());
        }
    }


    public static PublicKey getPublicKeyFromBytes(String crtBase64) throws Exception {
        try {
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(CMBBase64.decode(crtBase64));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey key = keyFactory.generatePublic(keySpec);
            return key;
        } catch (Exception e) {
            throw new Exception("getPublicKeyFromBytes error" + e.getMessage());
        }
    }


    public static String doPostForm(String httpUrl, Map param) {

        HttpURLConnection connection = null;
        InputStream is = null;
        OutputStream os = null;
        BufferedReader br = null;
        String result = null;
        try {
            URL url = new URL(httpUrl);
            // trustAllHttpsCertificates();

            SSLContext sslcontext;
            sslcontext = SSLContext.getInstance("SSL", "SunJSSE");
            sslcontext.init(null, new TrustManager[] { new MyX509TrustManager() }, new java.security.SecureRandom());
            // URL url = new URL("https://xxxx");
            HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
                public boolean verify(String s, SSLSession sslsession) {
                    System.out.println("WARNING: Hostname is not matched for cert.");
                    return true;
                }
            };
            HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());


            connection = (HttpURLConnection) url.openConnection();

            connection.setRequestMethod("POST");

            connection.setConnectTimeout(15000);

            connection.setReadTimeout(60000);
            connection.setInstanceFollowRedirects(true);

            connection.setDoOutput(true);

            connection.setDoInput(true);


            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            os = connection.getOutputStream();

            os.write(createLinkString(param).getBytes());

            if (connection.getResponseCode() != 200) {
                is = connection.getErrorStream();

                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                StringBuffer sbf = new StringBuffer();
                String temp = null;

                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            } else {
                is = connection.getInputStream();

                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                StringBuffer sbf = new StringBuffer();
                String temp = null;

                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        } finally {

            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            connection.disconnect();
        }
        return result;
    }

    public static String createLinkString(Map<String, String> params) throws UnsupportedEncodingException {

        ArrayList<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        StringBuilder prestr = new StringBuilder();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (i == keys.size() - 1) {
                prestr.append(key).append("=").append(value);
            } else {
                prestr.append(key).append("=").append(value).append("&");
            }
        }

        return prestr.toString();
    }


    public static String serialJsonOrdered(JSONObject json) {
        StringBuilder appender = new StringBuilder();
        appender.append("{");
        Iterator<String> keys = new TreeSet<>(json.keySet()).iterator();
        boolean isFirstEle = true;
        while (keys.hasNext()) {
            if (!isFirstEle) {
                appender.append(",");
            }
            String key = keys.next();
            Object val = json.get(key);
            if (val instanceof JSONObject) {
                appender.append("\"").append(key).append("\":");
                appender.append(serialJsonOrdered((JSONObject) val));
            } else if (val instanceof JSONArray) {
                JSONArray jarray = (JSONArray) val;
                appender.append("\"").append(key).append("\":[");
                boolean isFirstArrEle = true;
                for (int i = 0; i < jarray.size(); i++) {
                    if (!isFirstArrEle) {
                        appender.append(",");
                    }
                    Object obj = jarray.get(i);
                    if (obj instanceof JSONObject) {
                        appender.append(serialJsonOrdered((JSONObject) obj));
                    } else {
                        appender.append(obj.toString().replaceAll("\"", "\\\\\""));
                    }
                    isFirstArrEle = false;
                }
                appender.append("]");
            } else {
                String value = "";
                if (val instanceof String) {
                    value = "\"" + val.toString().replaceAll("\"", "\\\\\"") + "\"";
                } else {
                    value = val.toString().replaceAll("\"", "\\\\\"");
                }
                appender.append("\"").append(key).append("\":").append(value);
            }
            isFirstEle = false;
        }
        appender.append("}");
        return appender.toString();
    }
}

class MyX509TrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        // TODO Auto-generated method stub
        return null;
    }
}

4、工具类CMBBase64

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Base64;
import java.util.Map;

public class CMBBase64 {

    static {
        String errorString = "Failed manually overriding key-length permissions.";
        int newMaxKeyLength;
        try {
            if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) {
                Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection");
                Constructor con = c.getDeclaredConstructor();
                con.setAccessible(true);
                Object allPermissionCollection = con.newInstance();
                Field f = c.getDeclaredField("all_allowed");
                f.setAccessible(true);
                f.setBoolean(allPermissionCollection, true);

                c = Class.forName("javax.crypto.CryptoPermissions");
                con = c.getDeclaredConstructor();
                con.setAccessible(true);
                Object allPermissions = con.newInstance();
                f = c.getDeclaredField("perms");
                f.setAccessible(true);
                ((Map) f.get(allPermissions)).put("*", allPermissionCollection);

                c = Class.forName("javax.crypto.JceSecurityManager");
                f = c.getDeclaredField("defaultPolicy");
                f.setAccessible(true);
                Field mf = Field.class.getDeclaredField("modifiers");
                mf.setAccessible(true);
                mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
                f.set(null, allPermissions);

                newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
            }
        } catch (Exception e) {
            throw new RuntimeException(errorString, e);
        }
        if (newMaxKeyLength < 256)
            throw new RuntimeException(errorString); // hack failed
    }

    private CMBBase64() {
    }
    public static String encode(byte data[]) {
        StringBuilder sb = new StringBuilder();
        int len = data.length;
        for (int i = 0; i < len;) {
            int b1 = data[i++] & 255;
            if (i == len) {
                sb.append(ENCODE_CHARS[b1 >>> 2]);
                sb.append(ENCODE_CHARS[(b1 & 3) << 4]);
                sb.append("==");
                break;
            }
            int b2 = data[i++] & 255;
            if (i == len) {
                sb.append(ENCODE_CHARS[b1 >>> 2]);
                sb.append(ENCODE_CHARS[(b1 & 3) << 4 | (b2 & 240) >>> 4]);
                sb.append(ENCODE_CHARS[(b2 & 15) << 2]);
                sb.append("=");
                break;
            }
            int b3 = data[i++] & 255;
            sb.append(ENCODE_CHARS[b1 >>> 2]);
            sb.append(ENCODE_CHARS[(b1 & 3) << 4 | (b2 & 240) >>> 4]);
            sb.append(ENCODE_CHARS[(b2 & 15) << 2 | (b3 & 192) >>> 6]);
            sb.append(ENCODE_CHARS[b3 & 63]);
        }

        return sb.toString();
    }

    public static byte[] decode(String str) {
        byte data[] = str.getBytes();
        int len = data.length;
        ByteArrayOutputStream buf = new ByteArrayOutputStream(len);
        for (int i = 0; i < len;) {
            int b1;
            do
                b1 = DECODE_CHARS[data[i++]];
            while (i < len && b1 == -1);
            if (b1 == -1)
                break;
            int b2;
            do
                b2 = DECODE_CHARS[data[i++]];
            while (i < len && b2 == -1);
            if (b2 == -1)
                break;
            buf.write(b1 << 2 | (b2 & 48) >>> 4);
            int b3;
            do {
                b3 = data[i++];
                if (b3 == 61)
                    return buf.toByteArray();
                b3 = DECODE_CHARS[b3];
            } while (i < len && b3 == -1);
            if (b3 == -1)
                break;
            buf.write((b2 & 15) << 4 | (b3 & 60) >>> 2);
            int b4;
            do {
                b4 = data[i++];
                if (b4 == 61)
                    return buf.toByteArray();
                b4 = DECODE_CHARS[b4];
            } while (i < len && b4 == -1);
            if (b4 == -1)
                break;
            buf.write((b3 & 3) << 6 | b4);
        }

        return buf.toByteArray();
    }

    private static final int INT2 = 2;
    private static final int INT4 = 4;
    private static final int INT6 = 6;
    private static final int INT61 = 61;
    private static final char ENCODE_CHARS[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
            'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
    private static final byte DECODE_CHARS[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
            22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 };

    public static String baseConvertStr(String str) {
        if(null != str){
            Base64.Decoder decoder = Base64.getDecoder();
            try {
                return new String(decoder.decode(str.getBytes()), "GBK");
            } catch (UnsupportedEncodingException e) {
                return null;
            }
        }
        return null;
    }
}
招商银行银企直连接口说明书 version 5.36.0 目录 1.1 用户登录..........................................................15 1.2 用户退出..........................................................17 1.3 系统参数设置......................................................18 1.4 取新的通知........................................................20 1.5 取系统信息........................................................26 1.6 查询可经办的业务模式信息..........................................28 1.7 设置客户端和银行端保持连接........................................30 1.8 查询历史通知......................................................32 1.9 查询历史通知()................................................34 2 帐户管理 38 2.1 查询可查询/可经办的账户列表.......................................38 2.2 查询账户详细信息..................................................40 2.3 查询账户交易信息..................................................44 2.4 账户交易信息断点查询..............................................49 2.5 查询账户历史余额..................................................54 2.6 查询分行号信息....................................................57 2.7 查询电子回单信息..................................................58 2.8 查询电子回单信息(保存图片)......................................86 2.9 批量查询余额......................................................88 3 支付结算 91 3.1 支付..............................................................91 3.2 内部转账..........................................................97 3.3 支付结果列表查询.................................................101 3.4 查询收方限制列表.................................................105 3.5 查询批量支付经办结果.............................................107 3.6 直接支付.........................................................111 3.7 直接内转.........................................................116 3.8 支付经办(需要网银审批).........................................120 3.9 批量查询支付信息.................................................125 3.10 跨境划拨额度查询 ................................................. 130 3.11 支付结果查询-按业务参考号 ........................................ 133 银企直连 接口设计说明书 4 代发代扣 136 4.1 查询交易代码.....................................................136 4.2 直接代发代扣.....................................................139 4.3 查询交易概要信息.................................................143 4.4 查询交易明细信息.................................................146 4.5 代发工资额度查询.................................................148 4.6 大批量代发工资经办...............................................150 4.7 大批量代发经办...................................................154 4.8 大批量代扣经办...................................................158 4.9 查询大批量代发代扣明细信息.......................................162 4.10 代发结果查询-按业务参考号 ........................................ 164 5 国内信用证 168 5.1 国内信用证经办...................................................168 5.2 申请人查询开证申请...............................................174 5.3 查询开证申请详细信息.............................................177 5.4 受益人查询来证(通知行).........................................183 5.5 查询来证要素信息.................................................185 5.6 查询信用证详细信息(单笔,带单据信息)............................190 6 商务支付 193 6.1 查询订单状态信息.................................................193 6.2 验证签名.........................................................197 6.3 生成签名.........................................................199 6.4 商户确认查询.....................................................201 6.5 订单确认.........................................................203 6.6 商务支付退款功能.................................................205 6.7 商务支付现金退款查询信息.........................................208 6.8 批量支付数据列表查询.............................................211 6.9 批量支付数据确认经办/撤销........................................214 6.10 订单列表查询 ..................................................... 217 6.11 订单单笔查询 ..................................................... 222 6.12 电票出票担保支付平台确认 ......................................... 225 6.13 采购分离平台订单推送 ............................................. 227 6.14 平台撤销订单(买方支付前) ....................................... 231 6.15 平台查询票据明细信息 ............................................. 232 7 委托贷款 240 7.1 查询委托贷款业务控制信息.........................................240 银企直连 接口设计说明书 7.2 查询委托贷款合同.................................................243 7.3 查询委托贷款可用额度列表.........................................246 7.4 委托贷款放款经办请求.............................................249 7.5 查询待确认委托贷款业务...........................................252 7.6 委贷借款确认请求.................................................255 7.7 查询待还款委托贷款业务...........................................257 7.8 委贷还款经办请求.................................................259 7.9 查询委托贷款业务.................................................261 8 投资理财业务 265 9 信用管理 265 9.1 查询所有可信用母子公司...........................................265 9.2 汇总查询.........................................................266 9.3 信用额度查询.....................................................269 9.4 额度加信息查询.................................................271 9.5 业务查询.........................................................273 9.6 交易查询.........................................................277 10 人民币现金池 280 10.1 查询用户有权资源 ................................................. 280 10.2 现金池账户额度积数查询 ........................................... 283 10.3 现金池账户额度历史查询 ........................................... 286 10.4 子公司现金池交易查询 ............................................. 288 10.5 子公司现金池当天交易查询 ......................................... 293 10.6 母子公司现金池交易查询 ........................................... 297 10.7 查询指定母公司和子公司协议产品信息 ............................... 303 10.8 基准利率维护 ..................................................... 309 10.9 基准利率维护历史查询 ............................................. 311 10.10 点差维护......................................................313 10.11 点差利率查询...................................................314 10.12 透支额度查询...................................................320 10.13 利息查询......................................................322 10.14 委托贷款历史查询...............................................324 10.15 资金汇总查询...................................................327 10.16 现金流查询....................................................329 10.17 查询协议信息...................................................331 10.18 大额资金划拨...................................................338 10.19 查询基准利率...................................................340 10.20 查询子公司点差利率.............................................342 银企直连 接口设计说明书 11 代理清算 344 11.1 代理清算申请经办 ................................................. 344 11.2 查询所有代理清算申请 ............................................. 347 11.3 查询代理清算申请详细信息 ......................................... 351 11.4 查询代理清算批量经办处理结果 ..................................... 354 12 国际业务 357 13 支付限额协议管理 357 13.1 增加支付限额协议 ................................................. 357 13.2 终止支付限额协议 ................................................. 360 13.3 修改支付限额协议 ................................................. 361 13.4 查询支付限额协议 ................................................. 364 14 资金余额管理大额划拨 369 14.1 查询用户有权协议列表 ............................................. 369 14.2 查询母子公司户口联机余额 ......................................... 371 14.3 大额划拨经办 ..................................................... 373 14.4 大额划拨交易综合查询 ............................................. 375 14.5 大额划拨交易明细查询 ............................................. 379 15 外币现金池 382 15.1 资金池账号查询 ................................................... 382 15.2 现金流查询 ....................................................... 385 15.3 资金汇总查询 ..................................................... 387 15.4 子公司资金查询 ................................................... 390 15.5 额度汇总查询 ..................................................... 392 15.6 额度使用历史查询 ................................................. 395 15.7 额度详细信息查询 ................................................. 398 15.8 利息查询 ......................................................... 401 15.9 委贷区间累计利息查询 ............................................. 403 15.10 利率/点差维护记录查询..........................................406 15.11 利率/点差维护..................................................408 15.12 日间委贷放款经办...............................................410 15.13 日间委贷还款经办...............................................412 15.14 交易概要查询...................................................414 15.15 交易明细信息查询...............................................418 16 人行电子票据 421 银企直连 接口设计说明书 17 记账宝 421 17.1 查询记账宝帐号列表 ............................................... 421 17.2 查询虚拟户信息 ................................................... 423 17.3 新增虚拟户 ....................................................... 426 17.4 关闭虚拟户 ....................................................... 427 17.5 记账宝交易查询 ................................................... 430 17.6 手工记账 ......................................................... 433 17.7 虚拟户冲账 ....................................................... 435 17.8 查询虚拟户当天交易 ............................................... 437 17.9 查询虚拟户历史交易 ............................................... 440 17.10 查询虚拟户余额和当月积数.......................................443 17.11 查询虚拟户历史月积数...........................................445 17.12 虚拟户利息试算.................................................447 17.13 虚拟户内部转账.................................................449 17.14 批量新增虚拟户.................................................451 17.15 查询虚拟户关联公司卡列表.......................................453 17.16 设置虚拟户关联公司卡...........................................457 17.17 虚拟户解除公司卡关联...........................................458 17.18 流水号查询虚拟户交易信息.......................................460 17.19 修改虚拟户....................................................462 17.20 设置虚拟户关联付款方信息.......................................463 17.21 修改虚拟户非关联付款方入账方式.................................465 17.22 删除虚拟户关联付款方信息.......................................467 17.23 查询虚拟户关联付款方信息.......................................468 17.24 查询虚拟户关联公司卡列表(续传).................................470 17.25 单笔设置公司卡关联付方账号.....................................473 17.26 单笔设置公司卡非关联付方账号的入账方式.........................474 17.27 除公司卡关联付款方信息请求报文说明.............................475 17.28 查询公司卡关联付款方信息.......................................476 17.29 查询所有虚拟户的某日余额 ...................................... 478 17.30 查询单个虚拟户的历史余额 ......................................... 480 18 跨境账户视图 481 18.1 查询可经办帐号列表 ............................................... 481 18.2 新增境外账户经办 ................................................. 483 18.3 修改境外账户经办 ................................................. 486 18.4 删除境外账户经办 ................................................. 488 18.5 境外账户维护综合查询 ............................................. 490 18.6 境外账户维护明细 ................................................. 493 18.7 境外账户查询 ..................................................... 495 18.8 查询账单列表 ..................................................... 497 银企直连 接口设计说明书 18.9 查询电文明细 ..................................................... 499 18.10 查询账单正文/原文..............................................502 19 票据通 505 20 联动支付 505 20.1 查询可经办帐号列表 ............................................... 505 20.2 查询授权帐号列表 ................................................. 507 20.3 联动支付经办 ..................................................... 509 20.4 联动支付综合查询 ................................................. 512 20.5 联动支付交易明细查询 ............................................. 515 21 网银互联 518 22 票据管家 519 23 公司一卡通 519 23.1 查询公司卡业务控制信息 ........................................... 519 23.2 取公司结算户下面所有公司卡信息...................................522 23.3 取公司卡详细信息.................................................525 23.4 取公司卡当天交易.................................................529 23.5 取公司卡历史交易.................................................542 23.6 消费额度设置.....................................................545 23.7 批量消费额度设置.................................................547 23.8 POS消费额度设置..................................................550 23.9 批量POS额度设置.................................................552 23.10 临时额度设置 ..................................................... 555 23.11 临时额度取消 ..................................................... 557 23.12 查询所有公司卡申请 ............................................... 559 23.13 查询消费额度设置信息...........................................562 23.14 查询批量公司卡处理信息 ......................................... 564 23.15 公司卡激活....................................................566 23.16 取款密码重置...................................................568 23.17 口头挂失......................................................570 23.18 取公司结算户当天交易...........................................571 23.19 取公司结算户历史交易...........................................574 23.20 自定义业务信息设置.............................................576 23.21 公司卡中止业务功能(锁卡) ..................................... 578 23.22 公司卡解除中止业务(解锁) ..................................... 579 23.23 取公司结算户下面所有公司卡信息(续传)...........................581 23.24 取公司卡某日交易(续传).......................................583 银企直连 接口设计说明书 23.25 取关联结算户某日交易(续传) ..................................... 586 23.26 公司卡可入账状态查询...........................................589 23.27 公司卡入金锁定状态查询......................................... 591 24 银企对账 593 24.1 网银对账待经办数据查询 ........................................... 593 24.2 网银对账明细数据查询 ............................................. 598 24.3 网银电子对账经办 ................................................. 602 24.4 网银电子对帐业务查询 ............................................. 605 25 法人账户透支 608 25.1 查询网上自助还款业务控制信息 ..................................... 608 25.2 查询待还款信息列表 ............................................... 611 25.3 还款业务经办 ..................................................... 613 25.4 还款利息查询 ..................................................... 615 25.5 还款维护综合查询 ................................................. 617 25.6 还款功能业务明细 ................................................. 619 26 移动支票 622 26.1 取模式信息 ....................................................... 622 26.2 移动支票查询可选有权使用人列表 ................................... 624 26.3 单笔开票经办 ..................................................... 626 26.4 批量开票经办 ..................................................... 629 26.5 支付状态查询 ..................................................... 632 26.6 支票管理查询 ..................................................... 635 26.7 批量作废经办 ..................................................... 638 26.8 综合查询接口 ..................................................... 640 26.9 修改经办 ......................................................... 643 27 多级现金池 646 27.1 多级现金池账户历史余额查询 ....................................... 646 27.2 多级现金池综合交易查询 ........................................... 650 27.3 查询多级现金池业务控制账号 ....................................... 657 27.4 查询内部户信息 ................................................... 659 27.5 划拨关系明细查询 ................................................. 661 27.6 自动划拨协议查询 ................................................. 665 27.7 自动划拨协议详情查询 ............................................. 669 27.8 内部户限额单笔设置 ............................................... 677 27.9 维护/终止内部户限额 .............................................. 682 银企直连 接口设计说明书 27.10 查询内部户限额.................................................686 27.11 子账户内部户限额查询...........................................690 27.12 划拨关系限额设置经办...........................................693 27.13 维护/终止划拨关系限额..........................................698 27.14 查询划拨关系限额...............................................702 27.15 多级现金池设置详情查询 ......................................... 706 27.16 手工划拨......................................................720 27.17 划拨综合查询...................................................723 27.18 划拨详情查询...................................................726 27.19 多级现金池当天综合交易查询.....................................728 27.20 多级现金池设置综合查询 ......................................... 732 27.21 查询划拨关系列表...............................................734 27.22 内部计价结息经办...............................................741 27.23 多级现金池内部计价查询 ......................................... 743 27.24 结息结果查询...................................................746 27.25 查询内部计价余额历史信息.......................................750 28 C+交易管家 754 29 聚合收款 754 29.1 商户清分列表查询 ................................................. 754 29.2 商户清分交易处理 ................................................. 755 29.3 商户清分处理综合查询 ............................................. 756 29.4 商户清分处理结果查询 ............................................. 757 30 速汇易 758 30.1 速汇易建批经办 ................................................... 758 30.2 速汇易明细传入 ................................................... 760 30.3 速汇易-直连交易批次查询 .......................................... 762 30.4 速汇易-直连批次明细查询 .......................................... 763 31 内部户 MT940 业务 764 31.1 发送内部户日初日终余额及交易报文经办..............................764 31.2 内部户MT940业务综合查询.........................................768 31.3 按参考号查询业务.................................................769 31.4 内部户MT940业务详情查询.........................................771 32 国际信用证业务 773 银企直连 接口设计说明书 32.1 国际信用证开证经办 ............................................... 773 32.2 国际信用证综合查询 ............................................... 780 32.3 查询开证申请详细信息 ............................................. 783 32.4 国际信用证修改申请经办 ........................................... 787 32.5 国际信用证单笔查询-按业务参考号 .................................. 790 录A 793 A.1 招行分行 .......................................................... 793 A.2 返回代码 .......................................................... 794 A.3 货币代码表 ........................................................ 794 A.4 业务代码 .......................................................... 795 A.5 业务请求状态 ...................................................... 796 A.6 业务处理结果 ...................................................... 796 A.7 凭证类型 .......................................................... 796 A.8 交易分析码 ........................................................ 797 A.9 交易代码 .......................................................... 798 A.10 利率类型 ......................................................... 798 A.11 结息方式 ......................................................... 799 A.12 贷款用途 ......................................................... 799 A.13 信用管理-业务类别 ................................................ 799 A.14 信用管理-本金状态 ................................................ 800 A.15 交易代码 ......................................................... 801 A.16 消息类型 ......................................................... 807 A.17 存期代码 ......................................................... 807 A.18 城市代码 ......................................................... 807 A.19 记账方向代码 ..................................................... 818 A.20 交易类型 ......................................................... 818 A.21 协议状态 ......................................................... 818 A.22 冻结状态 ......................................................... 818 A.23 协议执行状态 ..................................................... 818 A.24 支付管理类型 ..................................................... 818 A.25 支付额度使用类型 ................................................. 819 A.26 收入转账间隔 ..................................................... 819 A.27 现金回流方式 ..................................................... 819 A.28 利率方向 ......................................................... 819 A.29 帐户类型 ......................................................... 819 A.30 收支标志 ......................................................... 819 A.31 维护方 ........................................................... 819 A.32 划拨方向 ......................................................... 820 A.33 上存(下借)结息方式................................................ 820 A.34 交易种类 ......................................................... 820 A.35 利率类型码 ....................................................... 820 A.36 国际收支交易编码表................................................ 820 银企直连 接口设计说明书 A.37 业务类别(LOBUSTYP).............................................. 821 A.38 担保方式(LOGRTTYP).............................................. 822 A.39 申请状态(LOAPPSTS).............................................. 822 A.40 国际支出交易编码 ................................................. 822 A.41 涉外支出交易编码 ................................................. 822 A.42 资本项下支出交易编码.............................................. 823 A.43 离岸存期代码 ..................................................... 823 A.44 同业存期代码 ..................................................... 823 A.45 代发代扣交易类型 ................................................. 823 A.46 定期业务编码 ..................................................... 824 A.47 国际业务货币代码表................................................ 827 A.48 招行分行(3 位) .................................................. 828 A.49 信用管理产品类别(8 位) .......................................... 833 A.50 人行票据状态 ..................................................... 834 A.51 锁票业务编码 ..................................................... 836 A.52 资金用途编码 ..................................................... 837 录B 839 B.1 数据类型约定 ...................................................... 839 B.2 历史通知接口格式 .................................................. 839
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值