PayPal REST API:在重定向URL或Webhook呼叫上完成订单/付款


PayPal REST API: Fulfill Order/Payment on Redirect URL or on Webhook call?

我正在Symfony 2 web应用程序中集成PayPal REST API。我不确定完成订单/付款的正确时间/地点:

连同其他参数,如金额、客户数据等,我将两个URL转移到PayPal API:一个URL在接受付款时被重定向到用户,另一个URL则在取消付款时被重新定向到用户。

这没有任何问题,当付款完成时,当用户使用我之前转移的URL重定向到我的页面时,我会获得完成订单所需的所有信息(例如解锁一些内容)。

然而,我不确定这是否是正确的做法:

  • 如果由于任何原因将用户重定向回我的页面失败,尽管付款已经完成,但购买将不会完成(没有解锁的内容)
  • 如果客户使用手动银行转账,付款将创建为pending,当他手动将钱转账到他的PayPal账户时,付款将设置为completed。我必须以某种方式处理第二条completed消息

这些问题可以通过使用Webhooks来解决:我在PayPal配置文件中指定了一个特殊的回调URL,API将使用此URL通知我的系统不同的事件。

这样,当付款挂起时,我会得到通知,并在付款完成后立即得到第二次通知。听起来不错。但是Webhooks是否也意味着即时支付?Dok说,Webhook调用是异步执行的,并且不能保证它们的顺序。

我可以确定,在用户重定向到我的页面之前,我的系统将通过Webhook接收PAYMENT.SALE.COMPLETED事件吗?或者有可能,他先被重定向,我稍后会收到事件?在这种情况下,用户会回到页面上,看不到购买的结果。

那么,处理重定向URL和webhook事件以完成支付的正确方式/顺序是什么?

您不能相信用户被重定向到您指定的某个页面以标记付款已完成。不要那样做。

客户只需中止交易,并通过手动将其输入地址栏来访问此"成功"页面。然后没有付款。

如果你从PayPal收到PAYMENT.SALE.COMPLETED,你就可以也应该信任它。

您可以向PayPal提供一个成功的URL,客户可以在其中看到"等待付款完成",直到您的Webhook端点的请求按预期到达。然后你将他转发到他想要购买的真正成功的页面或内容。

如果您没有收到预期的WebHook请求,请在一段时间后显示超时错误。使用Ajax或Websockets来完成这个等待循环。

或者,您可以显示一个"成功"页面,但只有在Webhook请求到达后才允许客户使用/解锁内容,如果客户试图在以Webhook请求的形式收到付款确认之前访问该内容,则显示"出了问题"消息。

请记住,我们讨论的是从重定向用户到发送Webhook之间的几毫秒时间。通常,Webhook请求是在为客户进行重定向之前发送的,但您不能相信这一点。

关于订单,这是我在v2 Paypal API中的做法。

  1. POST:/v2/checkout/orders创建订单,并使用intent=CAPUTRE,如果格式正确,将回复我一个带有4个链接的JSON。其中有";批准";链接在同一步骤中,我在本地创建并存储您在该响应中收到的订单/交易付款ID。添加一个";status=挂起";

  2. 使用Approval链接将用户重定向到它。

  3. 在步骤1中,您需要告诉Paypal"return_url";以及"cancel_url";为您的脚本。当一切正常,用户点击PAY时,他将被重定向到";return_url";。

return_url脚本包含什么

使用GET参数";令牌";贝宝发送,我检查我的数据库,并在步骤1检索保存的订单。我确保订单的状态为";挂起";所以;s未完成。

Do"POST:/v2/结账/订单/$token/capture";要获取付款,它将使用JSON进行回复。如果状态为已完成(99.9%的情况),则完成。付款成功等,您在本地数据库中将订单标记为";status=completed";并且可以向用户提供产品。

如果CAPTURE请求出现错误,这意味着钱没有转移,所以你可以很容易地向用户抛出错误,并一起取消订单,这样他就可以开始/创建新的订单。因此,正如您所看到/所知,只有在用户返回您的网站后,支付和产品交换才会发生。

唯一奇怪的情况是如果CAPTURE返回PENDING如果您在帐户/API选项中启用捕获前查看每个订单,则会发生这种情况在这种情况下,交易没有完成,所以买家不应该得到产品。所以只需设置您的本地订单";状态=未决";,并监听webhook以启用/验证它。然而,对于这种特殊情况,您需要存储CAPTURE_id(在CAPTURING时从响应中获得),并将其附加到本地订单。当PAYMENT.CAPTURE.COMPLETED挂钩出现时,这是你唯一能得到的身份证明。因此,您需要使用钩子中的id来获取产品。

在用户没有足够的资金用于订单的情况下,他将无法";批准";贝宝上的订单。意思是:他不会被重定向到"return_url"

如果他手动插入return_url,您的脚本将无法捕获,Paypal将返回一个错误:;捕获只能在批准的订单上执行";。

正如您所看到的,在这种情况下不需要WEBHOOKS,贝宝的响应是即时的(或者至少对您的支付验证脚本是同步的)。