建行对接微信支付

news2024/11/25 0:27:47

1、获取配置信息,基础代码设置

1.1 建行支付、退款需要商户提供以下信息:

商户代码支付使用
商户柜台代码支付使用
分行代码支付使用
公钥外联平台使用、支付使用
操作员号外联平台使用
操作员号交易密码外联平台使用
证书外联平台使用
证书密码外联平台使用

1.2 创建工具类、实体类

1.2.1 映射信息

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 支付查询

//支付查询
@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 单笔退款申请

//退款申请
@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 退款查询

//退款查询
@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映射工具

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 网络请求工具

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、开启外联平台

2.1 下载外联平台

在这里插入图片描述

2.2 将证书 存放在 cert 目录下

在这里插入图片描述

2.3 修改设置,bin目录下启动 设置.bat

在这里插入图片描述
在这里插入图片描述
将 1.1 中配置信息填进去后,点击确定

2.4 启动外联平台服务

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、支付

3.1 充值

    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 充值回调

//为了安全情况下,需要把参数,进行校验,一下方法简写,忽略校验了

	@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、退款

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、查询

5.1 充值查询

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 退款查询

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、 外联平台发布k8s

为了方便可以在本地将证书添加到外联品台里,或者使用pv挂载

6.1 将文件打成压缩包

ccb_web_connect.zip

6.2 构建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 构建无状态服务

kubectl create -f 文件名称

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、 帮助指导

