Guide: Set Up Stripe Subscriptions & Webhooks

1. Backend Setup (Ruby on Rails)

First, set up your backend to handle Stripe subscriptions. You will use the Stripe gem and the following code in your Rails controller. Add this to your `StripeController`:

class StripeController < ApplicationController
  skip_before_action :verify_authenticity_token, only: %i[webhook]

  def checkout
    @session = Stripe::Checkout::Session.create({
      mode: "subscription",
      success_url: root_url,
      cancel_url: root_url,
      customer: current_user.stripe_customer_id,
      line_items: [{
        price: "your-price-id",
        quantity: 1,
      }]
    })
    redirect_to @session.url, status: 303, allow_other_host: true
  end

  def webhook
    Stripe.api_key = ENV["STRIPE_SECRET_KEY"]
    endpoint_secret = ENV["STRIPE_SIGNING_SECRET"]

    payload = request.body.read
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(payload, sig_header, endpoint_secret)
    rescue JSON::ParserError, Stripe::SignatureVerificationError
      render json: { error: "Invalid" }, status: 400
      return
    end

    case event.type
    when 'customer.subscription.deleted'
      stripe_subscription = event.data.object
      user = User.find_by(stripe_customer_id: stripe_subscription.customer)
      user.update(subscription_status: "Free")
    when 'customer.subscription.updated'
      stripe_subscription = event.data.object
      user = User.find_by(stripe_customer_id: stripe_subscription.customer)
      user.update(subscription_status: "starter") if stripe_subscription.amount_total == 2000
      user.update(subscription_status: "premium") if stripe_subscription.amount_total == 4000
    end

    head :ok
  end
end

This controller handles the creation of Stripe subscription sessions and webhook events to update subscription statuses.

2. Frontend Setup with TailwindCSS

Use this simple HTML and TailwindCSS structure for your frontend. This will create a **Subscribe Now** button that users can click to trigger the Stripe Checkout session.

<div class="min-h-screen flex items-center justify-center bg-gray-100">
  <div class="bg-white p-8 rounded-lg shadow-lg w-full max-w-md">
    <h1 class="text-2xl font-bold mb-4 text-center">Subscribe to Premium Plan</h1>
    <p class="text-gray-600 mb-6 text-center">Unlock premium features with a subscription!</p>

    <form action="/stripe/checkout" method="POST">
      <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
      <button type="submit" class="w-full bg-blue-500 text-white py-2 px-4 rounded-lg hover:bg-blue-600">
        Subscribe Now
      </button>
    </form>
  </div>
</div>

This code creates a simple **Subscribe Now** button styled with TailwindCSS that triggers the checkout process for your Stripe subscription.

3. Webhooks & Testing with Stripe CLI

To handle Stripe webhook events (such as updates or cancellations of subscriptions), you need to configure your Stripe webhook endpoint. Use the provided Rails controller method to manage these events.

# Test Stripe webhooks locally using Stripe CLI:
$ stripe listen --forward-to localhost:3000/stripe/webhook
$ stripe trigger customer.subscription.created

You can test webhook events locally with the Stripe CLI. When a subscription is created, updated, or canceled, Stripe will send a webhook to your application. Use the `stripe listen` command to forward these events.

4. Configure Webhooks in Stripe Dashboard

Finally, configure the webhook endpoint in the Stripe Dashboard under **Developers** > **Webhooks**. Add your webhook endpoint URL (e.g., `https://yourdomain.com/stripe/webhook`) and choose the events you wish to receive (e.g., `customer.subscription.created`, `customer.subscription.updated`, etc.).

Ensure that you copy the **Signing Secret** and store it in your environment variables as `STRIPE_SIGNING_SECRET`.