Sunny Payments Ruby SDK
The official Ruby SDK for Sunny Payments - Payment processing made simple.
Installation
gem install sunny-payments
Or add to your Gemfile:
gem 'sunny-payments', '~> 1.0'
Quick Start
require 'sunny'
# Initialize the client
sunny = Sunny::Client.new('sk_live_your_api_key')
# Create a payment (currency is REQUIRED)
payment = sunny.payments.create(
amount: 1000,
currency: 'KES', # Required - no default!
source: 'mpesa',
description: 'Order #12345'
)
puts payment['id'] # pay_xxxxx
Features
- ✅ Payments - Create, capture, refund payments
- ✅ Mobile Money - M-Pesa STK Push, B2C, MTN MoMo, Airtel Money
- ✅ Invoices - Create and send invoices
- ✅ Bills - Airtime, data, electricity payments
- ✅ QR Codes - Static and dynamic QR payments
- ✅ Crypto - Accept BTC, ETH, USDT, USDC
- ✅ Webhooks - Register endpoints & verify signatures
- ✅ BNPL - Buy Now Pay Later
Usage Examples
M-Pesa STK Push
result = sunny.mobile_money.mpesa_stk_push(
phone_number: '254712345678',
amount: 1000,
currency: 'KES', # Required
account_reference: 'ORDER-001'
)
# Check status
status = sunny.mobile_money.mpesa_status(result['checkout_request_id'])
Bills
# Purchase airtime
sunny.bills.purchase_airtime(
phone_number: '+254712345678',
amount: 100,
network: 'safaricom'
)
# Buy electricity tokens
electricity = sunny.bills.purchase_electricity(
meter_number: '12345678',
amount: 500,
phone_number: '+254712345678'
)
puts electricity['token'] # KPLC token
Crypto Payments
address = sunny.crypto.create_address(
cryptocurrency: 'USDT',
amount: 10000,
currency: 'KES' # Required
)
Webhooks
# Register webhook
webhook = sunny.webhooks.create(
url: 'https://example.com/webhooks/sunny',
events: ['payment.succeeded', 'payment.failed']
)
# In your Sinatra/Rails controller:
post '/webhooks/sunny' do
payload = request.body.read
signature = request.env['HTTP_X_SUNNY_SIGNATURE']
unless Sunny::Resources::Webhooks.verify_signature(payload, signature, WEBHOOK_SECRET)
halt 400, 'Invalid signature'
end
event = JSON.parse(payload)
case event['type']
when 'payment.succeeded'
# Handle successful payment
end
status 200
'OK'
end
Error Handling
begin
payment = sunny.payments.create(amount: 1000, currency: 'KES', source: 'mpesa')
rescue Sunny::AuthenticationError
puts "Invalid API key"
rescue Sunny::ValidationError => e
puts "Validation error: #{e.message}, field: #{e.field}"
rescue Sunny::RateLimitError => e
puts "Rate limited. Retry after #{e.retry_after} seconds"
rescue Sunny::APIError => e
puts "API error: #{e.message}"
end
Configuration
# Via environment variable
ENV['SUNNY_API_KEY'] = 'sk_live_xxx'
# Or configure directly
sunny = Sunny::Client.new('sk_live_xxx', {
base_url: 'https://api.sunnypay.co.ke/v1',
timeout: 30
})
License
MIT License - see LICENSE for details.