RECURRING PAYMENT IN STRIPE, SUBSCRIPTION PAYMENT IN STRIPE RAILS
Using Recurring Payment (Subscription Based) Rails
Quickly integrate Recurring payment into your Ruby on Rails-based site to provide your users with a streamlined, mobile-ready payment experience.
Getting started
The first step is adding the Stripe gem to your application’s Gemfile:
gem 'stripe'
Then, run bundle install to install the gem.
https://dashboard.stripe.com/account/apikeys
Then, run bundle install to install the gem.
https://dashboard.stripe.com/account/apikeys
Create config/initializers/stripe.rb:
Rails.configuration.stripe = {
publishable_key: Rails.application.secrets.stripe_publishable_key,
secret_key: Rails.application.secrets.stripe_secret_key
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
We will use testing keys for the development environment. For production environment you need to configure with live keys to receive real payments.
Add these keys at config/secrets.yml:
development:
stripe_publishable_key: pk_test_xxxxxxxxxxxxxxxxxxxxxxxx
stripe_secret_key: sk_test_xxxxxxxxxxxxxxxxxxxxxxxx
production:
stripe_publishable_key: ENV['stripe_publishable_key']
stripe_secret_key: ENV['stripe_publishable_key']
We need to create the Plan in the Stripe.
There is two way to create the plan on stripe.
1) We can directly go to the Stripe and create the product and it's Plan.
2) We can create the Plan at the time of when we create the plan in our database using seed.rb file:-
Example :-
For Stripe :-
https://stripe.com/docs/billing/subscriptions/products-and-plans
product = Stripe::Product.create({
name: 'Basic Plan',
type: 'service'
})
plan = Stripe::Plan.create(
:amount => 2000,
:interval => 'month',
:nickname => 'First Plan',
:currency => 'usd',
:product => product.id,
:id => SecureRandom.uuid
)
For our Database :-
BulkPlan.find_or_create_by(name: "Basic Plan", plan_type: "basic", stripe_plan_id: plan.id, display_price: (plan.amount.to_f / 100))
https://dashboard.stripe.com/subscriptions/products
Next, generate subscription controller :-
Create Routes :-
get 'new' => 'subscriptions#new'
post 'subscription_payment' => 'subscriptions#subscription_payment'
post 'webhooks' => 'subscriptions#webhooks'
class SubscriptionsController < ApplicationController
protect_from_forgery :except => :webhooks
before_action :authenticate_bulk_user!, except: [:webhooks]
def new
end
# this is for recursive
def subscription_payment
begin
plan = Stripe::Plan.retrieve(params[:stripe_plan_id])
customer = Stripe::Customer.create(
:description => "Customer for #{params[:stripeEmail]}",
:source => params[:stripeToken],
:email => params[:stripeEmail]
)
stripe_subscription = customer.subscriptions.create(:plan => plan.id)
@subscription = Subscription.find_or_create_by(bulk_user_id: current_bulk_user.id)
@subscription.update(stripe_customer_id: customer.id, stripe_subscription_id: stripe_subscription.id, is_premium_user: true)
flash[:notice] = 'You have successfully got the premium.'
redirect_to root_path
rescue Stripe::StripeError => e
flash[:error] = e.message
redirect_to root_path
end
end
# Method responsbile for handling stripe webhooks
# reference https://stripe.com/docs/webhooks
def webhooks
begin
event_json = JSON.parse(request.body.read)
event_object = event_json['data']['object']
#refer event types here https://stripe.com/docs/api#event_types
case event_json['type']
when 'invoice.payment_succeeded'
handle_success_invoice event_object
when 'invoice.payment_failed'
handle_failure_invoice event_object
when 'charge.failed'
handle_failure_charge event_object
when 'customer.subscription.deleted'
when 'customer.subscription.updated'
end
rescue Exception => ex
render :json => {:status => 422, :error => "Webhook call failed"}
return
end
render :json => {:status => 200}
end
end
Views:-
new.html.erb
<%= form_tag subscription_payment_path, method: :post do %>
Grand Total : <%= @plan.display_price %> $
Create Routes :-
get 'new' => 'subscriptions#new'
post 'subscription_payment' => 'subscriptions#subscription_payment'
post 'webhooks' => 'subscriptions#webhooks'
class SubscriptionsController < ApplicationController
protect_from_forgery :except => :webhooks
before_action :authenticate_bulk_user!, except: [:webhooks]
def new
end
# this is for recursive
def subscription_payment
begin
plan = Stripe::Plan.retrieve(params[:stripe_plan_id])
customer = Stripe::Customer.create(
:description => "Customer for #{params[:stripeEmail]}",
:source => params[:stripeToken],
:email => params[:stripeEmail]
)
stripe_subscription = customer.subscriptions.create(:plan => plan.id)
@subscription = Subscription.find_or_create_by(bulk_user_id: current_bulk_user.id)
@subscription.update(stripe_customer_id: customer.id, stripe_subscription_id: stripe_subscription.id, is_premium_user: true)
flash[:notice] = 'You have successfully got the premium.'
redirect_to root_path
rescue Stripe::StripeError => e
flash[:error] = e.message
redirect_to root_path
end
end
# Method responsbile for handling stripe webhooks
# reference https://stripe.com/docs/webhooks
def webhooks
begin
event_json = JSON.parse(request.body.read)
event_object = event_json['data']['object']
#refer event types here https://stripe.com/docs/api#event_types
case event_json['type']
when 'invoice.payment_succeeded'
handle_success_invoice event_object
when 'invoice.payment_failed'
handle_failure_invoice event_object
when 'charge.failed'
handle_failure_charge event_object
when 'customer.subscription.deleted'
when 'customer.subscription.updated'
end
rescue Exception => ex
render :json => {:status => 422, :error => "Webhook call failed"}
return
end
render :json => {:status => 200}
end
end
Views:-
new.html.erb
<%= form_tag subscription_payment_path, method: :post do %>
Grand Total : <%= @plan.display_price %> $
<%= hidden_field_tag :stripe_plan_id, @plan.stripe_plan_id %>
<script class="stripe-button"
data-amount="<%= @plan.display_price.to_i*100 %>"
data-currency="usd"
data-email="<%= current_bulk_user.email %>"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
src="https://checkout.stripe.com/checkout.js">
</script>
<% end %>
<% end %>
For using the web hook on stripe :-
Expose our service to be accessed by Stripe
When we are running with the development mode, our webhook can not be accessed from Stripe to be tested directly because it is not exposed in the public internet, it is on our localhost.
We will use Ngrok to tunnel our local application to a Ngrok subdomain. We can then allow Stripe to send a HTTP POST to our localhost and test our payment process locally.
You can download Ngrok and install it for your system.
Now you can publish your application just running the command: ngrok 3000, since the rails port is 3000.
It will respond with a URL, http://95251194.ngrok.io in my case. You have to create the webhook into Stripe settings:
1. Log in to your dashboard.
2. Select your Developers > Webhooks.
3. Click Add URL and enter your webhook URL (http://95251194.ngrok.io/webhooks in my case). Indicate whether this is for live or test transactions.
Click Create webhook URL
http://95251194.ngrok.io/webhooks
this is the our route url.
After adding webhooks on stripe , then before executing all the request firstly webhook will call after that other stripe functionality call.
For the recurring payment we need to create the Plan, Customer and Subscription on the Stripe.
We can also follow the links below :-
https://www.sitepoint.com/stripe-subscriptions-rails/
https://stripe.com/docs/checkout/rails
https://launchschool.com/blog/stripe-recurring
https://chrisherring.co/posts/subscriptions-with-your-rails-app-and-stripe
We can also follow the links below :-
https://www.sitepoint.com/stripe-subscriptions-rails/
https://stripe.com/docs/checkout/rails
https://launchschool.com/blog/stripe-recurring
https://chrisherring.co/posts/subscriptions-with-your-rails-app-and-stripe
Comments