为啥Paypal在使用django-paypal时会重试IPN

Posted

技术标签:

【中文标题】为啥Paypal在使用django-paypal时会重试IPN【英文标题】:Why does Paypal retry IPN when using django-paypal为什么Paypal在使用django-paypal时会重试IPN 【发布时间】:2013-01-17 15:47:50 【问题描述】:

我一直在尝试让 django-paypal 应用程序在我的 Django 项目中运行。我正在使用带有 Django 1.4 的 dcramer fork。我还在使用带有企业和个人帐户的 Paypal 开发者帐户,通过 Paypal 沙盒网站处理交易。

如果我没有连接到payment_was_successful 信号的接收器功能,事情似乎按预期工作。事务发生后,会在数据库的paypal_ipn 表中创建一个新行,该行在response 列中的值为“VERIFIED”。 Paypal IPN 日志报告此交易没有重试。

当我确实有一个连接到payment_was_successful 信号的接收器函数时,paypal_ipn 表包括两个新行,created_at 时间戳相隔 10-15 秒。它们在响应列中的值都为“VERIFIED”,但两者中的后者被标记为flag_info,表示类似:

'重复 txn_id。 (5M907276M1007902B)'

Paypal 企业帐户报告 IPN 已重试 1 次。

我找到了可能的解决方案,其中提到了在将接收器功能连接到我尚未尝试的信号时使用dispatch_uid。我的问题是我查看了相关的 django-paypal 源代码,但我不明白为什么 Paypal 会在验证第一个回发后重试 IPN。

有没有其他人遇到过这个问题并找到了他们理解的解决方案?


更新:

我发现我的接收器函数代码中存在错误,这会引发异常。现在我已经解决了这个问题,Paypal 不再重试 IPN。我很高兴问题已经消失,但我仍然无法弄清楚为什么会发生。

以下是数据库中最近重复记录的摘录。请注意,第一行是在后续行之前至少 10 秒创建和更新的。

created_at                       updated_at                       response    flag
2013-02-03 07:53:56.628013+00    2013-02-03 07:53:56.628057+00    VERIFIED    FALSE
2013-02-03 07:54:07.393795+00    2013-02-03 07:54:07.403008+00    VERIFIED    TRUE

【问题讨论】:

【参考方案1】:

我已经弄清楚了这一点。简短的回答是确保您的接收器功能正常工作。

当 Paypal 向您指定的 URL 发送 IPN 时,他们会期待 HTTP 状态代码为 200 的响应。如果响应代码是其他任何内容,他们将重试。即使您处理回调并收到 VERIFIED 消息,来自 Paypal 的 IPN 也需要响应 200 OK。

我查看了我的 Apache 访问日志,发现当我的接收器函数中出现 payment_was_successful 信号错误时,paypal 的初始 IPN 收到了 HTTP 状态代码 500。

django-paypal 包仅在处理完其他所有内容后才以 HttpResponse("OKAY") 响应,包括返回“已验证”的 Paypal 回发、将 PayPalIPN 对象保存到数据库以及发送信号。当我的信号接收器函数出现问题并引发未处理的异常时,Django 以 HTTP 状态代码 500 进行响应。

当 Paypal 重试 IPN 时,django-paypal 包检测到重复的 txn_id 并发送payment_was_flagged 信号。我的这个信号的接收函数没有错误,所以 Paypal 收到了它所期望的 HTTP 状态代码 200 并停止重试。

希望这对将来的其他人有所帮助。

【讨论】:

以上是关于为啥Paypal在使用django-paypal时会重试IPN的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 django-paypal 获取付款通知

Django-paypal 不在 DB 中创建 IPN 表 - 如何修复?

django-paypal 收不到 ipn 信号

用户不能互相支付 django-paypal

django-paypal 弃用错误:不推荐使用初始 ['return_url']

Django-Paypal IPN 403 错误