Skip to main content
What you’ll be able to do
  • Obtain the sender’s signed authorization for a one-time payment.
  • Collect the payment by submitting that authorization from the recipient’s account.
  • Accept an agent’s payment for an HTTP resource through a facilitator.
  • Verify settlement before completing delivery and recover uncertain outcomes.
An authorized payment lets a sender sign a transfer authorization while another account submits the transaction. The submitting signing account pays the transaction fee from its balance in the gas token. The authorization fixes one recipient and amount and can be used once within its validity window. An agent authorized to sign for the sender can use this flow to pay for an HTTP resource through a facilitator. A merchant can also collect a customer’s signed payment directly. In both cases, the sender can pay without holding the gas token. Choose the path that matches who submits the payment: The recipient receives the payment in both paths. In the API flow, the seller operates the HTTP service, the agent signs for the sender and the facilitator submits settlement. The sender signs ReceiveWithAuthorization for recipient-submitted collection and TransferWithAuthorization for ordinary facilitator submission. Those types have different signing digests, so their signatures cannot be substituted. The first procedure collects from the recipient’s account. For the HTTP workflow, go to Use a facilitator. An agent authorized through a mandate uses the account-specific pull path, described in Pay under spending limits.

Prepare the payment

Use senderWallet to authorize the payment and recipientWallet to submit it. The sender supplies the payment tokens, and the recipient pays gas. Install the public dependencies with pnpm add @metalntwx/metal-ts@0.3.2 viem@2.57.7. Resolve the trusted token and its name and decimals using Read metadata. Convert the order’s decimal amount to the positive base-unit amount using Convert a payment amount. Check the sender’s spendable balance before requesting a signature. Check the current deployment and the credit from sender to recipient with Receive policy. The documented screening and quarantine behavior requires compatible deployed token and ReceivePolicy code. Stop if that prerequisite is missing. Save an immutable order record containing the chain ID, token, sender, recipient, amount and the application order ID. An authorization nonce is a random 32-byte value, separate from the submitter’s transaction nonce.
The timestamp window is strict: validAfter < block.timestamp < validBefore. Wait for chain time to advance beyond validAfter before simulation. Choose a window that allows the sender to review the payment and the recipient to submit it. If it expires before submission, close that attempt before requesting a new authorization.

Obtain and check the signature

Have the sender or its authorized agent check the chain ID, token, recipient, amount and expiry against the approved order. The wallet client signs the complete authorization using the sender’s signing account and the token’s EIP-712 domain.
This verification uses a sender account controlled by a private key. For signatures validated through ERC-1271, simulate the token call so it checks the signature against the sender’s code. See the authorization signature rules. Store the exact authorization and signature with the order before submitting.

Submit from the recipient

Only authorization.to can call receiveWithAuthorization. The outer transaction must therefore be signed for the recipient’s account. An agent collecting on the recipient’s behalf must be authorized to sign for that account. A relayer cannot submit this variant for an ordinary recipient account.
Estimate this call and check the recipient signing account’s balance in the gas token using Estimate and record fees. Use the recipient as sender, with this call’s gasLimit, and the quoted price as maxFeePerGas. Check the sender’s balance in the token being transferred separately from the recipient signing account’s balance in the gas token.
Save the signed attempt before calling await signed.send(). Retain the signed transaction hash and bytes alongside the authorization nonce. Serialize transactions from the recipient account so concurrent collections cannot select the same transaction nonce.

Verify and record collection

Load the transaction receipt by the saved transaction hash and require successful execution. Use Verify a finalized transfer for the exact token, sender, recipient and amount, including the canonical block and finality checks. Match that transfer to AuthorizationUsed from the same token with this sender and authorization nonce. Scan forward from that event, skipping the token’s transfers involving its own address that settle yield, and require the next transfer to match the sender, recipient and amount. Stop if another authorization event intervenes. Two unrelated matching events somewhere in a transaction receipt do not establish that this authorization paid the order. Read authorizationState and require true after the transaction. Credit the order once using the verified transfer’s event identity. A consumed nonce alone does not identify the order’s recipient or amount. An authorization can consume its nonce while the payment is quarantined. In that case, verify the token’s transfer from the sender to ReceivePolicy and matching quarantine receipt, save the full recovery record, and leave the order unpaid. Do not request a new authorization as an automatic retry. Routing requires a call to the smart contract function that forwards the funds. If this collection is part of that call, also verify its required downstream transfer with Route incoming payments.

