由于工行的支付接口目前是没有向B2B商户提供按订单号查询订单状态的,因此处理订单成功支付后的消息就显得非常重要了,以下为鲁炬在做银行支付项目时处理工行订单支付成功通知的核心代码。
[java]
/**
* 处理工行支付成功通知
*/
public void notifyDate(String notifyDataBase64, String signMsg, String merVAR, String realPath) {
String encoding = "gbk";
log.debug("接收工行通知信息原文:notifyData:" + notifyDataBase64);
log.debug("接收工行通知信息原文:signMsg:" + signMsg);
log.debug("接收工行通知信息原文:merVAR:" + merVAR);
byte[] notifyDataBytes = null;
String notifyData = null;
try {
notifyDataBytes = ReturnValue.base64dec(notifyDataBase64.getBytes(encoding));
notifyData = new String(notifyDataBytes, encoding);
log.debug("接收工行通知信息:notifyData:base64解码后:" + notifyData);
} catch(UnsupportedEncodingException e) {
log.error("工行解析通知内容出错:", e);
throw new RuntimeException(e);
}
String dir = realPath + "/resources/files/bank/icbc/crt/";
//获取工行证书
byte[] bCert = null;
try {
FileInputStream fis = new FileInputStream(dir + "admin.crt");
bCert = new byte[fis.available()];
fis.read(bCert);
fis.close();
} catch(IOException e) {
log.error("读取admin.crt,文件出错:", e);
throw new RuntimeException(e);
}
byte[] bSign = cn.com.infosec.icbc.ReturnValue.base64dec((signMsg.getBytes()));
byte[] bSrc = notifyDataBytes;
//开始验签
int recode = -1;
try {
recode = cn.com.infosec.icbc.ReturnValue.verifySign(bSrc, bSrc.length, bCert, bSign);
} catch(Exception e) {
log.error("验签出错:", e);
throw new RuntimeException(e);
}
if(recode != 0) {
log.debug("工行验签失败验证返回码:" + recode);
return;
}
log.debug("工行验签成功,开始解析通知内容");
//解析通知内容 : 订单号、是否支付成功、金额
//notifyData
XmlParser xmlParser = new XmlParser(new ByteArrayInputStream(notifyDataBytes));
String orderId = xmlParser.getElementText("/B2CRes/orderInfo/subOrderInfoList/subOrderInfo/orderid");
String amount = xmlParser.getElementText("/B2CRes/orderInfo/subOrderInfoList/subOrderInfo/amount");
String tranStat = xmlParser.getElementText("/B2CRes/bank/tranStat");
log.debug("工行订单支付成功通知: 订单号:" + orderId + " 支付状态:" + tranStat + " 金额:" + amount);
if(!"1".equals(tranStat)) {
log.debug("订单状态为未支付成功,返回");
return;
}
//查询订单信息
ExamOrder examOrder = this.examOrderService.queryExamOrderByOrderNum(orderId);
int examOrderMoney = (new Double(examOrder.getMoney() * 100)).intValue();
if(!amount.equals(Integer.valueOf(examOrderMoney).toString())) {
log.debug("实际支付订单金额与应付金额不等,返回");
return;
}
//更新订单状态为已结算
try {
log.debug("更新订单" + orderId + "状态为已结算");
this.examOrderService.updateSuccessOrder(orderId);
} catch(Exception e) {
log.error("更新订单状态为已结算出错", e);
throw new RuntimeException(e);
}
}