情景:这个很好理解,比如说你用同一个支付宝商户账号,给不同网站(系统)使用的时候,如果各自的网站(系统)产生的订单规则都类似甚至相同,就很有可能发生这种错误。
解决方法:一定要让产生的订单号在支付宝商户账号里保持唯一。
“美男子,能不能默默的退出,再登录一下呀?因为,这个那个……”如果我这么说,你一定会杀了我吧
——滚!
因为支付过后,虽然余额确实充值到当前用户的账户里,但是因为没有更新当前Session信息,而显示的时候因为用的是当前的Session数据,So……
不过是支付宝支付还是财富通的支付,其实都差不多。支付成功后,同步返回,而此时异步的请求也是同时发出。所以在returnurl的页面和notifyurl的页面,要对返回来的状态做相应处理。而尤其要注意的是,比如“担保交易”,有可能优先在notifyurl页面里已经经过了“处理模块”的处理,假如是“卖家确认发货”,导致在返回到returnurl页面的时候状态已经变成了“等待买家确认”,所以要在returnurl页面的“等待买家确认”状态下做已经处理过后的处理,比如要返回具体信息给的结果页面,比如订单号,支付了多少钱等信息。
我一般都会把对订单号的处理写在一个模块方法里,在新订单的时候才做处理,这里的处理一般都有更改订单状态,业务复杂的话会关联其他的表,还得对其他表数据的增删改等操作。
我遇到的问题:
比如我的处理模块方法叫ExcelEven,里面当订单状态为“新订单”的时候发一封Email,这时候会偶尔的发声一次支付发多封的Email。
情景:
在支付回来的页面里的每个状态方法块里,查询订单信息,当订单状态为新订单的时候就会调用ExcelEven方法进行处理, 虽然支付成功后同时请求异步和同步页面,但是理论上也不会多发Email呀?
原因:
因为支付成功后,支付宝会同时请求我们提供的异步处理页面(notifyurl)和同步处理页面(returnurl),而当ExcelEven方法处理时间过长的时候,有可能在请求两个处理页面的时候订单都为“新订单”,所以才会多发了Email。
解决:
在处理订单的时候,要在where条件后面多加条件,即Status=新订单,否则rollback,有其他表的处理也类似地加上后置条件,而不是相信前面已经在页面(notifyurl和returnurl)上用if判断语句断言了是新订单。
在支付成功后,如果要对当前用户更新信息的时候,比如余额积分等等,一定要做Session的更新哦。
第一次如此工工整整的写,感觉好麻烦,好好看。