Reputation: 2080
So I have been having an interesting time trying to get Stripe up and running in my app, currently the problem is that a payment token is not being generated for transactions. When I try to process a test payment I get this error: Must provide source or customer.
Inside of console I get this error: Uncaught ReferenceError: Stripe is not defined
I think the problem is that the <script type="text/javascript" src="https://js.stripe.com/v2/"></script>
file is not being read, as it is what should be giving me my token. I have been at this for quite some time, and have read everything I could get my hands on online, but haven't found a solution that works for me yet. It is probably something small, and any help is really really appreciated.
Here is my controller:
require "stripe"
class ChargesController < ApplicationController
def new
@project = Project.find(params[:project_id])
end
def create
binding.pry
@project = Project.find(params[:project_id])
Stripe.api_key = "sk_test_JlKC4V7nmCQ0sE4iNAVyoAxA"
#Get the credit card details submitted by the form
token = params[:stripeToken]
# Amount in cents, this is being read and recorded in stripe dashboard
amount = (params[:amount].to_f * 100).to_i
charge = Stripe::Charge.create(
:amount => amount,
:source => token,
:description => 'Rails Stripe customer',
:currency => 'usd'
)
rescue Stripe::CardError => e
flash[:error] = e.message
#save what we need for our server as a new payment
binding.pry
@payment = Payment.create({
user_id: current_user.id,
project_id: @project.id,
amount: @amount,
comments: params[:comments]
})
#make a function in payments model that will convert the cents back into dollars
@project.addMoney(@amount) #add it to project
@payment.save
end
private
def charges_params
params.require(:payment).permit(:comments, :user_id, :project_id, :amount)
end
end
I am not creating a customer, as I was explicitly told by Stripe support via email, that I need not if I am only processing one-time payments, which I am. Here is the payment form, which includes the Javascript in the head (as per Stripe's example):
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">
// The required Stripe lib
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script>
Stripe.setPublishableKey('<%= ENV['SECRET_KEY'] %>');
function stripeResponseHandler(status, response) {
var $form = $('#payment-form');
if (response.error) {
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('button').prop('disabled', false);
} else {
// response contains id and card, which contains additional card details
var token = response.id;
// Insert the token into the form so it gets submitted to the server
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
// and submit
$form.get(0).submit();
}
}
$('#payment-form').submit(function(event) {
var $form = $(this);
alert('you clicked submit');
console.log('this function was hit');
// Disable the submit button to prevent repeated clicks
$form.find('submit').prop('disabled', true);
Stripe.card.createToken($form, stripeResponseHandler);
// Prevent the form from submitting with the default action
return false;
});
</script>
</head>
<!-- form -->
<div class="container">
<div class="row Row one">
<div class="col-sm-12 col-md-10">
<h1>Make your contribution</h1>
<%= form_for @project, url: project_charges_path, :html => {:id => "payment-form"}, method: 'post' do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.hidden_field :@project_id, :value => @project.id %>
<div class= "field">
<%= label_tag :card_number, "Credit Card Number" %><br>
<%= text_field_tag :card_number, nil, name: nil, class: 'form-control', :required => true %><br>
</div>
<div class= "field">
<%= label_tag :card_code, "Security Code (cvc)" %><br>
<%= text_field_tag :card_code, nil, name: nil, class: 'form-control', :required => true %><br>
</div>
<div class= "field">
<%= label_tag :card_month, "Expiration" %>
<%= select_month nil, {add_month_numbers: true}, {name: nil, id: "card_month"} %>
<%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: "card_year"}%>
</div>
<div class= "field">
<%= label_tag :amount, "Amount" %><br>
<%= text_field_tag :amount, nil, name: nil, class: 'form-control', :required => true %>
</div>
<div class= "field">
<%= label_tag :comments, "Add a comment?" %><br>
<%= text_area_tag :comments, nil, name: nil, class: 'form-control', :required => true %>
</div>
<div class= "actions">
<%= f.submit 'Submit', :class => 'contribution-submit' %>
</div>
<div id="stripe_error">
<noscript>JavaScript is not enabled and is required for this form. First enable it in your web browser settings.</noscript>
</div>
<% end %>
</div>
</div>
<!-- <div class="row"></div> -->
</div>
Another thing I find odd that may be worth mentioning in case it is indicative of what the problem may be - the files in this view folder (where the form lives) are not picking up any of the sites css which is provided in the application.html.erb. That is why I had to manually include it in the head of the form's html.erb, as well as include the js.stripe.com
file. The css is now rendering, but this file does not seem to be doing anything.
Upvotes: 3
Views: 4111
Reputation: 2080
not sure what did it exactly, but went back and copied Stripes code again and it now works. My form now looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Contribution Form</title>
<!-- The required Stripe lib -->
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<!-- jQuery is used only for this example; it isn't required to use Stripe -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
// This identifies your website in the createToken call below
Stripe.setPublishableKey('<%= 'pk_test_KfCg1YmVXwBYyEdPEWnfibF8'%>');
var stripeResponseHandler = function(status, response) {
var $form = $('#payment-form');
if (response.error) {
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('button').prop('disabled', false);
} else {
// 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" />').val(token));
// and re-submit
$form.get(0).submit();
}
};
jQuery(function($) {
$('#payment-form').submit(function(e) {
var $form = $(this);
// Disable the submit button to prevent repeated clicks
$form.find('button').prop('disabled', true);
Stripe.card.createToken({
number: $('.card-number').val(),
cvc: $('.card-cvc').val(),
exp_month: $('.card-expiry-month').val(),
exp_year: $('.card-expiry-year').val()}, stripeResponseHandler);
// Prevent the form from submitting with the default action
return false;
});
});
</script>
</head>
<body>
<!-- form -->
<div class="container">
<div class="row Row one">
<div class="col-sm-12 col-md-10">
<h1>Make your contribution</h1>
<%= form_for @project, url: project_charges_path, :html => {:id => "payment-form"}, method: 'post' do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.hidden_field :@project_id, :value => @project.id %>
<div class= "field">
<%= label_tag :card_number, "Credit Card Number" %><br>
<%= text_field_tag :card_number, nil, name: nil, class: ' card-number form-control', :required => true %><br>
</div>
<div class= "field">
<%= label_tag :card_code, "Security Code (cvc)" %><br>
<%= text_field_tag :card_code, nil, name: nil, class: 'card-cvc form-control', :required => true %><br>
</div>
<div class= "field">
<%= label_tag :card_month, "Expiration" %>
<%= select_month nil, {add_month_numbers: true}, {name: nil, class: "card-expiry-month"} %>
<%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, class: "card-expiry-year"}%>
</div>
<div class= "field">
<%= label_tag :amount, "Amount" %><br>
<%= text_field_tag :amount %>
</div>
<div class= "field">
<%= label_tag :comments, "Add a comment?" %><br>
<%= text_area_tag :comments %>
</div>
<div class= "actions">
<%= f.submit 'Submit', :class => 'contribution-submit' %>
</div>
<div id="stripe_error">
<noscript>JavaScript is not enabled and is required for this form. First enable it in your web browser settings.</noscript>
</div>
<% end %>
</div>
</div>
<!-- <div class="row"></div> -->
</div>
</body>
</html>
Upvotes: 1