Skip to main content
The Ruby SDK provides a simple and intuitive way to integrate Dodo Payments into your Ruby applications. It follows Ruby conventions and best practices, offering comprehensive error handling, pagination, and middleware support.

Installation

Add the gem to your Gemfile:
Gemfile
gem "dodopayments", "~> 1.53.4"
Then run:
bundle install
The SDK supports Ruby 3.2.0 and later versions, with comprehensive types, error handling, and retry mechanisms.

Quick Start

Initialize the client and create a checkout session:
require "bundler/setup"
require "dodopayments"

dodo_payments = Dodopayments::Client.new(
  bearer_token: ENV["DODO_PAYMENTS_API_KEY"], # This is the default and can be omitted
  environment: "test_mode" # defaults to "live_mode"
)

checkout_session_response = dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 1}]
)

puts(checkout_session_response.session_id)
Store your API keys securely using environment variables. Never commit them to version control or expose them in your code.

Core Features

Ruby Conventions

Follows Ruby naming conventions and idiomatic patterns

Elegant Syntax

Clean, readable API that feels natural to Ruby developers

Auto-Pagination

Built-in auto-paging iterators for list responses

Type Safety

Optional Sorbet types for enhanced type safety

Configuration

Timeout Configuration

Configure request timeouts:
# Configure default for all requests (default is 60 seconds)
dodo_payments = Dodopayments::Client.new(
  timeout: nil # disable timeout
)

# Or, configure per-request
dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 0}],
  request_options: {timeout: 5}
)

Retry Configuration

Configure automatic retry behavior:
# Configure default for all requests (default is 2)
dodo_payments = Dodopayments::Client.new(
  max_retries: 0 # disable retries
)

# Or, configure per-request
dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 0}],
  request_options: {max_retries: 5}
)

Common Operations

Create a Checkout Session

Generate a checkout session:
session = dodo_payments.checkout_sessions.create(
  product_cart: [
    {
      product_id: "prod_123",
      quantity: 1
    }
  ],
  return_url: "https://yourdomain.com/return"
)

# Redirect to checkout
redirect_to session.url

Manage Customers

Create and retrieve customer information:
# Create a customer
customer = dodo_payments.customers.create(
  email: "customer@example.com",
  name: "John Doe",
  metadata: {
    user_id: "12345"
  }
)

# Retrieve customer
customer = dodo_payments.customers.retrieve("cus_123")
puts "Customer: #{customer.name} (#{customer.email})"

Handle Subscriptions

Create and manage recurring subscriptions:
# Create a subscription
subscription = dodo_payments.subscriptions.create(
  customer_id: "cus_123",
  product_id: "prod_456",
  price_id: "price_789"
)

# Update subscription
updated = dodo_payments.subscriptions.update(
  subscription.id,
  metadata: { plan_type: "premium" }
)

# Cancel subscription
dodo_payments.subscriptions.cancel(subscription.id)

Pagination

Auto-Pagination

Automatically iterate through all pages:
page = dodo_payments.payments.list

# Fetch single item from page
payment = page.items[0]
puts(payment.brand_id)

# Automatically fetches more pages as needed
page.auto_paging_each do |payment|
  puts(payment.brand_id)
end

Manual Pagination

For more control over pagination:
page = dodo_payments.payments.list

if page.next_page?
  new_page = page.next_page
  puts(new_page.items[0].brand_id)
end

Error Handling

Handle various Dodo Payments API errors:
begin
  checkout_session = dodo_payments.checkout_sessions.create(
    product_cart: [{product_id: "product_id", quantity: 0}]
  )
rescue Dodopayments::Errors::APIConnectionError => e
  puts("The server could not be reached")
  puts(e.cause)  # an underlying Exception, likely raised within `net/http`
rescue Dodopayments::Errors::RateLimitError => e
  puts("A 429 status code was received; we should back off a bit.")
rescue Dodopayments::Errors::APIStatusError => e
  puts("Another non-200-range status code was received")
  puts(e.status)
end
Implement retry logic with exponential backoff for rate limit errors to ensure your application handles high-volume scenarios gracefully.

Type Safety with Sorbet

Use Sorbet for type-safe request parameters:
# Type-safe using Sorbet RBI definitions
dodo_payments.checkout_sessions.create(
  product_cart: [
    Dodopayments::CheckoutSessionRequest::ProductCart.new(
      product_id: "product_id",
      quantity: 0
    )
  ]
)

# Hashes work, but are not typesafe
dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 0}]
)

# You can also splat a full Params class
params = Dodopayments::CheckoutSessionCreateParams.new(
  product_cart: [
    Dodopayments::CheckoutSessionRequest::ProductCart.new(
      product_id: "product_id",
      quantity: 0
    )
  ]
)
dodo_payments.checkout_sessions.create(**params)

Advanced Usage

Undocumented Endpoints

Make requests to undocumented endpoints:
response = dodo_payments.request(
  method: :post,
  path: '/undocumented/endpoint',
  query: {"dog": "woof"},
  headers: {"useful-header": "interesting-value"},
  body: {"hello": "world"}
)

Undocumented Parameters

Send undocumented parameters:
checkout_session_response = dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 0}],
  request_options: {
    extra_query: {my_query_parameter: value},
    extra_body: {my_body_parameter: value},
    extra_headers: {"my-header": value}
  }
)

# Access undocumented response properties
puts(checkout_session_response[:my_undocumented_property])

Rails Integration

Create an Initializer

Create config/initializers/dodo_payments.rb:
require "dodopayments"

DODO_CLIENT = Dodopayments::Client.new(
  bearer_token: Rails.application.credentials.dodo_api_key,
  environment: Rails.env.production? ? "live_mode" : "test_mode"
)

Service Object Pattern

Create a payment service:
# app/services/payment_service.rb
class PaymentService
  def initialize
    @client = DODO_CLIENT
  end

  def create_checkout(items)
    @client.checkout_sessions.create(
      product_cart: items,
      return_url: Rails.application.routes.url_helpers.checkout_return_url
    )
  end

  def process_payment(amount:, currency:, customer_id:)
    @client.payments.create(
      amount: amount,
      currency: currency,
      customer_id: customer_id
    )
  end
end

Controller Integration

Use in your Rails controllers:
# app/controllers/checkouts_controller.rb
class CheckoutsController < ApplicationController
  def create
    service = PaymentService.new
    session = service.create_checkout(checkout_params[:items])
    
    redirect_to session.url, allow_other_host: true
  rescue Dodopayments::Errors::APIError => e
    flash[:error] = "Payment error: #{e.message}"
    redirect_to cart_path
  end

  private

  def checkout_params
    params.require(:checkout).permit(items: [:product_id, :quantity])
  end
end

Sinatra Integration

Use with Sinatra applications:
require "sinatra"
require "dodopayments"

configure do
  set :dodo_client, Dodopayments::Client.new(
    bearer_token: ENV["DODO_API_KEY"]
  )
end

post "/create-checkout" do
  content_type :json
  
  begin
    session = settings.dodo_client.checkout_sessions.create(
      product_cart: JSON.parse(request.body.read)["items"],
      return_url: "#{request.base_url}/return"
    )
    
    { checkout_url: session.url }.to_json
  rescue Dodopayments::Errors::APIError => e
    status 400
    { error: e.message }.to_json
  end
end

Resources

Support

Need help with the Ruby SDK?

Contributing

We welcome contributions! Check the contributing guidelines to get started.