前两篇文章介绍了对接微信支付和农行支付的方法,这篇文章介绍一下建行支付。
使用场景:
在微信公众号中调用微信付款,或者公众号内页面调用龙支付或者H5页面支付。
一、微信支付
参考建行给的接口文档
交易流程如下:
按照接口要求拼接参数之后,使用post方式提交参数到https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?CCB_IBSVersion=V6,示例代码如下:
public Map<String, String> ccbWxOrder(String orderNo, String openId, String totalFee, String body) {
try {
//请求建行平台
String url = URL + "&" + getPayRequestStr(orderNo, NumberUtil.roundStr(Double.parseDouble(totalFee) / 100, 2), openId, body, "wx");
String post = HttpRequest.post(url).execute().body();
System.out.println("建行微信下单步骤1:" + post);
Map<String, String> map = JsonHelper.jsonToBean(Map.class, post);
if ("true".equals(map.get("SUCCESS"))) {
//请求成功
String payUrl = map.get("PAYURL");
System.out.println("payUrl:" + payUrl);
String s = HttpClientUtil.get(payUrl);
System.out.println("建行微信下单请求步骤2:" + s);
Map<String, String> result = JsonHelper.jsonToBean(Map.class, s);
if ("000000".equals(result.get("ERRCODE"))) {
//下单成功
return result;
} else {
log.info("建行微信支付下单接口二阶段请求失败,原因:{}", result.get("ERRMSG"));
}
} else {
//请求失败
log.info("建行微信支付下单接口一阶段请求失败");
}
} catch (Exception e) {
log.error("建行微信请求下单异常:{}", e);
}
return new HashMap<>();
}
//拼接请求参数,上面是微信下单接口参数,下面是龙支付h5请求参数
public String getPayRequestStr(String orderId, String money, String openId, String body, String type) {
String str = "";
if ("wx".equals(type)) {
str = "MERCHANTID=" + MERCHANTID + "&POSID=" + POSID + "&BRANCHID=" + BRANCHID + "&ORDERID=" + orderId + "&PAYMENT="
+ money + "&CURCODE=01&TXCODE=530590&REMARK1=&REMARK2=&TYPE=1&PUB=" + PUB.substring(PUB.length() - 30) +
"&GATEWAY=0&CLIENTIP=39.101.1.11®INFO=&PROINFO=" + "&REFERER=&TRADE_TYPE=JSAPI&SUB_APPID=" + systemConfig.getGzhAppId()
+ "&SUB_OPENID=" + openId;
} else {
str = "MERCHANTID=" + MERCHANTID + "&POSID=" + POSID + "&BRANCHID=" + BRANCHID + "&ORDERID=" + orderId + "&PAYMENT="
+ money + "&CURCODE=01&TXCODE=SDK005&REMARK1=&REMARK2=&TYPE=1&PUB=" + PUB.substring(PUB.length() - 30) +
"&GATEWAY=0&CLIENTIP=39.101.1.11®INFO=&PROINFO=" + "&REFERER=";
}
String MAC = MD5Helper.MD5Encode(str);
return str.replaceAll("&PUB=" + PUB.substring(PUB.length() - 30), "") + "&MAC=" + MAC;
}
接收返回参数如下,按照要求就可以调起微信支付控件进行支付了。
二、建行龙支付H5
这个很简单,示例代码如下:
public String ccbDragonOrder(String orderNo, String totalFee, String body) {
String dragonUrl = URL + "&" + getPayRequestStr(orderNo, NumberUtil.roundStr(Double.parseDouble(totalFee) / 100, 2), null, body, "dragon");
System.out.println(dragonUrl);
return dragonUrl;
}
拿到接口的url直接访问就行了。注意,H5龙支付需要建行设置商户白名单,否则就是这样
三、建行支付回调
首先需要在建行商户后台设置通知地址(具体路径:商户服务平台-服务管理-实时反 馈地址修改)。建行会对返回参数进行数字签名,商户接收到建行发送的商户通知后,需要对接收到的参数数据进行数字签名的验签。建行有SDK提供(netpay.jar)。示例代码如下:
@RequestMapping(value = "/ccb.api")
public void ccbNotify(@RequestBody String str){
System.out.println("-------接收到建行回调信息------"+str);
commonPayService.ccbNotify(str);
}
public void ccbNotify(String str) {
String now = DateUtil.now();
//签名校验
String[] split = str.split("&SIGN=");
String src = split[0];
String sign = split[1];
RSASig rsaSig = new RSASig();
rsaSig.setPublicKey(PUB);
boolean b = rsaSig.verifySigature(sign, src);
if (b) {
//签名验证成功
Map<String, String> map = new HashMap<>();
Arrays.stream(src.split("&")).map(s -> s.split("=")).filter(v -> v.length > 1).forEach((m) -> map.put(m[0], m[1]));
//商户柜台代码
String posId = map.get("POSID");
//分行代码
String branchId = map.get("BRANCHID");
//订单号
String orderId = map.get("ORDERID");
//付款金额(元转分)
String payment = Double.parseDouble(map.get("PAYMENT")) * 100 + "";
//币种
String curCode = map.get("CURCODE");
//账户类型
String accType = map.get("ACC_TYPE");
//成功标志
String success = map.get("SUCCESS");
//接口类型
String type = map.get("TYPE");
//客户端IP
String clientIp = map.get("CLIENTIP");
//系统记账日期
String accDate = map.get("ACCDATE");
//处理订单,业务逻辑
} else {
log.error("建行支付回调验签失败------{}", now);
}
}
四、退款、查询订单
建行这点很变态的,订单查询和退款需要额外部署一个外联平台,大致就是发送一笔退款请求到外联平台,然后外联平台转发给建行服务器,建行服务器处理请求之后告诉外联平台,然后外联平台再通知商户,等于通过外联平台中转了一下。外联平台的部署参考:
外联平台的一些功能在这里面都有说明的,按照要求来做就行了