CCB connects to WeChat payment

1. Obtain configuration information and basic code settings

1.1 CCB payment and refund require merchants to provide the following information:

merchant code Pay to use
Merchant counter code Pay to use
branch code Pay to use
public key Outreach platform use, payment use
operator number Use of Outreach Platform
Operator number transaction password Use of Outreach Platform
Certificate Use of Outreach Platform
certificate password Use of Outreach Platform

1.2 Create tool classes and entity classes

1.2.1 Mapping information

public class Const {
    
    
	//建行币种
    public static final String CCB_RMB= "01";//币种 01 人民币
    //建行交易码
    public static final String CCB_CODE= "530590";//由建行统一分配为 530590
    //建行接口类型
    public static final String CCB_METHOD_TYPE= "1";//1- 防钓鱼接口
    //建行语言
    public static final String CCB_LANGUAGE_CN= "CN";
    //建行支付方式
    public static final String CCB_TRADE_TYPE_JSAPI= "JSAPI";//JSAPI-- 公 众 号 支 付
    public static final String CCB_TRADE_TYPE_MINIPRO= "MINIPRO";//MINIPRO--小程序

    public static final String CCB_5W1001 = "5W1001";//商户连接交易
    public static final String CCB_5W1002 = "5W1002";//商户支付流水查询
    public static final String CCB_5W1003 = "5W1003";//商户退款流水查询
    public static final String CCB_5W1004 = "5W1004";//商户单笔退款交易
    public static final String CCB_5W1005 = "5W1005";//商户流水文件下载
    public static final String CCB_5W1006 = "5W1006";//E付通授权信息查询
    public static final String CCB_5W1007 = "5W1007";//外卡收单商户端mpi
    public static final String CCB_5W1015 = "5W1015";//历史订单退款交易
    public static final String CCB_5W1016 = "5W1016";//历史订单退款结果查询
    public static final String CCB_5W1024 = "5W1024";//线上集团商户单笔退款
    public static final String CCB_520200 = "520200";//商户支付交易
}

1.2.2 Payment inquiry

//支付查询
@XmlRootElement(name="TX")  // 父节点名称
@XmlAccessorType(XmlAccessType.FIELD) //定义这个类中的何种类型需要映射到XML
@Data
public class AccountPayJournalRequest {
    
    
    /**
     *请求序列号  只可以使用数字
     */
    @XmlElement(name = "REQUEST_SN")
    public String REQUEST_SN;
    /**
     *商户号
     */
    @XmlElement(name = "CUST_ID")
    public String CUST_ID;
    /**
     *操作员号
     */
    @XmlElement(name = "USER_ID")
    public String USER_ID;
    /**
     *密码
     */
    @XmlElement(name = "PASSWORD")
    public String PASSWORD;
    /**
     *交易码
     */
    @XmlElement(name = "TX_CODE")
    public String TX_CODE;
    /**
     *语言
     */
    @XmlElement(name = "LANGUAGE")
    public String LANGUAGE;

    @XmlElement(name = "TX_INFO")
    public Body body;

    @XmlRootElement(name="TX_INFO")
    @XmlAccessorType(XmlAccessType.FIELD)
    @Data
    public static class Body{
    
    
        /**
         *起始日期
         */
        public String START;
        /**
         *开始小时
         */
        public String STARTHOUR;
        /**
         *开始分钟
         */
        public String STARTMIN;
        /**
         *截止日期
         */
        public String END;
        /**
         *结束小时
         */
        public String ENDHOUR;
        /**
         *结束分钟
         */
        public String ENDMIN;
        /**
         *流水类型
         */
        public String KIND;
        /**
         *订单号
         */
        public String ORDER;
        /**
         *结算账户号
         */
        public String ACCOUNT;
        /**
         *文件类型
         */
        public String DEXCEL;
        /**
         *金额
         */
        public BigDecimal MONEY;
        /**
         *排序
         */
        public String NORDERBY;
        /**
         *当前页次
         */
        public int PAGE;
        /**
         *柜台号
         */
        public String POS_CODE;
        /**
         *流水状态
         */
        public String STATUS;
        /**
         *子商户号
         */
        public String Mrch_No;
    }

}
//支付查询响应
@XmlRootElement(name="TX")  // 父节点名称
@XmlAccessorType(XmlAccessType.FIELD) //定义这个类中的何种类型需要映射到XML
@Data
public class AccountPayJournalResponse {
    
    
    /**
     *请求序列号  只可以使用数字
     */
    @XmlElement(name = "REQUEST_SN")
    public String REQUEST_SN;
    /**
     *商户号
     */
    @XmlElement(name = "CUST_ID")
    public String CUST_ID;
    /**
     *交易码
     */
    @XmlElement(name = "TX_CODE")
    public String TX_CODE;
    /**
     *响应码
     */
    @XmlElement(name = "RETURN_CODE")
    public String RETURN_CODE;
    /**
     *交易响应信息
     */
    @XmlElement(name = "RETURN_MSG")
    public String RETURN_MSG;
    /**
     *语言
     */
    @XmlElement(name = "LANGUAGE")
    public String LANGUAGE;

//    @XmlElementWrapper(name = "TX_INFO") // 数组或集合节点名称
    @XmlElement(name = "TX_INFO")
    public Body body;

