项目实战03第三方接口对接之注意事项

近期和p2p公司合作进行闲置资金的货币基金购买。
核心功能自然是原有的网上交易核心service层,之前的service层服务的是ctrl层,现在ctrl层变成了第三方接口,而非常规的网页的ctrl层,简单来说就是重写ctrl层,返回json而非网页。

何种交互方式

解决问题:客户端如何调用服务器接口or服务。
主要有3种方案,socket,webservice,json+http。

socket

socket偏底层,效率高。但是不考虑,因为开发成本大

webservice

优点:支持跨平台,跨语言,远程调用
缺点:wsdl文件不大容易看懂,并且调试抓包来的内容也难以理解。
从使用角度,好处在于只需定义好server的interface,根据interface生成wsdl文件,对方(client)根据wsdl文件生成可以调用的client的方的interface,然后直接调用即可。一般需要server提供interface使用demo或者文档,否则裸接口也不大看得明白。

定制型json

直接使用http+json
优点:灵活,简单高效。json没有什么门槛。

最终选择json+http,主要原因是json报文对人更友好,容易抓包调试和记录到全局日志中,且报文紧凑,节约网络。

连接加密和报文加密

解决问题:报文泄露和篡改,还有就是避免报文抵赖(对方发出的报文,不承认自己发出过,产生纠纷)

金融公司业务肯定是需要加密传输的,这里的加密包含2层。
第一层:https层的加密,也就是非对称加密获取秘钥和对称加密发送报文。
第二层:对https传输内容的加密,主要是报文加密+加签(己方私钥),然后对整体加密(对方公钥)
整个流程是双加密的过程(https一次,内容二次)
举例:json content(post的body)

1
2
3
4
5
6
7
8
9
10
11
12
13
{
req:{
reqId:001,# 唯一id
reqType:022,# 操作类型,申购
data:{
name:xxx,# 业务参数
age:xxx,
amount:100.0,
vol:100.0
},
}
sign:qrwefafdaf# 己方私钥对req的加签
}

再对json content 整体用对方公钥加密,发送给对方。
由于使用对方的公钥加密,所以只要对方私钥不泄露,则报文就是防偷窥的。(即使泄露了,责任也在对方一侧)。
由于sign有己方私钥的加签,所以报文也做到了防“己方耍赖”的要求。
这种方案优点就是安全最重要的是双方都无法抵赖
缺点就是慢,一次交互,需要做加密和解密,加签验签,四个流程(如果再考虑https自己还有一层非对称+对称加密就更复杂了)。好在基金公司并发量都不会太高,即使高了也可以通过升级机器解决(在不行做分布式呗,反正基金公司钱多,能用钱解决的问题都好办)

免登录

公司自己站点网页上通过登录来校验用户,和第三方对接时,用户在对方网站登录就认为登录过。凡对方接口发过来请求,都认为是用户授权过的操作。
所以对内部接口做免登处理,这个可能需要改动部分service层。

幂等和重试

解决问题:报文已处理和报文未处理情况下的响应丢失问题。
分2种情况:
1,报文丢失,真的丢了,server没收到,所以业务实际没执行
2,报文响应丢失,报文到达server,server也处理了。但是response后,client未收到
以上2种情况,应该处理的方式是不一样的
第一种,client重发
第二种,client发出查询请求,传入刚才未response的消息reqid,查询到执行结果。
但可惜的是,从client的角度看,这2种错误,都是同一种现象,就是自己没有收到response。
也就是说client无法区分到底发生了第一种错误还是第二种错误。自然也就无法判断目前是那种情况,自己应该采用何中应对之策。而且第二种处理,对不同类型消息,查询到的响应信息是不同的,也就是说各接口需要独立实现额外的查询功能,有较大开发量

解决方案:对所有请求的唯一标志,reqId建立独立日志表,记录reqId和response。
如果新报文的reqId
01,不在表中,说明全新请求,正常执行业务逻辑即可。
02,在表中,但是response为空,说明这个请求正在处理中,返回约定错误码,让其稍后再试。
03,在表中,且response为空,说明这个请求已经处理过,且响应过报文,直接将上次的response再返回一次即可。

在这种方案下,如果对方未收到response,重试即可。

日志体系

解密前日志,解密后日志,

研发对接形式

demo形式(testcase)

提供我方各接口的自测test case,加上各函数的字段注释,以及产品部门提供给对方的业务背景知识指导和教育信息。
优点:简单,便于快速启动对接
缺点:沟通成本太高,尤其是缺乏行业背景知识。从我们视角看,各种诡异报文都有,没有申购就赎回(类似于没有买就卖),没有确认就给用户加份额等。
除此之外,字符类型和数字类型有的用string表示,有的用int,有的用float,非常随意,虽能跑,但感觉在溜冰。一旦我方未校验到,有可能导致非法数据入库。
这种对接模式下,从研发介入到最终上线,大约持续2个月左右。6周对接,2周联调加灰度。