Recover or reject an attempt

An uncertain send retains both identities: the saved transaction hash and (sender, authorization nonce). Follow Recover an uncertain submission. Check the original transaction receipt before resending the same signed bytes. If another submission consumed the authorization, locate its AuthorizationUsed or AuthorizationCanceled event. A reverted transaction rolls back authorization consumption and token transfers. Record its gas charge, inspect the error, and retry only when the original authorization remains unused and valid. A policy refusal in REVERT mode rolls back consumption. In QUARANTINE mode, the authorization is consumed and funds are in custody even though the intended recipient has not been paid. Before enabling collection, test these cases using simulation or controlled fixtures:

Use a facilitator

Use exact x402 payments to let an agent pay for an HTTP resource. For an ordinary sender account, the agent needs a wallet client authorized to sign for that account, and the account needs the payment token. The seller needs a controlled recipient address, a price, an HTTP service and a facilitator that advertises exact for the target network through /supported. The facilitator’s signing account pays the transaction fee from its balance in the gas token. Implement the middleware using the seller quickstart. The facilitator reference describes its requests, results and refusal reasons. The payment and delivery stages are:
  1. Offer a price. The seller answers the agent’s unpaid request with HTTP 402 and PAYMENT-REQUIRED, naming the scheme, network, token, recipient and amount. Associate that offer with a durable application request ID and resource.
  2. Obtain the signed payment. The agent checks the offer against its payment rights and retries with PAYMENT-SIGNATURE. For an ordinary account, this carries a TransferWithAuthorization signature binding the exact payment and validity window. Check that it answers the seller’s offer.
  3. Verify. The seller passes the payment and offer to /verify. For exact, the facilitator checks the authorization and simulates the transfer. Verification says the payment could succeed against the checked state. It neither transfers funds nor reserves the sender’s balance.
  4. Settle. The seller submits the same payment and offer to /settle. The facilitator rechecks them, submits transferWithAuthorization and returns the transaction outcome. A mandate-backed payment instead calls the smart account’s pull, which enforces the mandate before calling the token.
  5. Verify delivery conditions. Match the resulting token transfer to the authorization and expected recipient, amount and network. Apply the collection checks, including finality and quarantine handling, before marking the order paid or completing an irreversible delivery.
The Express middleware runs the route handler after verification and before settlement. Keep work in that handler reversible. Stage the result and complete delivery only after the payment checks succeed. Use the successful settlement’s extra.settlement.id as a durable deduplication key. first: true identifies the request that claimed the payment, but your application still needs to save the delivery state and recover interrupted work. Return an already completed result on a retry without charging or delivering again. Save the request, offer and signed payment before settlement. An onAfterSettle notification cannot block the middleware response if its work fails. For irreversible operations, return only a pending request ID from the protected handler, then expose the completed result through an authenticated status route after durable recipient-credit and finality checks. The seller quickstart explains that delivery boundary. Retain the request ID, resource and price, full offer and signed payment, authorization nonce, facilitator payment ID, settlement transaction hash when present, verified event identity and delivery state. Use Verify and reconcile payments for durable records and uncertain-submission recovery. Use the facilitator’s response or listing to locate the payment, then verify the finalized transfer to establish the recipient credit. If settlement times out, keep the request pending. Retry /settle with the same signed payment and investigate the returned transaction or /settlements. Do not request a second authorization from the agent while the original is unresolved. already_settled requires reconciling the original payment and delivery record. A quarantined payment leaves the recipient unpaid and needs recovery even though its authorization is consumed. For frequent API charges through a deposit, use Offer Pay-per-Call Clearing. That flow uses signed Clearing receipts and epoch finalization. An exact verification response carries no Clearing preconfirmation. MIP20 exposes no WithPolicy variants or transfer callbacks. If collection requires additional application evidence, authenticate its issuer, exact payment binding, expiry and replay protection before submission, or enforce those checks in a send policy contract before it requests the transfer.