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

时间:2013-02-02 11:29:26

标签: django paypal-ipn django-paypal

我一直试图在我的Django项目中使用django-paypal应用程序。我正在使用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已重试一次。

我找到了可能的解决方案,提到在将接收器功能连接到我尚未尝试的信号时使用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 个答案:

答案 0 :(得分:7)

我已经想到了这一个。简短的回答是确保您的接收器功能正常工作。

当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并停止了重试。

希望将来可以帮助其他人。