A comprehensive Python SDK for the Blaaiz RaaS (Remittance as a Service) API
Project description
Blaaiz Python SDK
A comprehensive Python SDK for the Blaaiz RaaS (Remittance as a Service) API. This SDK provides easy-to-use methods for payment processing, collections, payouts, customer management, and more.
Installation
pip install blaaiz-python-sdk
Quick Start
from blaaiz import Blaaiz
# Initialize the SDK
blaaiz = Blaaiz('your-api-key-here', base_url='https://api-dev.blaaiz.com')
# Test the connection
is_connected = blaaiz.test_connection()
print(f'API Connected: {is_connected}')
Features
- Customer Management: Create, update, and manage customers with KYC verification
- Collections: Support for multiple collection methods (Open Banking, Card, Crypto, Bank Transfer)
- Payouts: Bank transfers and Interac payouts across multiple currencies
- Virtual Bank Accounts: Create and manage virtual accounts for NGN collections
- Wallets: Multi-currency wallet management
- Transactions: Transaction history and status tracking
- Webhooks: Webhook configuration and management with signature verification
- Files: Document upload with pre-signed URLs
- Fees: Real-time fee calculations and breakdowns
- Banks & Currencies: Access to supported banks and currencies
Supported Currencies & Methods
Collections
- CAD: Interac (push mechanism)
- NGN: Bank Transfer (VBA) and Card Payment
- USD: Card Payment
- EUR/GBP: Open Banking
Payouts
- Bank Transfer: All supported currencies
- Interac: CAD transactions
API Reference
Customer Management
Create a Customer
# Individual customer
customer = blaaiz.customers.create({
'first_name': "John", # Required for individual
'last_name': "Doe", # Required for individual
'type': "individual",
'email': "john.doe@example.com",
'country': "NG",
'id_type': "passport", # drivers_license, passport, id_card, resident_permit
'id_number': "A12345678",
})
# Business customer
business_customer = blaaiz.customers.create({
'type': "business",
'business_name': "Company Name", # Required for business
'email': "business@example.com",
'country': "NG",
'id_type': "certificate_of_incorporation",
'id_number': "RC123456",
})
print(f'Customer ID: {customer["data"]["data"]["id"]}')
Get Customer
customer = blaaiz.customers.get('customer-id')
print(f'Customer: {customer["data"]}')
List All Customers
customers = blaaiz.customers.list()
print(f'Customers: {customers["data"]}')
You can also pass optional filters and opt-in pagination. Supported filters
are email, id_number, registration_number, verification_status, and
type. Set paginate=True to receive a paginated response that includes
links and meta (with current_page, total, etc.) alongside data.
verified = blaaiz.customers.list({
"email": "john@example.com",
"verification_status": "VERIFIED",
"type": "individual",
"paginate": True,
})
print(f'Page: {verified["data"]["meta"]["current_page"]}')
print(f'Customers: {verified["data"]["data"]}')
Update Customer
updated_customer = blaaiz.customers.update('customer-id', {
'first_name': "Jane",
'email': "jane.doe@example.com"
})
List Customer Beneficiaries
beneficiaries = blaaiz.customers.list_beneficiaries('customer-id')
print(f'Beneficiaries: {beneficiaries["data"]}')
Get Specific Beneficiary
beneficiary = blaaiz.customers.get_beneficiary('customer-id', 'beneficiary-id')
print(f'Beneficiary: {beneficiary["data"]}')
### File Management & KYC
#### Upload Customer Documents
**Method 1: Complete File Upload (Recommended)**
```python
# Option A: Upload from bytes
with open('passport.jpg', 'rb') as f:
file_data = f.read()
result = blaaiz.customers.upload_file_complete('customer-id', {
'file': file_data,
'file_category': 'identity', # identity, proof_of_address, liveness_check
'filename': 'passport.jpg',
'content_type': 'image/jpeg'
})
# Option B: Upload from Base64 string
result = blaaiz.customers.upload_file_complete('customer-id', {
'file': 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
'file_category': 'identity'
})
# Option C: Upload from Data URL
result = blaaiz.customers.upload_file_complete('customer-id', {
'file': 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
'file_category': 'identity'
})
# Option D: Upload from Public URL
result = blaaiz.customers.upload_file_complete('customer-id', {
'file': 'https://example.com/documents/passport.jpg',
'file_category': 'identity'
})
print(f'Upload complete: {result["data"]}')
print(f'File ID: {result["file_id"]}')
Method 2: Manual 3-Step Process
# Step 1: Get pre-signed URL
presigned_url = blaaiz.files.get_presigned_url({
'customer_id': 'customer-id',
'file_category': 'identity'
})
# Step 2: Upload file to the pre-signed URL (implement your file upload logic)
# Step 3: Associate file with customer
file_association = blaaiz.customers.upload_files('customer-id', {
'id_file': presigned_url['data']['data']['file_id']
})
Collections
Initiate Open Banking Collection (EUR/GBP)
collection = blaaiz.collections.initiate({
'customer_id': "customer-id",
'wallet_id': "wallet-id",
'amount': 100.00,
'currency': "EUR", # or "GBP"
'method': "open_banking",
'phone': "+1234567890" # Optional
})
print(f'Payment URL: {collection["data"]["url"]}')
print(f'Transaction ID: {collection["data"]["transaction_id"]}')
Initiate Card Collection (NGN/USD)
collection = blaaiz.collections.initiate({
'customer_id': "customer-id",
'wallet_id': "wallet-id",
'amount': 5000,
'currency': "NGN", # or "USD"
'method': "card",
})
print(f'Payment URL: {collection["data"]["url"]}')
Crypto Collection
# Get available networks
networks = blaaiz.collections.get_crypto_networks()
print(f'Available networks: {networks["data"]}')
# Initiate crypto collection
crypto_collection = blaaiz.collections.initiate_crypto({
'amount': 100,
'network': "ethereum",
'token': "USDT",
'wallet_id': "wallet-id"
})
Attach Customer to Collection
attachment = blaaiz.collections.attach_customer({
'customer_id': "customer-id",
'transaction_id': "transaction-id"
})
Accept Interac Money Request (CAD)
result = blaaiz.collections.accept_interac_money_request({
'reference_number': "interac-reference-number"
})
Payouts
Bank Transfer Payout (NGN)
payout = blaaiz.payouts.initiate({
'wallet_id': "wallet-id",
'customer_id': "customer-id",
'method': "bank_transfer",
'from_amount': 1000, # OR use 'to_amount' for exact recipient amount
'from_currency_id': "NGN",
'to_currency_id': "NGN",
'bank_id': "1",
'account_number': "0123456789",
})
print(f'Payout Status: {payout["data"]["transaction"]["status"]}')
Bank Transfer Payout (GBP)
gbp_payout = blaaiz.payouts.initiate({
'wallet_id': "wallet-id",
'customer_id': "customer-id",
'method': "bank_transfer",
'from_amount': 500,
'from_currency_id': "GBP",
'to_currency_id': "GBP",
'sort_code': "12-34-56",
'account_number': "12345678",
'account_name': "John Doe",
})
Bank Transfer Payout (EUR)
eur_payout = blaaiz.payouts.initiate({
'wallet_id': "wallet-id",
'customer_id': "customer-id",
'method': "bank_transfer",
'from_amount': 500,
'from_currency_id': "EUR",
'to_currency_id': "EUR",
'iban': "DE89370400440532013000",
'bic_code': "COBADEFFXXX",
'account_name': "John Doe",
})
Interac Payout (CAD)
interac_payout = blaaiz.payouts.initiate({
'wallet_id': "wallet-id",
'customer_id': "customer-id",
'method': "interac",
'from_amount': 100,
'from_currency_id': "CAD",
'to_currency_id': "CAD",
'email': "recipient@example.com",
'interac_first_name': "John",
'interac_last_name': "Doe"
})
ACH Payout (USD)
ach_payout = blaaiz.payouts.initiate({
'wallet_id': "wallet-id",
'customer_id': "customer-id",
'method': "ach",
'from_amount': 1000,
'from_currency_id': "USD",
'to_currency_id': "USD",
'type': "individual", # or "business"
'account_number': "123456789",
'account_name': "John Doe",
'account_type': "checking", # or "savings"
'bank_name': "Chase Bank",
'routing_number': "021000021",
})
Wire Payout (USD)
wire_payout = blaaiz.payouts.initiate({
'wallet_id': "wallet-id",
'customer_id': "customer-id",
'method': "wire",
'from_amount': 5000,
'from_currency_id': "USD",
'to_currency_id': "USD",
'type': "individual",
'account_number': "123456789",
'account_name': "John Doe",
'account_type': "checking",
'bank_name': "Chase Bank",
'routing_number': "021000021",
'swift_code': "CHASUS33",
})
Crypto Payout (USD)
crypto_payout = blaaiz.payouts.initiate({
'wallet_id': "wallet-id",
'customer_id': "customer-id",
'method': "crypto",
'from_amount': 100,
'from_currency_id': "USD",
'to_currency_id': "USD",
'wallet_address': "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
'wallet_token': "USDT",
'wallet_network': "ethereum",
})
Virtual Bank Accounts
Create Virtual Bank Account
vba = blaaiz.virtual_bank_accounts.create({
'wallet_id': "wallet-id",
'account_name': "John Doe"
})
print(f'Account Number: {vba["data"]["account_number"]}')
print(f'Bank Name: {vba["data"]["bank_name"]}')
List Virtual Bank Accounts
# Filter by wallet ID
vbas = blaaiz.virtual_bank_accounts.list(wallet_id="wallet-id")
print(f'Virtual Accounts: {vbas["data"]}')
# Filter by customer ID
vbas = blaaiz.virtual_bank_accounts.list(customer_id="customer-id")
# Filter by both
vbas = blaaiz.virtual_bank_accounts.list(wallet_id="wallet-id", customer_id="customer-id")
Get Virtual Bank Account
vba = blaaiz.virtual_bank_accounts.get("vba-id")
print(f'Account Details: {vba["data"]}')
Close Virtual Bank Account
result = blaaiz.virtual_bank_accounts.close("vba-id", reason="No longer needed")
print(f'Closed: {result["data"]}')
Get Identification Type Requirements
# Using customer ID
id_types = blaaiz.virtual_bank_accounts.get_identification_type(customer_id="customer-id")
# Using country and type
id_types = blaaiz.virtual_bank_accounts.get_identification_type(country="US", type="individual")
print(f'Required ID Types: {id_types["data"]}')
Wallets
List All Wallets
wallets = blaaiz.wallets.list()
print(f'Wallets: {wallets["data"]}')
Get Specific Wallet
wallet = blaaiz.wallets.get("wallet-id")
print(f'Wallet Balance: {wallet["data"]["balance"]}')
Transactions
List Transactions
transactions = blaaiz.transactions.list({
'page': 1,
'limit': 10,
'status': "SUCCESSFUL" # Optional filter
})
print(f'Transactions: {transactions["data"]}')
Get Transaction Details
transaction = blaaiz.transactions.get("transaction-id")
print(f'Transaction: {transaction["data"]}')
Banks & Currencies
List Banks
banks = blaaiz.banks.list()
print(f'Available Banks: {banks["data"]}')
Bank Account Lookup
account_info = blaaiz.banks.lookup_account({
'account_number': "0123456789",
'bank_id': "1"
})
print(f'Account Name: {account_info["data"]["account_name"]}')
List Currencies
currencies = blaaiz.currencies.list()
print(f'Supported Currencies: {currencies["data"]}')
Fees
Get Fee Breakdown
# Calculate fees based on amount you want to send
fee_breakdown = blaaiz.fees.get_breakdown({
'from_currency_id': "NGN",
'to_currency_id': "CAD",
'from_amount': 100000
})
print(f'You send: {fee_breakdown["data"]["you_send"]}')
print(f'Recipient gets: {fee_breakdown["data"]["recipient_gets"]}')
print(f'Total fees: {fee_breakdown["data"]["total_fees"]}')
# OR calculate fees based on exact amount recipient should receive
fee_breakdown = blaaiz.fees.get_breakdown({
'from_currency_id': "NGN",
'to_currency_id': "CAD",
'to_amount': 500 # Recipient gets exactly 500 CAD
})
Webhooks
Register Webhooks
webhook = blaaiz.webhooks.register({
'collection_url': "https://your-domain.com/webhooks/collection",
'payout_url': "https://your-domain.com/webhooks/payout"
})
Get Webhook Configuration
webhook_config = blaaiz.webhooks.get()
print(f'Webhook URLs: {webhook_config["data"]}')
Replay Webhook
replay = blaaiz.webhooks.replay({
'transaction_id': "transaction-id"
})
Simulate Interac Webhook (Non-Production Only)
# Only available in non-production environments
result = blaaiz.webhooks.simulate_interac_webhook({
'amount': 100,
'collection_email': "sender@example.com"
})
Advanced Usage
Complete Payout Workflow
complete_payout_result = blaaiz.create_complete_payout({
'customer_data': {
'first_name': "John",
'last_name': "Doe",
'type': "individual",
'email': "john@example.com",
'country': "NG",
'id_type': "passport",
'id_number': "A12345678"
},
'payout_data': {
'wallet_id': "wallet-id",
'method': "bank_transfer",
'from_amount': 1000, # OR 'to_amount' for exact recipient amount
'from_currency_id': "NGN",
'to_currency_id': "NGN",
'bank_id': "1",
'account_number': "0123456789",
}
})
print(f'Customer ID: {complete_payout_result["customer_id"]}')
print(f'Payout: {complete_payout_result["payout"]}')
print(f'Fees: {complete_payout_result["fees"]}')
Complete Collection Workflow
complete_collection_result = blaaiz.create_complete_collection({
'customer_data': {
'first_name': "Jane",
'last_name': "Smith",
'type': "individual",
'email': "jane@example.com",
'country': "NG",
'id_type': "drivers_license",
'id_number': "ABC123456"
},
'collection_data': {
'method': "card",
'amount': 5000,
'currency': "NGN",
'wallet_id': "wallet-id"
},
'create_vba': True # Optionally create a virtual bank account
})
print(f'Customer ID: {complete_collection_result["customer_id"]}')
print(f'Collection: {complete_collection_result["collection"]}')
print(f'Virtual Account: {complete_collection_result["virtual_account"]}')
Context Manager Support
with Blaaiz('your-api-key') as blaaiz:
customers = blaaiz.customers.list()
print(f'Total customers: {len(customers["data"])}')
Error Handling
The SDK uses a custom BlaaizError class that provides detailed error information:
from blaaiz import Blaaiz, BlaaizError
try:
blaaiz = Blaaiz('your-api-key')
customer = blaaiz.customers.create(invalid_data)
except BlaaizError as e:
print(f'Blaaiz API Error: {e.message}')
print(f'Status Code: {e.status}')
print(f'Error Code: {e.code}')
except Exception as e:
print(f'Unexpected Error: {str(e)}')
Webhook Handling
Webhook Signature Verification
The SDK provides built-in webhook signature verification. Blaaiz uses HMAC-SHA256 to sign webhooks with the format timestamp.payload.
from blaaiz import Blaaiz
blaaiz = Blaaiz('your-api-key')
# Method 1: Verify signature manually
is_valid = blaaiz.webhooks.verify_signature(
raw_body, # Raw webhook payload string
signature, # x-blaaiz-signature header
timestamp, # x-blaaiz-timestamp header
webhook_secret # Your API secret key
)
if is_valid:
print('Webhook signature is valid')
else:
print('Invalid webhook signature')
# Method 2: Construct verified event (recommended)
try:
event = blaaiz.webhooks.construct_event(
payload, # Raw webhook payload string
signature, # x-blaaiz-signature header
timestamp, # x-blaaiz-timestamp header
webhook_secret # Your API secret key
)
print(f'Verified event: {event}')
# event['verified'] will be True
# event['timestamp'] will contain verification timestamp
except ValueError as e:
print(f'Webhook verification failed: {str(e)}')
Flask Webhook Handler Example
from flask import Flask, request, jsonify
from blaaiz import Blaaiz
import os
app = Flask(__name__)
blaaiz = Blaaiz(os.getenv('BLAAIZ_API_KEY'))
# Webhook secret (your API secret key)
WEBHOOK_SECRET = os.getenv('BLAAIZ_WEBHOOK_SECRET')
@app.route('/webhooks/collection', methods=['POST'])
def handle_collection_webhook():
signature = request.headers.get('x-blaaiz-signature')
timestamp = request.headers.get('x-blaaiz-timestamp')
payload = request.get_data(as_text=True)
try:
# Verify webhook signature and construct event
event = blaaiz.webhooks.construct_event(payload, signature, timestamp, WEBHOOK_SECRET)
print(f'Verified collection event: {event}')
# Process the collection
# Update your database, send notifications, etc.
return jsonify({'received': True}), 200
except ValueError as e:
print(f'Webhook verification failed: {str(e)}')
return jsonify({'error': 'Invalid signature'}), 400
@app.route('/webhooks/payout', methods=['POST'])
def handle_payout_webhook():
signature = request.headers.get('x-blaaiz-signature')
timestamp = request.headers.get('x-blaaiz-timestamp')
payload = request.get_data(as_text=True)
try:
# Verify webhook signature and construct event
event = blaaiz.webhooks.construct_event(payload, signature, timestamp, WEBHOOK_SECRET)
print(f'Verified payout event: {event}')
# Process the payout completion
# Update your database, send notifications, etc.
return jsonify({'received': True}), 200
except ValueError as e:
print(f'Webhook verification failed: {str(e)}')
return jsonify({'error': 'Invalid signature'}), 400
if __name__ == '__main__':
app.run(debug=True)
Environment Configuration
# Development
blaaiz_dev = Blaaiz('dev-api-key', base_url='https://api-dev.blaaiz.com')
# Production (when available)
blaaiz_prod = Blaaiz('prod-api-key', base_url='https://api.blaaiz.com')
Best Practices
- Always validate customer data before creating customers
- Use the fees API to calculate and display fees to users
- Always verify webhook signatures using the SDK's built-in methods
- Store customer IDs and transaction IDs for tracking
- Handle rate limiting gracefully with exponential backoff
- Use environment variables for API keys and webhook secrets
- Implement proper error handling and logging
- Test webhook endpoints thoroughly with signature verification
- Use the context manager for automatic resource cleanup
- Return appropriate HTTP status codes from webhook handlers
Development
To set up the development environment:
# Clone the repository
git clone https://github.com/blaaiz/blaaiz-python-sdk.git
cd blaaiz-python-sdk
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run linting
flake8 blaaiz/
black blaaiz/
# Run type checking
mypy blaaiz/
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run the test suite
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For support and additional documentation:
- Email: onboarding@blaaiz.com
- Documentation: https://docs.business.blaaiz.com
- Issues: https://github.com/blaaiz/blaaiz-python-sdk/issues
Changelog
1.1.0
- Customer Service:
- Added
list_beneficiaries()method to list customer beneficiaries - Added
get_beneficiary()method to get specific beneficiary - Updated
create()validation:first_name/last_namenow only required for individuals
- Added
- Collection Service:
- Added
accept_interac_money_request()method for CAD Interac transfers - Updated
initiate()required fields: now requirescustomer_idandcurrency
- Added
- Payout Service:
- Added
customer_idas required field - Added support for
to_amountas alternative tofrom_amount - Added currency-specific validation for bank transfers (NGN, GBP, EUR)
- Added ACH payout support (USD)
- Added Wire payout support (USD)
- Added Crypto payout support (USD)
- Added
- Virtual Bank Account Service:
- Added
close()method to close virtual bank accounts - Added
get_identification_type()method for ID type requirements - Updated
list()to supportcustomer_idfilter parameter
- Added
- Webhook Service:
- Added
simulate_interac_webhook()method (non-production only) - Updated
verify_signature()to use timestamp-based verification - Updated
construct_event()to require timestamp parameter
- Added
- Fees Service:
- Added support for
to_amountas alternative tofrom_amount
- Added support for
1.0.0
- Initial release
- Support for all Blaaiz API endpoints
- Comprehensive error handling
- Webhook signature verification
- File upload functionality
- Complete workflow helpers
- Context manager support
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file blaaiz_python_sdk-1.1.1.tar.gz.
File metadata
- Download URL: blaaiz_python_sdk-1.1.1.tar.gz
- Upload date:
- Size: 44.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b1db0971529c0cbf34c401b3f7de4a74fea75a6836934d2f13bc8db704108ae
|
|
| MD5 |
e6f4498149e7251b825ba997625bdc4b
|
|
| BLAKE2b-256 |
d6d1994dff2d7930629376cfc702471e80e47a0fcba94bdbe8a8d9f1fd7fa437
|
File details
Details for the file blaaiz_python_sdk-1.1.1-py3-none-any.whl.
File metadata
- Download URL: blaaiz_python_sdk-1.1.1-py3-none-any.whl
- Upload date:
- Size: 24.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32523d922cb6b7076b806a02d6ed23eb3ad33523dbe2ed59b0f06663f25a0bb8
|
|
| MD5 |
6dc4f3f5731f030993d2dc0e8fa96544
|
|
| BLAKE2b-256 |
f94b296a0e2cffb3700036fb84dd5764d40376ca81b7ecf3cb018ac525e17043
|