django-paypal没有收到ipn信号

时间:2011-04-29 15:19:00

标签: django paypal paypal-ipn

我正在尝试使用django-paypal。我正在关注上面提到的内容 Jay on Django

这就是我做的......

##in my view.py file    
def ask_payment(request):
   # What you want the button to do.
   paypal_dict = {
    "business": settings.PAYPAL_RECEIVER_EMAIL,
    "amount": "0.10",
    "item_name": "book",
    "invoice": "yong138peng",
    "notify_url": "http://127.0.0.1:8000/accounts/my-ipn-location/",
    "return_url": "http://127.0.0.1:8000/accounts/my-return-location/",
    "cancel_return": "http://127.0.0.1:8000/accounts/my-cancel-location/",
   }  
   # Create the instance.
   form = PayPalPaymentsForm(initial=paypal_dict)
   context = {"PP_form": form}
   return render_to_response("paypal/payment.html",{'PP_form':form},context_instance=RequestContext(request))

@csrf_exempt
def payment_status(request,status):
   return render_to_response("paypal/payment_status.html",       
             {'status':status},context_instance=RequestContext(request))

##then in my urls.py file 
(r'^askforpayment/$','coltrane.views.ask_payment'),
(r'^my-ipn-location/', include('paypal.standard.ipn.urls')),
(r'^my-return-location/$','coltrane.views.payment_status',{'status':'success'}),
(r'^my-cancel-location/$','coltrane.views.payment_status',{'status':'cancel'}),

##in my models.py
def show_me_the_money(sender, **kwargs):
   ipn_obj = sender
   print "payment was successful!"
   # Undertake some action depending upon `ipn_obj`.
   if ipn_obj.custom == "Upgrade all users!":  ## what is this for, this is sent by paypal??
       Users.objects.update(paid=True)        
payment_was_successful.connect(show_me_the_money)

我的问题是:

  1. 根据jay on django,我必须在paypay.standard.ipn.views.ipn函数之前放置一个@csrf_exempt,以避免django抱怨@csrf_token问题。我做到了,但我仍面临同样的问题。然后我把@csrf_exempt放在我的返回url视图函数之前,在这种情况下为payment_status(请求,状态),csrf_token问题就消失了。所以我不确定为什么会这样。

  2. 信号处理程序中的这个语句是为了什么? “if ipn_obj.custom ==”升级所有用户!“:......” 这来自paypay吗?除了“升级所有用户?”之外,还有什么可能的价值?

  3. 我设法在沙盒中进行购买并完成整个付款流程。但现在的问题是,paypal不会将IPN发回我的notify_url,这是一个本地主机。我从Paypal Sandbox IPN Problem读到我无法使用localhost(http://127.0.0.1:8000)来测试IPN。那么测试需要哪些步骤?我不理解post中提供的解决方案。有人可以教我如何在不部署真实生产服务器的情况下测试IPN吗?

3 个答案:

答案 0 :(得分:4)

关于你的第三点,正如Daniel在你所链接的问题的答案中所说,你需要允许Paypal POST到你的本地机器。这意味着您需要在路由器上打开端口80并将请求转发到端口8000上的开发计算机。转到http://whatismyip.com,获取IP并尝试在浏览器中访问它。除非你的路由器配置正确,否则你什么也得不到。

设置路由器后,您需要运行django服务器:

python manage.py runserver 0.0.0.0:8000

然后您就可以从外部访问它了。您可以通过将Internet连接的IP放入浏览器来测试这一点 - 您应该看到您的Django站点。如果你不这样做,那么Paypal也无法“看到”你,也永远无法回复。

答案 1 :(得分:2)

我被困在这个问题很长一段时间了!事实证明我的信号代码有错误,但错误从未显示过,只是看起来好像信号没有被调用。最终通过修改paypal-django中的代码来跟踪它:

在paypal.standard.ipn.views.py中 - 从底部开出3行:

        try:
            ipn_obj.verify(item_check_callable)
        except:
            import sys, traceback
            traceback.print_exc(file=sys.stdout)

然后检查apache错误日志中是否有任何错误。

答案 2 :(得分:0)

对于#1 - 我需要将@csrf_exempt标记放在return_url调用的视图上。无论出于何种原因,PayPal实际上也会将大量有关付款的数据发布到此网址。

对于#2 - 您可以指定"自定义" paypal_dict中的字段,然后将传递回notify_url。如果您只是从一个网址或端点进行销售,那么与您指定的发票相结合,付款的目的就很明显。但您可能希望在此处提供其他字段以供使用。 "升级所有用户!"这只是django-paypal文档的随机示例。

对于#3 - 我使用了ngrok,正如django-paypal docs中提到的那样(http://django-paypal.readthedocs.org/en/stable/standard/ipn.html#testing)。我发现它很容易设置,事先不了解该工具。

另外 - 有关我的一段时间内发现的一个问题是:我认为PayPal没有发布到我的notify_url,我正在研究这样的答案。

最终我意识到PayPal实际上是发布到我的notify_url,但是我的本地计算机使用的是旧版本的SSL,在回发到PayPal沙箱(获取VERIFIED / INVALID结果)时无法完成握手。我的版本是0.9.8,他们需要1.0或更高的内容。总而言之,notify_url是一个多步骤的过程,问题可能是除了PayPal向notify_url发布初始帖子之外的其他问题。