YDCA02910001流水记录不存在查询成功
0250E0200001流水记录不存在查询成功
YFCP1001A00D通讯故障查询失败建议重发查询交易
YALA02910002查询过于频繁,请稍后再试查询失败减少不必要的查询
0130Z1109064操作员已被冻结,不能进行交易。请向主管咨询有关情况查询失败找商户主管解冻操作员
0130Z1101018您输入的信息不正确,请重新输入。查询失败“1、商户主管不能发外联交易,要使用操作员 2、PC端用操作员登书登录一次商户服务平台(https://merchant.ccb.com/MCMain.htm)”
0130Z1101002您输入的交易要素格式或范围不正确,请重新输入。查询失败发送报文参数有误,请核验报文与接口字段
0130Z1101021您输入的密码不正确,请重新输入。查询失败检查报文交易密码是否正确
YBLA06412001子商户与主商户信息不匹配查询失败检查主子商户关系
YBLP1MERCX01子商户与主商户信息不匹配查询失败联系银行维护集团商户关系
YBLP1MERCX02***(主商户号)无查询权限查询失败联系银行维护商户集团使用目的
YBLP1MERCX05***(子商户号)不是集团商户的子商户查询失败联系银行维护集团商户关系
YBLA02910011不符合规则查询失败发送报文参数有误,请核验报文与接口字段
YBLA02910003商户已经注销查询失败联系银行处理
0130Z0100001暂时未能处理您的请求,请稍后再试。【交易超时】状态不确定先调用5W1003退款查询,返回退款记录,则无需发起退款;无退款记录返回,则在120秒后再发起5W1003退款查询;
ZTLAP101AL03未知错误,@@20000Service Currently Unavailableaop.ACQ.SYSTEM_ERROR~~系统异常@@状态不确定建议商户核实商户账处理状态后再发起退款
ZBLAP101WX03未知报错,@@SYSTEMERROR~~请求平台数据返回异常,请稍后再试@@状态不确定建议商户隔段时间重试
YBLP1MERTH01此笔订单正在退款中,不可以重复退款退款失败不要重复退款
0130Z0100002暂时未能处理您的请求,请稍后再试。【通讯故障】退款失败建议重发退款交易
YFCP1001A00E暂时未能处理您的请求,请稍后再试。退款失败建议重发退款交易
YALA02910002查询过于频繁,请稍后再试查询失败建议降低退款频率后,重发退款交易
YBLA02910008终端【***(终端号)】不允许退货退款失败联系银行开通退款功能
YBLA02910010金额不足. 退款失败
YBLA02910011退款金额与原交易的订单金额不一致,交易拒绝退款失败该交易仅支持全额退款,建议检查退款金额后重发退款交易
YBLA02910014累计退款金额超限,交易拒绝退款失败
ZBLAP101WX01支付不成功,@@ERROR~~您的请求参数与订单信息不一致@@ 扣商户账成功,入客户账失败 需核实退款中上送的微信商户信息(如channel_id上送是否正确),若正确还报此类错误,则需要提供相关信息,找微信排查下。
XFCF40100001超出流量限制退款失败
0130Z110C064没有查询到符合条件的记录。退款失败
0130Z110C405退款金额不能大于原支付金额。退款失败
0130Z110C032退款金额不能大于原交易金额。退款失败
0130Z110W001序列号错误退款失败不能用同一序列号发两次退款
YBLA06412001未查询到相关数据退款失败退款对应的支付订单不存在
YBLP1MERCX05***(子商户号)不是集团商户的子商户退款失败联系银行维护集团商户关系

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/585005.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python-import request失败

mac电脑 vscode。 &#xff01;&#xff01;&#xff01;踩坑&#xff0c;搞了2天 烦了哦 1&#xff1a;python安装&#xff1a; 下载地址&#xff1a;https://cdn.npmmirror.com/binaries/python/3.12.0/python-3.12.0a7-macos11.pkg 2: python配置PATH terminal指令打which …

JVM学习(十二):执行引擎

目录 一、执行引擎概述 二、执行引擎的工作过程 三、Java代码编译和执行 3.1 过程概述 3.1 javac前端编译 3.2 Java字节码的执行 3.3 编译和解释概述 3.4 高级语言理解与执行过程&#xff08;机器码、指令、汇编&#xff09; 3.4.1 机器码 3.4.2 指令 3.4.3 指…

Apache的配置、应用和优化(遥不可及)

文章目录 一、构建虚拟web主机二、配置虚拟主机1.基于域名&#xff08;1&#xff09;为虚拟主机提供域名解析&#xff08;2&#xff09;为虚拟主机准备网页文档&#xff08;3&#xff09;添加虚拟主机配置&#xff08;5&#xff09;启用上一步的子配置文件&#xff08;6&#x…

Python来写一个童话故事

Python来写一个童话故事 主题&#xff1a;冒险&#xff0c; 风格&#xff1a;惊险&#xff0c; 人物&#xff1a;男孩&#xff0c; 地点&#xff1a;海底。 循环遍历鱼列表中的每一条鱼 for fish in fishes:# 获取男孩和鱼的坐标和距离boy_x, boy_y boy.position()fish_x, …

亿发生产管理信息化系统,生产制造型企业信息化建设

在不断发展的先进制造格局中&#xff0c;传统生产管理模式的固化限制了企业规模化生产能力。为适应这个充满活力的时代需求&#xff0c;实现战略目标&#xff0c;企业必须借助信息技术的力量加强生产过程管理&#xff0c;踏上企业生产信息化的征程。亿发生产管理信息化系统&…

Python3数据分析与挖掘建模(4)集中趋势与离中趋势、数据分布与抽样

分析理论是统计学和数据分析中的重要概念&#xff0c;它们用于描述和理解数据的集中趋势、离中趋势、数据分布以及抽样理论。下面是对这些概念的简要说明&#xff1a; 集中趋势&#xff1a; 均值、中位数与分位数、众数离中趋势&#xff1a;标准差、方差数据分布&#xff1a;偏…

[Nacos] Nacos Server与Nacos Client间的UDP通信 (十)

文章目录 1.Nacos Server与Nacos Client间的UDP通信1.1 Nacos Server向Nacos Client进行UDP推送1.2 Nacos Client接收Nacos Server的UDP推送 1.Nacos Server与Nacos Client间的UDP通信 Nacos Server向Nacos Client进行UDP推送Nacos Client接收Nacos Server的UDP推送 1.1 Naco…

黑客常用工具合集

首先恭喜你发现了宝藏。 本文章集成了全网优秀的开源攻防武器项目&#xff0c;包含&#xff1a; 信息收集工具&#xff08;自动化利用工具、资产发现工具、目录扫描工具、子域名收集工具、指纹识别工具、端口扫描工具、各种插件....etc...&#xff09;漏洞利用工具&#xff0…

枚举_源码_分析

枚举源码分析 前言 这是所有Java语言枚举类型的公共基类。关于枚举的更多信息&#xff0c;包括编译器合成的隐式声明方法的描述&#xff0c;可以在Java的第8.9节中找到™ 语言规范。 请注意&#xff0c;当使用枚举类型作为集合的类型或映射中键的类型时&#xff0c;可以使用专…

[NOIP2004 普及组] FBI 树 队列解法

[NOIP2004 普及组] FBI 树 题目描述: 我们可以把由 0 和 1 组成的字符串分为三类&#xff1a;全 0 串称为 B 串&#xff0c;全 1 串称为 I 串&#xff0c;既含 0 又含 1 的串则称为 F 串。 FBI 树是一种二叉树&#xff0c;它的结点类型也包括 F 结点&#xff0c;B 结点和 I …

RocketMQ实现一个简单的秒杀接口

预设场景&#xff1a; “秒杀”这一词多半出现在购物方面&#xff0c;但是又不单单只是购物&#xff0c;比如12306购票和学校抢课&#xff08;大学生的痛苦&#xff09;也可以看成一个秒杀。秒杀应该是一个“三高”&#xff0c;这个三高不是指高血脂&#xff0c;高血压和高血糖…

数据中间件 - MyCat2 配置文件说明

数据中间件 - MyCat2 配置文件说明 本章内容基于 MyCat2 版本. 会对 Mycat 中的配置文件作用,以及结合 Mycat 的一些概念进行介绍,比起一上来就盲目的开始操作,然后遇到各种问题,先从全局进行了解对提高效率是有帮助的. MyCat 的配置文件都存放在 conf 路径下. server.jso…

学习Node.js的9大理由以及日常开发中的14个高级特性和代码示例分享

目录 为什么要学Nodejs 1. 高级事件处理&#xff1a;事件驱动机制 2. 非阻塞I/O 3. 异步编程 4. 模块系统 5. 流式数据处理 6. 跨平台支持 7. 高性能网络编程 8. 调试工具 9. 第三方模块 10. 升级 V8 引擎至 10.7 11. 函数式编程 12. 高级路由 13. 试验 Node wat…

国内免费可用的ChatGPT网页版

ChatGPT 一、ChatGPT是个啥&#xff1f;二、16个国内免费的ChatGPT网站。三、ChatGPT使用方式 一、ChatGPT是个啥&#xff1f; chat&#xff1a;表示“聊天”。 GPT&#xff1a;则是Generative、Pre-trained、Transformer的缩写&#xff0c;表示“预训练语言模型”&#xff0…

【Unity100个实用小技巧】同一个Canvas下的UI顺序通过代码如何修改

☀️博客主页&#xff1a;CSDN博客主页&#x1f4a8;本文由 萌萌的小木屋 原创&#xff0c;首发于 CSDN&#x1f4a2;&#x1f525;学习专栏推荐&#xff1a;面试汇总❗️游戏框架专栏推荐&#xff1a;游戏实用框架专栏⛅️点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd;&#…

三维场景重建经典论文详解

来源&#xff1a;投稿 作者&#xff1a;小灰灰 编辑&#xff1a;学姐 论文标题&#xff1a; 《REAL-TIME INDOOR SCENE RECONSTRUCTION WITH RGBD AND INERTIA INPUT》 论文链接: https://arxiv.org/pdf/2008.00490.pdf https://github.com/CWanli/RecoNet 数据集&#xff1a;P…

停车系统多位多车算法

1、算法代码 下面代码是伪Java代码&#xff0c;看得懂就行。 //查询当前车牌号对应的车主的其他的车牌号的入场纪录&#xff0c;根据时间倒叙排列。 List<Record> comeRecords mapper.selectFromDB; //车主所有的在场车辆数量-车主拥有车位数量 等于需要计费的车辆数量…

虚拟机NAT模式下修改linux静态ip

首先修改VMware的虚拟网络编辑器&#xff0c;NAT设置-> 设置网关&#xff0c;一般ip的第四部分网关为2&#xff0c;第三部分自己设置。 然后设置自己windows电脑 右键属性里面的ipv4&#xff0c;设置为静态的&#xff0c;dns除了对应网关还加一个通用dns 8.8.8.8。 这些外…

基于Q-Table的强化学习笔记

基于Q-Table的强化学习笔记 1 几个概念1.1 状态空间 S S S和动作空间 A A A1.2 奖励 R R R1.3 价值函数与Q-Table1.4 马尔可夫性 2 基于Q-Table的强化学习算法2.1 SARSA算法2.2 Q-learning算法 1 几个概念 最近也从小白入手看了些强化学习(Reinforcement Learning&#xff0c;…

中国人民大学与加拿大女王大学金融硕士——每天都要优于过去的自己,加油!

职场中拉开人与人之间差距的&#xff0c;往往是日复一日微小的积累。满足已取得的成就会让人停滞不前&#xff0c;一旦停止学习&#xff0c;人就会止步不前。懂得持续学习、终生成长的人&#xff0c;能保持积极进取的状态。金融行业的你有计划来人民大学与加拿大女王大学金融硕…