npm packages are not installable yet: [email protected] can be published after 2026-09-16 10:30 UTC. Details
Tollstile

Rails

How an agent pays, and what each payment protocol can do.

Public Beta · early access

A rail is how a payment is made and proven. It turns a price into an offer in its own asset, issues the protocol's challenge, verifies proofs, and settles, refunds, releases, and looks up charges through its provider.

Rails are not policies

A subscription is not a payment protocol, and x402 is not a pricing model. Rails decide how a payment is made; access policies decide whether a caller pays. See Access policies.

Capabilities

Rails genuinely differ. Each declares what it can do instead of pretending to be identical.

CapabilityMeaning
flowsWhich flows it supports
authorizationsingle or reusable proofs
variableAmountCan settle less than the authorized maximum
quotesCarries a signed quote through its protocol
refund · partialRefundCan return settled money
lookupCan ask its provider what happened to a charge — required

A rail without lookup is refused: without it, an unknown outcome could only be guessed.

Execution plan

Each route is compiled against your rails when you define it. Rails that cannot serve the route are left out, with the reason; a route no rail can serve is refused at startup.

const toll = createTollstile({
  rails: [x402({ ...x402Options, upto: { facilitatorAddress } }), mppStripe(stripeOptions)],
  ledger,
  secret,
});
const gate = toll.price(upTo("$1.00"));

console.log(toll.explain(gate));
Route upTo("$1.00")
  pricing: up_to, quote bound to: route
  access: everyone pays
  requirements: none
  rails:
    x402: authorization flow, settles after handler, single authorization, up-to amounts, release on handler failure
  excluded:
    mpp-stripe: needs the authorization flow. The rail supports: upfront.

gate.plan holds the same information as data, for tests and tooling.

When a provider is down

  • While issuing a challenge (a Lightning node cannot create an invoice), that rail is left out of the 402. If no rail can offer, the answer is 503 payment_unavailable.
  • While verifying, the request gets 503 and the handler does not run.
  • While settling or refunding, the charge becomes unknown and reconciliation asks the provider later.

Payer evidence

Some proofs must be kept to settle after a crash, such as a signed x402 payload. A rail keeps them in the authorization's data only until the charge is final, then redact drops them. Evidence never appears in logs, errors, events, or receipts.

Price and asset

A route is priced in a currency; a rail settles in an asset. The rail's offer states the asset, network, integer amount, and the basis of conversion — par for a USD stablecoin configured as USD, or rate for a merchant-supplied rate. Tollstile never converts currencies on its own.

Available rails

RailAuthorizationFlowsVerification status
Test railsingle or reusableauthorization, upfrontImplemented; local only
x402 exact · uptosingleauthorizationTested against a fake facilitator, a simulated chain, and @x402/core; not verified live
MPP Stripe chargesingleupfrontTested against an in-memory Stripe; not verified live
MPP Tempo chargesingleauthorization (push: paid at verification)Tested against a fake node; not verified live
MPP Tempo sessionreusableupfrontExperimental
L402reusableauthorizationTested against macaroon vectors and a fake LND; not verified live
KYAPayreusableauthorizationTested against a fake Skyfire; not verified live

On this page