Back to Blog

Stripe Embedded Checkout with Rails Stimulus

Digital Forge

Use Stripe Embedded Components with Rails Stimulus

post featured image

Implementing Stripe Embedded Checkout with Rails and Stimulus.js

Stripe’s Embedded Components revolutionize the checkout experience by allowing developers to create seamless, secure payment flows directly within their applications. Unlike traditional redirect-based checkouts, embedded components keep users in your application while maintaining Stripe’s robust security and reliability.

In this guide, we’ll walk through implementing Stripe’s Embedded Checkout in a Ruby on Rails application using Stimulus.js. We’ll create a complete checkout flow that can be customized to match your application’s design while leveraging Stripe’s powerful payment infrastructure.

Prerequisites

Before we begin, ensure you have:

  • A Rails application (Rails 7+ recommended)
  • Stimulus.js installed
  • A Stripe account with API keys
  • The stripe gem installed

Setting Up Stripe

First, add the Stripe gem to your Gemfile:

# Gemfile
gem 'stripe'

Then install the required JavaScript packages:

yarn add @stripe/stripe-js

Implementation Steps

1. Create the Checkout Controller

First, let’s create a controller to handle the checkout session creation:

# app/controllers/checkout_controller.rb
class CheckoutController < ApplicationController
def create
@checkout_session = Stripe::Checkout::Session.create({
ui_mode: 'embedded',
payment_method_types: ['card'],
line_items: [{
price: 'price_H5ggYwtDq4fbrJ', # Replace with your price ID
quantity: 1,
}],
mode: 'payment',
return_url: "#{request.base_url}/checkout/success",
metadata: {
order_id: '123' # Add any relevant metadata
}
})
respond_to do |format|
format.json { render json: { client_secret: @checkout_session.client_secret } }
end
end
end

2. Create the Stimulus Controller

Next, create a Stimulus controller to handle the embedded checkout:

// app/javascript/controllers/stripe_checkout_controller.js
import { Controller } from "@hotwired/stimulus"
import { loadStripe } from '@stripe/stripe-js'
export default class extends Controller {
static values = {
publishableKey: String,
clientSecret: String
}
connect() {
this.initializeCheckout()
}
async initializeCheckout() {
try {
this.stripe = await loadStripe(this.publishableKeyValue)
const checkout = await this.stripe.initEmbeddedCheckout({
clientSecret: this.clientSecretValue
});
// Mount the checkout element
checkout.mount(this.element);
} catch (error) {
console.error('Error initializing Stripe checkout:', error);
// Handle error appropriately
}
}
}

3. Create the View

Create a view to display the checkout:

app/views/checkout/show.html.erb

<div class="checkout-container">
<div
data-controller="stripe-checkout"
data-stripe-checkout-publishable-key-value="<%= Rails.application.credentials.stripe[:publishable_key] %>"
data-stripe-checkout-client-secret-value="<%= @checkout_session.client_secret %>"
></div>
</div>

Security Considerations

  • Always use environment variables or Rails credentials for sensitive keys
  • Implement proper CSRF protection
  • Use HTTPS in production
  • Validate all incoming webhook events
  • Implement proper error handling and logging

Additional Resources

Conclusion

By implementing Stripe’s Embedded Checkout with Rails and Stimulus.js, you can create a seamless payment experience that keeps users in your application while maintaining the highest security standards. The embedded components handle all the complex payment logic, allowing you to focus on creating a great user experience.

Remember to test thoroughly in Stripe’s test mode before going live, and always follow security best practices when handling payment information.

© 2026 Matthew Thompson