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

# Require a Signed Order

> Require a second signature on a route, the agent's own over the order it placed with you, and keep it as proof the agent agreed to that exact purchase

A payment proves the agent paid you, not that it agreed to this order at
this price. Say you sell a market report for `40 *USDZ` and the buyer
contests the charge a month later. If you required a second signature on
the route, the agent's own over the order itself, you hold proof of that
exact purchase, which anyone can check against the payment on chain.
Without the signed order, an x402 payment carries only the one signature
the chain checks.

Only an agent paying under a [mandate](https://docs.metalntwx.com/agents/mandates.md) can provide the
second signature, so a route that requires it is paid only by those
agents. Their `pay` signs the order when your `402` requires it.

## 1. Require it on a route

In code the signed order is the signed offer: `SIGNED_OFFER_REQUIRED` asks
for it, `signedOfferOf` reads it, and `verifyMandatePayment` takes it as
`checkoutMandate`. On the server from the
[Seller Quickstart](https://docs.metalntwx.com/agents/quickstart-accept.md):

```typescript theme={null}
import { SIGNED_OFFER_REQUIRED, requireSignedOffer, signedOfferOf } from "@metalntwx/metal-pay/mandates";

const server = requireSignedOffer(
  registerMetalScheme(new x402ResourceServer(facilitator), { networks: ["testnet"] }),
  { rpcUrl: process.env.METAL_RPC_URL! },
);

// in the route table
"GET /report": {
  accepts: {
    scheme: "exact",
    network: "eip155:63825",
    payTo: "<your Metal address>",
    price: "40",
    extra: { ...SIGNED_OFFER_REQUIRED, resource: "GET /report" },
  },
},
```

The check reads the payer's mandate from the chain through your
[endpoint](https://docs.metalntwx.com/network/endpoints.md). `resource` names the item the signature
buys; without it, the item is your address. The signed order covers the
offer the route serves: its `resource`, the price, the payee and the
network, not the request's parameters such as its query string. When an
order must name the item bought, serve one route per item, each with its
own `resource`.

## 2. Receive a paid request

The check runs in your server, before the payment goes to the
facilitator. A payment without the signed order, with one over another
offer, or under a mandate the account does not bind gets a `402` naming
why.

Keep the signed order with the settlement's transaction hash, to check a
disputed payment later:

```typescript theme={null}
server.onAfterSettle(async ({ paymentPayload, result }) => {
  const settlement = result.extra?.settlement as { first: boolean } | undefined;
  if (!result.success || !settlement?.first) return;
  const order = signedOfferOf(paymentPayload);
  // Store order beside result.transaction, wherever you keep your sales.
});
```

Through the HTTP middleware, the hook's `transportContext`, typed
`unknown`, is an `HTTPTransportContext` from `@x402/core/http`: cast it, and
`request.adapter.getHeader(name)` and `request.adapter.getUrl()` read the
paid request's headers and URL, and `responseBody` holds what your handler
answered, to keep the sale with what you delivered.

## 3. Verify what you were paid

```typescript theme={null}
import { verifyMandatePayment } from "@metalntwx/metal-pay/mandates";

const { ok, steps, payments } = await verifyMandatePayment(publicClient, {
  tx: transaction as `0x${string}`,
  checkoutMandate: order,
});
if (!ok) throw new Error(steps.find((s) => s.outcome === "fail")?.detail);
```

`transaction` and `order` are what you stored in step 2, and `publicClient`
is a viem client on your endpoint. The payment is checked against the
mandate's limits at its block, and the signed order against the payment: the
same key, payee, amount and window. One of another payment fails as `the
checkout mandate belongs to another payment`. Given no `checkoutMandate`, it
checks no signed order, and a passing step 4's detail ends `the order was
not checked`. Without the buyer's credential, the limits come from the
mandate's binding on chain, and the steps that check a credential are
skipped. An event under the mandate that the SDK does not decode, as an
account of another version emits, names its topic and the account: it throws
when the transaction carries nothing else, and fails step 4 otherwise.

> [card] [Seller Quickstart](https://docs.metalntwx.com/agents/quickstart-accept.md)
>
> The route this check is added to.

> [card] [Pay under spending limits](https://docs.metalntwx.com/agents/spending-limits.md)
>
> The buyer's side: the agent that provides the second signature.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.