To accept Paystack payments in Rails, create a PaymentsController that uses Net::HTTP or the httparty gem to call the Paystack API. Initialize a transaction, redirect the customer to Paystack checkout, and verify the payment in a callback action.
Add your Paystack key to Rails credentials or .env:
# .env
PAYSTACK_SECRET_KEY=sk_test_xxxxxxxxxxxxxxxxxxxxx
Add the dotenv gem if using .env:
# Gemfile
gem 'dotenv-rails', groups: [:development, :test]
# app/services/paystack_service.rb
require 'net/http'
require 'json'
class PaystackService
BASE_URL = 'https://api.paystack.co'
def initialize
@secret_key = ENV['PAYSTACK_SECRET_KEY']
end
def initialize_transaction(email:, amount_kobo:, reference:, callback_url:)
uri = URI(BASE_URL + '/transaction/initialize')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer ' + @secret_key
request['Content-Type'] = 'application/json'
request.body = {
email: email,
amount: amount_kobo,
reference: reference,
callback_url: callback_url
}.to_json
response = http.request(request)
JSON.parse(response.body)
end
def verify_transaction(reference)
uri = URI(BASE_URL + '/transaction/verify/' + reference)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer ' + @secret_key
response = http.request(request)
JSON.parse(response.body)
end
end
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
# app/controllers/payments_controller.rb
class PaymentsController < ApplicationController
def create
email = params[:email]
amount = params[:amount].to_f
reference = "order_#{SecureRandom.hex(6)}"
order = Order.create!(
email: email,
amount_kobo: (amount * 100).to_i,
reference: reference
)
service = PaystackService.new
result = service.initialize_transaction(
email: email,
amount_kobo: order.amount_kobo,
reference: reference,
callback_url: payment_callback_url
)
if result['status']
redirect_to result['data']['authorization_url'], allow_other_host: true
else
flash[:error] = result['message'] || 'Failed'
redirect_to checkout_path
end
end
def callback
reference = params[:reference] || params[:trxref]
unless reference
flash[:error] = 'Missing reference'
return redirect_to root_path
end
service = PaystackService.new
result = service.verify_transaction(reference)
if result['status'] && result['data']['status'] == 'success'
order = Order.find_by(reference: reference)
if order && result['data']['amount'] == order.amount_kobo
Order.where(reference: reference, paid: false).update_all(paid: true, paid_at: Time.current)
render :success
else
render :failed
end
else
render :failed
end
end
end
# config/routes.rb
Rails.application.routes.draw do
post '/pay', to: 'payments#create'
get '/payment/callback', to: 'payments#callback', as: :payment_callback
end
rails generate model Order reference:string:uniq email:string amount_kobo:integer currency:string paid:boolean paid_at:datetime
rails db:migrate
rails credentials:edit instead of .env in production.KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course