第三方支付系统集成实践

集成对象,支付宝、易宝支付系统集成,平台语言Java。

集成服务费率
支付宝,预交600元,在12个月内, 可走合作交易流量42000元,超量后单笔费率1.5%,视交易金额可以协商服务费率。
易宝百分之一,视交易金额也可以协商服务费率。

支付宝采用电子合同签约方式,易宝采用纸质合同签约,而且需要身份证复印件等内容,相对麻烦一点,还好不用现场签约,打印后填写完毕,附上复印件快递过去即可。正式签约完成后第三方支付会提供商家代码和接口集成文档和代码。

两种支付系统都提供了各自的签名包和支付URL生成函数。
在支付银行方面,支付宝是跳转到自己的平台后,用户选择网上银行。也可以先设置默认银行代码,转到支付宝后会默认选中对应的银行。易宝还支持在源网站以银行代码的方式设置HTML代码参数,完成直连对应的网上银行。

用户输入支付金额->选择银行种类->提交->系统接收数据生成订单号、支付主题、签名、交易时间、同步设置等,例子如下:

支付宝支付提交HTML代码
<input type=hidden name="body" value="<支付主题>">
<input type=hidden name="notify_url" value="<支付通知页URL>">
<input type=hidden name="return_url" value="<支付完成返回页URL>">
<input type=hidden name="out_trade_no" value="<交易时间>">
<input type=hidden name="total_fee" value="<交易金额>">
<input type=hidden name="partner" value="<商家代码>">
<input type=hidden name="payment_type" value="<支付方式>">
<input type=hidden name="seller_email" value="<商家mail>">
<input type=hidden name="service" value="<交易方式>">
<input type=hidden name="sign" value="<交易信息签名>">
<input type=hidden name="sign_type" value="<签名方式>">     
<input type=hidden name="subject" value="<标题>">
<input type=hidden name="show_url" value="<URL信息>">
<input type=hidden name="paymethod" value="<支付类型>">
<input type=hidden name="defaultbank" value="<银行编码>">
[img align=M][^upload^]/1267619947.jpg[/img]

易宝支付提交HTML代码
<input type="hidden" name="p0_Cmd"   value="Buy">
<input type="hidden" name="p1_MerId" value="<商家代码>">
<input type="hidden" name="p2_Order" value="<订单号>">
<input type="hidden" name="p3_Amt"   value="<交易金额>">
<input type="hidden" name="p4_Cur"   value="<交易币种>">
<input type="hidden" name="p5_Pid"   value="<支付主题>">
<input type="hidden" name="p6_Pcat"  value="<商品种类>">
<input type="hidden" name="p7_Pdesc" value="<商品描述>">
<input type="hidden" name="p8_Url"   value="<支付完成返回页URL>">
<input type="hidden" name="p9_SAF"   value="<是否配送>">
<input type="hidden" name="pa_MP"    value="<扩展信息>">
<input type="hidden" name="pd_FrpId" value="<银行编码>">
<input type="hidden" name="pr_NeedResponse"  value="<应答机制>">
<input type="hidden" name="hmac"     value="<交易信息签名>">
[img align=M][^upload^]/1267619979.jpg[/img]
支付宝的sign和易宝的hmac,都是为了保证支付内容完整性而生成的加密信息,其中包含商家代码、编码、日期等集合的hash值,第三发支付收到后可以根据表单中的元素验算一次,即可知信息有无篡改。特别是对于交易金额,商家代码等信息的验证非常重要。支付提交目的URL都是各自平台的HTTPS链接,即使DNS被劫持也能检查出来。

<支付完成返回页URL>和<支付通知页URL>的不同:
<支付完成返回页URL>是支付完成后网银跳转到对应商户指定URL,一般发起方是商业银行的网银系统。<支付通知页URL>由第三方支付的通知服务器发起。

