在Django视图中处理Paypal IPN

时间:2015-12-01 03:08:55

标签: django paypal paypal-ipn

根据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响应,因为我不知道原始请求的来源,我想确保我将响应发送给{{ 1}}。我查看了urllib2,请求和PyCurl,我一直无法找到一种方法来创建对特定URL的空响应。

2 个答案:

答案 0 :(得分:0)

只是回应paypal提出的要求。对于其他请求没有响应(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的完美选择。

答案 1 :(得分:0)

您希望使用requestsurllib2发出POST请求,以便在返回HttpResponse('')之前验证IPN ;文档暗示你必须以相反的顺序执行它,但是你实际上并不需要这样做,而且这种方式在大多数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,这可能会更糟。)