Better Programming

Advice for programmers.

Follow publication

Integrating Stripe’s Product API Into Your Rails API

A hands-on guide on Stripe’s Product API Integration

Bruno Feres
Better Programming
Published in
5 min readApr 4, 2022

Getting Started

Stripe APIs have amazing features for e-commerces and marketplaces. To make our developer’s life easier, they offer SDK for some programming languages, including Ruby.

We will start adding the Stripe SDK Gem to our Gemfile using the following command:

gem 'stripe'

Don’t forget to run bundle install in your terminal after that.

Now you will need to create a stripe initializer file in your application. For that, run the command below in your terminal:

touch config/initializers/stripe.rb

Then, open the stripe.rb file and write the content below:

Stripe.api_key = Rails.application.credentials.stripe_secret_key

We didn’t add that Stripe’s Secret Key in our credential file, so let’s do this.

To open your credential file, run the following in your terminal:

EDITOR=nano rails credentials:edit

Get your Stripe Secret Key here.

Your credential file must look like this:

# aws:
# access_key_id: 123
# secret_access_key: 345
# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: [YOUR SECRET KEY BASE]
stripe_secret_key: [YOUR SECRET KEY HERE]

Note that the secret_key_base is autogenerated; you don’t need to edit.

The Product Logic

This section is about the product logic on our side, our API. It will consist of two models: Product and Price.

Board with Post-It

Our product model will have as many Prices related to it as the application needs. But why?

Let’s assume one of your products is an iPhone 13. As you may know, the iPhone 13 has a bunch of variants, including different colors and storage. We want to create a single Product record that represents the iPhone, and a Price record for each color variant.

The Product Code

Now we will code the Product based on the logic we saw above.

Run the following in your terminal:

rails g model Product name description:text stripe_id

Take a closer look at the Product attributes:

  • name will be a string that represents the name of the product;
  • description will be a string that represents a short text, describing the product;
  • stripe_id will be a string that represents a reference to our Product in the Stripe API.

Now, run:

rails g model Price title details:text amount_cents:integer product:references stripe_id

When we take a closer look at the Price attribute, we see the following:

  • title will be a string that represents the variant of the product we are selling; it could be "Green" for example
  • details will be a string that represents a short text, describing the product variant
  • amount_cents will be an integer that represents the value of the product in cents
  • product_id will be an integer that represents a reference to a Product
  • stripe_id will be a string that represents a reference to our Price in the Stripe API.

The product model

  • Validation to make sure that name and stripe_id attributes will be always present.
  • Validation to make sure that stripe_id will be unique in the database.
  • Setup for accepting nested attributes through the product JSON object on creating the endpoint.
  • Has Many associations with prices.
  • The "after" callbacks will be triggered when one of the record-handling actions is called. This is important to keep our stripe records up to date with our database.

The price model

  • Validation to make sure that title, stripe_id, and amount_cents attributes will be always present.
  • Belongs To association with a product.
  • The “after” callbacks will be triggered when one of the record-handling actions is called. This is important to keep our stripe records up to date with our database.

The products controller

Through this step, we will create a controller for products. The actions will be a simple CRUD.

Run in your terminal:

rails g controller Api::V1::Products index show create update destroy

With the controller created, you will need to edit it and make it look like this:

I will not describe this controller code once I consider you probably already know the logic of a Rails Controller. If you are not familiar, I encourage you to read this article.

The prices controller

Through this step, we will create a controller for prices. The actions will be a simple CRUD.

rails g controller Api::V1::Prices index show create update destroy

With the controller created, you will need to edit it and make it look like this:

Our controllers look awesome!!

The Routes

We will have to edit our routes.rb file now.

It must look like this:

Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :products, except: %i[new edit] do
resources :prices, only: %i[index create]
end
resources :prices, only: %i[show update destroy]
end
end
end

Basically, we are setting up CRUD routes for products and prices, but the price routes will be under a product namespace. That means that the format for prices endpoint will always be the following:

/api/v1/products/:product_id/prices

Testing Our API on an HTTP Client

To test our API, you need to raise your server, and run it on your terminal using the following command:

rails s

Creating the product

Method: POST | URL: http://localhost:3000/api/v1/products

Headers: { “Content-Type”: “application/json” }

Updating the product

Method: PUT | URL: http://localhost:3000/api/v1/products/1

{
"product": {
"name": "iPhone 13"
}
}

Listing all products

Method: GET | URL: http://localhost:3000/api/v1/products

Retrieving product

Method: GET | URL: http://localhost:3000/api/v1/products/1

Destroying product

Method: DELETE | URL: http://localhost:3000/api/v1/products/1

Creating price (for an existing product)

Method: POST | URL: http://localhost:3000/api/v1/products/1/prices

Headers: { “Content-Type”: “application/json” }

{
"price": {
"title": "Black - 128GB",
"details": "New Green Finish",
"amount_cents": 69900
}
}

Updating Price

Method: PUT | URL: http://localhost:3000/api/v1/prices/1

Headers: { “Content-Type”: “application/json” }

{
"price": {
"amount_cents": 59900
}
}

Retrieving price

Method: GET | URL: http://localhost:3000/api/v1/prices/1

Destroying price

Method: DELETE | URL: http://localhost:3000/api/v1/prices/1

Stripe makes the integration with their API pretty simple and easy with the SDK.

There are a lot of resources on Stripe API that were not explored during this article. I mean to publish other ones in the future, related to charges payment intent, and webhooks.

You can check the complete Stripe Docs here.

Want to Connect?If you have any questions or suggestions, text me on Twitter.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Bruno Feres
Bruno Feres

Written by Bruno Feres

Sr. Software Engineer, obsessed reader and silly jokes teller.

No responses yet

Write a response