    @XmlRootElement(name="TX_INFO")
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Body{
    
    
        /**
         *总页次
         */
        public int TPAGE;
        /**
         *当前页次
         */
        public int CUR_PAGE;
        /**
         *提示
         */
        public String NOTICE;

        @XmlElementWrapper(name = "LIST")
        public List<ListInfo> listInfoList;

        @XmlRootElement(name="LIST")
        @XmlAccessorType(XmlAccessType.FIELD)
        @Data
        public static class ListInfo{
    
    
            public String TRAN_DATE; //交易日期
            public String ACC_DATE; //记账日期
            public String ORDER; //订单号
            public String ACCOUNT; //付款方账号
            public String ACC_NAME; //付款方户名
            public BigDecimal PAYMENT_MONEY; //支付金额
            public BigDecimal REFUND_MONEY; //退款金额
            public String POS_ID; //柜台号
            public String REM1; //备注1public String
            public String REM2; //备注2
            public String ORDER_STATUS; //订单状态
            public String PAY_MODE; //支付方式
            public BigDecimal Orig_Amt; //订单金额
            public BigDecimal Txn_ClrgAmt; //结算金额
            public BigDecimal MrchCmsn_Amt; //手续费金额
            public BigDecimal Discount_Amt; //优惠金额
            public String OriOvrlsttnEV_Trck_No; //银行流水号
            public String MsgRp_Jrnl_No; //商户流水号
            public String OnlnPcsgInd_1_Bmp_ECD; //交易标志位图编码
            public String TxnAmt; //交易金额
            public String Cst_Tp_Prft_Dsc; //客户类型优惠描述
            public String Jrnl_TpCd; //流水类型代码
            public String CrCrd_Instm_Prd_Num; //信用卡分期期数
            public String Crd_Attr_Bmp_Def_ID; //卡属性位图
            public String DstCrd_IssuBnk_InsNo; //发卡行机构号
         }
}

1.2.3 Single Refund Application

//退款申请
@XmlRootElement(name="TX")  // 父节点名称
@XmlAccessorType(XmlAccessType.FIELD) //定义这个类中的何种类型需要映射到XML
@Data
public class OneRefundRequest {
    
    
    /**
     *请求序列号  只可以使用数字
     */
    @XmlElement(name = "REQUEST_SN")
    public String REQUEST_SN;
    /**
     *商户号
     */
    @XmlElement(name = "CUST_ID")
    public String CUST_ID;
    /**
     *操作员号
     */
    @XmlElement(name = "USER_ID")
    public String USER_ID;
    /**
     *密码
     */
    @XmlElement(name = "PASSWORD")
    public String PASSWORD;
    /**
     *交易码
     */
    @XmlElement(name = "TX_CODE")
    public String TX_CODE;
    /**
     *语言
     */
    @XmlElement(name = "LANGUAGE")
    public String LANGUAGE;

    //    @XmlElementWrapper(name = "TX_INFO") // 数组或集合节点名称
    @XmlElement(name = "TX_INFO")
    public Body body;
    /**
     *签名信息
     */
    @XmlElement(name = "SIGN_INFO")
    public String SIGN_INFO;

    /**
     *签名CA信息
     */
    @XmlElement(name = "SIGNCERT")
    public String SIGNCERT;

    @XmlRootElement(name="TX_INFO")
    @XmlAccessorType(XmlAccessType.FIELD)
    @Data
    public static class Body{
    
    
        /**
         * 退款金额
         */
        public String MONEY;
        /**
         * 订单号
         */
        public String ORDER;
        /**
         * 退款流水号
         * 可不填,商户可根据需要填写,退款流水号由商户的系统生成
         */
        public String REFUND_CODE;
    }
}
//退款响应
@XmlRootElement(name="TX")  // 父节点名称
@XmlAccessorType(XmlAccessType.FIELD) //定义这个类中的何种类型需要映射到XML
@Data
public class OneRefundResponse {
    
    
    /**
     *请求序列号  只可以使用数字
     */
    @XmlElement(name = "REQUEST_SN")
    public String REQUEST_SN;
    /**
     *商户号
     */
    @XmlElement(name = "CUST_ID")
    public String CUST_ID;
    /**
     *交易码
     */
    @XmlElement(name = "TX_CODE")
    public String TX_CODE;
    /**
     *响应码
     */
    @XmlElement(name = "RETURN_CODE")
    public String RETURN_CODE;
    /**
     *交易响应信息
     */
    @XmlElement(name = "RETURN_MSG")
    public String RETURN_MSG;
    /**
     *语言
     */
    @XmlElement(name = "LANGUAGE")
    public String LANGUAGE;

