examples/ledgerly in the payman-connect repo is Ledgerly: a bookkeeping product with a chat box, built on the SDK. Ask it to pay an invoice and a connect button appears in the conversation; consent happens on Payman’s pages, and the answer is already streaming when you land back. A payment over threshold freezes into an approval card and settles to “Payment sent”.
Ledgerly’s own agent is a real model with payman.tool() as its only tool (a labelled keyword stub fills in when no model key is set).
http://localhost:4321/payman/callback in the developer console; the app key is the whole configuration.
Against a local stack, point
PAYMAN_BASE_URL at it (.env.example already does). Otherwise the SDK talks to production, where the app self-read fails and the client throws on the first call.── PAYMAN, so the whole integration is one grep. examples/nextjs (port 3000) and examples/slack are the App Router and no-browser siblings.
Worth stealing
SameSite=Laxon the session cookie (sessions.mjs):Strictdrops it on the consent return, in production only.refuseRequestinserver.mjs: Host,Content-Type,Sec-Fetch-Site,Origin, checked before any route dispatches.- The prose before the connect button (
stub.mjs): bank access always gets a reason first. - The model-loop invariants: a round-trip cap and exactly one
tool_resultpertool_useinassistant.mjs, the rollback on a failed turn inserver.mjs. - What the page never holds: both keys stay server-side, and the browser talks only to this app’s origin.

