Zai Payment Ruby Library
A lightweight and extensible Ruby client for the Zai (AssemblyPay) API โ starting with secure OAuth2 authentication, and ready for Payments, Virtual Accounts, Webhooks, and more.
โจ Features
- ๐ OAuth2 Authentication - Client Credentials flow with automatic token management
- ๐ง Smart Token Caching - Auto-refresh before expiration, thread-safe storage
- ๐ฅ User Management - Create and manage payin (buyers) & payout (sellers) users
- ๐ฆ Item Management - Full CRUD for transactions/payments between buyers and sellers
- ๐ซ Token Auth - Generate secure tokens for bank and card account data collection
- ๐ช Webhooks - Full CRUD + secure signature verification (HMAC SHA256)
- โ๏ธ Environment-Aware - Seamless Pre-live / Production switching
- ๐งฑ Modular & Extensible - Clean resource-based architecture
- ๐งฐ Zero Heavy Dependencies - Lightweight, fast, and reliable
- ๐ฆ Production Ready - 88%+ test coverage, RuboCop compliant
๐งญ Installation
Add this line to your Gemfile:
gem 'zai_payment'Then install
bundle installโ๏ธ Configuration
# config/initializers/zai_payment.rb
ZaiPayment.configure do |c|
c.environment = Rails.env.production? ? :production : :prelive
c.client_id = ENV.fetch("ZAI_CLIENT_ID")
c.client_secret = ENV.fetch("ZAI_CLIENT_SECRET")
c.scope = ENV.fetch("ZAI_OAUTH_SCOPE")
# Optional: Configure timeout settings (defaults shown)
c.timeout = 30 # General request timeout in seconds
c.open_timeout = 10 # Connection open timeout in seconds
c.read_timeout = 30 # Read timeout in seconds
end๐ Quick Start
Authentication
Get an OAuth2 token with automatic caching and refresh:
# Simple one-liner (recommended)
token = ZaiPayment.token
# Or with full control (advanced)
config = ZaiPayment::Config.new
config.environment = :prelive
config.client_id = 'your_client_id'
config.client_secret = 'your_client_secret'
config.scope = 'your_scope'
token_provider = ZaiPayment::Auth::TokenProvider.new(config: config)
token = token_provider.bearer_tokenThe gem handles OAuth2 Client Credentials flow automatically - tokens are cached and refreshed before expiration.
๐ Complete Authentication Guide - Two approaches, examples, and best practices
Users
Manage payin (buyer) and payout (seller/merchant) users:
# Create a payin user (buyer)
response = ZaiPayment.users.create(
user_type: 'payin',
email: 'buyer@example.com',
first_name: 'John',
last_name: 'Doe',
country: 'USA',
mobile: '+1234567890'
)
# Create a payout user (seller/merchant)
response = ZaiPayment.users.create(
user_type: 'payout',
email: 'seller@example.com',
first_name: 'Jane',
last_name: 'Smith',
country: 'AUS',
dob: '01/01/1990',
address_line1: '456 Market St',
city: 'Sydney',
state: 'NSW',
zip: '2000'
)
# Create a business user with company details
response = ZaiPayment.users.create(
user_type: 'payout',
email: 'director@company.com',
first_name: 'John',
last_name: 'Director',
country: 'AUS',
mobile: '+61412345678',
authorized_signer_title: 'Director',
company: {
name: 'My Company',
legal_name: 'My Company Pty Ltd',
tax_number: '123456789',
business_email: 'admin@company.com',
country: 'AUS',
charge_tax: true
}
)
# List users
response = ZaiPayment.users.list(limit: 10, offset: 0)
# Get user details
response = ZaiPayment.users.show('user_id')
# Update user
response = ZaiPayment.users.update('user_id', mobile: '+9876543210')
# Show user wallet account
response = ZaiPayment.users.wallet_account('user_id')
# List user items with pagination
response = ZaiPayment.users.items('user_id', limit: 50, offset: 10)
# Set user disbursement account
response = ZaiPayment.users.set_disbursement_account('user_id', 'bank_account_id')
# Show user bank account
response = ZaiPayment.users.bank_account('user_id')
# Verify user (prelive only)
response = ZaiPayment.users.verify('user_id')
# Show user card account
response = ZaiPayment.users.card_account('user_id')
# List user's BPay accounts
response = ZaiPayment.users.bpay_accounts('user_id')๐ Documentation:
- ๐ User Management Guide - Complete guide for payin and payout users
- ๐ก User Examples - Real-world usage patterns and Rails integration
- ๐ Zai: Onboarding a Payin User
- ๐ Zai: Onboarding a Payout User
Items
Manage transactions/payments between buyers and sellers:
# Create an item
response = ZaiPayment.items.create(
name: "Product Purchase",
amount: 10000, # Amount in cents ($100.00)
payment_type: 2, # Credit card
buyer_id: "buyer-123",
seller_id: "seller-456",
description: "Purchase of premium product",
currency: "AUD",
tax_invoice: true
)
# List items
response = ZaiPayment.items.list(limit: 20, offset: 0)
# Get item details
response = ZaiPayment.items.show('item_id')
# Update item
response = ZaiPayment.items.update('item_id', name: 'Updated Name')
# Get item status
response = ZaiPayment.items.show_status('item_id')
# Get buyer/seller details
response = ZaiPayment.items.show_buyer('item_id')
response = ZaiPayment.items.show_seller('item_id')
# List transactions
response = ZaiPayment.items.list_transactions('item_id')๐ Documentation:
- ๐ Item Management Guide - Complete guide for creating and managing items
- ๐ก Item Examples - Real-world usage patterns and complete workflows
- ๐ Zai: Items API Reference
Token Auth
Generate secure tokens for collecting bank and card account information:
# Generate a bank token (for collecting bank account details)
response = ZaiPayment.token_auths.generate(
user_id: "seller-68611249",
token_type: "bank"
)
token = response.data['token_auth']['token']
# Use this token with PromisePay.js on the frontend
# Generate a card token (for collecting credit card details)
response = ZaiPayment.token_auths.generate(
user_id: "buyer-12345",
token_type: "card"
)
token = response.data['token_auth']['token']
# Use this token with PromisePay.js on the frontend๐ Documentation:
- ๐ก Token Auth Examples - Complete integration guide with PromisePay.js
- ๐ Zai: Generate Token API Reference
Webhooks
Manage webhook endpoints:
# List webhooks
response = ZaiPayment.webhooks.list
webhooks = response.data
# Create a webhook
response = ZaiPayment.webhooks.create(
url: 'https://example.com/webhooks/zai',
object_type: 'transactions',
enabled: true
)
# Secure your webhooks with signature verification
secret_key = SecureRandom.alphanumeric(32)
ZaiPayment.webhooks.create_secret_key(secret_key: secret_key)๐ Documentation:
- ๐ Webhook Examples & Complete Guide - Full CRUD operations and patterns
- ๐ Security Quick Start - 5-minute webhook security setup
- ๐๏ธ Architecture & Implementation - Detailed technical documentation
- ๐ Signature Verification Details - Security implementation specs
Error Handling
The gem provides specific error classes for different scenarios:
begin
response = ZaiPayment.webhooks.create(
url: 'https://example.com/webhook',
object_type: 'transactions'
)
rescue ZaiPayment::Errors::ValidationError => e
# Handle validation errors (400, 422)
puts "Validation error: #{e.message}"
rescue ZaiPayment::Errors::UnauthorizedError => e
# Handle authentication errors (401)
puts "Authentication failed: #{e.message}"
rescue ZaiPayment::Errors::NotFoundError => e
# Handle not found errors (404)
puts "Resource not found: #{e.message}"
rescue ZaiPayment::Errors::ApiError => e
# Handle other API errors
puts "API error: #{e.message}"
end๐งฉ Roadmap
| Area | Description | Status |
|---|---|---|
| โ Authentication | OAuth2 Client Credentials flow | Done |
| โ Webhooks | CRUD for webhook endpoints | Done |
| โ Users | Manage PayIn / PayOut users | Done |
| โ Items | Transactions/payments (CRUD) | Done |
| โ Token Auth | Generate bank/card tokens | Done |
| ๐ณ Payments | Single and recurring payments | ๐ง In progress |
| ๐ฆ Virtual Accounts (VA / PIPU) | Manage virtual accounts & PayTo | โณ Planned |
| ๐ผ Wallets | Create and manage wallet accounts | โณ Planned |
๐งช Development
After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install.
Running Tests
bundle exec rspecCode Quality
This project uses RuboCop for linting. Run it with:
bundle exec rubocopInteractive Console
For development and testing, use the interactive console:
bin/consoleThis will load the gem and all its dependencies, allowing you to experiment with the API in a REPL environment.
๐งพ Versioning
This gem follows Semantic Versioning.
See changelog.md for release history.
๐ค Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/Sentia/zai-payment. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
๐ชช License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the ZaiPayment project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
๐ Documentation
Getting Started
- Authentication Guide - Two approaches to getting tokens, automatic management
- User Management Guide - Managing payin and payout users
- Item Management Guide - Creating and managing transactions/payments
- Webhook Examples - Complete webhook usage guide
- Documentation Index - Full documentation navigation
Examples & Patterns
- User Examples - Real-world user management patterns
- Item Examples - Transaction and payment workflows
- Token Auth Examples - Secure token generation and integration
- Webhook Examples - Webhook integration patterns
Technical Guides
- Webhook Architecture - Technical implementation details
- Architecture Overview - System architecture and design
Security
- Webhook Security Quick Start - 5-minute setup guide
- Signature Verification - Implementation details