为啥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 不在 DB 中创建 IPN 表 - 如何修复?