支付宝和微信的付款没网络时也可以支付是怎么做到的? ...

[复制链接]
查看1218 | 回复2 | 2019-4-13 18:09:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
用支付宝时发现没开网络也能付款成功,原理是什么呢?有没有被破解的可能?
回复

使用道具 举报

linxijun_bd | 2019-4-13 17:42:48 | 显示全部楼层
没网络时也能进行支付(离线支付),是一个听上去挺神奇,实现原理又很巧妙的支付方式。
如果你的手机因为停机或信号不好等原因,无法联网,但又没有带现金,借助离线支付技术,你依然可以通过手机进行支付。
离线支付的大体情况见  的介绍,这里再补充一些信息。
---
离线支付的全过程如下图所示。用户出示付款码,商家使用扫码枪等扫描付款码完成收款。
hz8FHbsSSioSbsDP.jpg



离线支付的关键点一:付款码可以离线生成
付款码生成过程:
1、用户打开支付宝App时,会向服务端申请令牌种子;2、支付宝服务器会根据算法生成一个令牌种子,返回给支付宝App;3、支付宝App得到令牌种子后,根据算法生成付款码(可以离线生成)。

离线支付的关键点二:付款码是一次性且实时更新
1、支付宝App生成的付款码会包含有用户标识、令牌值等信息;2、付款码是一次性的,且每分钟会更新一次。
这样就不会出现别人把你的付款码打印出来再去付款。

离线支付的关键点三:付款码能离线,扫码枪需在线
付款码离线支付过程:
1、线下支付时,用户打开支付宝App,出示付款码(可以离线);2、商家用扫码枪读取付款码,并上传至支付宝服务器;3、支付宝服务器收到商家传来的付款码后,与令牌系统里保存的信息进行对比;4、比对通过则创建支付订单,并返回给商户订单信息,如果余额足够便可完成支付。
也就是说,付款方可以离线,但收款方得在线。通过在线的收款方搭桥,将离线的付款信息传到支付宝服务器端进行校验。

离线支付的特殊情况:付款方、收款方双离线
前面说到离线支付通常得付款方、收款方有一方得在线。但有一种特殊的场景,双方都能离线。
在支付宝的城市服务里,有公交付款的功能,目前已在部分城市部分线路落地。将来出门再也不必带公交卡、带零钱了,带着手机就行。开通这个功能的用户,页面会生成特定的付款码(与支付宝首页的付款码不是同一个),通过花呗进行付款,也是一次性、每分钟更新的。
gv9ZPa39ADyNx1o1.jpg



用户乘坐公交车时,用公交车付款码进行付款。但有些公交车的收款系统不是实时在线的,可能是一路车跑完一趟后联网,也可能是一天结束时联网,而只有在公交车的收款系统联网时才会进行扣费。
所以一句话来说,就是手机离线,就通过扣款电脑搭桥做安全验证;如果双方都离线,就先记账,等能做安全验证时再扣款
回复 支持 反对

使用道具 举报

开心小子zy | 2019-4-13 18:42:29 | 显示全部楼层
看到很多人都回答了,忍不住手痒回答一下吧,尽量撇掉技术细节,让大家都看得懂。

先反对一下排名第一同学的回答(在我点了一个反对后该答案神奇地跌出了前三……知乎权重算法威武),事实上支付宝和微信的“当面付”产品,是一款联机在线支付产品,所以不允许双方均离线的场景下支付(这一点和公交卡圈存支付不一样,公交卡的近场支付事实上允许双方脱机)。
题目中所知的支付宝和微信没有网络,指的都是消费者客户端没有网络,而不是双方都没有网络。
严格来说,当面付产品(特指商户主动扫消费者钱包客户端上的token码进行支付的形态)必须要商户在线方可进行联机交易,原因有以下两点:

  • 支付公司为了保证资金安全必须要确保每笔用户的支付行为背后都真正发生了资金扣款,所以在线联机确保支付成功是必要的。(这里解释了为什么不允许双方脱机)
  • 商户为了确保用户的支付结果可信赖,必须要自己的终端或者系统从支付公司获得支付结果,而不能以消费者的支付结果凭证作为结论。以传统POS业务举例,你可以认为你的刷卡信息等同于支付宝的当面付码,商户必须要看到POS机打出支付成功单据后才认为支付有效,如果POS支付超时没有回执,光凭客户手中的银行短信通知是不会让客户走的,而是会冲正掉上一笔交易让客户重新刷一笔。(这里解释了为什么要选择商户必须联机的方案)
那么,我们来看看一个标准的当面付产品的信息流是什么样的(原谅我草草画了一下):
d3gK0kG2R2PKKgmk.jpg



