langgraph-ucashpay
LangGraph nodes and LangChain tools to monetize individual graph steps via U.CASH (HTTP-402). Non-custodial: the only credential in flight is a publishable store Cloud token, and funds always settle directly to the merchant. This library never touches money.
Gate an expensive LLM call, a tool, or a whole subgraph behind a hosted U.CASH checkout link. The library exposes three layers of increasing convenience:
UcashPayClient- a thin client over the two pay.u.cash public pay endpoints (embed link + server-tracked checkout).build_ucashpay_node(...)/require_payment(...)- LangGraph nodes that inject a pay link into your graph state.ucashpay_tool(...)- a LangChainStructuredToolan agent can call to charge-and-return a link.
Install
pip install langgraph-ucashpay
# with the LangGraph / LangChain extras:
pip install "langgraph-ucashpay[langgraph]"
Python 3.9+. The only hard runtime dependency is httpx. LangGraph and LangChain are optional (installed via the [langgraph] extra) so the client is usable in any project.
Quick start
1. Client: build a publishable pay link
from langgraph_ucashpay import UcashPayClient
client = UcashPayClient.from_cloud(
"st_your_store_cloud_token", # publishable, safe in the browser/app
default_currency="USD",
default_title="Premium answer",
)
link = client.embed_url(
amount=0.05,
external_reference="order_123", # your idempotency / order id
)
print(link) # https://pay.u.cash/embed.php?cloud=st_...&amount=0.05&...
2. LangGraph: gate a step behind a checkout
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict
from langgraph_ucashpay import build_ucashpay_node
class State(TypedDict, total=False):
input: str
payment_url: str
payment_reference: str
payment_pending: bool
answer: str
def expensive_step(state: State) -> dict:
# only run if payment has been completed upstream
return {"answer": run_your_llm(state["input"])}
g = StateGraph(State)
g.add_node("bill", build_ucashpay_node(client, amount=0.05))
g.add_node("work", expensive_step)
g.add_edge(START, "bill")
# Branch: if payment is still pending, end with the pay link; else continue to work.
g.add_conditional_edges(
"bill",
lambda s: "work" if not s.get("payment_pending") else END,
{"work": "work", END: END},
)
g.add_edge("work", END)
graph = g.compile()
print(graph.invoke({"input": "Summarize the changelog."}))
By default the node builds the publishable embed link locally (no network call, fully non-custodial). Pass use_embed_link=False to instead POST to pay.u.cash and create a server-tracked, idempotent checkout from a server route:
bill = build_ucashpay_node(client, amount=0.05, use_embed_link=False)
3. LangChain: expose "charge and return a link" as a tool
from langgraph_ucashpay import ucashpay_tool
tool = ucashpay_tool(client, amount=0.05, name="ucash_pay")
# An agent can now call ucash_pay(reference="order_123", amount=0.05)
# and receive the hosted pay link to surface to the user.
4. Decorator: wrap any node
from langgraph_ucashpay import require_payment
@require_payment(client, amount=0.05)
def summarize(state):
return {"answer": run_your_llm(state["input"])}
How it maps to the pay.u.cash API
This package implements exactly two documented endpoints. It does not invent fields.
Client-side hosted pay link (publishable Cloud token, usable straight from the browser, no server secret):
GET https://pay.u.cash/embed.php
query: cloud, amount, currency (default USD), title,
external_reference, redirect
UcashPayClient.embed_url() and the default node mode produce this URL. Because the Cloud token is publishable, this URL is safe to render in a chat message, embed in a tool result, or ship to the browser.
Server-side tracked checkout (call from a server route; idempotent per external_reference):
POST https://pay.u.cash/payment/ajax.php
body (application/x-www-form-urlencoded):
function=create-transaction, amount, currency_code,
cryptocurrency_code= (empty string), external_reference, title,
redirect, cloud, idempotent=1
response JSON { success: true, response: [paymentUrl, transactionId, ...] }
-> the payment URL is the array element that starts with http(s)://
UcashPayClient.create_checkout() / create_checkout_async() and the node in use_embed_link=False mode call this. The client locates the payment URL by scanning the response array for the first element starting with http:// or https://.
Both clients also ship async variants (embed_url_async, create_checkout_async) for use in async servers and async LangGraph runtimes.
Non-custodial model and limitations
- Non-custodial. This library carries only the publishable store Cloud token. It never receives, holds, or moves funds. Settlement goes directly to the merchant's configured receive addresses.
- The Cloud token is publishable. It is safe to embed in the browser, in a rendered tool result, or in an LLM message. It is not an account secret.
- HTTP-402 framing, request-then-pay. A graph step produces a hosted pay link the caller opens; the caller pays on pay.u.cash; you reconcile via your own webhook or a status check before running the paid work. This is the U.CASH agent model.
- No automatic crypto recurring billing. pay.u.cash does not provide a hosted auto-charge API for recurring crypto payments. For recurring revenue, treat each graph run as a discrete, idempotent checkout keyed on
external_referenceand re-gate per invocation. This package does not attempt to fake recurring billing. - Payment confirmation is out of scope for this client. pay.u.cash notifies you via webhook of completion. Configure your webhook (see your pay.u.cash store settings) and flip your state's
payment_pendingflag when the webhook confirmsexternal_reference. The example graph above shows the branch pattern; the webhook handler is yours to wire.
Examples
See examples/gated_graph.py for a runnable end-to-end gating demo:
UCASH_CLOUD_TOKEN=st_your_store_token python examples/gated_graph.py
Publish
This repository ships the packaging files; publishing is left to the maintainer. To build and publish to PyPI:
python -m pip install --upgrade build twine
python -m build
python -m twine upload dist/*
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.
License
MIT, see LICENSE.
Metadata
Release files for langgraph-ucashpay 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| langgraph_ucashpay-0.1.0.tar.gz | 15.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| langgraph_ucashpay-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.0 kB
Release files / langgraph_ucashpay-0.1.0.tar.gz
| Download URL | langgraph_ucashpay-0.1.0.tar.gz |
|---|---|
| Size | 15.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fb916b7269293bb24a6d27080ef35eb1cf339be043b7419e96f54fd18bb82901
|
|
BLAKE2b-256 checksum How to use checksums |
5c6212eef4464cb1413c0e41211f6f50d9122ad9e425436720464d4742b9ce21
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|
Release files / langgraph_ucashpay-0.1.0-py3-none-any.whl
| Download URL | langgraph_ucashpay-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b1b88fa5497e3b250f5bc2065a69ed5cc5c408cf617ec1330b6d57f92eea87c7
|
|
BLAKE2b-256 checksum How to use checksums |
568ce2bda38d79ebd1275df1048135f683ece013650ae196d58f3165d8853571
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|