2012-03-25 11 views
3

私はthis appを使って私のアプリケーションにpaypalを実装しています。しかし、私が支払いをしてすべてを行うと、djangoはすでにテンプレートフォームに挿入したときにcsrf_tokenを持っていないと不満を持ち続けます。django-paypal ipn not responding

これは私のテンプレートです:

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

そして、これはPayPalの要素を扱う私の見解である:

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'クッキーを持っていますか?あなたは 'TEMPLATE_CONTEXT_PROCESSORS'に' django.core.context_processors.csrf'を持っていますか(これは実際にはこれを行う最良の方法です)?そうでない場合、CSRFトークンに描画する前に変数 'c'を上書きしていることが多分問題です。 – ilvar

+0

こんにちは@ivar返信ありがとうございます。私の答えは次のとおりです:URLに失敗していません。購入後にリターンをクリックするとreturn_urlに当たっていないだけです。はい、私はdjango.core.context_processors.csrfを持っています。私はそれが私の変数Cであるという奇妙な気持ちを持っていますが、最初にもっとデバッグしようとしましょう。 –

+0

あなたの 'paypal'ビューはあなたをPaypalにリダイレクトします、そうですか?その後はもっと意味をなさない。あなたは、あなたのトランザクション後にIPNにリダイレクトされるべきではなく、Paypal自身によって呼び出されています。あなたはあなたのIPN URLをPaypalに提供しますか?インターネット上のローカルホストまたは実サーバ上にありますか?それはPaypal IPNロボットのためにアクセス可能ですか? – ilvar

答えて

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を処理します。