I’m following a Rails cast to implement subscription billing. It’s here:
http://railscasts.com/episodes/288-billing-with-stripe
My code is virtually identical, though I pass some additional fields to Stripe. The trouble is, the error message in the javascript ALWAYS displays the error message when the submit button is hit… even on successful charges. I’m not sure if Strip is returning something that triggers the error, or if there’s a JS problem.
jQuery ->
Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'))
subscription.setupForm()
subscription =
setupForm: ->
$('#new_membership').submit ->
$('input[type=submit]').attr('disabled', true)
if $('#card_number').length
subscription.processCard()
false
else
true
processCard: ->
card =
number: $('#card_number').val()
cvc: $('#card_code').val()
expMonth: $('#card_month').val()
expYear: $('#card_year').val()
Stripe.createToken(card, subscription.handleStripeResponse)
handleStripeResponse: (status, response) ->
if status == 200
$('#membership_stripe_card_token').val(response.id)
$('#new_membership')[0].submit()
else
$('#stripe_error').text(response.error.message)
$('input[type=submit]').attr('disabled', false)
This is the example stripe gives for error handling. They flip the process and test for errors first:
function stripeResponseHandler(status, response) {
if (response.error) {
...
//show the errors on the form
$(".payment-errors").html(response.error.message);
} else {
var form$ = $("#payment-form");
// token contains id, last4, and card type
var token = response['id'];
// insert the token into the form so it gets submitted to the server
form$.append("<input type='hidden' name='stripeToken' value='" + token + "'/>");
// and submit
form$.get(0).submit();
}
}
UPDATE: So I can tell you what’s happening, but not exactly why or how to fix it.
I added a console log statement and can see now that handleStripeResponse is being called twice, once when the user hits submit, and it returns a 200, then it seems again (maybe because the form then has to be posted to the Rails app for actual processing? and it returns a 0, which kicks up the error message. BUT — because Rails is now handling the processing server side, the charge goes through.
Here’s the compiled JS, if that helps:
(function() {
var subscription;
jQuery(function() {
Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'));
return subscription.setupForm();
});
subscription = {
setupForm: function() {
return $('#new_membership').submit(function() {
$('input[type=submit]').attr('disabled', true);
if ($('#card_number').length) {
subscription.processCard();
return false;
} else {
return true;
}
});
},
processCard: function() {
var card;
card = {
number: $('#card_number').val(),
cvc: $('#card_code').val(),
expMonth: $('#card_month').val(),
expYear: $('#card_year').val()
};
return Stripe.createToken(card, subscription.handleStripeResponse);
},
handleStripeResponse: function(status, response) {
if (status === 200) {
$('#membership_stripe_card_token').val(response.id);
return $('#new_membership')[0].submit();
} else {
$('#stripe_error').text(response.error.message);
return $('input[type=submit]').attr('disabled', false);
}
}
};
}).call(this);
So, my hacky solution thus far is to do this, since the second time through the callback it consistently returns a 0.
At least that way, the user doesn’t get the error message and the submit button isn’t reactivated.