支付过程为:
生成支付表单后->用户点击提交->打开新页面->导向第三方支付接口网关->接口网关完成数据验算和商家验证->第三方支付生成系统与网银的URL->然后跳转到具体银行的网银付款界面->付款成功后->网银跳转到到支付表单中定义的<支付完成返回页>。
易宝和支付宝唯一不同的是最后一步,付款成功后网银会先跳转回易宝的支付网关,然后带参数导向<支付完成返回页URL>,以招商银行的网银HTML代码片段为例:
<form action="https://netpay.cmbchina.com/netpayment/BaseHttp.dll?LoadWalletVersion" method="post" id="fmNetBank" target="_blank">
<input type="hidden" name="Version" value="36S">
<input type="hidden" name="CoNo" value="002288">
<input type="hidden" name="OrderNo" value="awkMOi">
<input type="hidden" name="Date" value="20100304">
<input type="hidden" name="Amount" value="1.01">
<input type="hidden" name="BranchID" value="0010">
<input type="hidden" name="Connect" value="2">
<input type="hidden" name="MerchantURL" value="http://bank.yeepay.com/app-merchant-proxy/netcmbchinarecv.action">
<input type="hidden" name="SignFlag" value="0">
<input type="hidden" name="MerchantSig" value="">
<input type="hidden" name="MerchantCode" value="">
</form>
<input  type="hidden" name="FormSele" value="1">
<input  type="hidden" name="MerchantNo" value="002288">
<input  type="hidden" name="MerchantName" value="易宝支付">
<input  type="hidden" name="PO" value="awkMOi">
<input  type="hidden" name="PODate" value="20100304">
<input  type="hidden" name="Amt" value="1.01">
<input  type="hidden" name="ConnectType" value="2">
<input  type="hidden" name="MerchantURL" value="http://bank.yeepay.com/app-merchant-proxy/netcmbchinarecv.action">
<input  type="hidden" name="MerchantSignFlag" value="0">
<input  type="hidden" name="MerchantSign" value="">
<input  type="hidden" name="MerchantBankNo" value="0010">
招行完成支付后会通知到易宝的netcmbchinarecv.action,并跳转到易宝,易宝从数据库查询出源服务器支付表单参数中的<支付完成返回页URL>,带参数导向回<支付完成返回页URL>。

支付宝还区分了通知页URL和返回页URL,易宝为同一URL,根据参数区分。
网银付款完成后,支付宝用Get方法向<支付通知页URL>发送notify_id、trade_status、trade_no、body等参数,notify_id=支付宝通知流水号,body=支付主题(其中包含订单号,需要自己解析出来),trade_status=TRADE_FINISHED即代表支付完成。一般Get传参返回,并验证后就可以判断支付到帐,系统后台将订单状态置为成功。
但我个人对现金信息的处理更加谨慎,Get通知系单向传递,可能人为伪造Get传递假参数使订单到账。
支付宝完成Get传参后,还会发起POST传参,取其中POST发送的流水号加上商户代码拼接为验证URL,再调用检查函数主动与支付宝服务器交互查询,检查完毕后从POST传参的body中解析出订单号,系统后台将订单状态置为成功,并在数据库和日志中存入支付宝返回的ATN参数和POST方法发起IP地址,然后输出"SUCCESS",告知支付宝通知收到。
够麻烦吧,其实~~ 我也觉得自己对安全性的要求有点,有点….那个啥…[emot]sweat[/emot] 闲话少说,接下来是易宝。
易宝的通知方式与支付宝类似,但两次传参都用Get方法完成。
用参数r9_BType来区别通知方式,=1为易宝传参数导向,=2为易宝为点对点通知。
先从易宝Get传参中取出订单原始数据,调用hmacSign函数比对签名,如果无误再判断返回值r1_Code是否等于1,即可确认订单成功。
如将表单参数的pr_NeedResponse应答机制设为1,在1~2分钟后,易宝的服务器还会发起一次点对点传参,调用相同的函数对比即可,确认订单成功需输出"SUCCESS"告知易宝,通知收到。在我坚持使用导向通知和点对点通信双重确认时,就遇到了易宝同步时间过长的问题,因要求两种方式都要得到确认,导向很早就完成了,点对点通信迟迟不到,联系易宝后才得知,易宝的点对点通信延迟时间大于1分钟,一般在5分钟内通知。
汗~~ 要是限时抢购的话,用易宝没啥优势啊,于是对方客服建议我用导向通知就可以了,但我还坚持使用双重验证来确保交易无误。

