Skip to main content
Invoices vs orders: These guides walk through invoices (formal billing, line items, publish). The collect flow is the same for orders — use /v1/orders/* instead of /v1/invoices/* and set source_type: "ORDER" on the checkout session. See Orders and Parties & counterparties.Hosted checkout: To skip party, invoice, session, and execute steps entirely, see Hosted checkout.
End-to-end invoice collection with reqwest and serde_json (add to Cargo.toml).
API Reference: Obtain token · Collect

Prerequisites

[dependencies]
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
uuid = { version = "1", features = ["v4"] }
Load DOLLR_CLIENT_ID and DOLLR_CLIENT_SECRET from the environment (e.g. dotenvy).

Steps

1

Obtain token

const BASE: &str = "https://api.heydollr.app";

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let client = reqwest::Client::new();
    let token_res: serde_json::Value = client
        .post(format!("{BASE}/v1/jwt/client/obtain/token"))
        .json(&serde_json::json!({
            "client_id": std::env::var("DOLLR_CLIENT_ID").unwrap(),
            "client_secret": std::env::var("DOLLR_CLIENT_SECRET").unwrap(),
        }))
        .send()
        .await?
        .json()
        .await?;
    let bearer = token_res["access_token"].as_str().unwrap();
    Ok(())
}
2

Party → invoice

async fn post(
    client: &reqwest::Client,
    bearer: &str,
    path: &str,
    body: serde_json::Value,
) -> serde_json::Value {
    client
        .post(format!("{BASE}{path}"))
        .bearer_auth(bearer)
        .json(&body)
        .send()
        .await
        .unwrap()
        .json()
        .await
        .unwrap()
}
Create party, counterparty, invoice, line item, then PUT publish.
3

Execute

let reference_id = uuid::Uuid::new_v4().to_string();
post(client, bearer, "/v1/executions/collection", serde_json::json!({
    "session_id": session_id,
    "payment_account_id": payment_account_id,
    "currency": "USD",
    "reference_id": reference_id,
})).await;
4

Poll status

let status: serde_json::Value = client
    .get(format!("{BASE}/v1/status/collection/{reference_id}"))
    .bearer_auth(bearer)
    .send()
    .await?
    .json()
    .await?;

Try it yourself

Hosted checkout

Mobile money and card on a Dollr-hosted page — fastest path.

Orders

Same collect flow with source_type: ORDER and /v1/orders/*.

Direct checkout

One API call to create source — API-embedded flow.
Last modified on May 22, 2026