# Terminal
rails g scaffold product title 'value:decimal{8,2}'
rails g mannequin order session_id stripe_checkout_id standing:integer
rails g controller checkouts
rails g controller funds
bundle add stripe
bin/rails credentials:edit
rails g stimulus stripe
# credentials stripe: publishable_key: pk_test_XXX secret_key: sk_test_XXX
# db/migrate/20231001004208_create_orders.rb
class CreateOrders < ActiveRecord::Migration[7.1]
def change
create_table :orders do |t|
t.string :session_id
t.string :stripe_checkout_id
t.integer :standing, default: 0
t.timestamps
finish
finish
finish
# app/fashions/order.rb
class Order < ApplicationRecord
enum standing: {
pending: 0,
paid: 1
}
finish
# config/routes.rb assets :merchandise useful resource :checkout, solely: :present useful resource :funds, solely: :present
# app/views/merchandise/index.html.erb <td><%= link_to "Buy", checkout_path(id: product) %></td>
# config/initializers/stripe.rb Stripe.api_key = Rails.software.credentials.dig(:stripe, :secret_key) Stripe.api_version = "2023-08-16;embedded_checkout_beta=v2"
# app/views/layouts/software.html.erb <%= javascript_include_tag "https://js.stripe.com/v3/", "data-turbo-track": "reload" %>
# app/controllers/checkouts_controller.rb
class CheckoutsController < ApplicationController
def present
@session = Stripe::Checkout::Session.create(
line_items: [{
price_data: {
currency: "usd",
product_data: {
name: product.name
},
unit_amount: (product.price * 100).to_i
},
quantity: 1
}],
mode: "fee",
ui_mode: "embedded",
return_url: CGI.unescape(payments_url(session_id: '{CHECKOUT_SESSION_ID}'))
)
Order.create(session_id: session.id, stripe_checkout_id: @session.id)
# current_user.orders.create(stripe_checkout_id: @session.id)
finish
non-public
def product
@product ||= Product.discover(params[:id])
finish
finish
# app/views/checkouts/present.html.erb <div data-controller="stripe" data-stripe-public-key-value="<%= Rails.software.credentials.dig(:stripe, :publishable_key) %>" data-stripe-client-secret-value="<%= @session.client_secret %>"> </div>
# app/javascript/controllers/stripe_controller.js
import { Controller } from "@hotwired/stimulus"
// Connects to data-controller="stripe"
export default class extends Controller {
static values = { publicKey: String, clientSecret: String }
stripe = Stripe(this.publicKeyValue, { betas: ["embedded_checkout_beta_1"] })
async join() {
this.checkout = await this.stripe.initEmbeddedCheckout({
clientSecret: this.clientSecretValue
})
this.checkout.mount(this.component)
}
disconnect() {
this.checkout.destroy()
}
}
# app/controllers/payments_controller.rb
class PaymentsController < ApplicationController
def present
@order = Order.find_by(
session_id: session.id.to_s,
stripe_checkout_id: params[:session_id]
)
stripe_session = Stripe::Checkout::Session.retrieve(params[:session_id])
if stripe_session.standing == "full"
@order.paid!
# Different enterprise logic
# elsif stripe_session.standing == "open"
else
@order.pending!
finish
finish
finish
# app/views/funds/present.html.erb <h1>Profitable Fee</h1> <%= @order.examine %>

