Bill LiteLLM LLM proxy calls via U.CASH pay-per-token. Non-custodial.
litellm-ucashpay is a LiteLLM custom logger/callback that, after every successful completion, computes the token cost in USD and mints a U.CASH checkout for that amount. Payers settle in crypto (or fiat cards via the merchant's own Stripe) directly to your U.CASH store. Funds never touch this package: it only mints payment links, so the integration is non-custodial end to end.
- Per-request billing keyed on a stable
external_reference, so retries never double-mint (idempotent checkout creation). - Two modes:
link(default, browser/app-safe): builds a hostedpay.u.cash/embed.phplink for the cost and attaches it to the response. No server secret needed.server(server route): callspay.u.cash/payment/ajax.phpto create a tracked, idempotent checkout and attaches the payment URL + transaction id.
- The store Cloud Token is publishable: it can mint checkouts that pay your store but cannot move funds. Safe to ship in proxy config and frontends.
- Falls back to a tiny rate card when LiteLLM's own cost calculation is unavailable, so there is always a number to bill.
pip install litellm-ucashpayFrom source (editable):
git clone https://github.com/UdotCASH/litellm-ucashpay
cd litellm-ucashpay
pip install -e .import litellm
from ucashpay_litellm import UCashPayLogger
# Register the U.CASH pay-per-token logger as a global LiteLLM callback.
litellm.callbacks = [UCashPayLogger(cloud_token="st_YOUR_STORE_CLOUD_TOKEN")]
resp = litellm.completion(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Say hello."}],
)
# The payment link + billed USD are attached to the response metadata.
meta = getattr(resp, "_hidden_params", {}) or {}
print("billed_usd:", meta.get("ucash_billed_usd"))
print("pay_link: ", meta.get("ucash_payment_url"))In server mode the callback also returns a tracked checkout:
from ucashpay_litellm import UCashPayLogger
logger = UCashPayLogger(cloud_token="st_YOUR_STORE_CLOUD_TOKEN", mode="server")The checkout is attached to the response as meta["ucash_checkout"] (a Checkout with payment_url, transaction_id, external_reference).
The LiteLLM proxy reads callbacks from litellm_settings.callbacks. Point it at the env-driven factory so no code edit is needed:
# config.yaml
model_list:
- model_name: gpt-4o
litellm_params:
model: openai/gpt-4o
api_key: os.environ/OPENAI_API_KEY
litellm_settings:
callbacks: ucashpay_litellm.config.logger_from_env
general_settings:
master_key: sk-litellm-masterThen set environment variables and run the proxy:
export UCASH_CLOUD_TOKEN="st_YOUR_STORE_CLOUD_TOKEN"
export OPENAI_API_KEY="sk-..."
# optional:
# UCASH_MODE=server # mint tracked checkouts server-side (default: link)
# UCASH_MARKUP_PCT=10 # add a 10% margin on top of cost
# UCASH_MIN_USD=0.05 # skip minting checkouts below 5 cents
# UCASH_CURRENCY=USD
# UCASH_TITLE_PREFIX="My App"
litellm --config config.yamlA full example config lives in examples/config.yaml.
- If LiteLLM already computed a cost (
response.costor the hiddenresponse_cost), that value is used as-is. This is the recommended path: it honors LiteLLM's provider pricing, caching discounts, and anylitellm_paramscost overrides. - Otherwise the package estimates from
usagetokens using a small fallback rate card (ucashpay_litellm.pricing.DEFAULT_RATES_PER_M). This is a safety net, not authoritative pricing. Override it withUCashPayLogger(..., rates={...})if you want your own card.
A configurable markup_pct lets you add margin on top of cost (e.g. markup_pct=10 for a 10% surcharge). Checkouts below min_usd (default $0.01) are skipped to avoid dust.
This package only mints checkouts. It never holds or moves funds.
- Client-side hosted pay link (
linkmode, default): buildsGET https://pay.u.cash/embed.phpwithcloud,amount,currency,title,external_reference,redirect. The payer is sent to the hosted U.CASH checkout and picks a coin there. - Server-side tracked checkout (
servermode): posts toPOST https://pay.u.cash/payment/ajax.phpwithfunction=create-transaction,amount,currency_code,cryptocurrency_code(empty string, so the payer chooses the coin at the hosted checkout),external_reference,title,redirect,cloud,idempotent=1. The response is{ "success": true, "response": [paymentUrl, transactionId, ...] }; the payment URL is the array element that starts withhttp(s)://. Creation is idempotent perexternal_reference, so retries return the same checkout rather than minting a duplicate.
Payers can settle in crypto, or by fiat card if the store connects its own Stripe processor in the U.CASH dashboard.
- It does not gate or block the LLM call. It records a payable checkout after the call succeeds. Use it where you surface the payment link to the end user (your app, your agent UI, your API response), or reconcile it server-side via
external_reference. - It does not automatically verify that a given request was paid before serving it. LiteLLM + U.CASH is a billing surface; gating access is your app's job (for example, by checking payment status against
external_referenceon your own backend before returning the response). - U.CASH checkouts are one-time, pay-per-call. There is no automatic recurring crypto subscription; per-call billing is the natural fit and that is what this package implements.
- The fallback rate card is a convenience. For production accuracy, rely on LiteLLM's cost calculation (default) or pass your own
rates.
| Option | Env var | Default | Description |
|---|---|---|---|
cloud_token |
UCASH_CLOUD_TOKEN |
(required) | Store Cloud Token. Publishable. |
mode |
UCASH_MODE |
link |
link (hosted URL) or server (tracked checkout). |
currency |
UCASH_CURRENCY |
USD |
Checkout currency. |
title_prefix |
UCASH_TITLE_PREFIX |
LLM |
Prefix for the checkout title. |
min_usd |
UCASH_MIN_USD |
0.01 |
Minimum USD to mint a checkout. |
markup_pct |
UCASH_MARKUP_PCT |
0.0 |
Percentage markup added to cost. |
pip install -e ".[dev]"
pytest -qTests use respx to mock the U.CASH HTTP endpoints; no network is required.
- Sign up at pay.u.cash, then click the verification link in the email.
- Set receive addresses under Settings -> Addresses (raw address, ENS, Unstoppable Domains, or FIO).
- Create a store under Account -> Stores and copy its Store Cloud Token (use the store-level token, not the account-wide one).
- For fiat cards, connect your own Stripe under Settings -> Payment processors.
This repo ships packaging files but does not auto-publish. To release to PyPI:
pip install build twine
python -m build
twine upload dist/*The first publish requires a PyPI API token scoped to the litellm-ucashpay project (or "All projects" for a brand-new project name).
MIT. See LICENSE.