Create an account at Stripe 2. Account Setting/Api Key Grab your Api key here 3. Put your Key in secrets.yml as
stripe_secret_key: your key here
stripe_publishable_key: your key here
We are going to use Fundsy as an example We would need to implement a transaction table to store some of the information we will get from stripe For the simplicity we are going to use pledge table
Setting Up the database
bin/rails g migration add_stripe_fields_to_db
def chagnge
add_column :pledges, :stripe_txn_id, :string
add_column :users, stripe_customer_id, :string
add_column :users, stripe_last_4, :string
add_column :users, stripe_card_type, :string
add_column :users, stripe_card_expiry, :string
end
bin/rake db:migrate
Look at pledges controller for more info Campaigns controller
@pledge = Pledge.new
After We will start by adding pledge to campaign show.html.erb
<h2>Pledge</h2>
<%= Simple_form_for [@campaign,@pledge] do |f| %>
<%= f.input :amount %>
<%= f.button :submit, :class " btn btn-priamry"%>
<%end%>
After a uesr makes a pledge let's send the user to payment page
Lets start by creating the controller
bin/rails g controller payments
In the case of transaction we need 3 information pledge/campaign/user
we can get user from current_user and campaign is accessible from pledge Thus, in your routes we are going to nest the payment route under pledges
resources :pledges, only: [] do
resources :payments, only: [:new, :create]
end
In your Payments controller
before_action :authenticate_user
def new
end
def create
end
We need to create view files
view/payments
create new.html.erb
we now can create a path from campaign show cage to redirect the user to new payment page In your campaign controller
redirect_to new_pledge_payment_path(@pledge)
Now we need to build a ajax form 2 forms are needed
<%= form_tag "" do%>
<div class="form-group">
<%=label_tag :card_number%>
<%=text_field_tag :card_number,"", class: "form-control"%>
</div>
<div class="form-group">
<%=label_tag :cvc%>
<%=text_field_tag :cvc,"", class: "form-control"%>
</div>
<% end %>
Now we need drop down bar for exp date for the card
<%= select_month Date.today, {add_month_numbers: true}, {class: "form-control"}%>
<%= select_year Date.today, {start_year: Time.now.year, end_year: Time.now.year}, {class: "form-control"}%>
<%= submit_tag "make payment", class: "btn btn-primary"%>
Now we have the form we need to work with Ajax to receive the token from Stripe google stripe javascript api Place the code in application.html.erb
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
#This code is needed to send our public key
<meta name="stripe-publishable-key" content="<%= Rails.application.secrets.stripe_publishable_key %>"
The next step is to sent a file in js to send the key
publishable key is a public key
Assets/payments.js
$(document).ready(function(){
Stripe.setPublishableKey('pk_test_Ir3Dz5nsnoiWv8lrKIclpNvF');
});
in the js function we need to grab the public key so
$(document).ready(function(){
var stripPublishableKey = $("meta[name='stripe-publishable-key']").attr("content");
Stripe.setPublishableKey(stripPublishableKey);
});
var stripPublishableKey = $("meta[name='stripe-publishable-key']").attr("content");
this is the added line.
<div class="form-group">
<%= label_tag :card_expiry %>
<%= select_month Date.today, {add_month_numbers: true}, {class: "form-control", data: {stripe: "exp-month"}} %>
<%= select_year Date.today, {start_year: Time.now.year, end_year: Time.now.year + 10}, {class: "form-control", data: {stripe: "exp-year"}} %>
</div>
<%= form_tag "", id: "payment-form" do %>
add this line
$("#payment-form").on("submit", function(event){
event.preventDefault();
Stripe.card.createToken($("#payment-form"), stripeResponseHandler);
});
your js file should look like this
$(document).ready(function(){
var stripPublishableKey = $("meta[name='stripe-publishable-key']").attr("content");
Stripe.setPublishableKey(stripPublishableKey);
$("#payment-form").on("submit", function(event){
event.preventDefault();
Stripe.card.createToken($("#payment-form"), stripeResponseHandler);
});
});
We need to add another line
$("#payment-form").find("input:submit").attr("disabled", true);
$(document).ready(function(){
var stripPublishableKey = $("meta[name='stripe-publishable-key']").attr("content");
Stripe.setPublishableKey(stripPublishableKey);
$("#payment-form").on("submit", function(event){
event.preventDefault();
$("#payment-form").find("input:submit").attr("disabled", true);
Stripe.card.createToken($("#payment-form"), stripeResponseHandler);
});
});
var stripeResponseHandler = function(status, data) {
if(status === 200) {
// successful => submit second form to the server
var token = data.id;
} else {
var errMessage = data.error.message;
$("#payment-form").find("input:submit").attr("disabled", false);
}
}
var stripeResponseHandler = function(status, data) {
if(status === 200) {
// successful => submit second form to the server
var token = data.id;
} else {
var errMessage = data.error.message;
$("#stripe-error-message").html(errMessage);
$("#payment-form").find("input:submit").attr("disabled", false);
}
}
To display error message
<div class="alert alert-danger" id="stripe-error-message"></div>
$(document).ready(function(){
var stripPublishableKey = $("meta[name='stripe-publishable-key']").attr("content");
Stripe.setPublishableKey(stripPublishableKey);
$("#payment-form").on("submit", function(event){
event.preventDefault();
$("#stripe-error-message").addClass("hide");
$("#payment-form").find("input:submit").attr("disabled", true);
Stripe.card.createToken($("#payment-form"), stripeResponseHandler);
});
var stripeResponseHandler = function(status, data) {
if(status === 200) {
// successful => submit second form to the server
var token = data.id;
alert("Wohooo! " + token);
} else {
var errMessage = data.error.message;
$("#stripe-error-message").html(errMessage);
$("#stripe-error-message").removeClass("hide");
$("#payment-form").find("input:submit").attr("disabled", false);
}
}
});
payment controller
class PaymentsController < ApplicationController
before_action :authenticate_user
def new
@pledge = current_user.pledges.find params[:pledge_id]
end
def create
render text: "Got the token #{params[:stripe_token]}"
end
end
<h1>Make a Payment</h1>
<div class="alert alert-danger hide" id="stripe-error-message"></div>
<%= form_tag "", id: "payment-form" do %>
<div class="form-group">
<%= label_tag :card_number %>
<%= text_field_tag :card_number, "", class: "form-control", data: {stripe: "number"} %>
</div>
<div class="form-group">
<%= label_tag :cvc %>
<%= text_field_tag :cvc, "", class: "form-control", data: {stripe: "cvc"} %>
</div>
<div class="form-group">
<%= label_tag :card_expiry %>
<%= select_month Date.today, {add_month_numbers: true}, {class: "form-control", data: {stripe: "exp-month"}} %>
<%= select_year Date.today, {start_year: Time.now.year, end_year: Time.now.year + 10}, {class: "form-control", data: {stripe: "exp-year"}} %>
</div>
<%= submit_tag "Make the Payment", class: "btn btn-primary" %>
<% end %>
<%= form_tag pledge_payments_path(@pledge) do %>
<%= hidden_field_tag :stripe_token %>
<% end %>
We need two types of code Stripe Javascript Stripe Ruby Rails
Stripe Ruby Gem gem 'stripe'
config/initializer/stripe.rb
stripe.api_key = Rails.application.secrets.stripe_secret_key
bin/rake db:rollback
class AddStripeFieldsToDb < ActiveRecord::Migration
def change
add_column :pledges, :stripe_txn_id, :string
add_column :users, :stripe_customer_id, :string
add_column :users, :stripe_last_4, :string
add_column :users, :stripe_card_type, :string
add_column :users, :stripe_card_expiry_month, :integer
add_column :users, :stripe_card_expiry_year, :integer
end
end
class PaymentsController < ApplicationController
before_action :authenticate_user
before_action :find_pledge
def new
end
def create
stripe_customer = Stripe::Customer.create(
description: "Customer for #{current_user.email}",
source: params[:stripe_token]
)
current_user.stripe_customer_id = stripe_customer.id
current_user.stripe_last_4 = stripe_customer.sources.data[0].last4
current_user.stripe_card_type = stripe_customer.sources.data[0].brand
current_user.stripe_card_expiry_month = stripe_customer.sources.data[0].exp_month
current_user.stripe_card_expiry_year = stripe_customer.sources.data[0].exp_year
current_user.save
charge = Stripe::Charge.create(
amount: @pledge.amount * 100,
currency: "cad",
customer: current_user.stripe_customer_id,
description: "Charge for pledge id: #{@pledge.id}"
)
@pledge.stripe_txn_id = charge.id
@pledge.save
redirect_to @pledge.campaign, notice: "Thanks for completing the payment"
end
private
def find_pledge
@pledge = current_user.pledges.find params[:pledge_id]
end
end