数据交换说明:
企业客户端通过HTTP POST向民生银行的网上银行(以下简称网上银行)服务器发送请求命令,网上银行处理企业客户端发出的请求,并生成响应内容,请求与响应的报文结构包括:
1) HTTPheaders
2) MIMEtype application/x-NS-BDES
3) XMLdeclaration
4) CMBC declaration
5) CMBC XMLblock
以上1-2遵照HTTP协议规范(www.w3c.org),3-5部分为请求或响应文件内容,依照HTTP协议这两部分内容之间通过一个空行(CR LF)分隔。
CMBC内容类型为application/x-NS-BDES。
民生银行银企直连客户端代理 配置:
批量支付()
批量转帐交易,用于企业端程序向银行系统提出多笔支付或主动收款时使用,名称为batchXfer。另外,由于转账交易需要保证客户端与服务器间的同步,因此需要定义同步机制。
注意:本接口返回成功标记只表示申请已接收,每条支付是否成功需要调用批量付款对账接口查询。
请求(batchXfer)
标记 | 说明 | 长度 |
<xDataBody> |
|
|
<trnId>
| 客户端产生的交易唯一标(必输,但无作用) | 64 |
<insId> | 流水号(★) | 64 |
<cltcookie> | 可选,客户端cookie,响应时原值返回 |
|
<payerAcct> | 付款账户(★) | 32 |
<payType> | 付款类型 0:支付 1:代发工资(预留、暂不支持) 2:费用报销(预留、暂不支持) |
|
<totalRow> | 总记录数(★) | 6 |
<totalAmt> | 总金额数(★) | 15,2 |
<fileContent> | 竖线“|”分割数据元素,以尖号“^”为数据行分割符,具体格式定义与付款类型有关(★) |
|
</xDataBody> |
|
|
响应(batchXfer)
标记 | 说明 | 长度 |
<xDataBody> |
|
|
<batchTransfers> |
|
|
<trnId>
| 原值返回 | 64 |
<insId> | 流水号 | 64 |
</batchTransfers> |
|
|
</xDataBody> |
|
|
支付文件数据格式<fileContent>:
汇路|凭证号|支付业务种类|业务种类代码|收款帐户类型|收款账号|收款户名|收款行联行号|收款行名|备注|发送短信给收款方标识|收款方手机号|收款方email地址|常用用途代码|金额^汇路|凭证号|支付业务种类|业务种类代码|收款帐户类型|收款账号|收款户名|收款行联行号|收款行名|备注|发送短信给收款方标识|收款方手机号|收款方email地址|常用用途代码|金额
域名称 | 说明 | 长度 |
汇路 | 行内交易输入0 跨行交易汇路为: 6 小额实时支付 7 大额实时支付 11 网银互联 | 2 |
凭证号:输入企业自制凭证号 | 必输 用于企业ERP系统更新流水状态的标识,目前支持8位 | 8 |
支付业务种类 | 可不输入 |
|
业务种类代码 | 可不输入 |
|
收款帐户类型 | 必输 0.企业 1.个人卡 2.个人折 | 1 |
收款账号 | 必输 | 32 |
收款户名
| 必输 | 60 |
收款行联行号 | 行内转账不用输入 大小额时填支付行号 网易互联时填写网银互联支付行号
| 12 |
收款行名 | 行内转帐不输,跨行转帐必须输入。 大小额时填写支付行名 网银互联是填写网银互联支付行名
| 40 |
备注 | 可不输入 | 20 |
发送短信给收款方标识 | 0:不通知收款方(目前只支持0) 1:通知收款方 |
|
收款方手机号 | 如果通知收款方,手机号码和邮箱至少输入一项。手机号必须是134——139。 |
|
收款方email地址 |
| |
常用用途代码 | 可不输入 |
|
金额 | 必输 | 15,2 |
直接看service实现类处理
/**
* 民生批量支付处理(批量支付提交部分)
*@param:monitorAddress (此处为:192.168.0.18)
*/
public void setPayBillCMBC(PlatformStationBill platformStationBill,String monitorAddress){
/*业务处理可忽略
Session session=this.getSession();
StringBuffer fileContent=new StringBuffer();
BigDecimal totalAmt=BigDecimal.ZERO;
BatchReconciliation batchReconciliation=new BatchReconciliation();
List<BatchReconciliationDetail> details=new ArrayList<BatchReconciliationDetail>();
batchReconciliation.setInsid(this.dataHelperService.getIdentifier(session, AutoNoTable.BATCH_PAY.getValue()));
batchReconciliation.setSettlementType(BatchPayType.STATION_PAY.getValue());
batchReconciliation.setReconciliationStatus(BatchPayStatus.PENDING.getValue());
batchReconciliation.setCreateTime(new Date());
batchReconciliation.setCreateUser(Constants.SYSTEM_USER);
for(PlatformStationBillDetail detail:platformStationBill.getPlatformStationBillDetail()){
StationBill stationBill=(StationBill) session.get(StationBill.class, detail.getId());
ServiceStation serviceStation=(ServiceStation)
session.get(ServiceStation.class, stationBill.getServiceStationId());
BigDecimal amt = nullToZero(stationBill.getRapairCharges())
.add(nullToZero(stationBill.getSortCharges()))
.add(nullToZero(stationBill.getStorageCharges()))
.add(nullToZero(stationBill.getTransportCharges()))
.add(nullToZero(stationBill.getGodownentryCharges()))
.add(nullToZero(stationBill.getOutboundCharges()))
.add(nullToZero(stationBill.getRegistrationCharges()));
//合计
totalAmt=totalAmt.add(amt);
BatchReconciliationDetail batchDetail=new BatchReconciliationDetail();
batchDetail.setBatchReconciliation(batchReconciliation);
batchDetail.setVoucher(String.valueOf(stationBill.getId()));
batchDetail.setAmt(amt);
//TODO
batchDetail.setAccountType(serviceStation.getAccountType());
batchDetail.setAccountId(serviceStation.getBankAccount());
batchDetail.setAccountName(serviceStation.getBankName());
batchDetail.setCreateTime(new Date());
batchDetail.setCreateUser(Constants.SYSTEM_USER);
//汇路:行内交易输入0; 跨行交易汇路为:6 小额实时支付 7 大额实时支付 11 网银互联
//TODO
if(serviceStation.getBankId()!=143){
if(amt.compareTo(new BigDecimal(50000))==1){
// 大额实时支付
batchDetail.setRoute("7");
//TODO
batchDetail.setLianHangId(serviceStation.getNumberBank());
batchDetail.setLianHangName(serviceStation.getNameBank());
fileContent.append("7|".concat(String.valueOf(stationBill.getId())).concat("|||")
.concat(serviceStation.getAccountType()).concat("|")
.concat(serviceStation.getBankAccount()).concat("|")
.concat(serviceStation.getBankName()).concat("|")
.concat(serviceStation.getNumberBank()).concat("|")
.concat(serviceStation.getNameBank()).concat("||||||")
.concat(amt.toString()).concat("^"));
}else{
//网银互联
batchDetail.setRoute("11");
//TODO
Bank bank=(Bank) session.get(Bank.class, serviceStation.getBankId());
batchDetail.setLianHangId(bank.getLianHangId());
batchDetail.setLianHangName(bank.getBankName());
fileContent.append("11|".concat(String.valueOf(stationBill.getId())).concat("|||")
.concat(serviceStation.getAccountType()).concat("|")
.concat(serviceStation.getBankAccount()).concat("|")
.concat(serviceStation.getBankName()).concat("|")
.concat(bank.getLianHangId()).concat("|")
.concat(bank.getBankName()).concat("||||||")
.concat(amt.toString()).concat("^"));
}
}else{
//行内交易
batchDetail.setRoute("0");
fileContent.append("0|".concat(String.valueOf(stationBill.getId())).concat("|||")
.concat(serviceStation.getAccountType()).concat("|")
.concat(serviceStation.getBankAccount()).concat("|")
.concat(serviceStation.getBankName()).concat("||||||||")
.concat(amt.toString()).concat("^"));
}
details.add(batchDetail);
}
batchReconciliation.setTotalRow(platformStationBill.getPlatformStationBillDetail().size());
batchReconciliation.setTotalAmt(totalAmt);
batchReconciliation.setBatchReconciliationDetail(details);
String fileContents=fileContent.substring(0,fileContent.length()-1);
//fileContent.substring(0,fileContent.length());
*/
String stringXml = null;
String url ="http://"+monitorAddress+"/eweb/b2e/connect.do";
BatchDataModel batchData=new BatchDataModel();
try {
StringBuilder sb = new StringBuilder();
sb.append("<?xml version='1.0' encoding='UTF-8' standalone='no'?>");
sb.append("<CMBC header='100' version='100' security='none' lang='chs' trnCode='batchXfer'>");
sb.append("<requestHeader>");
sb.append("<dtClient>"+DateUtil.getStringDate() +"</dtClient>");
sb.append("<clientId>2200003220</clientId>");
sb.append("<userId>2200003220001</userId>>");
sb.append("<userPswd>123123</userPswd>");
sb.append("<language>chs</language>");
sb.append("<appId>nsbdes</appId>");
sb.append("<appVer>201</appVer>");
sb.append("</requestHeader>");
//
sb.append("<xDataBody>");
sb.append("<trnId>"+ batchReconciliation.getInsid()+"</trnId>");
sb.append("<cltcookie></cltcookie>");
sb.append("<insId>"+ batchReconciliation.getInsid()+"</insId>");
sb.append("<payerAcct>600033029</payerAcct>");
sb.append("<payType>0</payType>");
sb.append("<totalRow>"+platformStationBill.getPlatformStationBillDetail().size()+"</totalRow>");
sb.append("<totalAmt>"+totalAmt+"</totalAmt>");
sb.append("<fileContent>"+fileContents +"</fileContent>");
sb.append("</xDataBody>");
//
// sb.append("<xDataBody>");
// sb.append("<trnId>20151023110951185</trnId>");
// sb.append("<insId>batch20151023110951185</insId>");
// sb.append("<payType>0</payType>");
// sb.append("</xDataBody>");
sb.append("</CMBC>");
System.out.println("发送的报文:");
System.out.println(sb);
URL sendUrl = new URL(url.trim());
URLConnection connection = sendUrl.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Connection", "close");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "utf-8");
out.write(sb.toString());
// HttpURLConnection httpUrlConnection = (HttpURLConnection) connection;
// httpUrlConnection.setConnectTimeout(30000);
// httpUrlConnection.setReadTimeout(30000);
// httpUrlConnection.setDoOutput(true);
// httpUrlConnection.setDoInput(true);
// httpUrlConnection.setRequestProperty("Connection", "close");
// httpUrlConnection.setRequestProperty("accept", "*/*");
// httpUrlConnection.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
// httpUrlConnection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// httpUrlConnection.setRequestMethod("POST");
// DataOutputStream out = new DataOutputStream(httpUrlConnection.getOutputStream());
// out.writeBytes(sb.toString());
out.flush();
out.close();
String sCurrentLine;
sCurrentLine = "";
stringXml="";
InputStream l_urlStream = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(l_urlStream,"GB2312");
BufferedReader l_reader = new BufferedReader(isr);
while ((sCurrentLine = l_reader.readLine()) != null) {
stringXml+=sCurrentLine;
}
System.out.println(stringXml);
//
//获取报文数据
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(stringXml)));
//解析报文数据
Node t=doc.getElementsByTagName("CMBC").item(0);
batchData.setTrnCode(t.getAttributes().getNamedItem("trnCode").getFirstChild().getNodeValue());
NodeList s=doc.getElementsByTagName("status");
if (s != null) {
for (int i = 0; i < s.getLength(); i++) {
Element node = (Element)s.item(i);
batchData.setCode(node.getElementsByTagName("code").item(0).getFirstChild().getNodeValue());
batchData.setSeverity(node.getElementsByTagName("severity").item(0).getFirstChild().getNodeValue());
batchData.setMessage(node.getElementsByTagName("message").item(0).getFirstChild().getNodeValue());
}
}
NodeList s2=doc.getElementsByTagName("batchTransfers");
if (s != null) {
for (int i = 0; i < s2.getLength(); i++) {
Element node = (Element)s2.item(i);
batchData.setTrnId(node.getElementsByTagName("trnId").item(0).getFirstChild().getNodeValue());
batchData.setInsId(node.getElementsByTagName("insId").item(0).getFirstChild().getNodeValue());
}
}
}catch(Exception e){
e.printStackTrace();
}
//提交后的处理
if(batchData.getTrnCode()!=null){
if(StringUtils.equals(batchData.getCode(), "0")){
//成功进行相应的业务处理
for(PlatformStationBillDetail detail:platformStationBill.getPlatformStationBillDetail()){
StationBill stationBill=(StationBill) session.get(StationBill.class, detail.getId());
stationBill.setPayFalg(BatchPayFalg.ADD_CMBCEPAY.getValue());
stationBill.setUpdateUser(Constants.SYSTEM_USER);
stationBill.setUpdateTime(new Date());
session.update(stationBill);
}
//生成批量对账数据
session.save(batchReconciliation);
this.setMessage("提交成功!");
}else{
this.setMessage("提交失败:"+batchData.getMessage());
}
}else{
this.setMessage("提交失败,请确认民生支付配置是否正确或CFCA软件是否开启服务!");
}
}