Create product and price on stripe using ruby on rails

Umeriqbal
2 min readDec 4, 2023

--

image take form

here is how you can configure stripe in rails

Step 1:
create packages table

class CreatePackages < ActiveRecord::Migration[7.0]
def change
create_table :packages do |t|
t.string :name, default: ""
t.integer :price, default: 0
t.string :stripe_product_id
t.string :stripe_price_id
t.boolean :status, default: true

t.timestamps
end
end
end

Step 2:
we will create stripe product on after_create callback in package controller

class Package < ApplicationRecord
has_one_attached :avatar

validates :name, :price, presence: true
validates :avatar, content_type: { in: %w[image/png image/jpg image/jpeg image/webp], message: 'has not a valid image type' }

after_create :create_stripe_product
before_update :update_stripe_product

def update_stripe_product
if self.stripe_product_id.present?
if self.price != price_was
response = Stripe::Price.create(product: self.stripe_product_id, unit_amount: self.price*100, currency: 'usd')

Stripe::Product.update(self.stripe_product_id, {default_price: response["id"]})
Stripe::Price.update(self.stripe_price_id, {active: false}) #archive previous price
self.stripe_price_id = response["id"]
end

if self.name != name_was
images_array = self.avatar.present? ? [Rails.application.routes.url_helpers.rails_blob_url(self.avatar)] : [""]
Stripe::Product.update(self.stripe_product_id, { name: name, images: images_array })
end

Stripe::Product.update(self.stripe_product_id, { active: self.status }) if self.status != status_was
end
end


def create_stripe_product
image_link = self.avatar.present? ? [Rails.application.routes.url_helpers.rails_blob_url(self.avatar)] : [""]
response = Stripe::Product.create({
name: self.name,
images: image_link,
description: self.id,
default_price_data: {
unit_amount: (self.price)*100,
currency: 'usd'
}
})
self.update(stripe_product_id: response["id"], stripe_price_id: response["default_price"])
end
end

create_stripe_product callback will create product and a default price for that product (due to default_price_data attribute in product.create ) on stripe.

Edit product price
here is a little problem we can not edit stripe product, stripe not allow to edit price. So instead of edit price we will create new price and assign it to the specific product. like we did in update_stripe_product in after_update call back in this block

if self.price != price_was
response = Stripe::Price.create(product: self.stripe_product_id, unit_amount: self.price*100, currency: 'usd')

Stripe::Product.update(self.stripe_product_id, {default_price: response["id"]})
Stripe::Price.update(self.stripe_price_id, {active: false}) #archive previous price
self.stripe_price_id = response["id"]
end

here what we are doing is we are creating new price and add it in the specific product after that we archive the default price of the product that was already assign to the product by making active: false and then replace the stripe_price_id with the new price id in our local database to access it in future

--

--

Umeriqbal

I am a full stack software engineer specializing in Ruby on Rails, I have extensive experience in developing and deploying web applications.