Receipts and checking

How it works

Receipts and checking

Every payment ends in a receipt. Anyone can check it.

A receipt is one small signed file. It names the mandate, then holds the rules' answer, the person's yes and what happened at the rail.

Format
JSON in one exact order (RFC 8785), so the same receipt always gives the same bytes.
Signature
Ed25519, signed by Onbehalf.
Version
New receipts are 0.4.0. They also say whether the yes came by passkey or by wallet. From the release that adds charges and credits they are 0.5.0, which also names the partner's own Stripe test account. The Base Sepolia sample is 0.3.0. The Stripe sample is 0.2.0. Receipts name the approver and say how many decimal places the amount uses.
Outside record
A Base Sepolia receipt carries the chain id, the transaction id and whether it was final when signed. A Stripe receipt carries the Stripe id. A stand-in receipt says nothing moved.
Checking it
Verify checks the signature and every signed field, in your browser. Change one character we signed, and the check fails.

Every field

The receipt format, 0.2.0 to 0.5.0, field by field, as the code defines it. A receipt file has three parts: receiptCore (the signed part), cryptographicProof and anchorProof. Only the first is signed; the other two carry the proof and the timestamp state.

FieldHoldsMeaning
schemaone valueAlways onbehalf.action-receipt.
schemaVersionone value0.2.0 for the Stripe sample; 0.3.0 for receipts made from Oct 7, 2026; 0.4.0 for receipts made from Oct 18, 2026; 0.5.0 from the release that adds charges and credits.
receiptIdone valueThe receipt's own id, starting rct_.
issuedAtone valueWhen the receipt was signed.
issuerissuerId keyId Who signed it and with which key. The key id is derived from the public key.
scopeenvironment coveredRoute coverageClaim Test or live, the one route Onbehalf covers, and the exact sentence it claims.
subjectorganizationRef agentRef agentVersion Whose agent acted, and which version of it.
authoritymandateRef mandateVersion mandateDigest activeAtEvaluation activeAtExecution The mandate the agent acted under, and whether it was active when checked and when the money moved.
actionactionId actionVersion actionType targetRef amountMinor currency currencyDecimals? requestDigest The exact action: type, target, amount in minor units, currency, and a fingerprint of the request. From 0.3.0 the receipt states its own scale: 2 for cents, 6 for USDC units.
policypolicyRef policyVersion policyDigest decision reasonCodes evaluatedAt Which rules ran and what they said: ALLOW, OBSERVE, REQUIRE_APPROVAL or DENY.
approvalrequired decision approverRef bindingDigest decidedAt approverName? undoWindow? confirmation? Whether a person had to say yes, who did, when, and the digest that locks the yes to this exact action. New in 0.2.0: the approver's name and the undo window (seconds, opened, closed). New in 0.4.0: how the approver confirmed (kind passkey or wallet, the credential id or signer address as ref, and the sentence the receipt shows).
executionprovider providerEnvironment operationRef providerObjectRef attemptedAt observedState observedAt observationSources chain? providerAccountRef? What the rail was asked, its object id, and what it reported: SUCCEEDED, FAILED or UNKNOWN. From 0.5.0 an action on a partner's own Stripe test account names that account (acct_...). From 0.3.0 a payment sent on a chain also carries its chain record: chain id, token, payer, recipient, exact units, the payment fingerprint, the transaction id, the block and whether it was final when signed.
evidencelevel recordedEventCount evidenceManifestDigest limitations How far the evidence goes, how many events were recorded, and the limitations in plain words.
commitmentNonceone value256 random bits, so the receipt's fingerprint reveals nothing about its contents.
PartHoldsMeaning
cryptographicProofcanonicalization digestAlgorithm digest signatureAlgorithm signature publicKey publicKeyFingerprint RFC 8785 canonical JSON, SHA-256, Ed25519. The public key travels with the receipt; the fingerprint is what a trusted key list pins.
anchorProofstate reason NOT_SUBMITTED on every receipt today, with the reason in words. The public timestamp is not built yet.

Amounts are whole numbers in the smallest unit. A USDC receipt counts units of six decimals: 7500000 is 7.50 USDC. A USD receipt counts cents: 75000 is $750.00. From 0.3.0, the receipt says which. Fields marked ? may be missing.

The five checks

What the Verify page tests, in the order it shows them.

CheckOn screenWhat it tests
SchemaFormat is correctThe file has every field the format requires, with the right types, and names a version the checker supports.
DigestContents match the fingerprintThe signed part is put into RFC 8785 canonical form and hashed with SHA-256. The result must equal the fingerprint in the file.
SignatureSignature is genuineThe Ed25519 signature in the file must verify over those exact bytes under the public key the file carries.
IssuerSigned by the configured issuerThe public key's fingerprint, the issuer id and the key id must match the trusted key list. On this site that list holds the hosted Console's key and the keys behind the two samples. The page picks the key by the fingerprint the file carries.
AnchorPublic timestampA public timestamp of the fingerprint. Not built yet, so this line reads Not yet on every file.

Each check reads Pass, Fail or Not yet. The result is Valid when every check passes (the public timestamp counts as Not yet today), and Not valid when the contents or the signature no longer match what was signed. A file signed by a key this site does not publish reads as checked but unrecognized, in amber.

Our public keys

Key id
key_4900f3bfa9088c80
Algorithm
Ed25519
Public key
sG2cgnBPZ4GZFksoWQCdRq_pp-1hK4EDw58J8opx4Ro
Fingerprint
sha256:4900f3bfa9088c80b8d21737b3749bbd3a5e6c7a2306dfe407ad012f1aed5870
Issuer
onbehalf-local
Run started
Oct 5, 2026, 18:55 UTC
Key id
key_6d24407f745f853d
Algorithm
Ed25519
Public key
r7QywjkyCqYhSwPja4_UDFDVTBicP4gu74hsgL6yvUI
Fingerprint
sha256:6d24407f745f853de158346ca7cc2ddd3e4f7e3d8400c52f4126f8ba9cec1d70
Issuer
onbehalf-local
Run started
Oct 8, 2026, 21:15 UTC
Key id
key_499f5f7b0ba9030f
Algorithm
Ed25519
Public key
NccPn3533fa03zpJiTBte9-Yek1ebeaCd9PZmNWHBzY
Fingerprint
sha256:499f5f7b0ba9030f868c4424491886ad8d0b19a73beb7a579b8821132db1e880
Issuer
onbehalf-test
In use since
Oct 16, 2026, 00:00 UTC

The hosted Console signs with one long-term key. This site publishes it, with the keys behind the two older samples. The page picks the right one from the file's fingerprint.

The sample receipts

The two records this site publishes, each from a real run: a USDC payment on Base Sepolia, a test network, and a Stripe test-mode refund.

The USDC payment on Base Sepolia

The Stripe test-mode refund

J. Tan is a demo approver in a test workspace, not a real person or customer.

Questions? Email hello@getonbehalf.com. We reply within two working days.