Skip to main content
The official billing.io SDK for Ruby 3.0+. Zero runtime dependencies — uses only the Ruby standard library.

RubyGems

billingio

GitHub

billingio/billingio-ruby

Installation

gem install billingio
Or add to your Gemfile:
gem "billingio"

Quick Start

require "billingio"

client = BillingIO::Client.new(api_key: "sk_live_...")

checkout = client.checkouts.create(
  amount_usd: 49.99,
  chain: "tron",
  token: "USDT",
  metadata: { order_id: "ord_12345" }
)

puts checkout.checkout_id
puts checkout.deposit_address

List with Pagination

Fetch a single page:
page = client.checkouts.list(limit: 10)

page.data.each do |checkout|
  puts "#{checkout.checkout_id} - #{checkout.status}"
end
Auto-paginate through all results (uses Enumerable):
client.checkouts.list.auto_paginate.each do |checkout|
  puts checkout.checkout_id
end

Get Checkout Status

status = client.checkouts.get_status("chk_abc123")

puts status.status                  # "confirming"
puts status.confirmations            # 8
puts status.required_confirmations   # 19

Webhook Signature Verification

Rails

class WebhooksController < ApplicationController
  skip_before_action :verify_authenticity_token

  def billing
    is_valid = BillingIO::WebhookSignature.verify(
      payload: request.raw_post,
      signature: request.headers["X-Billing-Signature"],
      secret: "whsec_..."
    )

    unless is_valid
      return head :unauthorized
    end

    event = JSON.parse(request.raw_post)
    # process event...
    head :ok
  end
end

Sinatra

post "/webhooks/billing" do
  payload = request.body.read

  unless BillingIO::WebhookSignature.verify(
    payload: payload,
    signature: request.env["HTTP_X_BILLING_SIGNATURE"],
    secret: "whsec_..."
  )
    halt 401, "Invalid signature"
  end

  event = JSON.parse(payload)
  # process event...
  status 200
end

Customers

customer = client.customers.create(
  email: "alice@example.com",
  name: "Alice Johnson",
  metadata: { plan: "pro" }
)

customer = client.customers.get("cus_abc123")
updated = client.customers.update("cus_abc123", name: "Alice Smith")

client.customers.list.auto_paginate.each do |c|
  puts "#{c.name} - #{c.email}"
end

Payment Methods

pm = client.payment_methods.create(
  chain: "tron",
  token: "USDT",
  display_name: "Primary USDT"
)

client.payment_methods.set_default("pm_abc123")

Subscriptions

plan = client.subscription_plans.create(
  name: "Pro Monthly",
  amount_usd: 29.99,
  interval: "monthly",
  token: "USDT",
  chain: "tron"
)

sub = client.subscriptions.create(
  customer_id: "cus_abc123",
  plan_id: plan.id,
  payment_method_id: "pm_abc123"
)

# Cancel
client.subscriptions.update("sub_abc123", status: "canceled")

# Renewals
client.subscription_renewals.list(subscription_id: "sub_abc123").auto_paginate.each do |r|
  puts "#{r.status} - #{r.amount_usd}"
end

Entitlements

ent = client.entitlements.create(
  plan_id: "plan_abc123",
  feature_key: "api_calls",
  value_type: "numeric",
  value_numeric: 10000
)

check = client.entitlements.check(customer_id: "cus_abc123", feature_key: "api_calls")
puts "#{check.has_access} - #{check.value}"

Payouts

payout = client.payout_intents.create(
  recipient_address: "TXyz...",
  chain: "tron",
  token: "USDT",
  amount: 500.00,
  currency: "USD"
)

client.payout_intents.execute("po_abc123", tx_hash: "0xabc...")

client.settlements.list.auto_paginate.each do |s|
  puts "#{s.tx_hash} - #{s.confirmed_at}"
end

Revenue

client.revenue_events.list.auto_paginate.each do |e|
  puts "#{e.event_type} - #{e.amount} #{e.currency}"
end

adj = client.adjustments.create(
  type: "credit",
  amount_usd: 10.00,
  description: "Loyalty discount",
  customer_id: "cus_abc123"
)

Error Handling

begin
  client.checkouts.create(amount_usd: -1, chain: "tron", token: "USDT")
rescue BillingIO::Error => e
  puts e.status   # 422
  puts e.code     # "validation_error"
  puts e.message  # "amount_usd must be positive"
end