我们可以看到在这个图里红色圈圈部分,商户系统和支付宝系统是对接上的,所以商户系统是联机的——而用户的手机,在展示code的时候,我并未强调是否和支付宝服务端联机。
事实上,不论是微信还是支付宝都支持两种用户码生成模式,即在线码和离线码。
在线码其实很容易理解,用户目前是登录钱包的状态,只要点击【付款】按钮,客户端就向支付宝的服务端申请一个针对这个客户账户的支付凭证码并展现到客户手机上。
这个支付凭证码在支付宝的服务端会有一组数据库记录其与真实客户账户之间的关联,并且这份关联的有效期为60S,超过时效即便商户上送这个码,支付宝也会认为这是作废码而不予处理。
用户每次点开【付款】、等待超过60S、主动刷新付款码,都会触发客户端向服务器申请一个新码的请求。
这个方案的好处是:

  • 相对安全,每次码都是服务端生成。
  • 业务灵活,即便对码的安全算法等进行较大的调整,也不用升级客户端,因为是服务端发码。
这个方案的坏处也显而易见:

  • 用户的手机客户端必须在线联网,如果没有网络则无法获取付款码
  • 用户即便在线,如果网络连接不好,也会出现点了付款等好久才看到码的情况,体验会不可控。

为了解决在线码方案的问题,离线码方案就出现了。
离线码的基本技术原理其实也不复杂,可以参考  的回答,比较简单的实现方式是:
用户登录后,服务端通过可信网络向用户客户端发送一个种子数据(每个客户的种子数据唯一,换用户登录后销毁原种子,重新下载种子)本地保存,当用户点击【付款】时,客户端利用这个种子数据+时间戳+一套安全算法可以生成一串数字,即离线码。
当用户使用离线码支付时,服务端通过一定算法校验这个码的确是来自于这个用户,随即确认用户授权完成支付。
离线码的好处不言而喻:

  • 用户无需在线,就算在地下室等没有网络的场景一样可以使用
  • 由于不依赖网络,所有码本地生成,所以客户体验很好,一点付款码就能出来
那离线码的劣势呢,我们看看:

  • 用户root/越狱手机后,保密存储的种子数据有可能被不法分子利用恶意程序获取到,导致离线码被随意生成用于消费。
恩……怎么说呢,毕竟现在不是发烧友主动root越狱的用户并不多,这是其一。
即便是root越狱,如果用户使用手机的习惯良好,被恶意程序攻击手机的概率也很低,这是其二。
每家公司都有自己的安全团队去保障自己客户端的数据安全,并不是说root的用户就只能坐以待毙了,否则微信和支付宝早被搞破产了,这是其三。
当然从我个人的角度来说,普通用户我都不建议去root或者越狱。
这个问题最粗暴的方案就跟反方向的钟所说的一样,监测到系统被root了就对用户限权(很多银行的客户端方案都是这么搞的)。
作为直接面向消费者市场且充分竞争的产品,微信支付和支付宝断然不会采用上面那个方案的。
JKWWi3r8Nz6wZrko.jpg


怎么能又开放离线码给用户,又能确保用户支付安全,本身也是支付公司安全竞争力的一部分,这里就省略几万字了。

  • 数据碰撞可能导致A用户的码扣到B用户的账户
恩,这里涉及一些算法问题,业务上就是碰了巧了A用户码算出来和B用户码一模一样且都有效(两个客户端都没作弊)。
在线码之所以可以避免这个问题是因为在线码是服务端发的,可以控幂等。
离线码是客户端自己根据算法生成的,所以没法控。
其实原因和哈希算法的数据碰撞类似,是个小概率的纯技术问题,就不展开赘述了。
解决方案:优化算法(确保碰撞概率低到一定程度甚至杜绝),如果真的出现就认栽给客户赔钱(赔多了技术部门老大就肯定痛定思痛优化算法了)。
事实上这个问题发生的概率极低极低,所以可以忽略不计。

  • 算法调整不如在线码灵活
因为离线码生成逻辑都在客户端,所以通常来说安全算法升级会导致客户端升级,比在线码升级更影响用户一些。

分析到上面这层,各位产品经理相信应该就知道如何做方案选型了。(装个逼,事实上我觉得了解到上面那个层面是支付行业产品经理的基本素质)

后话:
我在写这个答案的时候其实都在刻意回避公司实现这些业务的具体逻辑和算法。而我个人并非当面付产品的产品经理,所以大家放心,这篇文章不算泄密。
写这个答案的目的是希望能尽量站在产品和业务角度还原业务原理,希望更多的非行业内的知友知其然,也知其所以然。
答案虽然写得有点乱,但也好歹花了一个小时,看在这个份上,大家多提提意见和指正错误,少些喷喷。等我有空了再改改用词和排版,争取让大家读起来舒服点。
闪了。

哦,对了,一如既往地。支付宝国际事业部招聘靠谱产品经理,请用简历把我砸死吧。
回复 支持 反对

使用道具 举报