    //    @XmlElementWrapper(name = "TX_INFO") // 数组或集合节点名称
    @XmlElement(name = "TX_INFO")
    public Body body;

    @XmlRootElement(name="TX_INFO")
    @XmlAccessorType(XmlAccessType.FIELD)
    @Data
    public static class Body{
    
    
        public String ORDER_NUM; //订单号
        public String PAY_AMOUNT; //支付金额
        public String AMOUNT; //退款金额
        public String REM1; //备注1
        public String REM2; //备注2
        public String PAY_MODE; //退款方式  ZFB:支付宝;CFT:微信;其他返回空
        public String MRCH_ACCENTRAMT; //商户实际退款金额。  PAY_MODE=ZFB或CFT时有效,否则返回空值
        public String CASH_REFUND_FEE; //买家退款金额  PAY_MODE=ZFB或CFT时有效,否则返回空值
        public String COUPON_REFUND_FEE; //代金券退款金额  PAY_MODE=CFT时有效,否则返回空值
        public String PRESENT_REFUND_DISCOUNT; //平台优惠退款金额   PAY_MODE=CFT时有效,否则返回空值
        public String PRESENT_REFUND_MDISCOUNT_AMOUNT; //商家优惠退款金额   PAY_MODE=CFT时有效,否则返回空值
        public String REFUND_FEE; //申请退款总金额  PAY_MODE=ZFB或CFT时有效,否则返回空值
        public String TXNAMT; //交易金额  折后金额 龙支付优惠退货,该字段返回实际退卡金额。
        /**
         * 龙支付优惠退货的情况返回:
         * 交易操作的权益位图(1-操作,0-不操作)
         * 第1位:建行综合积分
         * 第2位:客户回馈优惠券
         * 第3位:客户回馈优惠活动
         * 第4位:ELP优惠活动
         * 第5位:预付卡
         * 第6位:商户优惠券
         * 第7位:预留(银联优惠)
         * 第8位:预留(微信优惠)
         * 第9位:预留(支付宝优惠)
         * 第10位:激励金
         * 注:该字段仅对有需要的商户返回
         */
        public String ONLNPCSGIND_1_BMP_ECD; //联机处理标志一位图编码
    }
}

1.2.3 Refund inquiries

//退款查询
@XmlRootElement(name="TX")  // 父节点名称
@XmlAccessorType(XmlAccessType.FIELD) //定义这个类中的何种类型需要映射到XML
@Data
public class AccountRefundJournalRequest {
    
    
    /**
     *请求序列号  只可以使用数字
     */
    @XmlElement(name = "REQUEST_SN")
    public String REQUEST_SN;
    /**
     *商户号
     */
    @XmlElement(name = "CUST_ID")
    public String CUST_ID;
    /**
     *操作员号
     */
    @XmlElement(name = "USER_ID")
    public String USER_ID;
    /**
     *密码
     */
    @XmlElement(name = "PASSWORD")
    public String PASSWORD;
    /**
     *交易码
     */
    @XmlElement(name = "TX_CODE")
    public String TX_CODE;
    /**
     *语言
     */
    @XmlElement(name = "LANGUAGE")
    public String LANGUAGE;

//    @XmlElementWrapper(name = "TX_INFO") // 数组或集合节点名称
    @XmlElement(name = "TX_INFO")
    public Body body;

