# 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.
Connection listing is explicit about pagination: `connections().list(...)`
returns one page, `connections().list_page(...)` retains the server's
pagination metadata, and `connections().list_all(...)` fetches every matching
PSP connection.
## 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