我一直试图在我的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
答案 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并停止了重试。
希望将来可以帮助其他人。