CCB se conecta al pago de WeChat

1. Obtener información de configuración y configuración de código básico

1.1 El pago y el reembolso de CCB requieren que los comerciantes proporcionen la siguiente información:

código de comerciante Pagar para usar
Código de contador de comerciante Pagar para usar
código de sucursal Pagar para usar
Llave pública Uso de la plataforma de divulgación, uso de pago
número de operador Uso de la Plataforma de Alcance
Contraseña de transacción del número de operador Uso de la Plataforma de Alcance
Certificado Uso de la Plataforma de Alcance
contraseña del certificado Uso de la Plataforma de Alcance

1.2 Crear clases de herramientas y clases de entidades

1.2.1 Información cartográfica

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 Consulta de pago

//支付查询
@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 Solicitud de Devolución Única

//退款申请
@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 Consulta de reembolso

//退款查询
@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 Herramienta de mapeo XML

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 Herramienta de solicitud de red

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. Abre la plataforma de divulgación

2.1 Descargar plataforma de divulgación

inserte la descripción de la imagen aquí

2.2 Almacenar el certificado en el directorio cert

inserte la descripción de la imagen aquí

2.3 Modifique la configuración, inicie settings.bat en el directorio bin

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
Después de completar la información de configuración en 1.1, haga clic en Aceptar

2.4 Iniciar el servicio de la plataforma Wailian

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

3. Pagar

3.1 Recarga

    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 Devolución de llamada de recarga

//Para estar seguro, los parámetros deben verificarse, el siguiente método se abrevia y la verificación se ignora

	@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. Reembolso

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. Consulta

5.1 Consulta de recarga

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 Consulta de reembolso

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. La plataforma de divulgación lanza k8s

Para mayor comodidad, puede agregar el certificado localmente a la plataforma del producto externo o usar pv para montarlo.

6.1 Convierta el archivo en un paquete comprimido

ccb_web_connect.zip

6.2 Construir 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 Creación de un servicio sin estado

kubectl crear -f nombre de archivo

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. Guía de ayuda

