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

Emi*_*oni 1 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。
  • 与存储从A页到B页的会话相比,使用PayPal提供的GET有什么缺点吗?我真的不需要参加会议,因此GET对我来说是理想的选择。我想如果它在PayPal文档中可以安全使用。
  • 这是否也可以在实时页面上使用,还是只能在沙盒中使用?

b)在页面B上执行付款时,我得到了一个不错的JSON作为响应,但是同时我的IPN侦听器也被调用了,这使我很困惑。我可以/应该仅信任JSON响应中的所有数据,而或多或少忽略IPN侦听器吗?例如,这对于即时下载很有用,例如,它更易于处理,还是我仍然应该依靠IPN进行数据验证?

  • 如果仅使用返回到页面B的JSON,则要查找的正确字段是什么,值是什么?例如,有一个状态字段被批准,另一个(交易->相关项目->状态)被竞争。我需要检查哪一个?
  • 如果我依靠JSON,是否还需要检查支付的金额是否与原始金额匹配,或者我可以相信支付的金额等于我在通话中要求的金额吗?
  • 如果我使用IPN,如何将其与交易配对?PaymentID不会显示在发布到IPN的变量中。我能想到的唯一方法是从JSON响应中获取txn_id,但以某种方式感到奇怪,再加上如何知道JSON响应是否在IPN之前到达服务器?

我将不胜感激某些指导,请不要用贝宝(PayPal)文档的链接回答我,因为过去几天我花了无数次重新探访,以使事情有所作为,但我做不到。

谢谢。

Rob*_*bie 5

我可以/应该仅信任JSON响应中的所有数据,而或多或少忽略IPN侦听器吗?

是的,没有。以该顺序。

简而言之,您无法信任对“ B页”的调用中的付款ID(它可能是伪造的,伪造的,重复的等),但是您可以信任响应YourServer-> PayPalServer,因为它不会被拦截和伪造由最终用户。

所以您的过程是(如上所述)

  1. 页面A:创建一个sessionID(cookie),数量,购物车详细信息等,并存储在本地数据库/存储中。您还可以创建一个“自定义”字段来存储您自己的saleID
  2. 向Paypal发送金额等,这将使您返回...。
  3. 网页B:获取PayPal TransactionID,然后将其(服务器->服务器)发送回PayPal。Paypal返回金额,状态等。然后检查数据库中的金额是否相同并且属于sessionID。如果您还使用自定义字段,请也进行检查。如果一切顺利,那你就很好。如果没有,则取决于您如何处理。

此时,对于简单的销售,状态应为“完成”;但是(与下面的IPN一样),您应该对此进行验证。

请检查金额,以防万一。它们应该匹配,但是如果不匹配,那么贝宝将是您收到的,并且由您决定接受,标记(并打电话)或通过API退款并拒绝订单等。

那么为什么要使用IPN?

用户可能会在Paypal上完成交易,然后在调用“页面B”之前关闭其浏览器。在这种情况下,您唯一了解订单的方法是通过IPN。

如果您收到发送到IPN处理程序的IPN通知,则IPN仍然可以被伪造,但是验证的方式略有不同。

您实际上将IPN信息发送回Paypal(服务器到服务器),并且Paypal确认它是正确的还是错误的(https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNIntro/)。然后,您的IPN处理程序将检查事务ID(是,这就是您所使用的),并验证数据库中的所有内容是否匹配(就像您在“页面B”中所做的一样)。如果是的话,如果状态为完成(并且在“页面B”中尚未标记为完成),则将订单标记为完成。

显然,您目前无法向用户显示任何内容,因为他们不是调用页面的用户。

我知道您不要求提供文档链接,但是以上文档警告您,同一笔交易可以获取多个IPN,因此您还需要检查状态。

(注意:您可以像在“页面B”中一样使用API​​来验证transactionID)。

那么,为什么不回复IPN呢?

Paypal警告说IPN可能不会到达。贝宝最好的解释:

尽管PayPal通常会立即处理IPN消息,但IPN不会与您网站上的操作同步。Internet连接并不总是100%可靠,并且IPN消息可能会丢失或延迟。IPN服务会自动重新发送消息,直到侦听器确认为止。该服务最多可重发消息4天。

由于IPN不是实时服务,因此结帐流程不应等待IPN消息完成才允许其完成。如果结帐流程取决于接收IPN消息,则处理可能会由于系统负载或其他原因而延迟。您应该配置结帐流程以处理可能的延迟。

回到原始问题

是:依靠您进行的JSON(server-> server)调用来验证“ Page B”的参数(以及选择的in和IPN处理程序)

否:万一页面B永远不会被调用,请不要忽略IPN。但仍在此处运行验证检查。

是:检查状态=对“页面B”和“ IPN处理程序”均完成

是:使用Paypal TransactionID,但将其与自定义字段或sessionID混入您自己的数据库中。

是的,您可以/将同时收到B页和IPN通知,如果付款已标记为已完成,我建议您忽略IPN,否则请适当处理。他们应该使用相同的数据库。