简体   繁体   中英

Stripe payment form not working on Django, cannot retreive a token

I am trying to add a payment page to my site, I copied the code from the stripe documentation, however when I press on the pay button nothing happens. Through debugging, the returned token is empty. The thing is when I tried the code in JsFiddle it worked, but when I add it to my app, there is no response, the console is empty so I'm lost in troubleshooting. Here is the html file:

{% block content %}
<form   method="POST" id="payment-form" >
{% csrf_token %}
  <input type="hidden" name="token" />
    <div class="group">
      <label>
        <span>Card</span>
        <div id="card-element" class="field"></div>
          <div id="card-errors" role="alert"></div>
      </label>
    </div>
    <div class="group">
      <label>
        <span>Name</span>
        <input id="name" name="name" class="field" placeholder="Jane Doe" />
      </label>
    </div>
    <div class="group">
      <label>
        <span>Address</span>
        <input id="address-line1" name="address_line1" class="field" placeholder="77 Winchester Lane" />
      </label>
      <label>
        <span>Address (cont.)</span>
        <input id="address-line2" name="address_line2" class="field" placeholder="" />
      </label>
      <label>
        <span>City</span>
        <input id="address-city" name="address_city" class="field" placeholder="Coachella" />
      </label>
      <label>
        <span>State</span>
        <input id="address-state" name="address_state" class="field" placeholder="CA" />
      </label>
      <label>
        <span>ZIP</span>
        <input id="address-zip" name="address_zip" class="field" placeholder="92236" />
      </label>
      <label>
        <span>Country</span>
        <input id="address-country" name="address_country" class="field" placeholder="United States" />
      </label>
    </div>
    <button type="submit">Pay $25</button>
    <div class="outcome">
      <div class="error"></div>
      <div class="success">
        Success! Your Stripe token is <span class="token"></span>
      </div>
    </div>
  </form>




{% endblock %}

{% block body_scripts %}
<script >
var stripe = Stripe('stripeKeyGoesHere');
var elements = stripe.elements();

var card = elements.create('card', {
  hidePostalCode: true,
  style: {
    base: {
      iconColor: '#666EE8',
      color: '#31325F',
      lineHeight: '40px',
      fontWeight: 300,
      fontFamily: 'Helvetica Neue',
      fontSize: '15px',

      '::placeholder': {
        color: '#CFD7E0',
      },
    },
  }
});
card.mount('#card-element');

function setOutcome(result) {
  var successElement = document.querySelector('.success');
  var errorElement = document.querySelector('.error');
  successElement.classList.remove('visible');
  errorElement.classList.remove('visible');
console.log(result);
  if (result.token) {
    // In this example, we're simply displaying the token
    successElement.querySelector('.token').textContent = result.token.id;
    successElement.classList.add('visible');

    // In a real integration, you'd submit the form with the token to your backend server
    var form = document.querySelector('form');
    form.querySelector('input[name="token"]').setAttribute('value', result.token.id);
    form.submit();
  } else if (result.error) {
    errorElement.textContent = result.error.message;
    errorElement.classList.add('visible');
  }
}

card.on('change', function(event) {
  setOutcome(event);
});

document.querySelector('form').addEventListener('submit', function(e) {
  e.preventDefault();
  var options = {
    name: document.getElementById('name').value,
    address_line1: document.getElementById('address-line1').value,
    address_line2: document.getElementById('address-line2').value,
    address_city: document.getElementById('address-city').value,
    address_state: document.getElementById('address-state').value,
    address_zip: document.getElementById('address-zip').value,
    address_country: document.getElementById('address-country').value,
  };
  stripe.createToken(card, options).then(setOutcome);
});

</script>

and here is the view:

def payments(request):
    if request.user.profile.is_seller is False:
        key = settings.STRIPE_PUBLIC_KEY
        if request.method == 'POST':
            stripe.api_key = settings.STRIPE_SECRET_KEY
            #form = CreateCustomer(request.POST)
            token = request.POST.get('token')
            print(token)
            #if form.is_valid():
                #something
            return render(request, 'payment_card.html', {'key': key})
        else:
            print('it is a get')
            return render(request, 'payment_card.html', {'key':key})

    else:
        raise PermissionDenied

When you say that nothing happens when you click the button, could you see, when debugging (using the browser Dev tools?) if the form submission actually happened?

Also, can you try to add a console.log(result) in your setOutcome function right before if (result.token) { } ?

When you are debugging your server side code, can you see your controller/view/handler, ie payments(request) being called when if the form is submitted ? Can you check the content of the request.POST dictionary ?

The idea is to check if a POST request is actually made when you submit the form (client side using browser Dev tools), and if your server side controller does actually receives/handle the request and how the received POST request looks like (specifically the request.POST dictionary).

The issue was never solved as I did not find a way to debug and find where is the problem, however the Stripe team helped me build another form and here it is, fortunately working with Django 1.11, hopefully it will help someone running into the same issue:

var stripe = Stripe('stripe key');
var elements = stripe.elements();

var card = elements.create('card', {
  hidePostalCode: true,
  style: {
    base: {
      iconColor: '#666EE8',
      color: '#31325F',
      lineHeight: '40px',
      fontWeight: 300,
      fontFamily: 'Helvetica Neue',
      fontSize: '15px',
      border:'2px',

      '::placeholder': {
        color: '#CFD7E0',
      },
    },
  }
});
card.mount('#card-element');

function setOutcome(result) {
  var successElement = document.querySelector('.success');
  var errorElement = document.querySelector('.error');
  successElement.classList.remove('visible');
  errorElement.classList.remove('visible');

  if (result.token) {
    // In this example, we're simply displaying the token
    successElement.querySelector('.token').textContent = result.token.id;
    successElement.classList.add('visible');

    // In a real integration, you'd submit the form with the token to your backend server
    //var form = document.querySelector('form');
    //form.querySelector('input[name="token"]').setAttribute('value', result.token.id);
    //form.submit();
  } else if (result.error) {
    errorElement.textContent = result.error.message;
    errorElement.classList.add('visible');
  }
}

card.on('change', function(event) {
  setOutcome(event);
});

document.querySelector('form').addEventListener('submit', function(e) {
  e.preventDefault();
  var options = {
    name: document.getElementById('name').value,
    address_line1: document.getElementById('address-line1').value,
    address_line2: document.getElementById('address-line2').value,
    address_city: document.getElementById('address-city').value,
    address_state: document.getElementById('address-state').value,
    address_zip: document.getElementById('address-zip').value,
    address_country: document.getElementById('address-country').value,
  };
  stripe.createToken(card, options).then(setOutcome);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM