title: Stripe payment - Why when I call if payment_form.is_valid(): is it always invalid?
body: <p>I am trying to take a Stripe payment but every time the function is_valid() returns false and the message &quot;We were unable to take a payment with that card!&quot; is displayed.</p>
  <p>The payment is for a set amount of 5 Euros. I am using the credit card number 4242 4242 4242 4242 to test the payment.</p>
  <p>The terminal states that the 'stripe_id' is required but I am at a loss as to what to do about that.</p>
  <p>Can anyone help me find what is wrong with my code?</p>
  <p>checkout.html:</p>
  <pre><code>{% extends &quot;base.html&quot; %}
  {% load static from staticfiles %}
  {% load bootstrap_tags %}
  
  {% block head_js %}
  &lt;script type=&quot;text/javascript&quot; src=&quot;https://js.stripe.com/v2/&quot;&gt;&lt;/script&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;&quot;&gt;
      //&lt;![CDATA[
      Stripe.publishableKey = '{{ publishable }}';
     // ]]&gt;
  &lt;/script&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;{% static 'js/stripe.js' %}&quot;&gt;&lt;/script&gt;
  {% endblock %}
  
  {% block content %}
  
  &lt;form action=&quot;{% url 'checkout' %}&quot; method=&quot;post&quot; id=&quot;payment-form&quot; class=&quot;col-md-6 col-md-offset-3&quot;&gt;
      &lt;legend&gt;Payment Details&lt;/legend&gt;
  
      &lt;div id=&quot;credit-card-errors&quot; style=&quot;display: none;&quot;&gt;
          &lt;div class=&quot;alert-message block-message error&quot; id=&quot;stripe-error-message&quot;&gt;&lt;/div&gt;
      &lt;/div&gt;
  
      &lt;div class=&quot;form-group col-md-6&quot;&gt;
          {{ payment_form|as_bootstrap }}
      &lt;/div&gt;
  
      {% csrf_token %}
      &lt;div class=&quot;form-group col-md-12&quot;&gt;
          &lt;input class=&quot; btn btn-primary&quot; id=&quot;submit_payment_btn&quot; name=&quot;commit&quot; type=&quot;submit&quot; value=&quot;Submit Payment of 5 Euros&quot;&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  
  {% endblock %}
  </code></pre>
  <p>forms.py:</p>
  <pre><code>from django import forms
  
  class MakePaymentForm(forms.Form):
      print(&quot;MakePaymentForm...&quot;)
      MONTH_CHOICES = [(i, i) for i in range(1, 12)]
      YEAR_CHOICES = [(i, i) for i in range(2019, 2040)]
      
      credit_card_number = forms.CharField(label='Credit Card Number', required=False)
      cvv = forms.CharField(label ='Security Code (CVV)', required=False)
      expiry_month = forms.ChoiceField(label=&quot;Month&quot;,choices=MONTH_CHOICES, required=False)
      expiry_year = forms.ChoiceField(label='year',choices=YEAR_CHOICES, required=False)
      stripe_id = forms.CharField(widget=forms.HiddenInput,  required=False)
  
  </code></pre>
  <p>views.py:</p>
  <pre><code>from django.shortcuts import render, get_object_or_404, redirect, reverse
  from django.contrib.auth.decorators import login_required
  from django.contrib import messages
  from .forms import MakePaymentForm
  from tickets.forms import TicketsForm
  from tickets.models import Ticket
  from django.conf import settings
  from accounts.views import login, index 
  from django.utils import timezone
  import stripe
  # Create your views here.
  
  stripe.api_key = settings.STRIPE_SECRET
  
  @login_required()
  def checkout(request):
      if request.method == &quot;POST&quot;:
          payment_form = MakePaymentForm(request.POST)
          print(&quot;checkout...&quot;)
  
          if  payment_form.is_valid():
              print(&quot;Payment form is valid...&quot;)
              try:
                  print(&quot;Just about to charge the customer...&quot;)
                  customer = stripe.Charge.create(
                      amount=500,
                      currency=&quot;EUR&quot;,
                      description=&quot;Thank you for your contribution, it will really help our site&quot; and request.user.email,
                      card=payment_form.cleaned_data['stripe_id']
                  )
              except stripe.error.CardError:
                  messages.error(request, &quot;Your card was declined!&quot;)
              
              if customer.paid:
                  print(&quot;Customer has paid...&quot;)
                  messages.error(request, &quot;You have successfully paid&quot;)
                  return redirect(reverse('index'))
              else:
                  messages.error(request, &quot;Unable to take payment&quot;)
                  return redirect(reverse('index'))
          else:
              print(&quot;There are errors...&quot;)
              print(payment_form.errors)
              messages.error(request, &quot;We were unable to take a payment with that card!&quot;)
      else:
          print(&quot;Method isn't post...&quot;)
          payment_form = MakePaymentForm()
  
      return render(request, &quot;checkout.html&quot;, {&quot;payment_form&quot;: payment_form, &quot;publishable&quot;: settings.STRIPE_PUBLISHABLE})
  </code></pre>
  <p>Here is the output in the terminal:</p>
  <pre><code>[14/Dec/2020 22:47:40] &quot;GET /checkout/ HTTP/1.1&quot; 200 5688
  checkout...
  There are errors...
  &lt;ul class=&quot;errorlist&quot;&gt;&lt;li&gt;stripe_id&lt;ul class=&quot;errorlist&quot;&gt;&lt;li&gt;This field is required.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
  [14/Dec/2020 22:47:51] &quot;POST /checkout/ HTTP/1.1&quot; 200 5850
  </code></pre>
  <p>and here is stipe.js:</p>
  <pre><code>$(function(){
      $(&quot;#payment-form&quot;).submit(function() {
          console.log(&quot;#payment-form&quot;);
          var form = this;
          var card = {
              number: $(&quot;#id_credit_card_number&quot;).val(),
              expMonth: $(&quot;#id_expiry_month&quot;).val(),
              expYear: $(&quot;#id_expiry_year&quot;).val(),
              cvc: $(&quot;#id_cvv&quot;).val()
          };
      
      Stripe.createToken(card, function(status, response) {
          console.log(&quot;#createToken&quot;);
          if (status === 200) {
              $(&quot;#credit-card-errors&quot;).hide();
              $(&quot;#id_stripe_id&quot;).val(response.id);
  
              // Prevent the credit card details from being submitted
              // to our server
              $(&quot;#id_credit_card_number&quot;).removeAttr('name');
              $(&quot;#id_cvv&quot;).removeAttr('name');
              $(&quot;#id_expiry_month&quot;).removeAttr('name');
              $(&quot;#id_expiry_year&quot;).removeAttr('name');
  
              form.submit();
          } else {
              $(&quot;#stripe-error-message&quot;).text(response.error.message);
              $(&quot;#credit-card-errors&quot;).show();
              $(&quot;#validate_card_btn&quot;).attr(&quot;disabled&quot;, false);
          }
      });
      return false;
      });
  });
  </code></pre>
  <p>I have made and my form is now valid, but when it sends the payment request to Stripe I get the following error and it looks like stripe_id is blank. Any ideas?</p>
  <p><a href="https://i.stack.imgur.com/hUJGs.png" rel="nofollow noreferrer">InvalidRequestError at /checkout/1</a></p>
  <p><a href="https://i.stack.imgur.com/S6rCd.png" rel="nofollow noreferrer">InvalidRequestError at /checkout/2</a></p>