本文对接工行聚合支付二维码扫码支付接口,实现二维码生成(用户扫二维码支付)、二维码被扫(商户扫用户付款码)、支付查询、退款、退款查询、冲正的代码实现,首先下载工行聚合支付API文档,见链接“工行聚合支付二维码扫码支付”。开发者可以通过下载对应SDK进行学习使用,如图所示:
1.各个API对应请求地址
二维码生成:https://gw.open.icbc.com.cn/api/qrcode/V2/generate
此接口返回的二维码串为工商银行总行标准生成,非银联标准,建议商户将接口返回的字符串转化为二维码图片时使用业界通用的QR标准格式。
二维码退款:https://gw.open.icbc.com.cn/api/qrcode/V2/reject
二维码退款:https://gw.open.icbc.com.cn/api/qrcode/V2/reverse
二维码退款查询:https://gw.open.icbc.com.cn/api/qrcode/reject/query/V3
二维码被扫:https://gw.open.icbc.com.cn/api/qrcode/pay/V4
二维码查询:https://gw.open.icbc.com.cn/api/qrcode/query/V5
本接口由支付结果查询扩展为订单状态查询,含退款、冲正等情况,详细内容见响应参数pay_status描述。
2.代码实现:
下面列出各个接口的实现类,按照API文档上传对应参数即可,其中通用参数由申请开放平台时由平台分配。
其中request为请求工行聚合支付的请求参数枚举类(通用请求参数+请求参数);
bizContent为请求参数枚举类。
@Service
public class IcbcPayServiceImpl implements IcbcPayServiceInf {
private final static Logger logger = LoggerFactory.getLogger(IcbcPayServiceImpl.class);
/**
* 工行聚合支付,获取二维码
*/
@Override
public Map<String, Object> generateQrcode(Map<String, Object> data) {
// TODO Auto-generated method stub
Map<String, Object> icbcpaymap = new HashMap<String, Object>();
Map<String, Object> strResult = new HashMap<String, Object>();
logger.info("IcbcPayServiceImpl generateQrcode = " + data);
icbcpaymap = (Map<String, Object>) ICBCPayConstants.icbcConstantsmap.get(data.get("merchantId"));
// DefaultIcbcClient client = new DefaultIcbcClient(IcbcPayConstants.AppId,
// IcbcPayConstants.SIGN_TYPE_RSA2,
// IcbcPayConstants.private_key, IcbcPayConstants.public_key);
DefaultIcbcClient client = new DefaultIcbcClient((String) icbcpaymap.get("AppId"),
(String) icbcpaymap.get("SIGN_TYPE_RSA2"), (String) icbcpaymap.get("private_key"),
(String) icbcpaymap.get("public_key"));
QrcodeGenerateRequestV2 request = new QrcodeGenerateRequestV2(); //工行聚合支付生成支付二维码请求(通用请求参数+请求参数)的枚举类
// request.setServiceUrl(IcbcPayConstants.generateQrcodeURL);
request.setServiceUrl((String) icbcpaymap.get("generateQrcodeURL"));
QrcodeGenerateRequestV2Biz bizContent = new QrcodeGenerateRequestV2Biz(); //工行聚合支付请求参数的枚举类
// bizContent.setMerId(IcbcPayConstants.Mer_ID);//商户线下档案编号(特约商户12位,特约部门15位)
// bizContent.setStoreCode(IcbcPayConstants.Store_Code);//e生活档案编号
bizContent.setMerId((String) icbcpaymap.get("Mer_ID"));// 商户线下档案编号(特约商户12位,特约部门15位)
bizContent.setStoreCode((String) icbcpaymap.get("Store_Code"));// e生活档案编号
bizContent.setOutTradeNo((String) data.get("fOrdertrace"));// 商户系统订单号
bizContent.setOrderAmt((String) data.get("settleAmt"));// 订单总金额,单位:分
bizContent.setTradeDate((String) data.get("fRegdate"));// 商户订单生成日期,格式:yyyyMMdd
bizContent.setTradeTime((String) data.get("fRegtime"));// 商户订单生成时间,格式: HHmmss
// bizContent.setAttach("");//该字段非必输项,商户附加数据,最多21个汉字字符,原样返回
bizContent.setPayExpire("280");// 二维码有效期,单位:秒,必须小于24小时,终端页面超时时间要比这个长,且没有返回按钮
// bizContent.setNotifyUrl("127.0.0.1");//该字段非必输项,商户接收支付成功通知消息URL,当notify_flag为1时必输
bizContent.setTporderCreateIp("127.0.0.1");// 商户订单生成的机器IP
bizContent.setSpFlag("0");// 该字段非必输项,扫码后是否需要跳转分行,0:否,1:是;非1按0处理
bizContent.setNotifyFlag("0");// 商户是否开启通知接口 0-否;1-是;非1按0处理
request.setBizContent(bizContent);
QrcodeGenerateResponseV2 response = new QrcodeGenerateResponseV2();
try {
response = client.execute(request, "msgId");
if (response.isSuccess()) {// 成功
strResult.put("statuscode", response.getReturnCode() + "");
strResult.put("QrCodeData", response.getQrcode() + "");
logger.info("icbc generateQrcode isSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc generateQrcode isSuccess ReturnMsg = "+response.getReturnMsg());
} else {// 失败
strResult.put("statuscode", response.getReturnCode() + "");
logger.info("icbc generateQrcode notSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc generateQrcode notSuccess ReturnMsg = "+response.getReturnMsg());
}
} catch (Exception e) {
e.printStackTrace();
strResult.put("statuscode", "999");
}
logger.info("generateQrcode resp = " + strResult);
return strResult;
}
/**
* 工行聚合支付,商户扫描用户二维码
*/
@Override
public Map<String, Object> scanPay(Map<String, Object> data) {
// TODO Auto-generated method stub
Map<String, Object> icbcpaymap = new HashMap<String, Object>();
Map<String, Object> strResult = new HashMap<String, Object>();
logger.info("IcbcPayServiceImpl scanPay = " + data);
icbcpaymap = (Map<String, Object>) ICBCPayConstants.icbcConstantsmap.get(data.get("merchantId"));
// DefaultIcbcClient client = new DefaultIcbcClient(IcbcPayConstants.AppId,
// IcbcPayConstants.SIGN_TYPE_RSA2,
// IcbcPayConstants.private_key, IcbcPayConstants.public_key);
DefaultIcbcClient client = new DefaultIcbcClient((String) icbcpaymap.get("AppId"),
(String) icbcpaymap.get("SIGN_TYPE_RSA2"), (String) icbcpaymap.get("private_key"),
(String) icbcpaymap.get("public_key"));
QrcodePayRequestV2 request = new QrcodePayRequestV2();
// request.setServiceUrl(IcbcPayConstants.scanPayURL);
logger.info("scanPayURL = " + (String) icbcpaymap.get("scanPayURL"));
request.setServiceUrl((String) icbcpaymap.get("scanPayURL"));
QrcodePayRequestV2Biz bizContent = new QrcodePayRequestV2Biz();
bizContent.setQrCode((String) data.get("thirdAuthCode"));// 商户扫描上送,客户的付款码
// bizContent.setMerId(IcbcPayConstants.Mer_ID);
bizContent.setMerId((String) icbcpaymap.get("Mer_ID"));// 商户线下档案编号(特约商户12位,特约部门15位)
bizContent.setOutTradeNo((String) data.get("fOrdertrace"));// 商户系统订单号
bizContent.setOrderAmt((String) data.get("settleAmt"));
bizContent.setTradeDate((String) data.get("fRegdate"));
bizContent.setTradeTime((String) data.get("fRegtime"));
request.setBizContent(bizContent);
QrcodePayResponseV2 response;
try {
response = client.execute(request, "msgId");
if (response.isSuccess()) {// 成功
strResult.put("statuscode", response.getReturnCode() + "");
strResult.put("pay_status", response.getPayStatus() + "");// 交易结果标志,-1:下单失败,0:支付中,1:支付成功,2:支付失败
logger.info("icbc scanPay isSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc scanPay isSuccess pay_status = "+response.getPayStatus());
logger.info("icbc scanPay isSuccess ReturnMsg = "+response.getReturnMsg());
} else {// 失败
strResult.put("statuscode", response.getReturnCode() + "");
logger.info("icbc scanPay notSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc scanPay notSuccess pay_status = "+response.getPayStatus());
logger.info("icbc scanPay notSuccess ReturnMsg = "+response.getReturnMsg());
}
} catch (Exception e) {
e.printStackTrace();
strResult.put("statuscode", "999");
}
logger.info("scanPay resp = " + strResult);
return strResult;
}
/**
* 工行聚合支付,查询支付结果
*/
@Override
public Map<String, Object> queryPayResult(Map<String, Object> data) {
// TODO Auto-generated method stub
Map<String, Object> icbcpaymap = new HashMap<String, Object>();
Map<String, Object> strResult = new HashMap<String, Object>();
logger.info("IcbcPayServiceImpl queryPayResult = " + data);
icbcpaymap = (Map<String, Object>) ICBCPayConstants.icbcConstantsmap.get(data.get("merchantId"));
// DefaultIcbcClient client = new DefaultIcbcClient(IcbcPayConstants.AppId,
// IcbcPayConstants.SIGN_TYPE_RSA2,
// IcbcPayConstants.private_key, IcbcPayConstants.public_key);
DefaultIcbcClient client = new DefaultIcbcClient((String) icbcpaymap.get("AppId"),
(String) icbcpaymap.get("SIGN_TYPE_RSA2"), (String) icbcpaymap.get("private_key"),
(String) icbcpaymap.get("public_key"));
QrcodeQueryRequestV2 request = new QrcodeQueryRequestV2();
// request.setServiceUrl(IcbcPayConstants.queryPayResultURL);
request.setServiceUrl((String) icbcpaymap.get("queryPayResultURL"));
QrcodeQueryRequestV2Biz bizContent = new QrcodeQueryRequestV2Biz();
// bizContent.setMerId(IcbcPayConstants.Mer_ID);
bizContent.setMerId((String) icbcpaymap.get("Mer_ID"));// 商户线下档案编号(特约商户12位,特约部门15位)
// bizContent.setCustId("1076dAbpBsrJXpI4J+/HXthaHj+mORib");//该字段非必输项
bizContent.setOutTradeNo((String) data.get("orderId"));// 该字段非必输项,out_trade_no和order_id选一项上送即可,商户系统订单号
// bizContent.setOrderId("020002040095201802202148775");//该字段非必输项,out_trade_no和order_id选一项上送即可,行内系统订单号
request.setBizContent(bizContent);
QrcodeQueryResponseV2 response;
try {
response = client.execute(request, "msgId");
if (response.isSuccess()) {// 成功
strResult.put("statuscode", response.getReturnCode() + "");
strResult.put("PayStatus", response.getPayStatus() + "");// 交易结果标志,0:支付中,1:支付成功,2:支付失败
logger.info("icbc queryPayResult isSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc queryPayResult isSuccess ReturnMsg = "+response.getReturnMsg());
} else {// 失败
strResult.put("statuscode", response.getReturnCode() + "");
logger.info("icbc queryPayResult notSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc queryPayResult notSuccess ReturnMsg = "+response.getReturnMsg());
}
} catch (Exception e) {
e.printStackTrace();
strResult.put("statuscode", "999");
}
logger.info("queryPayResult resp = " + strResult);
return strResult;
}
/**
* 二维码退款
*/
@Override
public Map<String, Object> payReject(Map<String, Object> data) {
// TODO Auto-generated method stub
Map<String, Object> icbcpaymap = new HashMap<String, Object>();
Map<String, Object> strResult = new HashMap<String, Object>();
logger.info("IcbcPayServiceImpl payReject = " + data);
icbcpaymap = (Map<String, Object>) ICBCPayConstants.icbcConstantsmap.get(data.get("merchantId"));
// DefaultIcbcClient client = new DefaultIcbcClient(IcbcPayConstants.AppId,
// IcbcPayConstants.SIGN_TYPE_RSA2,
// IcbcPayConstants.private_key, IcbcPayConstants.public_key);
DefaultIcbcClient client = new DefaultIcbcClient((String) icbcpaymap.get("AppId"),
(String) icbcpaymap.get("SIGN_TYPE_RSA2"), (String) icbcpaymap.get("private_key"),
(String) icbcpaymap.get("public_key"));
QrcodeRejectRequestV2 request = new QrcodeRejectRequestV2();
// request.setServiceUrl(IcbcPayConstants.payRejectURL);
request.setServiceUrl((String) icbcpaymap.get("payRejectURL"));
QrcodeRejectRequestV2Biz bizContent = new QrcodeRejectRequestV2Biz();
// bizContent.setMerId(IcbcPayConstants.Mer_ID);
bizContent.setMerId((String) icbcpaymap.get("Mer_ID"));// 商户线下档案编号(特约商户12位,特约部门15位)
// bizContent.setCustId("1076dAbpBsrJXpI4J+/HXthaHj+mORib");//该字段非必输项
bizContent.setOutTradeNo((String) data.get("orderId"));// 该字段非必输项,out_trade_no和order_id选一项上送即可
// bizContent.setOrderId("020001515151201701030000001");//该字段非必输项,out_trade_no和order_id选一项上送即可
bizContent.setRejectNo((String) data.get("fOrdertrace"));
bizContent.setRejectAmt((String) data.get("refundAmt"));
// bizContent.setOperId("X000000001");//该字段非必输项,操作人员ID
request.setBizContent(bizContent);
QrcodeRejectResponseV2 response;
try {
response = client.execute(request, "msgId");
if (response.isSuccess()) {// 成功
strResult.put("statuscode", response.getReturnCode() + "");
logger.info("icbc payReject isSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc payReject isSuccess ReturnMsg = "+response.getReturnMsg());
} else {// 失败
strResult.put("statuscode", response.getReturnCode() + "");
logger.info("icbc payReject notSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc payReject notSuccess ReturnMsg = "+response.getReturnMsg());
}
} catch (Exception e) {
e.printStackTrace();
strResult.put("statuscode", "999");
}
logger.info("payReject resp = " + strResult);
return strResult;
}
/**
* 二维码冲正
*/
@Override
public Map<String, Object> payReverse(Map<String, Object> data) {
// TODO Auto-generated method stub
return null;
}
/**
* 二维码退款查询
*/
@Override
public Map<String, Object> queryRejectResult(Map<String, Object> data) {
// TODO Auto-generated method stub
Map<String, Object> icbcpaymap = new HashMap<String, Object>();
Map<String, Object> strResult = new HashMap<String, Object>();
logger.info("queryRejectResult payReject = " + data);
icbcpaymap = (Map<String, Object>) ICBCPayConstants.icbcConstantsmap.get(data.get("merchantId"));
// DefaultIcbcClient client = new DefaultIcbcClient(IcbcPayConstants.AppId,
// IcbcPayConstants.SIGN_TYPE_RSA2,
// IcbcPayConstants.private_key, IcbcPayConstants.public_key);
DefaultIcbcClient client = new DefaultIcbcClient((String) icbcpaymap.get("AppId"),
(String) icbcpaymap.get("SIGN_TYPE_RSA2"), (String) icbcpaymap.get("private_key"),
(String) icbcpaymap.get("public_key"));
QrcodeRejectQueryRequestV3 request = new QrcodeRejectQueryRequestV3();
// request.setServiceUrl(IcbcPayConstants.queryRejectResultURL);
request.setServiceUrl((String) icbcpaymap.get("queryRejectResultURL"));
QrcodeRejectQueryRequestV3Biz bizContent = new QrcodeRejectQueryRequestV3Biz();
// bizContent.setMerId(IcbcPayConstants.Mer_ID);
bizContent.setMerId((String) icbcpaymap.get("Mer_ID"));// 商户线下档案编号(特约商户12位,特约部门15位)
// bizContent.setCustId("1076dAbpBsrJXpI4J+/HXthaHj+mORib");//该字段非必输项
bizContent.setOutTradeNo((String) data.get("orderId"));
// bizContent.setOrderId("020001515151201701030000001");
bizContent.setRejectNo((String) data.get("refundorderId"));
request.setBizContent(bizContent);
QrcodeRejectQueryResponseV3 response;
try {
response = client.execute(request, "msgId");
if (response.isSuccess()) {// 成功
strResult.put("statuscode", response.getReturnCode() + "");
strResult.put("refund_json_list", response.getRefundJsonList());
logger.info("icbc queryRejectResult isSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc queryRejectResult isSuccess ReturnMsg = "+response.getReturnMsg());
} else {// 失败
strResult.put("statuscode", response.getReturnCode() + "");
logger.info("icbc queryRejectResult notSuccess ReturnCode = "+response.getReturnCode());
logger.info("icbc queryRejectResult notSuccess ReturnMsg = "+response.getReturnMsg());
}
} catch (Exception e) {
e.printStackTrace();
strResult.put("statuscode", "999");
}
logger.info("queryRejectResult resp = " + strResult);
return strResult;
}
}
```