# flowglad-rs
A Rust client library for the [FlowGlad](https://flowglad.com) billing API.
[](https://crates.io/crates/flowglad)
[](https://docs.rs/flowglad)
[](LICENSE)
## Overview
FlowGlad is an open-source billing infrastructure platform. This library provides a type-safe, ergonomic Rust interface to the FlowGlad API, with support for:
- Customer management (create, retrieve, update, list)
- Billing details and subscription information
- Strongly-typed request/response models
- Automatic retries with exponential backoff
- Comprehensive error handling
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
flowglad = "0.1"
tokio = { version = "1", features = ["full"] }
```
## Quick Start
```rust
use flowglad::{Client, Config};
use flowglad::types::customer::CreateCustomer;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize the client
let config = Config::new("sk_test_your_api_key");
let client = Client::new(config)?;
// Create a customer
let customer = client
.customers()
.create(
CreateCustomer::new("user_123", "Jane Doe")
.email("jane@example.com")
)
.await?;
println!("Created customer: {}", customer.id);
// Retrieve the customer by external ID
let retrieved = client.customers().get("user_123").await?;
println!("Retrieved: {}", retrieved.name.unwrap_or_default());
Ok(())
}
```
## Configuration
### Basic Configuration
```rust
use flowglad::Config;
let config = Config::new("sk_test_your_api_key");
```
### Environment Variables
```rust
use flowglad::Config;
// Reads from FLOWGLAD_API_KEY environment variable
let config = Config::from_env()?;
```
### Advanced Configuration
```rust
use flowglad::Config;
use std::time::Duration;
let config = Config::builder()
.api_key("sk_test_your_api_key")
.timeout(Duration::from_secs(60))
.max_retries(5)
.build()?;
```
## Features
### Type Safety
The library uses Rust's type system to prevent common mistakes:
```rust
use flowglad::types::customer::CreateCustomer;
// Compile-time enforcement of required fields
let customer = CreateCustomer::new("external_id", "customer_name")
.email("optional@email.com")
.phone("+1-555-0123");
```
### Error Handling
Comprehensive error types for robust error handling:
```rust
use flowglad::Error;
match client.customers().get("user_123").await {
Ok(customer) => println!("Found: {}", customer.id),
Err(Error::Api { status, message, .. }) => {
eprintln!("API error {}: {}", status, message);
}
Err(Error::Network(e)) => {
eprintln!("Network error: {}", e);
}
Err(Error::RateLimit { retry_after }) => {
eprintln!("Rate limited. Retry after: {:?}", retry_after);
}
Err(e) => {
eprintln!("Error: {}", e);
}
}
```
### Automatic Retries
The client automatically retries failed requests with exponential backoff for:
- 500 Internal Server Error
- 502 Bad Gateway
- 503 Service Unavailable
- 504 Gateway Timeout
Configurable via `Config::builder().max_retries()`.
### Metadata Support
Store custom key-value data with any resource:
```rust
use serde_json::json;
let customer = client
.customers()
.create(
CreateCustomer::new("user_123", "Jane Doe")
.metadata("plan", json!("premium"))
.metadata("tier", json!(3))
.metadata("features", json!(["api_access", "sso"]))
)
.await?;
```
## Examples
The [`examples/`](examples/) directory contains comprehensive examples:
- [`basic_customers.rs`](examples/basic_customers.rs) - CRUD operations for customers
- [`customer_metadata.rs`](examples/customer_metadata.rs) - Working with metadata
- [`error_handling.rs`](examples/error_handling.rs) - Robust error handling patterns
Run an example with:
```bash
FLOWGLAD_API_KEY=sk_test_... cargo run --example basic_customers
```
## API Coverage
### Customers
- `client.customers().create()` - Create a new customer
- `client.customers().get()` - Retrieve a customer by external ID
- `client.customers().update()` - Update customer information
- `client.customers().list()` - List all customers
- `client.customers().get_billing()` - Get billing details for a customer
## Testing
### Running Tests
```bash
# Run unit tests
cargo test
# Run integration tests (requires API key)
FLOWGLAD_API_KEY=sk_test_... cargo test --test integration_tests
```
### Environment Setup
For local development, create a `.env` file:
```bash
cp .env.example .env
# Edit .env and add your test API key
```
Integration tests will automatically load environment variables from `.env` if it exists.
## Design Principles
### External ID vs Internal ID
The FlowGlad API uses your system's identifiers (external IDs) for most operations:
```rust
// Create with your ID
let customer = client.customers()
.create(CreateCustomer::new("user_123", "Jane"))
.await?;
// customer.id is FlowGlad's internal ID (e.g., "cus_abc")
// customer.external_id is your ID ("user_123")
// Use external_id for retrieval and updates
let customer = client.customers().get("user_123").await?;
```
### Builder Pattern
All create and update operations use the builder pattern for ergonomic, self-documenting code:
```rust
CreateCustomer::new("required_id", "required_name")
.email("optional@example.com") // Optional fields
.phone("+1-555-0123") // chain naturally
.metadata("key", json!("value"));
```
## Documentation
Full API documentation is available at [docs.rs/flowglad](https://docs.rs/flowglad).
Build documentation locally:
```bash
cargo doc --open
```
## Requirements
- Rust 1.70 or later
- Tokio runtime for async support
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Before submitting:
```bash
# Run tests
cargo test --all-targets
# Check formatting
cargo fmt --check
# Run clippy
cargo clippy --all-targets --all-features
```
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
- Documentation: [docs.rs/flowglad](https://docs.rs/flowglad)
- API Reference: [FlowGlad API Docs](https://docs.flowglad.com/api-reference)
- Issues: [GitHub Issues](https://github.com/yourusername/flowglad-rs/issues)
## Acknowledgments
Built for the [FlowGlad](https://flowglad.com) open-source billing platform.