本文主要讨论PC端的用户付款接口html
用户输入支付宝帐号密码及确认支付等操做,都是在支付宝域下进行。数据库
网站将业务信息经过相似于重定向的方式提交到支付宝。api
<form name="alipaysubmit" action="https://mapi.alipay.com/gateway.do" method="get" > <input type="hidden" name="service" value="支付宝接口名"/> <input type="hidden" name="total_fee" value="订单金额"/> <input type="hidden" name="out_trade_no" value="对外订单编号"/> <input type="hidden" name="return_url" value="交易结果同步回调路径"/> <input type="hidden" name="notify_url" value="交易结果异步回调路径"/> ...... <input type="submit" value="确认" style="display:none;"> </form> <script> /*页面加载后当即执行,发起支付请求*/ document.forms['alipaysubmit'].submit(); </script>
如下截图:第一个是网站本身的,第二个是支付宝的。用户在第一个页面点击'当即支付',请求会发到网站后台,网站后台输出上面所说的html,浏览器会新开页并跳转至第二个页面。浏览器
在支付宝域下确认支付后,网站会收到支付宝交易结果通知,分为同步和异步。同步由浏览器发送(经过支付宝页面的JS执行),异步由支付宝后台主动发送直到收到网站的返回或者发送次数用完。同步通知,能够很方便地进行本地测试,但同步发起只有一次,并且浏览器可能被关闭,因此不能依赖于同步,对于异步通知,能够经过内网穿透工具(推荐natapp)进行模拟测试。网络
out_trade_no是网站对外的订单编号,采用‘用户订单编号'+'支付方式'的规则,这样对于同一笔订单同一种支付方式,不管用户在网站发起几回请求,out_trade_no始终惟一,能够避免重复扣款。 app
曾经注册了一号店、优酷、迅雷等网站,测试发现他们的out_trade_no规则主要包括2种:异步
1):直接使用原订单号,这样能够防止重复支付,可是不适合咱们网站,由于咱们网站的网银支付走的也是支付宝的接口,这样若是用户从支付宝支付切回网银支付时,支付宝会报错:交易已存在,意思就是说你已经提交过支付请求。若是网站的网银支付走的是银联接口,这种方式没有任何问题。工具
2):一笔订单每次提交支付请求时,out_trade_no都会变化。对于网站的同一笔订单,每次请求out_trade_no不同的话,支付宝就会当成一笔新的交易,这样极易出现重复支付。但话说回来,如今用户一点都不傻。测试
异步回调有次数限制,为防止异常状况下没有收到支付宝的交易通知,必须辅以支付宝的另外一接口"单笔交易查询",能够主动去查询交易结果。为了原路退款,同时须要开发“批量退款接口”。网站
支付宝的每一笔交易是以“支付宝流水号”惟一肯定的,为保证数据及逻辑的一致性,网站数据库须要使用惟一索引,应用层级须要使用事务(事务:登记支付宝流水信息,更新订单支付状态等)。
支付宝的交易通知可能屡次,若是网站已经处理过,须直接返回或忽略。若是发现是异常扣款(后面介绍),可能须要执行退款等业务操做。
防止串号,必定要保证测试环境发给支付宝的out_trade_no跟生产环境不同,通常会经过设置订单编号的前缀来区分,好比测试时都以“T”打头。
这里说的"异常支付"不是系统或代码异常,特指在支付宝接口开发中违背业务逻辑的需全额退款的支付。
主要包括如下2种状况:
重复扣款:网站的一笔订单,客户支付两次。
发生几率:很低
产生场景:客户选择了支付宝支付,因为网站订单状态未更新,客户觉得未支付成功,又选择网银等其余支付方式;另外一种状况是客户选择了支付宝支付并登陆成功但未确认支付,回到网站又选择了其余支付方式并支付成功,但支付宝的帐单记录还在那放着,有效期内客户又不当心点了确认支付。
说明:因为out_trade_no 设计根据订单编号+支付类别惟一辈子成,因此不会出现同一支付渠道下的重复扣款。
发生几率:很低
产生场景:用户在支付成功后立马去“取消订单”,因为网络延迟或其余缘由,网站没有收到支付结果通知,就主动去调用“单笔交易查询”接口,可是调用又出现系统异常,这个时候只能将订单状态置为已取消。待网站最终收到支付通知时,发现订单已取消了,那当前支付就是无效的。即使网站最终收不到该笔支付结果通知,客户也会投诉为何没收到退款。
PS: 即时到帐接口曾经支持“网银支付”,就是说不用登录支付宝, 用户直接登录网银, 但2016年支付宝已经下架了“网银通道”(老用户能够继续用一段时间)。想实现网银支付的朋友们,请联系银联, 或者找第三方代理机构.