> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usezentra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rust SDK

> Official Zentra library for Rust applications

The Zentra Rust SDK provides convenient access to the Zentra API from Rust applications.

The reviewed public HTTP surface for this SDK is transfers, webhooks, virtual accounts, payments, and cards. Identity and other generated helpers may still exist for tenant-specific or draft use cases, but they are not the default reviewed public API path.

```bash theme={null}
cargo add zentra
```

## Configuration

Initialize the client with your API key:

```rust theme={null}
use zentra::Client;

let client = Client::new(&std::env::var("ZENTRA_SECRET_KEY")?, None);
```

## Resources

The SDK maps to reviewed API resources as follows:

* `client.payments()`: Payment processing
* `client.transfers()`: Bank transfers
* `client.virtual_accounts()`: Virtual bank accounts
* `client.cards()`: Card issuing
* `client.identity()`: KYC verification
* `client.webhooks()`: Webhook handling

## Examples

### Create Charge

```rust theme={null}
use serde_json::json;

let charge = client
    .payments()
    .charge(&json!({
        "amount_minor": 500000, // ₦5,000.00
        "currency": "NGN",
        "email": "user@example.com",
        "reference": "ORD_12345",
        "capture_mode": "customer_action_required"
    }))?;

let verified = client
    .payments()
    .verify(charge["reference"].as_str().unwrap())?;

println!("Status: {}", verified["status"]);
```

### Verify Webhook Signature

```rust theme={null}
use axum::{extract::Json, http::HeaderMap};

async fn webhook_handler(
    headers: HeaderMap,
    body: String,
) -> impl IntoResponse {
    let signature = headers
        .get("X-Zentra-Signature")
        .and_then(|v| v.to_str().ok());

    match signature {
        Some(sig) if client.webhooks().verify(&body, sig) => {
            // Process webhook
            (StatusCode::OK, "Verified")
        }
        _ => (StatusCode::BAD_REQUEST, "Invalid signature"),
    }
}
```

## Error Handling

The SDK returns `Result` types with typed errors:

```rust theme={null}
use zentra::error::ZentraError;

match client.payments().verify("INVALID_REF") {
    Ok(payment) => println!("Payment: {:?}", payment),
    Err(ZentraError::InvalidRequest(e)) => eprintln!("Bad request: {}", e),
    Err(ZentraError::Authentication(_)) => eprintln!("Check your API key"),
    Err(e) => eprintln!("API error: {}", e),
}
```

## Runtime

The current checked-in SDK uses `reqwest`'s blocking client:

```rust theme={null}
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new(&std::env::var("ZENTRA_SECRET_KEY")?, None);
    let transfer = client.transfers().get("TRF_12345")?;
    let payment = client.payments().verify("ORD_12345")?;

    println!("transfer={:?}, payment={:?}", transfer, payment);
    Ok(())
}
```

## Source Code

<CardGroup cols={2}>
  <Card title="GitHub Repo" icon="github" href="https://github.com/zentra/zentra-rust">
    View source code
  </Card>

  <Card title="crates.io" icon="rust" href="https://crates.io/crates/zentra">
    Download crate
  </Card>
</CardGroup>