支付系统集成注意事项
1、系统主动向第三方支付系统发起验证URL,端口请求是否通畅,一些网络因为安全性问题,不允许服务器主动外联,甚至DNS都不允许被使用,在集成第三方支付时,需要修改网络设置。
2、跳转到第三方支付系统的https连接需要新开页面,不允许在框架页中,一开始集成我也选择了在不跳出网站框架的情况下跳转到https交易页,与第三方支付的技术人员了解后才知道是不可行的。应该是基于安全的考虑,比如利用j avascript获取子框架网银页面中敏感的卡号和密码。
3、http和https两种协议中的session不同,两种协议下浏览器会分别处理用户会话,也就是在https连接下,跳转回需要session的http页面是无法获取的,需要用中间页导向回网站的应用程序,也是return_url页面的作用。
4、到账通知的推和拉,服务器根据支付时生成的交易号在第三方系统中查询,或者第三方支付根据支付成功后主动通知到源服务器当时制定的URL。其实源服务器查询还是第三方支付通知,都存在更多的安全疑虑,比如DNS和通知信息的伪造。
所以,交易URL发起检查、第三方支付通知IP记录显得尤为必要。
5、即时与非即时到账数据同步,易宝的主动通知都存在1~2分钟的延迟,支付宝是到账通知基本上都可以在1~5秒内完成。

第三方支付系统集成的安全风险

第三方支付系统不验证订单来源,可能导致订单伪造。在调试两种第三方支付系统时发现,支付系统对来源地址无任何限制,任何地址都可以发送订单信息到第三方支付系统。

泄露签名算法和商家代码后可能导致:
1、被利用产生大量合法订单到第三发支付系统,阻塞或延迟业务进行。
2、泄露签名算法和商家代码后可能导致,劫持源服务器DNS伪造到账同志,未实际到账的订单获得系统确认。
3、恶意修改订单信息,使用户无法支付。

第三方支付应改进

1、接口代码统一版本控制,每次发起到第三方支付的URL中应该包含目前接口的版本号,以免出现莫名的异常又找不到头绪,服务器端检测到版本号后可以导向到提示信息页来引导集成方完成调试。
2、接口集成代码生成,对于受众广泛的语言,应该提供输入商家代码、通知导向页就可以生成对应语言的集成代码。
3、接口集成测试程序,这个真的非常让人汗颜,看看Discuz的向导试安装程序(自动检查:服务器版本,磁盘空间,数据库,读写权限,网络连接,类库版本)。
很明显第三方支付有没有考虑过支付集成方的技术能力。不管是php还是java环境,都完全可以提供向导式的集成程序。再怎么也提供个测试程序,测试源服务器的支付通信端口是否可用,能否正常连接到第三方支付,必须的集成类包版本是否匹配。
4、通知方式可通过参数设置,目前易宝设计了应答机制(pr_NeedResponse参数)设置,用户可以选择是否由第三方支付主动通知源服务到帐信息,支付宝是默认的。
但易宝的问题是,同步信息要在1~2分钟之后才能返回到源服务器,支付宝则延迟很小,基本可算同步通知。这就有个问题,对于网银提示支付成功的用户,在网站上又查询不到余额,用户会产生恐惧,即时同步还是理想的选择,但对于一些负荷较大的网站,同一时间返回大量同步信息,服务器并发处理又是问题。
所以,第三方支付不仅仅应该提供是否即时同步到帐信息,还可以让商家根据需要设置是否需要即时同步,在非即时同步的情况下,交易完成后1~2分钟再通知,就能缓解大部分服务器的处理压力。更人性化的设计是,用户可以根据目前服务器开销情况动态生成异步通知延迟时间,很好的平衡负载。
5、绑定商户网站域名,在每次提交订单时做IP反解析,确认交易来源的确发起于商户登记的域名。并且该IP反解析是否开启可以在商户后台设置,灵活处理。这个功能其实是商户网站和第三方支付的双赢,都规避部分安全风险,就像早期垃圾邮件的泛滥,现在用IP反解析可以很大程度上拦截掉,冒充163、雅虎服务器发来的垃圾邮件。

发表您的评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注