如何使用PayPal REST API和IPN验证销售

时间:2016-04-16 17:17:04

标签: php api rest paypal paypal-ipn

我目前通过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。

  • 这是一个新事物吗,PayPal真的开始将PaymentID作为GET变量发送吗?好的我在PayPal SDK文档中找到了这个(当然不是PHP的其他语言)他们返回了PaymentID以及GET。
  • 使用PayPal提供的GET与存储从A到B的会话相比有什么不利吗?我真的不想参加会议,所以GET对我来说非常理想。我想如果它在PayPal文档上,那么它是安全的。
  • 这是否也可以在实时页面上或仅在Sandbox中使用?

b)在页面B上,当我执行付款时,我得到一个很好的JSON作为响应,但同时我的IPN监听器也被调用,这就是让我困惑的时候。可以/我应该只信任JSON响应中的所有数据并且或多或少地忽略IPN侦听器?这对于即时下载是有意义的,例如,更容易处理,还是我还应该依靠IPN进行数据验证?

  • 如果我只使用返回到页面B的JSON,这是要查找的正确字段和值是什么?例如,存在被批准的状态字段和竞争的另一个(交易 - >相关项目 - >状态)。我需要检查哪一个?
  • 如果我依赖JSON,我还需要检查付款金额是否与原始金额相符,还是我相信付款金额等于我在通话中要求的金额?
  • 如果我使用IPN,我怎么能在交易中削减它? PaymentID未显示在发布到IPN的变量中。我能想到的唯一方法是从JSON响应中获取txn_id,但不知何故感觉很奇怪,另外我怎么知道JSON响应是否在IPN之前到达服务器?

我将非常感谢一些指示,请不要回复我的PayPal文档链接,因为我花了最近几天重新访问无数次,以了解它,我不能

谢谢。

1 个答案:

答案 0 :(得分:5)

  

可以/我应该只信任JSON响应中的所有数据并且或多或少地忽略IPN侦听器吗?

是的,不。按此顺序。

简而言之,您不能信任呼叫" Page B" (它可以伪造,伪造,重复等)但您可以信任响应YourServer-> PayPalServer,因为它不能被最终用户拦截和伪造。

所以您的流程(如上所述)

  1. 页面A:创建会话ID(cookie),金额,购物车详细信息等,并存储在本地数据库/存储中。您还可以创建一个" custom"字段来存储您自己的saleID
  2. 向Paypal发送金额等,然后返回....
  3. 页面B:获取PayPal TransactionID并将(服务器 - >服务器)发送回PayPal。 Paypal返回金额,状态等。然后检查您的数据库的金额是否相同,它是否属于sessionID。如果您还使用自定义字段,请检查它。如果一切都结婚了,你就会好起来的。如果没有,那就由你决定如何处理。
  4. 状态应该是"完成"在这一点上进行简单的销售;但是(与下面的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,否则请妥善处理和处理。他们应该使用相同的数据库。