【问题标题】:Process Paypal IPN in Django view在 Django 视图中处理 Paypal IPN
【发布时间】:2016-03-04 20:59:04
【问题描述】:

根据PayPal IPN 文档,您必须首先向https://www.sandbox.paypal.com/cgi-bin/webscr 发送一个空的HTTP 200 响应,然后发送一个HTTP POST 请求来响应IPN。我想出发送 HTTP 200 响应的唯一方法是在视图中返回 HttpResponse(''),因为 IPN 模拟器说“已发送 IPN 并且已验证握手”,所以该方法有效。但是,当视图已经返回时,我将如何发送 HTTP POST 请求?我的计划是使用 urllib2 来生成 POST 请求。

我还想在不使用 HttpResponse('') 的情况下发送 HTTP 200 响应,因为我不知道原始请求来自哪里,并且我想确保将响应发送到 https://www.sandbox.paypal.com/cgi-bin/webscr。我查看了 urllib2、requests 和 PyCurl,但一直无法找到一种方法来创建对特定 URL 的空响应。

【问题讨论】:

    标签: django paypal paypal-ipn


    【解决方案1】:

    您想使用requestsurllib2 发出POST 请求以验证IPN您返回HttpResponse('');文档暗示您必须以相反的顺序执行此操作,但实际上您不必这样做,而且这种方式在大多数 Web 框架中要简单得多。所以你的视图应该看起来有点像

    def ipn(request):
        verification = requests.POST(PAYPAL_URL, data=request.body)
        if verification.text == 'VERIFIED':
            # process IPN
            return HttpResponse('')
        else:
            return HttpResponseForbidden()
    

    请注意,如果此错误在某处,您将向 PayPal 返回 500,然后他们将重试。如果您这样做太多,他们会生您的气并最终停用您的帐户,因此请确保您以某种方式收到错误警报。 (您也可以将内容包装在 try/except 块中,但如果出现错误,您可能会在没有实际处理的情况下返回 200,这可能会更糟。)

    【讨论】:

    • 谢谢,我会试试这个。如果 PayPal 的人能确认一下就好了。我一直在向后弯腰尝试在响应后执行请求。昨晚我发现了 Django 信号。 request_finished 是我需要的,但我试图弄清楚如何仅为 IPN 请求触发信号。
    【解决方案2】:

    只需响应贝宝的请求即可。对于其他请求没有响应(403 http状态)

    from django.http import HttpResponseForbidden
    
    def answer_to_pp_ipn():
        # ...
        if 'paypal' in request.META['HTTP_HOST']:
            return HttpResponse('OK 200')
    
        return HttpResponseForbidden()
    

    正如您所提到的,requestsmake a post request 的完美选择。

    【讨论】:

    • 这当然不安全;任何人都可以使用他们想要的任何主机/用户代理/有效负载来访问您的端点。确认其合法性的唯一方法是将其发布回 Paypal。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 2013-11-02
    • 1970-01-01
    相关资源
    最近更新 更多