exact scheme is a fixed-price payment scheme. The seller advertises one amount, the buyer signs for that exact amount, and the facilitator settles that payment for the request.
Use exact when the final charge is known before the response is generated, such as a fixed-price API call, file download, or gated page.
Server Setup
- TypeScript
- Go
- Python
Upfront payment flow
By default,exact uses the authorization flow: the payment is verified before the resource handler runs and settled after. When your resource needs on-chain finality before execution — for example, a long-running handler on Solana where the signed transaction’s blockhash may expire before the handler finishes — you can opt in to the upfront flow instead.
With upfront, settlement happens before the handler runs. The facilitator’s /settle endpoint both validates and commits the payment; /verify is not called. The client signs the same payload as in authorization; only the server-side ordering changes.
To opt in, set paymentFlow: "upfront" in the route’s extra config:
- TypeScript
- Go
- Python
authorization flow remains the default. Clients prefer authorization when both flows are offered; the server signals the resolved flow to clients via extra.paymentFlow in the 402 response. See Payment flows for a comparison of all flows.
Client Setup
- TypeScript
- Go
- Python
Casper Setup
The Casper implementation uses CEP-3009 (transfer_with_authorization) — Casper’s adaptation of EIP-3009 for CEP-18 tokens. The client signs an off-chain EIP-712 authorization; the facilitator relays it on-chain and pays the gas.
Install the Casper package:
asset field is the 32-byte hex contract_package_hash of the CEP-18 token. The extra.name and extra.version fields are required — they are used to construct the CEP-3009 EIP-712 domain separator.
XRPL Setup
The XRPL implementation uses payer-signedPayment transactions. The payer pays the XRPL transaction fee; facilitator-sponsored fees are not supported.
Install the XRPL package:
extra.assetTransferMethod:
For
ticketSequence payments, the client automatically creates a ticket when none is available. To provision tickets explicitly:
Cardano Setup
The Cardano implementation uses a client-signed, facilitator-submitted model: the client builds and signs the complete transaction but never broadcasts it. The facilitator verifies and submits it after the resource handler runs. Install the Cardano package:Cardano asset transfer methods
The Cardano implementation supports three asset transfer methods viaextra.assetTransferMethod:
For testnet funds, get test ADA from the Cardano testnets faucet and preprod tUSDM from the tUSDM faucet.
Network Implementations
Theexact scheme has network specifications for EVM, SVM, AVM, Stellar, Aptos, Casper, Hedera, TON, Cardano, Keeta, Sui, Concordium, NEAR, and XRPL.
SVM Smart Wallet Support
By default, the SVM facilitator only accepts transactions from standard (EOA) wallets using static instruction-layout validation. To also accept payments from Solana smart wallets (Squads, Swig, SPL Governance, etc.), enable simulation-based verification when constructingExactSvmScheme on your facilitator:
- TypeScript
- Go
EnableSmartWalletVerification is enabled, transactions that fail static validation (because they contain smart wallet program instructions) are re-verified by simulating the transaction and inspecting CPI inner instructions for a valid TransferChecked. Only programs in the built-in allowlist (Squads Multisig v4, Squads Smart Account, Swig, SPL Governance, Metaplex Core, Lighthouse) can reach this path.
TypeScript:
toFacilitatorSvmSigner() is required when enabling smart wallet verification — it provides the simulateTransactionWithInnerInstructions, getConfirmedTransactionInnerInstructions, getTokenAccountBalance, and fetchAddressLookupTables methods needed for simulation-based verification.Go: Your signer must implement SmartWalletRPCCapabilities (i.e. SimulateTransactionWithInnerInstructions, GetConfirmedTransactionInnerInstructions, GetTokenAccountBalance, and FetchAddressLookupTables) — NewExactSvmScheme panics at startup if EnableSmartWalletVerification is true and the signer does not satisfy this interface.- TypeScript
- Go
EVM Transfer Methods
The EVM implementation supports two transfer methods:
Permit2 may require a one-time approval. The gas sponsoring extensions can let the facilitator handle that approval path for compatible tokens.
Examples
- TypeScript server example
- TypeScript upfront server example
- TypeScript client example
- Go server example
- Go upfront server example
- Go client example
- Python server example
- Python upfront server example
- Python client example
Specs
exactspecexactEVM specexactSVM specexactAVM specexactStellar specexactAptos specexactHedera specexactTON specexactKeeta specexactConcordium specexactCardano specexactCasper specexactSui specexactNEAR specexactXRPL spec