django-paypal 收不到 ipn 信号
Posted
技术标签:
【中文标题】django-paypal 收不到 ipn 信号【英文标题】:django-paypal does not receive ipn signal 【发布时间】:2011-08-15 14:10:30 【问题描述】:我正在尝试使用 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)
我的问题是:
根据jay on django,我必须在 paypay.standard.ipn.views.ipn 函数之前放置一个@csrf_exempt 以避免django 抱怨@csrf_token 问题。我做到了,但我仍然面临同样的问题。然后我把@csrf_exempt放在我的return url view函数之前,在这种情况下是payment_status(request,status),csrf_token问题就消失了。所以我不知道为什么会这样。
信号处理程序中的这条语句是干什么用的? "if ipn_obj.custom == "升级所有用户!": .... " 这是来自paypay吗?除了“升级所有用户”之外,还有什么可能的价值?
我设法在沙盒中完成了购买并完成了整个支付过程。但现在的问题是,paypal 没有将 IPN 发布回我的 notify_url,它是一个本地主机。我从Paypal Sandbox IPN Problem 读到我不能使用 localhost (http://127.0.0.1:8000) 来测试 IPN。那么测试需要哪些步骤呢?我不明白post 中提供的解决方案。谁能教我如何在不部署真正的生产服务器的情况下测试 IPN?
【问题讨论】:
【参考方案1】:#1 -- 我需要放置@csrf_exempt 标记的唯一位置是return_url 调用的视图。实际上,无论出于何种原因,PayPal 都会向该 URL 发布大量有关付款的数据。
#2 -- 您可以在 paypal_dict 中指定一个“自定义”字段,然后将其传递回 notify_url。如果您只从一个 url 或端点进行销售,那么结合您指定的发票,付款的用途就很明显了。但是您可能想在此处提供一个额外的字段来使用。 “升级所有用户!”只是 django-paypal 文档中的一个随机示例。
#3 -- 我使用了 ngrok,正如 django-paypal 文档中提到的那样 (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 之外,问题可能还存在。
【讨论】:
【参考方案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 错误日志是否有任何错误。
【讨论】:
【参考方案3】:关于您的第三点,正如丹尼尔在回答您链接的问题时所说,您需要允许 Paypal 发布到您的本地计算机。这意味着您需要打开路由器上的 80 端口并将请求转发到端口 8000 上的开发机器。转到http://whatismyip.com,获取 IP 并尝试在浏览器中访问它。除非您正确配置了路由器,否则您将一无所获。
设置好路由器后,您需要运行 django 服务器:
python manage.py runserver 0.0.0.0:8000
然后您就可以从外部访问它了。您可以通过将 Internet 连接的 IP 放入浏览器来进行测试——您应该会看到您的 Django 站点。如果您不这样做,那么 Paypal 也无法“看到”您,并且永远无法回帖。
【讨论】:
蒂姆,谢谢。我设法做到了。但我没有使用 whatismyip.com,因为返回的 IP 地址不正确(或者不是我的路由器的真实 IP,它返回 220.255.1.50)我使用的是dyndns.com/support/tools/openport.html 提供的工具。但是每次我重新启动路由器时,我都必须执行此步骤并更新 notify_url(到新的 ip)。有点不方便。寻找脚本以获取我的路由器的正确 IP,但大多数都不起作用。以上是关于django-paypal 收不到 ipn 信号的主要内容,如果未能解决你的问题,请参考以下文章
为啥Paypal在使用django-paypal时会重试IPN