Install, authenticate, request.
Three things you need from your Nomba dashboard: a client_id, a client_secret, and an account_id. The SDK handles the OAuth2 token exchange for you from there.
Install
cargo add nomba-rs
# or add to Cargo.toml:
# nomba-rs = "0.2"
# nomba-rs = { version = "0.2", features = ["async", "validation"] } # optional features
Feature flags
The SDK has three feature flags (all enabled by default except validation):
- blocking (default) — enables the synchronous
Nombaclient - async (default) — enables the asynchronous
AsyncNombaclient (requires Tokio) - validation — enables local request validation against the bundled OpenAPI spec
Sync client
Create one Nomba instance and reuse it; it manages its own HTTP connection pool and OAuth2 token cache.
use nomba_rs::{Nomba, NombaClientConfig};
fn main() -> nomba_rs::Result<()> {
let nomba = Nomba::new(
"your_client_id",
"your_client_secret",
"your_account_id",
)?;
// Or with custom config
let config = NombaClientConfig::new(
"client_id".into(),
"client_secret".into(),
"account_id".into(),
)
.sandbox(true)
.timeout(std::time::Duration::from_secs(60));
let account = nomba.virtual_accounts.create_virtual_account(
"acct-jane",
"Jane Doe",
None, None, None
)?;
println!("Account: {:?}", account.data.account_ref);
Ok(())
}
Async client
Rust async with Tokio — every resource method is an async function returning a Future.
use nomba_rs::AsyncNomba;
#[tokio::main]
async fn main() -> nomba_rs::Result<()> {
let nomba = AsyncNomba::new(
"your_client_id",
"your_client_secret",
"your_account_id",
).await?;
let account = nomba.virtual_accounts.create_virtual_account(
"acct-jane",
"Jane Doe",
None, None, None
).await?;
println!("Account: {:?}", account.data.account_ref);
Ok(())
}
Sandbox mode
Pass sandbox(true) in the config or use the convenience constructors:
let nomba = Nomba::new_sandbox("id", "secret", "account_id")?;
let async_nomba = AsyncNomba::new_sandbox("id", "secret", "account_id").await?;
Error handling
All errors are NombaError enum variants. Use match for exhaustive handling:
use nomba_rs::{NombaError, Result};
match nomba.virtual_accounts.create_virtual_account("ref", "Name", None, None, None) {
Ok(response) => println!("Success: {:?}", response),
Err(NombaError::Api { status_code, code, .. }) => {
eprintln!("API error: {} (status: {:?})", code.unwrap_or_default(), status_code);
}
Err(NombaError::Auth { .. }) => {
eprintln!("Authentication failed");
}
Err(NombaError::Validation { missing, .. }) => {
eprintln!("Validation failed: missing fields: {:?}", missing);
}
Err(e) => eprintln!("Error: {}", e),
}
NombaError::Validation is raised before any request goes out when the validation feature is enabled — it checks nested required fields against Nomba's own spec. See request validation.
Response shape
Every method returns a typed Result generated from Nomba's response schema, mirroring Nomba's actual JSON keys (camelCase, not snake_case):
let account = nomba.virtual_accounts.create_virtual_account(
"acct-jane", "Jane Doe", None, None, None
)?;
println!("{}", account.data.account_ref);
println!("{} {}", account.code, account.description);
Creating a checkout order
The checkout order body takes an order object with customer details and amount:
let order = nomba.checkout.create_order(
"order-001",
"1000",
"NGN",
"jane@example.com",
"Jane Doe",
"https://example.com/callback",
None, None
)?;
println!("Checkout link: {}", order.data.checkout_link);
Local request validation
With the validation feature, write calls (POST/PUT) are validated against Nomba's bundled OpenAPI spec before any network request:
use nomba_rs::{validate_body, NombaError};
use serde_json::json;
let body = json!({
"orderReference": "order-001",
"customerId": "cust-001",
"callbackUrl": "https://example.com/cb",
"customerEmail": "jane@example.com",
"amount": 1000,
"currency": "NGN",
"allowedPaymentMethods": ["CARD", "ACCOUNT_TRANSFER"],
});
match validate_body("post", "/v1/checkout/order", &body) {
Ok(_) => println!("Request is valid"),
Err(NombaError::Validation { missing, .. }) => {
eprintln!("Missing fields: {:?}", missing);
}
Err(e) => eprintln!("Error: {}", e),
}