准备工作
在对接建行支付之前,需要准备好这几个东西:商户代码、商户柜台代码、分行代码、公钥
创建常量类
/**
* @description: 支付参数
* @copyright: Copyright (c) 2020
* @author: liwei
* @date: 2020/5/25
* @version: 1.00
* @history:
*/
public class PayConstant {
/**
* 商户代码--由建行统一分配
*/
public static final String MERCHANTID="MERCHANTID";
public static final String MERCHANTID_VALUE="****";
/**
* 商户柜台代码--由建行统一分配
*/
public static final String POSID="POSID";
public static final String POSID_VALUE="****";
/**
* 分行代码--由建行统一指定
*/
public static final String BRANCHID="BRANCHID";
public static final String BRANCHID_VALUE="****";
/**
* 订单号--由商户提供,最长 30 位
*/
public static final String ORDERID="ORDERID";
/**
* 付款金额--由商户提供,按实际金额给出
* NUMBER(16,2)
*/
public static final String PAYMENT ="PAYMENT";
/**
* 币种--缺省为 01-人民币
*/
public static final String CURCODE="CURCODE";
public static final String CURCODE_VAUE="01";
/**
* 备注 1--一般作为商户自定义备注信
* 息使用,可在对账单中显示。
*/
public static final String REMARK1="REMARK1";
/**
* 备注 2--一般作为商户自定义备注信
* 息使用,可在对账单中显示。
*/
public static final String REMARK2="REMARK2";
/**
* 交易码--由建行统一分配为 520100
*/
public static final String TXCODE="TXCODE";
public static final String TXCODE_VAUE="520100";
/**
* MAC 校验域--采用标准 MD5 算法,由商户实现
*/
public static final String MAC="MAC";
/**
* TYPE--分行业务人员在 P2 员工渠道后台设置防钓鱼的开关。1- 防钓鱼接口
*/
public static final String TYPE="TYPE";
public static final String TYPE_VAUE="1";
/**
* 公钥后 30 位--商户从建行商户服务平台下载,截取后 30 位。仅作为源串参加 MD5 摘要,不作为参数传递
*/
public static final String PUB="PUB";
public static final String PUB_VAUE= "****";
public static String getPUB(){
return PUB_VAUE.substring(PUB_VAUE.length()-30,PUB_VAUE.length());
}
/**
* 网关类型--默认送 0
*/
public static final String GATEWAY="GATEWAY";
public static final String GATEWAY_VAUE="0";
/**
* 客户端 IP--客户在商户系统中的 IP,即客户登陆(访问)商户系统时使用的 ip
*/
public static final String CLIENTIP="CLIENTIP";
public static String getClientip(){
return IPUtil.getIPAddress();
}
/**
* 客户注册信息--客户在商户系统中注册的信息,中文需使用 escape 编码
*/
public static final String REGINFO="REGINFO";
/**
* 商品信息--客户购买的商品中文需使用 escape 编码
*/
public static final String PROINFO="PROINFO";
/**
* 商户 URL--商户送空值即可;具体请看 REFERER 设置说明
*/
public static final String REFERER="REFERER";
/**
* 分期期数--信用卡支付分期期数,一般为 3、6、12 等,必须为大于 1 的整数,当分期期数为空或无该字段上送时,
* 则视为普通的网上支付。当分期期数为空或无该字段上送时,该字段不参与 MAC校验,否则参与 MAC 校验。
*/
public static final String INSTALLNUM="INSTALLNUM";
/**
* 客户端标识--商 户 客 户 端 的 intent-filter/schema,
* 格式如下:comccbpay+ 商 户 代 码 ( 即 MERCHANTID 字段值)+商户自定义的标示 app 的字符串
* 商户自定义的标示 app 的字符串,只能为字母或数字。示例:comccbpay105320148140002alipay
* 当该字段有值时参与 MAC校验,否则不参与 MAC 校验。
*/
public static final String THIRDAPPINFO="THIRDAPPINFO";
public static final String THIRDAPPINFO_VAUE="comccbpay"+"****";
/**
* 订单超时时间--格式:
* YYYYMMDDHHMMSS如:20120214143005
* 银行系统时间> TIMEOUT时拒绝交易,若送空值则不判断超时。
* 当该字段有值时参与 MAC校验,否则不参与 MAC 校
*/
public static final String TIMEOUT="TIMEOUT";
/**
* 支付方式位图--10 位位图,1 为开,0 为关
* 第一位:支付宝支付
* 第二位:微信支付
* 第三位:银联支付(保留位,
* 暂不开放)
* 其余位数预留。
* 例如支持支付宝和微信支付
* 则上送 1100000000
* 该字段不参与 MAC 计算
*/
public static final String PAYMAP="PAYMAP";
public static final String PAYMAP_VAUE="1100000000";
}
上面这个常量类是我对照开发文档自己编写的,星号部分的商户号之类的需要替换成自己申请的。
编写支付工具类
/**
* @description: 支付工具类
* @copyright: Copyright (c) 2020
* @author: liwei
* @date: 2020/5/25
* @version: 1.00
* @history:
*/
public class PayUtils {
public String getPayParams(double amount,String orderid,String ip){
String params="";
String mReginfo= Escape.escape("小飞侠");
String mProinfo= Escape.escape("充值卡");
String prepareData=PayConstant.MERCHANTID+"="+PayConstant.MERCHANTID_VALUE+
"&"+PayConstant.POSID+"="+PayConstant.POSID_VALUE+
"&"+PayConstant.BRANCHID+"="+PayConstant.BRANCHID_VALUE+
"&"+PayConstant.ORDERID+"="+orderid+
"&"+PayConstant.PAYMENT+"="+amount+
"&"+PayConstant.CURCODE+"="+PayConstant.CURCODE_VAUE+
"&"+PayConstant.TXCODE+"="+PayConstant.TXCODE_VAUE+
"&"+PayConstant.REMARK1+"="+
"&"+PayConstant.REMARK2+"="+
"&"+PayConstant.TYPE+"="+PayConstant.TYPE_VAUE+
"&"+PayConstant.GATEWAY+"="+PayConstant.GATEWAY_VAUE+
"&"+PayConstant.PUB+"="+PayConstant.getPUB()+
"&"+PayConstant.CLIENTIP+"="+ip+
"&"+PayConstant.REGINFO+"="+mReginfo+
"&"+PayConstant.PROINFO+"="+mProinfo;
String md5ba=BaseUtils.getMd5(getMac(amount,orderid,ip,mReginfo,mProinfo));
//"https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?"+
params=prepareData+
"&"+PayConstant.MAC+"="+md5ba+
"&"+ PayConstant.PAYMAP+"="+PayConstant.PAYMAP_VAUE;
return params;
}
private String getMac(double amount,String orderid,String ip,String mReginfo,String mProinfo){
StringBuffer tmp = new StringBuffer();
tmp.append("MERCHANTID=");
tmp.append(PayConstant.MERCHANTID_VALUE);
tmp.append("&POSID=");
tmp.append(PayConstant.POSID_VALUE);
tmp.append("&BRANCHID=");
tmp.append(PayConstant.BRANCHID_VALUE);
tmp.append("&ORDERID=");
tmp.append(orderid);
tmp.append("&PAYMENT=");
tmp.append(amount);
tmp.append("&CURCODE=");
tmp.append(PayConstant.CURCODE_VAUE);
tmp.append("&TXCODE=");
tmp.append(PayConstant.TXCODE_VAUE);
tmp.append("&REMARK1=");
tmp.append("");
tmp.append("&REMARK2=");
tmp.append("");
tmp.append("&TYPE=");
tmp.append(PayConstant.TYPE_VAUE);
tmp.append("&PUB=");
tmp.append(PayConstant.getPUB());
tmp.append("&GATEWAY=");
tmp.append(PayConstant.GATEWAY_VAUE);
tmp.append("&CLIENTIP=");
tmp.append(ip);
tmp.append("®INFO=");
tmp.append(mReginfo);
tmp.append("&PROINFO=");
tmp.append(mProinfo);
tmp.append("&REFERER=");
tmp.append("");
return tmp.toString();
}
}
在写这个测试工具类的的时候遇到比较多的坑,所以代码比较乱,封装的也不是很好,在调通之后可以自行进行重写封装。
遇到的坑
1.参与md5计算的字段不是所有的都需要,只有我在getMac方法中写到的才需要
2.参与md5计算的字段顺序很重要,不能错
3.App端字段不要拼接https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?
用到的工具类
百度网盘链接:https://pan.baidu.com/s/113xITV5V8vHEMAojALln0Q
提取码:vs1h