完善文档+demo代码

提供完整的接口文档,包含功能说明,字段名称,含义,格式(int,float,str),取值范围,业务性关联(字段同现,或者二选一等内部逻辑性关联)
样例resquest,样例response等。
优点:减少合作方的一些低级错误。至少数字,字符串保持稳定一致性。参数保证合法区间,字段无逻辑矛盾。
缺点:己方维护文档成本较高,而且是一个持续维护的过程,实际对于部分简单接口,开发自测30分钟,维护文档可能需要2个小时(编造数据,模拟报文等)
但整体来说可以较好的提高对接效率,可以将对接时间缩短到1个月左右。文档维护虽然麻烦,但是由于是一份文档对多个合作方都是通用的,所以整体还是很划算的。而且也利于公司内部新人的学习和接手

jar包

最终大招就是为对方提供己方的jar包。后期和招行信用卡以及金蝶,用友的对接都是采用这总方式(当然,大客户都做了一些微定制)。
这种方式只需要稍有背景知识即可。至于参数校验,取值合法性,逻辑合法性等都在我方jar包内部做了检查。对方只要能梳理好业务逻辑即可。这个门槛已经很低了,基本类似于淘宝购物的门槛了
和招行信用卡对接也不过用了2周左右(大约1周驻场了),可见,这种方式的效果还是很给力的。

上线流程

双方自己开发

按照约定提供demo或者文档,自己开发自己的功能。

双方联调

双方开发完毕,进行接口对接联调,发现大家接口的一些基础错误(字段缺失,格式错误等)。
同时,也需要做全功能,全流程业务的逻辑测试验证。

双方上测试

双方测试组介入,研发组退出。
测试组有独立的测试环境,可以验证研发的上线步骤/计划是否有问题。
同时也能暴露出研发测试的一些测试遗漏点。

双方上灰度

所谓灰度就是准生产了,不过这个生成是对双方公司内部的生产,也就是只有双方公司内部人员才可以操作的流程。
确保出了问题的话,也都是公司自己人,不会给陌生用户带来影响。

其他坑和特殊点总结

1,知识背景

跨行业背景知识很重要,对方如果缺乏对己方的了解,会导致一些非常低级的错误出现,这种错误还是我们不大可能考虑到的(比如没有买就卖,如果没有考虑到,虽然造不成实际损害,但会导致报错信息难以理解)。最好的解决方法是让对方体验下自己的产品,比如就给对方100块,买10多笔基金,在卖10多笔,对方自然就明白了。
比产品给他们上半天课效果好多了。

2,永远不要信任对方接口(全部强校验)

永远不要相信对方接口,永远不要相信对方接口,永远不要相信对方接口!
金融行业用decimal保存数值是默认行规,人人都知道,但互联网大多float就够了,会导致0.999999这样的数据进来,如果不做校验,会导致一些金额或份额的视觉偏差(本来是整数份,结果显示成x.99999,虽然实际上也不会给用户带来损失,但会造成用户恐慌和对公司的不信任

3,语言坑(php json引号)

php在处理json时会自动对数值添加单引号,这个可能是php特定版本的包的问题。

4,float不精准

上面提到过,不在赘述

5,限制支付方式(只能走纯接口)

只支持快捷支付,不支持招行直付通(需要跳转到对方银行鉴权,再跳转回来的,Oauth2鉴权)。纯粹接口形式无法支持网页跳转,且对接代价高昂。(快捷支付包含最初的通联和后来的快捷支付)

6,RSA加密(略)

大质树+欧拉定理,脑子不够用,看不懂,只要知道公钥私钥不相同,以及公钥加密+验签,私钥解密+加签就够了。

7,提单时间依据

大多根据公司内部数据库时间,部分渠道经协商可以采用对方接口时间

8,沟通相关

邮箱沟通,万一后续涉及扯皮,可以避免甩锅

9,字段名转换

有些公司是一对多(一个公司对接多个基金公司),未必完全按照我们制定的接口标准,还有些是自己原本就有一套了。当然,同一个业务基本字段都是一致的(感谢基金业协会,一般各公司技术的boss都会进行协商出统一交易码和交易核心字段),只是一些非核心,或是针对特定定制业务的字段命名上可能不同,可能需要做字段映射。这个一般是写死到代码里的。一方面使用场景有限,另一方面和定制的特定渠道高度相关,不大好做成通用模块。

10,文件确认对账机制

行规,最终以确认文件为准。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×