reevit 0.1.0

Official Rust SDK for the Reevit payments API
Documentation
# Reevit Rust SDK

The official async Rust client for the [Reevit](https://reevit.io) payments API.

## Installation

```toml
[dependencies]
reevit = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```

## Quick start

Amounts use the smallest currency unit. For example, `5000` means GHS 50.00.

```rust,no_run
use reevit::{Client, PaymentIntentRequest, RequestOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::builder("pfk_test_xxx.secret", "org_123").build()?;

    let payment = client
        .payments()
        .create_intent(
            &PaymentIntentRequest {
                amount: 5_000,
                currency: "GHS".into(),
                method: Some("mobile_money".into()),
                country: "GH".into(),
                reference: Some("ORD-12345".into()),
                ..PaymentIntentRequest::default()
            },
            RequestOptions::default().idempotency_key("ORD-12345"),
        )
        .await?;

    println!("created payment {}", payment.id);
    Ok(())
}
```

The client sends `X-Reevit-Key` and `X-Org-Id` on every request, defaults to
`https://api.reevit.io`, and uses a 30-second timeout. Override the URL or timeout
through `Client::builder` for tests and specialized deployments.

## Server-created checkout sessions

Create a session on your server and pass only its `session_secret` to a Reevit
React, Vue, or Svelte checkout SDK.

```rust,no_run
# use reevit::{Client, PaymentIntentRequest, RequestOptions};
# async fn example(client: &Client) -> reevit::Result<()> {
let session = client
    .checkout_sessions()
    .create(
        &PaymentIntentRequest {
            amount: 5_000,
            currency: "GHS".into(),
            country: "GH".into(),
            ..PaymentIntentRequest::default()
        },
        RequestOptions::default().idempotency_key("ORD-12345"),
    )
    .await?;

println!("session secret: {}", session.session_secret);
# Ok(())
# }
```

## Webhook verification

Verify the exact bytes received from Reevit. Parsing and re-serializing JSON can
change whitespace or key order and invalidate a correct signature.

```rust
use reevit::verify_webhook_signature;

let raw_body = br#"{"id":"evt_123","type":"payment.succeeded"}"#;
let signature = "sha256=2f70e6b9d3f5f7dd-placeholder";

if verify_webhook_signature(raw_body, signature, "whsec_xxx") {
    // Process the verified event.
}
```

## Resource modules

- `client.payments()`
- `client.checkout_sessions()`
- `client.connections()`
- `client.subscriptions()`
- `client.fraud()`
- `client.customers()`
- `client.payment_links()`
- `client.webhooks()`
- `client.routing_rules()`
- `client.invoices()`

All mutating methods accept `RequestOptions`. Reuse the same idempotency key when
retrying the same logical mutation. The SDK does not automatically retry payment
mutations.

## Errors

`reevit::Error::Api` preserves the HTTP status, Reevit error code, details, and
request ID. `is_recoverable()` identifies transport failures and HTTP statuses
that may succeed when retried; callers still decide whether retrying a specific
operation is safe.

## Development

```bash
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
cargo test --doc
cargo publish --dry-run --locked
```

## License

MIT