我目前通过PayPal _xcart方法有一个完全正常工作的购物车和结帐流程,但我想将其迁移到REST API,主要是因为我想减轻价格上涨的可能性。目前,我的IPN会检查价格插孔并设置相应的标记,以便不下载产品(仅限销售数字产品)。无论如何,我发现PayPal文档非常混乱,我正在努力完成它的全部工作。
这是我迄今所理解和解决的问题。
1)使用我的PHP脚本(让我们称之为页面A)我创建购物车内容,然后创建新的PayPal销售并将客户端重定向到PayPal进行身份验证
2)PayPal上的客户端身份验证,然后将其重定向回我的站点到页面B(页面B在页面A中定义)
3)页面B需要获取PaymentID(来自第A页)并使用它来有效地完成交易。一旦参加比赛,最终确定结账。
现在我的问题出现了:
a)我读过很多论坛和教程,他们都提到我应该使用会话来存储来自页面A的PaymentId,然后在页面B中使用它来完成交易。 SO上的一些线程表明,PayPal实际上应该在对B页的调用中包含PaymentID,以及令牌和PayerID。那些是近3年的帖子,在我的测试中,我发现PayPal现在也确实返回了PaymentID。
b)在页面B上,当我执行付款时,我得到一个很好的JSON作为响应,但同时我的IPN监听器也被调用,这就是让我困惑的时候。可以/我应该只信任JSON响应中的所有数据并且或多或少地忽略IPN侦听器?这对于即时下载是有意义的,例如,更容易处理,还是我还应该依靠IPN进行数据验证?
我将非常感谢一些指示,请不要回复我的PayPal文档链接,因为我花了最近几天重新访问无数次,以了解它,我不能
谢谢。
答案 0 :(得分:5)
可以/我应该只信任JSON响应中的所有数据并且或多或少地忽略IPN侦听器吗?
是的,不。按此顺序。
简而言之,您不能信任呼叫" Page B" (它可以伪造,伪造,重复等)但您可以信任响应YourServer-> PayPalServer,因为它不能被最终用户拦截和伪造。
所以您的流程(如上所述)
状态应该是"完成"在这一点上进行简单的销售;但是(与下面的IPN一样)你应该验证这一点。
请检查金额,以防万一。它们应匹配,但如果不匹配,PayPal将是您收到的,它由您接受,标记(并打电话)或通过API退款并拒绝订单等。
为什么要拥有IPN?
用户可能在Paypal上完成交易,然后在" Page B"之前关闭他们的浏览器。叫做。在这种情况下,您了解订单的唯一方法是通过IPN。
如果您收到IPN处理程序的IPN通知,IPN仍然可以伪造,但验证方式略有不同。
您实际上将IPN信息发送回Paypal(服务器到服务器),Paypal确认其正确或错误(https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNIntro/)。然后,您的IPN处理程序将检查事务ID(是的,您使用的是什么)并验证数据库中的所有内容(就像您在" Page B"中所做的那样)。如果是,请在状态完成时将订单标记为完成(如果尚未在" B"中标记为已完成)。
显然,此时您无法向用户显示任何内容,因为它们不是调用该页面的内容。
我知道您没有要求提供指向文档的链接,但上述文档警告您,您可以为同一笔交易获取多个IPN,因此您还需要检查状态。
(注意:您可以像使用" Page B")一样使用API来验证transactionID。
那么为什么不回复IPN?
Paypal警告IPN可能无法到达。 Paypal最好地解释了:
虽然PayPal通常会立即处理IPN消息,但IPN与您网站上的操作不同步。互联网连接并非总是100%可靠,IPN消息可能会丢失或延迟。 IPN服务自动重新发送消息,直到侦听器确认它们。该服务重新发送邮件最多4天。
由于IPN不是实时服务,因此您的结帐流程不应等待IPN消息才能完成。如果结账流程取决于接收IPN消息,则可能由于系统负载或其他原因而延迟处理。您应配置结帐流程以处理可能的延迟。
回到最初的问题
是:依靠您进行的JSON(服务器 - >服务器)调用来验证参数" Page B" (如果你选择,在和IPN处理程序中)
否:如果页面B从未被调用,请不要忽略IPN。但是,这里也会运行验证检查。
是:检查状态=完成" Page B"和" IPN处理程序"
是:使用Paypal TransactionID,但使用自定义字段或sessionID混合到您自己的数据库中。
是的,您可以/将同时获得B页和IPN通知,如果付款已经标记为已完成,我建议忽略IPN,否则请妥善处理和处理。他们应该使用相同的数据库。