Getting started

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):

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),
}
Note

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),
}
nomba-rust · unofficial Rust SDK API reference · Advanced features