【问题标题】:django-paypal ipn not respondingdjango-paypal ipn 没有响应
【发布时间】:2012-04-09 07:56:56
【问题描述】:

我正在使用this app 在我的应用程序中实现贝宝。但是,当我付款时,django 一直抱怨我已经将 csrf_token 插入到我的模板表单中时没有它。

这是我的模板:

    <form method="post" action="/paypal/">
        {% csrf_token %}
        <p>
            To change your subscription, select a membership and the subscription rate:
        </p>
        <select name="membership_input" id="id_membership">
            <option>Silver</option>
            <option>Gold</option>
            <option>Platinum</option>
        </select>
        <select name="subscription_input" id="id_subscription" style = "float: center; margin-left: 30px;">
            <option>Monthly</option>
            <option>Quarterly</option>
            <option>Yearly</option>
        </select></br></br>
        {{ form }}
    </form>

这是我处理贝宝元素的观点:

def paypal(request):
    c = RequestContext(request,{})
    c.update(csrf(request))
    if request.method == 'POST':
    if 'membership_input' in request.POST:
        if 'subscription_input' in request.POST:
                membership = request.POST['membership_input']
            subscription = request.POST['subscription_input']
            if membership == "Gold":
                if subscription == "Quarterly":
                    price = "2400.00"
                if subscription == "Monthly":
                    price = "1000.00"
                if subscription == "Yearly":
                    price = "8000.00"
            elif membership == "Silver":
                if subscription == "Quarterly":
                    price = "1200.00"
                if subscription == "Monthly":
                    price = "500.00"
                if subscription == "Yearly":
                    price = "4000.00"
            elif membership == "Premium":
                if subscription == "Quarterly":
                    price = "4800.00"
                if subscription == "Monthly":
                    price = "2000.00"
                if subscription == "Yearly":
                    price = "16000.00"
            paypal_dict = {"business":settings.PAYPAL_RECEIVER_EMAIL,"amount": price ,"item_name": membership+" membership" ,"invoice": "09876543", "notify_url": "%s%s" % (settings.SITE_NAME, reverse('paypal-ipn')),"return_url": "http://rosebud.mosuma.net",}
                # Create the instance.
                form = PayPalPaymentsForm(initial=paypal_dict)
                context = {"form": form.sandbox()}
            c = RequestContext(request,{"form": form.sandbox()})
                return render_to_response("paypal.html", c)                 
    else:
        return HttpResponseRedirect("/")

如果有人需要我的 ipn 视图:

@require_POST
@csrf_exempt
def ipn(request, item_check_callable=None):
    """
    PayPal IPN endpoint (notify_url).
    Used by both PayPal Payments Pro and Payments Standard to confirm transactions.
    http://tinyurl.com/d9vu9d

    PayPal IPN Simulator:
    https://developer.paypal.com/cgi-bin/devscr?cmd=_ipn-link-session
    """
    flag = None
    ipn_obj = None

    # Clean up the data as PayPal sends some weird values such as "N/A"
    print "IPN"
    data = request.POST.copy()
    print "IPN"
    date_fields = ('time_created', 'payment_date', 'next_payment_date', 'subscr_date', 'subscr_effective')
    print "IPN"
    for date_field in date_fields:
    print "IPN"
        if data.get(date_field) == 'N/A':
        print "IPN" 
            del data[date_field]
    print "IPN"
    form = PayPalIPNForm(data)
    print "IPN"
    if form.is_valid():
        try:
            ipn_obj = form.save(commit=False)
        print "IPN"
        except Exception, e:
            flag = "Exception while processing. (%s)" % e
    else:
        flag = "Invalid form. (%s)" % form.errors

    if ipn_obj is None:
        ipn_obj = PayPalIPN()

    ipn_obj.initialize(request)
    if flag is not None:
        ipn_obj.set_flag(flag)
    else:
        # Secrets should only be used over SSL.
        if request.is_secure() and 'secret' in request.GET:
            ipn_obj.verify_secret(form, request.GET['secret'])
        else:
            ipn_obj.verify(item_check_callable)

    ipn_obj.save()
    return HttpResponse("OKAY")

我已经尝试过使用 django 提到的 requestContext 并插入了 csrf 令牌,但我不知道为什么它不起作用。

另外,如果我要启用定期贝宝订阅,我该怎么做?

感谢任何帮助。

【问题讨论】:

  • 哪个 URL 因 CSRF 令牌而失败 - ipn 或 paypal?你能在呈现的表单模板中看到一个带有隐藏输入的块吗?您的浏览器是否有csrf_token cookie? TEMPLATE_CONTEXT_PROCESSORS 中有 django.core.context_processors.csrf 吗(实际上这是最好的方法)?如果不是,可能问题是您在渲染到 CSRF 令牌之前覆盖变量 c 丢失。
  • 嗨@ivar 感谢您的回复。我的回答如下:没有 URL 失败。当我在购买后点击返回时,它只是没有点击 return_url。是的,我有 django.core.context_processors.csrf。我有一种奇怪的感觉,它是我的变量 C。但让我先尝试调试更多。
  • 所以您的paypal 视图会将您重定向到Paypal,对吗?那就更有意义了。交易后您不应该被重定向到 IPN,它是由 Paypal 本身调用的。那么,您是否向 Paypal 提供了您的 IPN 网址?它是在本地主机上还是在互联网上的真实服务器上? Paypal IPN 机器人可以访问吗?
  • @ilvar 是的,它会将我重定向到 Paypal,但根据我在网上阅读的一个教程,它说一旦按下立即购买按钮就会调用 ipn 方法?这是错误的还是我理解错误的ipn。
  • 是的,当交易完成时,paypal 会请求 IPN URL。因此,您应该确保 PayPal 可以访问您的服务器(即它不是本地主机或某些 VPN 主机)。我明白了,您正在向 PayPal 发送 notify_url,请检查这是否是 PayPal API 的有效变量以及它是否实际发送到 PayPal。另外,检查它的值 - 它应该是完整的 URL,包括“http://”和域名。

标签: django django-paypal


【解决方案1】:

在 Django 文档中,使用 RequestContext 或“手动导入并使用处理器生成 CSRF 令牌并将其添加到模板上下文中。”例如:

    from django.core.context_processors import csrf
    from django.shortcuts import render_to_response

    def my_view(request):
        c = {}
        c.update(csrf(request))
        # ... view code here
        return render_to_response("a_template.html", c)

这就是你应该如何使用render_to_response

    return render_to_response('my_template.html', 
                               my_data_dictionary,
                               context_instance=RequestContext(request))

所以,从顶部删除这些行:

    c = RequestContext(request,{})
    c.update(csrf(request))

并从以下位置更改底部:

    c = RequestContext(request,{"form": form.sandbox()})
    return render_to_response("paypal.html", c)  

    return render_to_response("paypal.html", 
              {"form": form.sandbox(), },
              context_instance=RequestContext(request))

这应该可以解决问题。就个人而言,我建议只使用 render (from django.shortcuts import render),它会为您处理 RequestContext。

【讨论】:

    猜你喜欢
    • 2014-07-31
    • 2016-04-04
    • 2011-04-25
    • 2012-08-14
    • 1970-01-01
    • 2016-05-18
    • 2023-03-13
    • 2017-02-14
    • 2012-10-31
    相关资源
    最近更新 更多