    @XmlRootElement(name="TX_INFO")
    @XmlAccessorType(XmlAccessType.FIELD)
    @Data
    public static class Body{
    
    
        /**
         *起始日期
         */
        public String START;
        /**
         *开始小时
         */
        public String STARTHOUR;
        /**
         *开始分钟
         */
        public String STARTMIN;
        /**
         *截止日期
         */
        public String END;
        /**
         *结束小时
         */
        public String ENDHOUR;
        /**
         *结束分钟
         */
        public String ENDMIN;
        /**
         *流水类型
         */
        public String KIND;
        /**
         *订单号
         */
        public String ORDER;
        /**
         *结算账户号
         */
        public String ACCOUNT;
        /**
         *金额
         */
        public BigDecimal MONEY;
        /**
         *排序
         */
        public String NORDERBY;
        /**
         *当前页次
         */
        public int PAGE;
        /**
         *柜台号
         */
        public String POS_CODE;
        /**
         *流水状态
         */
        public String STATUS;
        /**
         *子商户号
         */
        public String Mrch_No;
    }
}
//退款查询响应
@XmlRootElement(name="TX")  // 父节点名称
@XmlAccessorType(XmlAccessType.FIELD) //定义这个类中的何种类型需要映射到XML
@Data
public class AccountRefundJournalResponse {
    
    
    /**
     *请求序列号  只可以使用数字
     */
    @XmlElement(name = "REQUEST_SN")
    public String REQUEST_SN;
    /**
     *商户号
     */
    @XmlElement(name = "CUST_ID")
    public String CUST_ID;
    /**
     *交易码
     */
    @XmlElement(name = "TX_CODE")
    public String TX_CODE;
    /**
     *响应码
     */
    @XmlElement(name = "RETURN_CODE")
    public String RETURN_CODE;
    /**
     *交易响应信息
     */
    @XmlElement(name = "RETURN_MSG")
    public String RETURN_MSG;
    /**
     *语言
     */
    @XmlElement(name = "LANGUAGE")
    public String LANGUAGE;

//    @XmlElementWrapper(name = "TX_INFO") // 数组或集合节点名称
    @XmlElement(name = "TX_INFO")
    public Body body;

    @XmlRootElement(name="TX_INFO")
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Body{
    
    
        /**
         *总页次
         */
        public int TPAGE;
        /**
         *当前页次
         */
        public int CUR_PAGE;
        /**
         *提示
         */
        public String NOTICE;

        @XmlElementWrapper(name = "LIST")
        public List<ListInfo> listInfoList;

        @XmlRootElement(name="LIST")
        @XmlAccessorType(XmlAccessType.FIELD)
        @Data
        public static class ListInfo{
    
    
            public String TRAN_DATE; //交易日期
            public String REFUND_DATE; //退款日期
            public String ORDER_NUMBER; //订单号
            public String REFUND_ACCOUNT; //退款账号
            public BigDecimal PAY_AMOUNT; //支付金额
            public BigDecimal REFUNDEMENT_AMOUNT; //退款金额
            public String POS_CODE; //柜台号
            public String USERID; //操作员
            public String STATUS; //订单状态
            public String REFUND_CODE; //退款流水号
            public String REM1; //备注1
            public String REM2; //备注2
            public String PAY_MODE; //支付方式
            public BigDecimal Orig_Amt; //订单金额
            public BigDecimal Txn_ClrgAmt; //退款结算金额
            public BigDecimal MrchCmsn_Amt; //退款手续费金额
            public String OriOvrlsttnEV_Trck_No; //银行流水号
            public String MsgRp_Jrnl_No; //商户流水号
            public String Crd_Attr_Bmp_Def_ID; //卡属性位图
            public String DstCrd_IssuBnk_InsNo; //发卡行机构号
            public String OnlnPcsgInd_1_Bmp_ECD; //交易标志位图编码
            public String TxnAmt; //交易金额
            public String Cst_Tp_Prft_Dsc; //客户类型优惠描述
            public String Jrnl_TpCd; //流水类型代码
        }
 }

1.2.4 XML Mapping Tool

public class XmlUtil {
    
    
    protected static Logger logger = LoggerFactory.getLogger(XmlUtil.class);

    private static final Map<String,Class> clazzMap = new HashMap<String,Class>(){
    
    {
    
    
        this.put(AccountRefundJournalRequest.class.getName(), AccountRefundJournalRequest.class);//商户支付流水查询 商户退款流水查询
        this.put(OneRefundRequest.class.getName(),OneRefundRequest.class);//商户单笔退款交易
        this.put(AccountPayJournalResponse.class.getName(), AccountPayJournalResponse.class);//商户退款流水查询响应
        this.put(OneRefundResponse.class.getName(),OneRefundResponse.class);//商户单笔退款交易响应
    }};

    /**
     * 将对象转为流程XML
     *
     * @param graphModel
     * @return
     * @throws JAXBException
     */
    /**
     * 将对象转为流程XML
     *
     * @return
     * @throws JAXBException
     */
    public static String convertToXML(Object entry) throws JAXBException,RuntimeException {
    
    
        if(entry instanceof AccountRefundJournalRequest){
    
    
            return convertToClazz(AccountRefundJournalRequest.class,entry);
        }else if(entry instanceof OneRefundRequest){
    
    
            return convertToClazz(OneRefundRequest.class,entry);
        }else if(entry instanceof AccountPayJournalRequest){
    
    
            return convertToClazz(AccountPayJournalRequest.class,entry);
        }else {
    
    
            throw new RuntimeException("class not found, can not convert to xml");
        }
    }

