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.
Call the Dollr API from a Django service layer or view — never from templates with secrets. Uses requests (add to your project dependencies).
API Reference: Obtain token · Collect

Prerequisites

  • Django 4+ / 5+
  • pip install requests
  • Settings in settings.py (or environment):
DOLLR_BASE_URL = "https://api.heydollr.app"
DOLLR_CLIENT_ID = env("DOLLR_CLIENT_ID")
DOLLR_CLIENT_SECRET = env("DOLLR_CLIENT_SECRET")

Steps

1

Dollr client service

# myapp/services/dollr.py
import uuid
import requests
from django.conf import settings

class DollrClient:
    def __init__(self):
        self.base = settings.DOLLR_BASE_URL

    def token(self) -> str:
        r = requests.post(f"{self.base}/v1/jwt/client/obtain/token", json={
            "client_id": settings.DOLLR_CLIENT_ID,
            "client_secret": settings.DOLLR_CLIENT_SECRET,
        }, timeout=30)
        r.raise_for_status()
        return r.json()["access_token"]

    def headers(self):
        return {
            "Authorization": f"Bearer {self.token()}",
            "Content-Type": "application/json",
        }
Cache the token in Redis or memory with TTL — do not request a new token on every field in a form post.
2

Create invoice flow

client = DollrClient()
h = client.headers()

party = requests.post(f"{client.base}/v1/parties/create", headers=h, json={
    "fullname": "Amara Kamara", "phone": "231771234567",
    "country_code": "LR",
}, timeout=30).json()

cp = requests.post(f"{client.base}/v1/counterparties/create", headers=h, json={
    "relationship_type": "CUSTOMER", "party_id": party["id"],
}, timeout=30).json()

invoice = requests.post(f"{client.base}/v1/invoices/create", headers=h, json={
    "counterparty_id": cp["id"], "currency": "USD",
    "fee_bearer": "PAYER", "as_payment_link": True,
}, timeout=30).json()
3

Publish and collect

invoice_id = invoice["id"]
requests.post(f"{client.base}/v1/invoices/{invoice_id}/items/add", headers=h, json={
    "name": "Strategy Session", "currency": "USD", "qty": 1, "amount": 250.00,
}, timeout=30)
requests.put(f"{client.base}/v1/invoices/publish/{invoice_id}", headers=h, timeout=30)

reference_id = str(uuid.uuid4())
session = requests.post(f"{client.base}/v1/sessions/checkout", headers=h, json={
    "source_id": invoice_id, "source_type": "INVOICE",
}, timeout=30).json()

requests.post(f"{client.base}/v1/executions/collection", headers=h, json={
    "session_id": str(session["id"]),
    "payment_account_id": payment_account_id,
    "currency": "USD",
    "reference_id": reference_id,
}, timeout=30)
4

Poll status

status = requests.get(
    f"{client.base}/v1/status/collection/{reference_id}",
    headers=h, timeout=30,
).json()
Prefer a Celery task for polling MoMo PROCESSING states.

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