Reputation: 449
Using Django 1.9 & Stripe 1.35.0. I'm trying out Stripe in a project (stripe.js, NOT 'checkout'), however Stripe won't return a token. I've checked my STRIPE_SECRET_KEY & STRIPE_PUBLISHABLE_KEY to make sure they match. I've basically copied the HTML from the Stripe website directly along with the relevant javascript (https://stripe.com/docs/custom-form).
In my view when I use request.POST['stripeToken']
I get a MultiValueDictKeyError "stripeToken". If I use request.POST.get('stripeToken')
I get the error InvalidRequestError at /orders/checkout Request req_8ecvcXQcwmM1lk: Must provide source or customer. In other words, it's not providing the token to create the customer (or Charge).
Obviously I'm doing something wrong, however I can't find it. I've looked at what examples I can find (most are several yrs old) and the docs. Any help is appreciated. .Thanks.
#views.checkout
def checkout(request):
publishable_key = settings.STRIPE_PUBLISHABLE_KEY
if request.method == "POST":
stripe.api_key = settings.STRIPE_SECRET_KEY
token = request.POST.get('stripeToken')
#token = request.POST['stripeToken']
print token
customer = stripe.Customer.create(description='test', source=token)
print customer
stripe.Charge.create(amount=500, currency='usd', source=token, description='test')
return redirect('orders:thanks.html')
context = {'publishable_key': publishable_key}
return render(request, 'orders/checkout.html', context)
#checkout.html
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script type="text/javascript">
Stripe.setPublishableKey('{{ publishable_key }}');
function stripeResponseHandler(status, response) {
// Grab the form:
var $form = $('#payment-form');
if (response.error) { // Problem!
// Show the errors on the form:
$form.find('.payment-errors').text(response.error.message);
$form.find('.submit').prop('disabled', false); // Re-enable submission
} else { // Token was created!
// Get the token ID:
var token = response.id;
// Insert the token ID into the form so it gets submitted to the server:
$form.append($('<input type="hidden" name="stripeToken">').val(token));
// Submit the form:
$form.get(0).submit();
}
};
$(function() {
var $form = $('#payment-form');
$form.submit(function(event) {
// Disable the submit button to prevent repeated clicks:
$form.find('.submit').prop('disabled', true);
// Request a token from Stripe:
Stripe.card.createToken($form, stripeResponseHandler);
// Prevent the form from being submitted:
return false;
});
});
</script>
{% endblock %}
{% block content %}
<h3 class="text-center">Credit Card Payment</h3>
<div class="container">
<div class="row">
<form method="post" action="." id="checkout-form">
{% csrf_token %}
<div class="form-group">
<label class="control-label" for="card">Card</label>
<div class="controls">
<input type="text" id="card" class="form-control" data-stripe="number" />
</div>
</div>
<div class="form-group">
<label class="control-label" for="">Expiration (MM/YYYY)</label>
<div class="row">
<div class="col-xs-2">
<input type="text" size="2" data-stripe="exp-month" class="form-control" />
</div>
<div class="col-xs-2">
<input type="text" size="4" data-stripe="exp-year" class="form-control" />
</div>
</div>
</div>
<div class="form-group">
<label class="control-label" for="cvc">CVC</label>
<div class="controls">
<input type="text" id="cvc" size="4" class="form-control" data-stripe="cvc" />
</div>
</div>
<div class="form-group">
<div class="controls">
<input type="submit" value="Checkout" class="btn btn-primary" />
</div>
</div>
</form>
</div>
</div>
{% endblock %}
And in settings.py
# Stripe Settings:
STRIPE_SECRET_KEY = 'sk_test_XVDF17ppRvcOciF1xjQryhDX'
STRIPE_PUBLISHABLE_KEY = 'pk_test_RQjZcRmXjpVHfZv5x4KlI6wT'
Upvotes: 0
Views: 1545
Reputation: 5600
You need to pass the Customer
id to the Charge
endpoint, instead of the stripeToken
:
customer = stripe.Customer.create(description='test', source=token)
stripe.Charge.create(customer=customer.id, amount=500, currency='usd', description='test')
More here: Saving credit card details for later
Also, you should use Ajax or a better method than this to send the stripeToken
to your application:
// Get the token ID:
var token = response.id;
// Insert the token ID into the form so it gets submitted to the server:
$form.append($('<input type="hidden" name="stripeToken">').val(token));
// Submit the form:
$form.get(0).submit();
This will send all CC informations to your server. You should something like:
// Get the token ID:
var token = response.id;
$.ajax({
url: '/api/charge-customer',
type: 'POST',
data: {stripeToken: token},
success: function (data) {
Alert("You have been charged.");
},
error: function (data) {
Alert("Server Error.");
}
});
Upvotes: 0