Skip to content

Check a receipt

What a receipt looks like.

Every time a site records something you did, it makes one of these. This one is an example. Run the check on it, then look up your own on the check page.

The receipt

Example Notes · example.invalid

What the site recorded
A scoped action was authorized: publish a note.
When
2026-09-01 14:02 UTC
Paid to identity
did:oc:example
The site paid
240 sats
Platform fee
48 sats
The person earned
168 sats
Rebated to the site
24 sats

The four add up. The site's price is the whole of it, and the split is orangecheck's, inside published bounds. No sat appears from nowhere.

Check it yourself

Four steps, run in your browser against the published key.

  1. 01
    Fetch the signed bytesNot run
  2. 02
    Hash them. The id is a routing id, so the hash is for referenceNot run
  3. 03
    Fetch the published signing keyNot run
  4. 04
    Check the signature over those bytesNot run

Every step runs on your machine. The bytes come from /api/envelope/oc-me-example-receipt, the key from /.well-known/oc-envelope-jwks.json. The hash is computed by @noble/hashes and the signature checked by @noble/curves, in this tab. No orangecheck server takes part beyond serving those two files.

What step 2 checks, and what it does not

A billable event's id is a routing id, given when the event is recorded. It is not a hash of the contents, so step 2 reports the digest of the bytes and has nothing to compare it with. Step 4 is the one that binds: it checks the signature over those exact 358 bytes against the key published under oc-me-envelope-4dc2f420. Content-addressed envelopes (rebinds, payout bindings, distributions) do get the comparison, and the check page shows it for them.
The envelope, as signed
{
  "v": 1,
  "kind": "oc-me-event",
  "class": "B",
  "subtype": "scoped_action_authorization",
  "identity": "did:oc:example",
  "site": "example.invalid",
  "gross_fee_sats": 240,
  "platform_fee_sats": 48,
  "user_earned_sats": 168,
  "site_rebate_sats": 24,
  "occurred_at": "2026-09-01T14:02:11.000Z",
  "context": {
    "kind": "B",
    "subtype": "scoped_action_authorization",
    "action_label": "publish a note"
  }
}

These are the bytes the signature covers, in the order they were signed. Fetch them yourself from this receipt's URL; the response is the bytes, with no wrapper to strip.