litellm-ucashpay
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.
Install
pip install litellm-ucashpay
From source (editable):
git clone https://github.com/UdotCASH/litellm-ucashpay
cd litellm-ucashpay
pip install -e .
Quick start (Python)
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).
LiteLLM proxy usage (config.yaml)
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-master
Then 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.yaml
A full example config lives in examples/config.yaml.
How the cost is computed
- 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.
How U.CASH settlement works
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.
What this package does NOT do (honest limitations)
- 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.
Configuration reference
| 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. |
Tests
pip install -e ".[dev]"
pytest -q
Tests use respx to mock the U.CASH HTTP endpoints; no network is required.
Set up your pay.u.cash account
- 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.
Publish (maintainers only)
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).
License
MIT. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file litellm_ucashpay-0.1.0.tar.gz.
File metadata
- Download URL: litellm_ucashpay-0.1.0.tar.gz
- Upload date:
- Size: 11.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0acf4c7278a48dd0233178d1c76b78388d2ff12e2e5cee0d5ea57a1e6966ed0a
|
|
| MD5 |
4d1f113f573de098b3e83f0591d88da7
|
|
| BLAKE2b-256 |
5a208104a8023022a34cfc7edabade575863afcb4b01915b7c5385015a8f2cd4
|
File details
Details for the file litellm_ucashpay-0.1.0-py3-none-any.whl.
File metadata
- Download URL: litellm_ucashpay-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02bea4374282721c6fcda6a6c7cfc94fa9a5a4772c4f7552d73c8b2b110abea5
|
|
| MD5 |
6ed67ad9d6f5a0ba87f305764692c32a
|
|
| BLAKE2b-256 |
a3577ab6b176e0184d9e44dd185b6b3b0ecb2608dcfe38c1b86bb44b9fff1da3
|