    private static String convertToClazz(Class clazz,Object entry) throws JAXBException {
    
    
        JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
        StringWriter writer = new StringWriter();
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.marshal(entry, writer);
        String xmlStr = writer.toString();
        //建行编码方式是GB2312
        if(StringUtils.isNotBlank(xmlStr) && xmlStr.contains("encoding=\"UTF-8\"")){
    
    
            xmlStr = xmlStr.replace("encoding=\"UTF-8\"","encoding=\"GB2312\"");
        }
        xmlStr = StringUtils.replace(xmlStr, "&quot;", "'");
        return xmlStr;
    }
    public static Object convertToClass(String xml,Class clazz){
    
    
        Object xmlObject = null;
        Reader reader = null;
        try {
    
    
            JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
            // xml转为对象的接口 反序列化
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            reader = new StringReader(xml);
            xmlObject = unmarshaller.unmarshal(reader);
        } catch (Exception e) {
    
    
            logger.error(e.getMessage());
        } finally {
    
    
            if (reader != null) {
    
    
                try {
    
    
                    reader.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
        return xmlObject;
    }
}

1.2.5 Network Request Tool

public class HttpClientUtil {
    
    
    public static String httpPostCCB(String url, Map paramMap) {
    
    
        return HttpClientUtil.httpPost(url, paramMap, "UTF-8");
    }
    public static String httpPost(String url, Map paramMap, String code) {
    
    
        String content = null;
        if (url == null || url.trim().length() == 0 || paramMap == null || paramMap.isEmpty()) return null;
        HttpClient httpClient = new HttpClient();
        httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT,"Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.2) Gecko/20090803 Fedora/3.5.2-2.fc11 Firefox/3.5.2");//
        PostMethod method = new PostMethod(url);
        Iterator it = paramMap.keySet().iterator();
        while (it.hasNext()) {
    
    
            String key = it.next() + "";
            Object o = paramMap.get(key);
            if (o != null && o instanceof String) {
    
    
                method.addParameter(new org.apache.commons.httpclient.NameValuePair(key, o.toString()));
            }
            if (o != null && o instanceof String[]) {
    
    
                String[] s = (String[]) o;
                if (s != null)
                    for (int i = 0; i < s.length; i++) {
    
    
                        method.addParameter(new org.apache.commons.httpclient.NameValuePair(key, s[i]));
                    }
            }
        }
        try {
    
    
            int statusCode = httpClient.executeMethod(method);
            content = new String(method.getResponseBody(), code);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(method!=null)method.releaseConnection();
            method = null;
            httpClient = null;
        }
        return content;

    }
	public static String sendHttpRequest(String ipAdress, int nPort,String sRequest) {
    
    
        String sResult = "";
        OutputStream out = null;
        BufferedReader in = null;
        try {
    
    
            String encoding = "GB18030"; // ��ϵͳʹ��UTF-8���룬�轫������ת��ΪGB18030
            String params = "requestXml=" + sRequest;  //ע�⣺�����ı������requestXml������
            String path = "http://" + ipAdress + ":" + nPort;
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(10 * 1000); // �������ӳ�ʱʱ��
            conn.setDoOutput(true); // �� doOutput ��־����Ϊ true��ָʾӦ�ó���Ҫ������д�� URL
            conn.setDoInput(true); // //�� doInput ��־����Ϊ true��ָʾӦ�ó���Ҫ�� URL
            conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            conn.setRequestProperty("Content-Length",String.valueOf(params.length()));
            conn.setRequestProperty("Connection", "close");
            out = conn.getOutputStream();
            out.write(params.getBytes(encoding));
            out.flush();
            out.close();
            if (conn.getResponseCode() == 200) {
    
    
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoding));
            } else {
    
    
                in = new BufferedReader(new InputStreamReader(conn.getErrorStream(), encoding));
            }
            String sLine = null;
            StringBuffer sb = new StringBuffer();
            while ((sLine = in.readLine()) != null) {
    
    
                sb.append(sLine);
            }
            sResult = sb.toString();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            try {
    
    
                if (in != null)
                    in.close();
                if (out != null)
                    out.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
        return sResult;
    }

}

2. Open the outreach platform

2.1 Download Outreach Platform

insert image description here

2.2 Store the certificate in the cert directory

insert image description here

2.3 Modify the settings, start the settings.bat in the bin directory

insert image description here
insert image description here
After filling in the configuration information in 1.1, click OK

2.4 Start Wailian platform service

insert image description here
insert image description here
insert image description here

3. Pay

3.1 Recharge

    public static void main(String[] args) {
    
    
        String MERCHANTID = "1111111111111";//商户代码
        String POSID = "1111111";//商户柜台代码
        String BRANCHID = "11111111";//分行代码
        String PUB = "1111111111111111111111";//公钥后 30 位
        String ORDERID = "12aadsda2dsad944443";//定单号
        String PAYMENT = "0.01";//付款金额
        String CURCODE = Const.CCB_RMB;//币种
        String TXCODE = "530590";//交易码
        String REMARK1 = "";//备注 1
        String REMARK2 = "";//备注 2
        String TYPE = Const.CCB_METHOD_TYPE;//接口类型
        String GATEWAY = "0";//网关类型 默认0
        String CLIENTIP = "";//客户端 IP
        String REGINFO = "";//客户注册信息
        String PROINFO = "";//商品信息
        String REFERER = "";//商户 URL
        String TRADE_TYPE = Const.CCB_TRADE_TYPE_JSAPI;//交易类型
        String SUB_APPID = "";//微信公共号id
        String SUB_OPENID = "";//微信用户id
        String bankURL="https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6";//发送的url

        Map<String,String> map = new HashMap();
        map.put("MERCHANTID",MERCHANTID);
        map.put("POSID",POSID);
        map.put("BRANCHID",BRANCHID);
        map.put("ORDERID",ORDERID);
        map.put("PAYMENT",PAYMENT);
        map.put("CURCODE",CURCODE);
        map.put("TXCODE",TXCODE);
        map.put("REMARK1",REMARK1);
        map.put("REMARK2",REMARK2);
        map.put("TYPE",TYPE);
        map.put("PUB",PUB);
        map.put("GATEWAY",GATEWAY);
        map.put("CLIENTIP",CLIENTIP);
        map.put("REGINFO",REGINFO);
        map.put("PROINFO",PROINFO);
        map.put("REFERER",REFERER);
        map.put("TRADE_TYPE",TRADE_TYPE);
        map.put("SUB_APPID",SUB_APPID);
        map.put("SUB_OPENID",SUB_OPENID);

        String param = "MERCHANTID=" + MERCHANTID + "&POSID=" + POSID + "&BRANCHID=" + BRANCHID + "&ORDERID=" + ORDERID  + "&PAYMENT=" + PAYMENT + "&CURCODE=" + CURCODE +
                "&TXCODE=" + TXCODE +"&REMARK1=" + REMARK1 +"&REMARK2=" + REMARK2 + "&TYPE=" + TYPE + "&PUB=" + PUB + "&GATEWAY=" + GATEWAY
                + "&CLIENTIP=" + CLIENTIP +"&REGINFO=" + REGINFO+"&PROINFO=" + PROINFO+"&REFERER=" + REFERER
                + "&TRADE_TYPE=" + TRADE_TYPE + "&SUB_APPID=" + SUB_APPID +
                "&SUB_OPENID=" + SUB_OPENID;
        map.put("MAC", MD5Util.MD5Encode(param,"UTF-8"));
        String ret = HttpClientUtil.httpPostCCB(bankURL, map);
        System.out.println(ret);
    }

3.2 Recharge callback

//In order to be safe, the parameters need to be verified, the following method is abbreviated, and the verification is ignored

	@ApiOperation("建行服务器支付回调")
    @PostMapping("bank/callback")
    public String bankCallBack(HttpServletRequest request) {
    
    
		 Map<String, String> map = new HashMap<String, String>();
         Enumeration<String> parameterNames = request.getParameterNames();
         StringBuilder data = new StringBuilder();
         while (parameterNames.hasMoreElements()) {
    
    
             String name = (String) parameterNames.nextElement();
             String value = request.getParameter(name);
             map.put(name, value);
             data.append(name).append("=").append(value).append("&");
         }
         log.info("bank callBack data : {}",data);
         if (StringUtils.isBlank(map.get("BRANCHID")) || StringUtils.isBlank(map.get("POSID"))){
    
    
             return null;
         }
         String orderid = map.get("ORDERID");
         if (StringUtils.isBlank(orderid)){
    
    
             return null;
         }
         if ("Y".equals(map.get("SUCCESS"))) {
    
    //表示支付成功
         	
         }
         return "";
	}

4. Refund

public static void main(String[] args) {
    
    
	OneRefundRequest oneRefundRequest = new OneRefundRequest();
        oneRefundRequest.setREQUEST_SN("1111111111");//交易单号
        oneRefundRequest.setCUST_ID("1111111111111");//商户号
        oneRefundRequest.setUSER_ID("1111111111111-003");//操作员号
        oneRefundRequest.setPASSWORD("11111111");//操作员密码
        oneRefundRequest.setTX_CODE(Const.CCB_5W1004);//交易码
        oneRefundRequest.setLANGUAGE(Const.CCB_LANGUAGE_CN);//语言
        OneRefundRequest.Body body = new OneRefundRequest.Body();
        body.setMONEY("30.00");//退款金额
        body.setORDER("12aadsda2dsad944443");//订单号
        oneRefundRequest.setBody(body);
        String xmlMsg = null;
        try {
    
    
            xmlMsg = XmlUtil.convertToXML(oneRefundRequest);
        } catch (JAXBException e) {
    
    
            throw new RuntimeException(e.getMessage());
        }
        System.out.println(xmlMsg);
        String oneRefundRsponseStr = "";
        try {
    
    
        	//外联平台的ip和端口
            oneRefundRsponseStr = HttpClientUtil.sendHttpRequest("127.0.0.1",12345, xmlMsg);
        }catch (Exception e){
    
    
        }
        System.out.println(oneRefundRsponseStr);
}

5. Query

5.1 Recharge query

public static void main(String[] args) {
    
    
	   AccountPayJournalRequest accountPayJournalRequest = new AccountPayJournalRequest();
       accountPayJournalRequest.setREQUEST_SN("1111111111111");
       accountPayJournalRequest.setCUST_ID("1111111111111");//商户号
       accountPayJournalRequest.setUSER_ID("1111111111111-003");//操作员号
       accountPayJournalRequest.setPASSWORD("111111");//操作员面
       accountPayJournalRequest.setTX_CODE(Const.CCB_5W1002);//交易码
       accountPayJournalRequest.setLANGUAGE(Const.CCB_LANGUAGE_CN);//语言
       AccountPayJournalRequest.Body body = new AccountPayJournalRequest.Body();
       accountPayJournalRequest.setBody(body);
       body.setKIND("1");//0:未结流水,1:已结流水
       body.setORDER("0001000026821683267596082");//按订单号查询时,时间段不起作用
       body.setDEXCEL("1");//默认为“1”,1:不压缩,2.压缩成zip文件
       body.setNORDERBY("2");//排序 1:交易日期,2:订单号
       body.setPAGE(1);//当前页次
       body.setSTATUS("1");//0:交易失败,1:交易成功,2:待银行确认(针对未结流水查询);3:全部
       String xmlMsg = null;
       try {
    
    
           xmlMsg = XmlUtil.convertToXML(accountPayJournalRequest);
       } catch (JAXBException e) {
    
    
           throw new RuntimeException(e.getMessage());
       }
       String accountJournalRequestStr = "";
       try {
    
    
           accountJournalRequestStr = HttpClientUtil.sendHttpRequest("localhost",12345, xmlMsg);
       }catch (Exception e){
    
    
       }
       System.out.println(accountJournalRequestStr);
}

5.2 Refund inquiry

public static void main(String[] args) {
    
    
	AccountRefundJournalRequest oneRefundRequest = new AccountRefundJournalRequest();
    oneRefundRequest.setREQUEST_SN("111111111");//交易单号
    oneRefundRequest.setCUST_ID("1111111111111");//商户号
    oneRefundRequest.setUSER_ID("1111111111111-003");//操作员号
    oneRefundRequest.setPASSWORD("11111111");//操作员密码
    oneRefundRequest.setTX_CODE(Const.CCB_5W1003);//交易码
    oneRefundRequest.setLANGUAGE(Const.CCB_LANGUAGE_CN);//语言
    AccountRefundJournalRequest.Body body = new AccountRefundJournalRequest.Body();
    body.setORDER("0001000026821683267596082");//订单号
    body.setSTATUS("3");
    body.setPAGE(0);
    body.setNORDERBY("2");
    body.setKIND("1");
    oneRefundRequest.setBody(body);
    String xmlMsg = null;
    try {
    
    
        xmlMsg = XmlUtil.convertToXML(oneRefundRequest);
    } catch (JAXBException e) {
    
    
        throw new RuntimeException(e.getMessage());
    }
    System.out.println(xmlMsg);
    String oneRefundRsponseStr = "";
    try {
    
    
        oneRefundRsponseStr = HttpClientUtil.sendHttpRequest("localhost",12345, xmlMsg);
    }catch (Exception e){
    
    
    }
    System.out.println(oneRefundRsponseStr);
}

6. Outreach platform releases k8s

For convenience, you can add the certificate locally to the external product platform, or use pv to mount it

6.1 Make the file into a compressed package

ccb_web_connect.zip

6.2 Build Dockerfile

FROM java:8
ADD ccb_web_connect.zip ./
RUN unzip ccb_web_connect.zip && chmod 755 /ccb_web_connect/bin/startService.sh
WORKDIR /ccb_web_connect/bin
## 参数依次为------- 商户号  操作员号  操作员密码  证书密码  端口号
ENTRYPOINT ["sh","-c","./startService.sh 1111111111111 1111111111111-003 111111 123456 12345"]

6.3 Building a stateless service

kubectl create -f filename

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "12"
  labels:
    app: ccb-connect-test
  name: ccb-connect-test
  namespace: cloud-test
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: ccb-connect-test
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: ccb-connect-test
    spec:
      containers:
      - image: 192.168.32.14/prihub/ccb_connect:test
        imagePullPolicy: Always
        name: ccb-connect-dkxpw
        ports:
        - containerPort: 12345
          name: 12345aa
          protocol: TCP
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 30

7. Help guide

YDCA02910001 Flow record does not exist search successful
0250E0200001 Flow record does not exist search successful
YFCP1001A00D communication fail Query failed It is recommended to resend the query transaction
YALA02910002 Queries are too frequent, please try again later Query failed Reduce unnecessary queries
0130Z1109064 The operator has been frozen and cannot trade. Please consult your supervisor Query failed Find the merchant supervisor to unfreeze the operator
0130Z1101018 The information you entered is incorrect, please re-enter. Query failed "1. The supervisor of the merchant cannot send external transactions, and must use the operator. 2. On the PC side, use the operator to log in to the merchant service platform once (https://merchant.ccb.com/MCMain.htm)"
0130Z1101002 The format or range of the transaction element you entered is incorrect, please re-enter. Query failed The parameters of the sent message are incorrect, please check the message and interface fields
0130Z1101021 The password you entered is incorrect, please re-enter. Query failed Check whether the message transaction password is correct
YBLA06412001 The sub-merchant does not match the main merchant information Query failed Check master-sub-merchant relationship
YBLP1MERCX01 The sub-merchant does not match the main merchant information Query failed Contact the bank to maintain the relationship with the merchants of the group
YBLP1MERCX02 *** (Principal Merchant ID) has no inquiry authority Query failed Contact the bank to maintain the usage purpose of the merchant group
YBLP1MERCX05 *** (sub-merchant number) is not a sub-merchant of a group merchant Query failed Contact the bank to maintain the relationship with the merchants of the group
YBLA02910011 Does not comply with the rules Query failed The parameters of the sent message are incorrect, please check the message and interface fields
YBLA02910003 Merchant has been canceled Query failed Contact the bank for processing
0130Z0100001 Your request could not be processed at this time, please try again later. 【Transaction timeout】 Uncertain status Call 5W1003 Refund Query first, and return the refund record, then there is no need to initiate a refund; if no refund record is returned, then initiate 5W1003 Refund Query after 120 seconds;
ZTLAP101AL03 Unknown error, @@20000 Service Currently Unavailable aop.ACQ.SYSTEM_ERROR~~system exception@@ Uncertain status Merchants are advised to verify the merchant account processing status before issuing a refund
ZBLAP101WX03 Unknown error reported, @@SYSTEMERROR~~ request platform data returns exception, please try again later @@ Uncertain status It is recommended that merchants try again at intervals
YBLP1MERTH01 This order is being refunded and cannot be refunded repeatedly Refund failed Do not repeat refund
0130Z0100002 Your request could not be processed at this time, please try again later. 【communication fail】 Refund failed Suggest to resend refund transaction
YFCP1001A00E Your request could not be processed at this time, please try again later. Refund failed Suggest to resend refund transaction
YALA02910002 Queries are too frequent, please try again later Query failed It is recommended to resend the refund transaction after reducing the refund frequency
YBLA02910008 Terminal [*** (terminal number)] does not allow returns Refund failed Contact the bank to activate the refund function
YBLA02910010 Insufficient amount. Refund failed
YBLA02910011 The refund amount is inconsistent with the order amount of the original transaction, and the transaction is rejected Refund failed This transaction only supports full refund, it is recommended to resend the refund transaction after checking the refund amount
YBLA02910014 The accumulated refund amount exceeds the limit, and the transaction is rejected Refund failed
ZBLAP101WX01 Payment failed, @@ERROR~~Your request parameters are inconsistent with the order information@@ The merchant account was deducted successfully, but the customer account failed. Please verify the WeChat merchant information sent in the refund (such as whether the channel_id is correct), if correct If this type of error is still reported, you need to provide relevant information and find WeChat to check.
XFCF40100001 Traffic limit exceeded Refund failed
0130Z110C064 No matching records were found. Refund failed
0130Z110C405 The refund amount cannot be greater than the original payment amount. Refund failed
0130Z110C032 The refund amount cannot be greater than the original transaction amount. Refund failed
0130Z110W001 wrong serial number Refund failed Cannot send refund twice with same serial number
YBLA06412001 No related data found Refund failed The payment order corresponding to the refund does not exist
YBLP1MERCX05 *** (sub-merchant number) is not a sub-merchant of a group merchant Refund failed Contact the bank to maintain the relationship with the merchants of the group

Guess you like

Origin blog.csdn.net/weixin_47752736/article/details/130892777