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