x402 defines upto for EVM only. scheme_upto_hedera.md is the first non-EVM one — written from scratch, shipped in three npm packages, and destined for the upstream repo.
Under exact the charge must equal the signed amount. Under upto it may be anything from $0 up to the ceiling — but the signature is always verified against the maximum, never the settle amount. Get that wrong and you charge the full ceiling every time.
// verify(): against the MAXIMUM — what the client signed maxAmount = 500000 // $0.50 ceiling // settle(): the ACTUAL metered charge settleAmount = 130000 // ← you set this require(settleAmount <= maxAmount) // ✓ // re-verify signature against maxAmount, // NEVER against settleAmount.
accepted.amount is the signed maximum; the settle-time amount is the actual charge. The facilitator asserts actual ≤ maximum — and, unlike exact, must NOT require them equal.
ecrecover(digest) == authorization.from; from resolves to a real ECDSA-alias account; maxAmount matches the advertised ceiling; within the time bounds.
nonce unused (read from a consensus node, never a lagging relay); allowance covers the ceiling; balance covers the charge; payTo can receive the asset.
Re-run A–C at settle time, re-verifying the signature against the maximum. The amount may be 0 — the nonce still burns.
The canonical offer-receipt payloads carry no meter reading — the offer commits an amount, the receipt a payer and a transaction id. Neither commits the unit price or the units consumed. So an upto receipt is unverifiable as written, on any network. Tally documents this and fixes it with a signed price schedule and meter reading.