相关NC中间件的文章,已经放到个人公众号(“开发谈”栏目),扫码可以进入。
- 适用对象:自己动手开发银企互联的企业客户。
- 非官方产品,客户应优先根据官方开发手册自行开发。
- 开发者免责:开发者力求正确,也经过测试,但无法避免潜在的错误。任何软件都可能存在错误。
- 客户使用银企互联,应遵从谨小慎微的原则,从查询业务、小金额业务着手,必要时采用银企互联提交指令、企业网银授权的模式。
- 本WebService程序在Windows操作系统上部署,需要.net4.0框架。
- 未尽事宜,请参阅官方开发手册。
常规开发模式中,数据交互方式如下:
如果是签名类交易,业务发起流程如上图。客户开发的工作量主要是 1、3,较为繁琐。
如果是查询类交易,则上述步骤中 1、2 不做。
企业客户开发过程通常遇到的问题:
- 不太愿意看官方开发文档。实际上,我自己开始着手练习银企互联技术,就是按照官方文档来的。
- 不知道如何去做签名。
- 银行测试环境日期非标准,无法灵活应对请求信息中的日期、时间相关参数。
- 很少自己产生日志文件,遇到错误难以确定。向银行陈述错误没有依据。
- 采用过程化,很少对象化,代码复用性差,程序不健壮。
- 官方提供的DEMO比较少。
- 部分企业客户的系统不支持socket协议,需要银行或者开发商提供辅助手段。
- 一些高级技巧、应用无从谈起,比如大批量指令发送,制作PDF格式的电子回单。
本方案设计的数据交互为:
本方案图中步骤 2、5,相当于第一图中的 1、2、3、6,由 WebService 自动执行。
特点:
- ERP系统只需要通过HTTP协议将参数和发送内容一次性POST到WebService指定页面,接收应答即可。开发者不需要关注签名、提交页面格式、报文头参数、压缩模式等,实现了跨平台、跨语言的简单开发。
- 支持压缩模式提交大批量指令:rd最外层头尾套<zip>、</zip>即可,比如:……<zip><rd>……</rd>……<rd>……</rd></zip>……。WebService会自行压缩数据。如将压缩好的数据放入zip节点(官方做法)后使用本程序提交反而会出错。
- XML报文中日期/时间关键参数自动配置,大部分情况下自适应银行主机时间。特别是在测试环境的时候,不需要调整本机时间。
- ICBC_Log文件夹可以保存日志文件,方便跟踪。
- 提供PDF文件的高级应用。
部署本WebService,需要.NET4框架。
- 如果没有按照.net4框架,请安装。如果没有安装IIS,请安装。为减少错误,其中应用程序开发功能请全选。
- 添加网站,选择物理路径,自己定义一个不常用的端口,本例使用1398。
- 运行。浏览器打开对应地址,比如http://127.0.0.1:1398,点击WebService.asmx,可以看到提供的服务。点击CheckNC或者CheckWS,可以查看到对应返回内容,则表明部署成功。
- 如果需要从局域网其他电脑访问本WebService,则需要在防火墙中添加的本服务端口(入站、TCP)。
WebService中Web.Config信息:
nc_ip:NetSafeClient的IP地址。
nc_hp、nc_sp:NetSafeClient的HTTPS服务端口以及签名端口。
cis、id:客户企业网银对应的CIS编号和证书名称。使用ICBC_YQHL方法时与XML中信息校验。
log、pdf_save:是否产生日志文件,是否保留pdf回单文档。方便客户调试。
如果防火墙端口未添加,从其他电脑访问出错:
添加端口后,访问正常:
提供的方法以及需要的参数,可以自行点击WebService.asmx查看。比如QACCBAL,从图中看到就是acct一个参数:
本项目的第一个测试客户,是因为sap不支持socket协议,提出“银行给出中间服务层”的需求。给了他们第一个版本(参数个数和现在有些不同),经过调试,畅通。下图是客户sap界面,他们用了get方式,已经建议修改为post。
对于最重要的ICBC_YQHL方法做些说明:
- 程序自动替换内容的空白节点请使用<node></node>这种格式,如果写成<node/>这种,程序无法自动填充其数值。TranDate、TranTime、SignTime等字段,程序将自动补充,为避免部分系统自动将<TranDate></TranDate>变成<TranDate/>这种格式,可以随意输入些内容,比如<TranDate>NotCare</TranDate>。
- fSeqno节点内容如果空白或内容长度<=3,则由系统自动填写。个人建议:查询类的报文该字段可以空白或输入长度小于3的内容,交易类的请指定fseqno内容(长度>3),避免发送请求后没有接收到回执而无从判断银行究竟接收到了指令没有。
从网上摘录一些代码,作为本项目的多语言测试。
PHP:先查询余额;做一笔支付;再查询余额。由于是工行系统内支付,实时处理,故第二次查询的时候,余额已经变化了。
<?php
header('charset: GBK');
function send_post($url, $post_data) {
$postdata = http_build_query($post_data);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type:application/x-www-form-urlencoded',
'content' => $postdata,
'timeout' => 30 // 超时时间(单位:s)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
return $result;
}
$xml_info='<?xml version="1.0"encoding="GBK"?><CMS><eb><pub><TransCode>PAYENT</TransCode><CIS>46694306-XAAAAA</CIS>'
.'<BankCode>102</BankCode><ID>suzhouTest.y.1102</ID><TranDate></TranDate>NotCare<TranTime>NotCare</TranTime><fSeqno>X</fSeqno>'
.'</pub><in><OnlBatF>1</OnlBatF><SettleMode>0</SettleMode><TotalNum>1</TotalNum><TotalAmt>1122</TotalAmt><SignTime></SignTime>'
.'<ReqReserved1></ReqReserved1><ReqReserved2></ReqReserved2><rd><iSeqno>1</iSeqno><ReimburseNo></ReimburseNo><ReimburseNum>'
.'</ReimburseNum><StartDate></StartDate><StartTime></StartTime><PayType>1</PayType><PayAccNo>1102020109000009078</PayAccNo>'
.'<PayAccNameCN>剥滥火判酬</PayAccNameCN><PayAccNameEN></PayAccNameEN><RecAccNo>1102020109000203242</RecAccNo>'
.'<RecAccNameCN>剥滥判幕耕婚舒憾</RecAccNameCN><RecAccNameEN></RecAccNameEN><SysIOFlg>1</SysIOFlg><IsSameCity></IsSameCity>'
.'<Prop>