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



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 %> $

    <%= 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 %>

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.
Post a Comment

Popular posts from this blog

RAILS: UPLOADING PHOTOS VIA AMAZON S3 AND PAPERCLIP (UPLOADING FILES TO S3 IN RUBY WITH PAPERCLIP)

CARRIERWAVE - UPLOAD ANY MEDIA (AUDIO , VIDEO AND IMAGE ) FILE IN RAILS

SELECT COUNTRY WITH STATE AND IT'S CITIES RAILS

UNINITIALIZED CONSTANT PAPERCLIP::STORAGE::S3::AWS

Building native extensions. This could take a while... ERROR: Error installing mysql: ERROR: Failed to build gem native extension.

HOW TO CALL RAILS API FROM SIMPLE HTML PAGE.

CREATE API FOR USER SIGN UP, LOGIN AND CREATE PUBLISHER WITH CURRENT USER