YDCA02910001 El registro de flujo no existe búsqueda exitosa
0250E0200001 El registro de flujo no existe búsqueda exitosa
YFCP1001A00D fallo de comunicacion Consulta fallida Se recomienda reenviar la transacción de consulta
YALA02910002 Las consultas son demasiado frecuentes, inténtelo de nuevo más tarde Consulta fallida Reducir consultas innecesarias
0130Z1109064 El operador ha sido congelado y no puede comerciar. Por favor consulte a su supervisor Consulta fallida Encuentra al supervisor del comercio para descongelar al operador
0130Z1101018 La información que ingresó es incorrecta, vuelva a ingresarla. Consulta fallida "1. El supervisor del comerciante no puede enviar transacciones externas y debe usar el operador. 2. En el lado de la PC, use el operador para iniciar sesión en la plataforma de servicio comercial una vez (https://merchant.ccb.com/MCMain .htm)"
0130Z1101002 El formato o rango del elemento de transacción que ingresó es incorrecto, vuelva a ingresarlo. Consulta fallida Los parámetros del mensaje enviado son incorrectos, verifique los campos del mensaje y de la interfaz
0130Z1101021 La contraseña que ingresó es incorrecta, vuelva a ingresarla. Consulta fallida Compruebe si la contraseña de la transacción del mensaje es correcta
YBLA06412001 El comerciante secundario no coincide con la información del comerciante principal Consulta fallida Verifique la relación maestro-sub-comerciante
YBLP1MERCX01 El comerciante secundario no coincide con la información del comerciante principal Consulta fallida Contactar con el banco para mantener la relación con los comercios del grupo
YBLP1MERCX02 *** (ID de comerciante principal) no tiene autoridad de consulta Consulta fallida Póngase en contacto con el banco para mantener el propósito de uso del grupo comercial
YBLP1MERCX05 *** (número de comerciante secundario) no es un comerciante secundario de un comerciante del grupo Consulta fallida Contactar con el banco para mantener la relación con los comercios del grupo
YBLA02910011 No cumple con las reglas Consulta fallida Los parámetros del mensaje enviado son incorrectos, verifique los campos del mensaje y de la interfaz
YBLA02910003 El comerciante ha sido cancelado Consulta fallida Póngase en contacto con el banco para el procesamiento
0130Z0100001 Su solicitud no se pudo procesar en este momento, inténtelo de nuevo más tarde. 【Tiempo de espera de transacción】 Estado incierto Primero llame a Consulta de reembolso 5W1003 y devuelva el registro de reembolso, luego no es necesario iniciar un reembolso; si no se devuelve ningún registro de reembolso, inicie Consulta de reembolso 5W1003 después de 120 segundos;
ZTLAP101AL03 Error desconocido, @@20000 Servicio actualmente no disponible aop.ACQ.SYSTEM_ERROR~~excepción del sistema@@ Estado incierto Se recomienda a los comerciantes que verifiquen el estado de procesamiento de la cuenta del comerciante antes de emitir un reembolso
ZBLAP101WX03 Error desconocido informado, @@SYSTEMERROR~~ solicitud de excepción de devolución de datos de la plataforma, inténtelo de nuevo más tarde @@ Estado incierto Se recomienda que los comerciantes vuelvan a intentarlo a intervalos.
YBLP1MERTH01 Este pedido se está reembolsando y no se puede reembolsar repetidamente Reembolso fallido No repetir reembolso
0130Z0100002 Su solicitud no se pudo procesar en este momento, inténtelo de nuevo más tarde. 【fallo de comunicación】 Reembolso fallido Sugerir reenviar transacción de reembolso
YFCP1001A00E Su solicitud no se pudo procesar en este momento, inténtelo de nuevo más tarde. Reembolso fallido Sugerir reenviar transacción de reembolso
YALA02910002 Las consultas son demasiado frecuentes, inténtelo de nuevo más tarde Consulta fallida Se recomienda reenviar la transacción de reembolso después de reducir la frecuencia de reembolso
YBLA02910008 Terminal [*** (número de terminal)] no permite devoluciones Reembolso fallido Póngase en contacto con el banco para activar la función de reembolso
YBLA02910010 Importe insuficiente. Reembolso fallido
YBLA02910011 El monto del reembolso es inconsistente con el monto del pedido de la transacción original y la transacción es rechazada Reembolso fallido Esta transacción solo admite reembolso completo, se recomienda volver a enviar la transacción de reembolso después de verificar el monto del reembolso
YBLA02910014 El monto del reembolso acumulado excede el límite y la transacción se rechaza Reembolso fallido
ZBLAP101WX01 El pago falló, @@ERROR~~Los parámetros de su solicitud no concuerdan con la información del pedido@@ La cuenta del comerciante se dedujo con éxito, pero la cuenta del cliente falló. Verifique la información del comerciante de WeChat enviada en el reembolso (por ejemplo, si el channel_id es correcto ), si es correcto Si este tipo de error aún se informa, debe proporcionar información relevante y encontrar WeChat para verificar.
XFCF40100001 Límite de tráfico excedido Reembolso fallido
0130Z110C064 No se encontraron registros coincidentes. Reembolso fallido
0130Z110C405 El monto del reembolso no puede ser mayor que el monto del pago original. Reembolso fallido
0130Z110C032 El monto del reembolso no puede ser mayor que el monto de la transacción original. Reembolso fallido
0130Z110W001 número de serie incorrecto Reembolso fallido No se puede enviar el reembolso dos veces con el mismo número de serie
YBLA06412001 No se encontraron datos relacionados Reembolso fallido No existe la orden de pago correspondiente a la devolución
YBLP1MERCX05 *** (número de comerciante secundario) no es un comerciante secundario de un comerciante del grupo Reembolso fallido Contactar con el banco para mantener la relación con los comercios del grupo

Supongo que te gusta

Origin blog.csdn.net/weixin_47752736/article/details/130892777
Recomendado
Clasificación