> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cryptocheckout.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# On-chain verification

> How your customer's browser proves the money is going to you — even if our servers were compromised.

Most payment security asks you to trust that the processor's systems are intact. This one doesn't.

## The threat

Suppose an attacker fully compromises our database and rewrites your payout address to theirs. On a conventional processor, that's the end of the story — the checkout renders whatever the database says, and customers pay the attacker.

We designed so that attack fails.

## The mechanism

You pin your payout address in the embed code **on your own site**:

```html theme={null}
CryptoCheckout.init({
  merchantId: "…",
  settlementAnchor: "0xYourPayoutWalletAddress",  // ← the anchor
});
```

That value lives in your HTML, which our database cannot reach. Before showing any payment option, the checkout does this:

```mermaid theme={null}
flowchart TD
    A["Anchor from YOUR site"] --> B["Read effectiveRecipient()<br/>from the blockchain"]
    B --> C["Recompute what the pool<br/>address must be"]
    C --> D{"Matches what<br/>our server served?"}
    D -->|Yes| E["Show payment options"]
    D -->|No| F["Block. Hide the address.<br/>Tell the customer not to pay."]
    style E fill:#064e3b,stroke:#10B981,color:#fff
    style F fill:#7f1d1d,stroke:#ef4444,color:#fff
```

<Steps>
  <Step title="Read the chain" icon="link">
    The browser calls the on-chain registry to get your attested payout address. That attestation was written by **your** wallet and can only be changed by your wallet.
  </Step>

  <Step title="Recompute the address" icon="calculator">
    From that chain-read value, the browser recomputes what your pool address must be — the same deterministic derivation the contracts use.
  </Step>

  <Step title="Compare" icon="scale-balanced">
    If the recomputed address differs from what our API served, something is wrong.
  </Step>

  <Step title="Refuse" icon="ban">
    The checkout enters a terminal state, hides the payment address, and tells the customer not to pay.
  </Step>
</Steps>

The key property: because step 2 derives from the **chain-read** value rather than the served one, an attacker who consistently rewrites both the recipient and the pool address in our database still fails. The derivation anchors to the chain.

## Why the integrity hash matters too

```html theme={null}
<script src="https://www.cryptocheckout.ai/sdk.js"
        integrity="sha384-…"
        crossorigin="anonymous"></script>
```

The verification runs in JavaScript we serve — so what if that JavaScript were tampered with?

The `integrity` attribute pins its exact hash. If the file we serve differs by a single byte, the browser refuses to execute it at all. Tampered code fails closed rather than running altered.

<Danger>
  Keep both `integrity` and `settlementAnchor`. Removing either silently removes a protection that exists specifically for you. Neither affects how the checkout looks or behaves normally, which is exactly why they're easy to drop during a refactor.
</Danger>

## Honest limits

We won't overstate this. The conditions under which it holds:

<AccordionGroup>
  <Accordion title="It requires you to pin an anchor" icon="thumbtack">
    Without `settlementAnchor` in your embed, the checkout shows an unverified badge and does **not** block. The protection is opt-in per merchant because it depends on something only you can provide.
  </Accordion>

  <Accordion title="It defends database compromise, not everything" icon="shield-halved">
    A total compromise of our served code is *mitigated* by the integrity pin, not eliminated. Different threat, different (weaker) guarantee.
  </Accordion>

  <Accordion title="It covers the pool rails" icon="route">
    Both connect and deposit. An older atomic payment path exists for legacy integrations and is outside this guarantee.
  </Accordion>

  <Accordion title="TRON has no on-chain registry yet" icon="triangle-exclamation">
    The anchor check is EVM-only today. TRON payments settle correctly but do not carry this specific verification.
  </Accordion>

  <Accordion title="The audit is pending" icon="clipboard-check">
    A third-party security audit is a mainnet gate and has not completed. [Roadmap](/reference/roadmap).
  </Accordion>
</AccordionGroup>

<Note>
  We describe this as a mechanism with conditions, never as "unhackable." Any vendor who tells you their system cannot be compromised is telling you they haven't thought about it carefully.
</Note>

## Checking for yourself

<Columns cols={2}>
  <Card title="Verify page" icon="magnifying-glass" href="https://www.cryptocheckout.ai/verify">
    Every deployed contract, per chain, with explorer links.
  </Card>

  <Card title="Read your own pool" icon="cube">
    Call `recipient()` on your pool address on any block explorer. It should be your payout address, and you should be unable to change it.
  </Card>
</Columns>
