2012-03-25 106 views
3

我使用this app實現貝寶到我的應用程序。但是,當我付款和一切,django不斷抱怨,我沒有一個csrf_token當我已經插入到我的模板窗體。django-paypal ipn沒有迴應

這是我的模板:

<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標記,但我不知道爲什麼它不起作用。

另外,如果我要啓用定期paypal訂閱我該怎麼做?

任何幫助表示讚賞。

+0

由於CSRF令牌 - ipn或paypal導致哪些URL失敗?你能否在渲染表單模板中看到隱藏輸入塊?你的瀏覽器是否有'csrf_token' cookie?你有'TEMPLATE_CONTEXT_PROCESSORS'中的'django.core.context_processors.csrf'(實際上這是做這件事的最好方法)嗎?如果不是,可能問題是你在渲染CSRF令牌之前覆蓋變量'c'。 – ilvar 2012-03-26 02:23:06

+0

嗨@ivar謝謝你的回覆。我的回答如下:沒有URL失敗。當我在購買後單擊返回時,它不會觸及return_url。是的,我有django.core.context_processors.csrf。我有一種奇怪的感覺,那就是它是我的變量C.但是讓我先試着去調試一下。 – 2012-03-26 07:49:48

+0

所以你的'paypal'視圖重定向你到貝寶,對吧?那麼更有意義。您的交易後您不應該被重定向到IPN,它已被Paypal本身調用。那麼,您是否向PayPal提供了IPN網址?它在Internet上的本地主機還是真實服務器上? PayPal IPN機器人可以訪問嗎? – ilvar 2012-03-27 02:41:44

回答

0

從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)) 

這應該解決這個問題。我個人建議只使用renderfrom django.shortcuts import render),它會爲您處理RequestContext。