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.
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
UsesenderWallet 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.
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.Submit from the recipient
Onlyauthorization.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.
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.
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 toAuthorizationUsed 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
Useexact 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:
- Offer a price. The seller answers the agent’s unpaid request with HTTP
402andPAYMENT-REQUIRED, naming the scheme, network, token, recipient and amount. Associate that offer with a durable application request ID and resource. - Obtain the signed payment. The agent checks the offer against its payment
rights and retries with
PAYMENT-SIGNATURE. For an ordinary account, this carries aTransferWithAuthorizationsignature binding the exact payment and validity window. Check that it answers the seller’s offer. - Verify. The seller passes the payment and offer to
/verify. Forexact, 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. - Settle. The seller submits the same payment and offer to
/settle. The facilitator rechecks them, submitstransferWithAuthorizationand returns the transaction outcome. A mandate-backed payment instead calls the smart account’spull, which enforces the mandate before calling the token. - 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.
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.