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

# AgentScore Commerce (Node.js)

> Identity middleware + payment helpers + 402 builders + discovery + Stripe multichain. The full merchant-side toolkit for agentic commerce.

`@agent-score/commerce` is the full merchant-side SDK for agentic commerce. One install bundles identity gating, payment-protocol helpers, 402 challenge builders, discovery doc generators, and Stripe multichain support. Subpath imports keep bundle size focused: identity-only consumers pay no cost for payment helpers, and vice versa.

## Installation

```bash theme={"dark"}
npm install @agent-score/commerce
```

Framework + integration packages are optional peer deps; install only what you use:

```bash theme={"dark"}
npm install hono mppx @x402/core @x402/evm stripe   # whatever your stack needs
```

## Subpaths

| Import                                                               | What it gives you                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@agent-score/commerce` (top-level: the 2.0 high-level surface)      | `Checkout` orchestrator + `CheckoutContext` + `CheckoutGateConfig` + `CheckoutValidationError` + `DiscoveryProbeConfig` + `MountUcpRoutesOptions` + `SettleOutcome` + `MppxComposeOutcome` + `PricingResult` (one config object, hooks for `preValidate`/`computePricing`/`onSettled`/`mintRecipients`/`composeMppx`, auto-derived x402+mppx servers, per-framework adapters `handleHono`/`handleExpress`/`handleFastify`/`handleNextjs`/`handleWeb`, signed UCP routes via `mountUcpRoutes{Hono,Express,Fastify}`). Plus `computeFirstCheckout`: variable-cost pay-per-result helper (compute-first + exact-x402) that works on every exact-mode rail without upto / Permit2 / Settlement-Overrides. `createQuoteCache`: content-hash quote cache used by the compute-first helper (in-memory default; pass `redisUrl` for distributed deployments). `createResultCache`: the neutral keyed JSON-value cache underneath it (same body-hash key builder); cache any probe-leg result a `Checkout` merchant replays on the settle leg, for example a paid upstream call made in `preValidate`. `createDefaultOnDenied({merchantName, supportEmail, supportContext?, walletNotTrustedMessage?, paymentRequiredMessage?})`: canonical `onDenied(reason) => {status, body, headers?}` factory matching `Checkout`'s gate hook (handles `wallet_signer_mismatch`, `wallet_not_trusted` unfixable fallback, `payment_required`, `token_expired`/`invalid_credential`/`api_error`). \`hasPaymentHeader(req                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | headers)`: discriminator that splits discovery legs (no payment credential → 402) from settle legs (`payment-signature`/`x-payment`/`Authorization: Payment JWT-BYTES`); `hasX402Header`/`hasMppxHeader`: granular dispatch helpers (x402 vs MPP credential present). `malformedPaymentCredential(req | headers)`: wire-shape gate for payment credentials (values that are not base64 JSON and not token-shaped are rejected); `Checkout`runs it before any merchant hook by default, opt out with`credentialPreCheck: false`. `defaultReadOnlyOnDenied(reason)`: canonical `onDenied` for read-only resource gates (`GET /orders/:id`): collapses every denial to 401 `unauthorized`+`Cache-Control: no-store`while still spreading`denialReasonToBody`. `extractOwnerScope(headers)`(returns optional`walletAddress`+ optional`operatorTokenHash`): pull canonical owner identity from `X-Wallet-Address`/`X-Operator-Token`with safe token hashing. Plus factories:`pricingResult`(cents → typed PricingResult with optional`decimals`for sub-cent precision),`validationResponse{Hono,Express,Fastify,Nextjs,Web}\` (4xx envelope per framework). |
| `@agent-score/commerce/identity/{hono,express,fastify}`              | Trust gate middleware: KYC, age, sanctions (account name + signer wallet), jurisdiction. Context-getter pattern: `agentscoreGate(opts)` middleware + `getAgentScoreData(ctx)` / `getGateDegradedState(ctx)` / `getGateQuotaInfo(ctx)` / `getSignerVerdict(ctx)` accessors, `captureWallet(...)`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `@agent-score/commerce/identity/policy`                              | Per-product compliance helpers: `PolicyBlock`, `buildGateFromPolicy`, `runGateWithEnforcement`, `shippingCountryAllowed`, `shippingStateAllowed`, `validateShippingAgainstPolicy` (one-call country+state validator raising `CheckoutValidationError` with the canonical envelope on miss). All five are also re-exported at `@agent-score/commerce` top-level.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `@agent-score/commerce/identity/{nextjs,web}`                        | Same gate, wrapper pattern: `withAgentScoreGate(opts, handler)` / `createAgentScoreGate(opts) => guard(req)`. The `data` + `degraded` + `infraReason` fields land directly on the handler arg / guard result (no separate getter). Plus shared `captureWallet`, `getSignerVerdict`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `@agent-score/commerce/payment`                                      | `networks`, `USDC`, `rails` registries; `paymentDirective`, `buildPaymentHeaders` (one-call WWW-Authenticate + PAYMENT-REQUIRED bundle), `wwwAuthenticateHeader`, `paymentRequiredHeader`, `aliasAmountFields` (opt-in v1↔v2 amount-field shim; the 402 builders do NOT apply it by default: strict x402 v2 settlement matches the whole accepts object, so an extra field breaks settle; reach for it only when a specific client is hardcoded to read `maxAmountRequired`), `settlementOverrideHeader`, `dispatchSettlementByNetwork`, `extractPaymentSigner` (recovers signer from a Request: x402 EIP-3009 `payload.authorization.from` OR MPP `Authorization: Payment BASE64` `did:pkh:eip155:CHAIN:ADDR` / `did:pkh:solana:GENESIS:ADDR` source DID, including Solana `TransferChecked` authority fallback when `@solana/kit` is installed), `extractPaymentSignerFromAuth` (header-string variant for callers that already have the `Authorization` value in hand), `detectRailFromHeaders` (returns `"x402"` / `"mpp"` / `null` from inbound headers), `buildIdempotencyKey`; `createX402Server`, `buildX402AcceptsFor402` (one-call helper for the 402-emit path; derives `extra.name` from the registered scheme so EIP-712 domain matches the on-chain USDC contract), `createMppxServer`, `buildDefaultCheckoutRails({tempo?, x402Base?, solanaMpp?, stripe?})` (canonical 4-rail `rails` dict factory: flipping `network` alone derives the right `token` + `chainId`; Base Sepolia → Sepolia USDC + chainId 84532, Solana devnet → devnet USDC mint. Solana's `network` accepts both CAIP-2 and the raw `@solana/mpp` form `mainnet-beta` / `devnet` / `localnet`. Explicit overrides always win), `buildMppxComposeRails({amountUsd, tempoRecipient?, solanaRecipient?, ...})` (per-call intent factory replacing the hand-rolled `[['tempo/charge',{...}],['solana/charge',{...}],['stripe/charge',{...}]]` array; auto-handles USD→atomic conversion for Solana; auto-drops `stripe/charge` when `amountUsd < 0.50` since Stripe's fixed \~$0.30 fee makes sub-50-cent charges unprofitable; sub-50-cent APIs pass `includeStripe: false` explicitly), `composeMppxRequest` (typed wrapper around `mppx.compose(...intents)(request)` returning a narrowed `MppxComposeResult` union; replaces the `(mppx as any).compose(...)` cast in custom `composeMppx` hooks), `mppxChallengeHeaders` (one-call `Object.fromEntries(challenge.headers)` for the 402 path); drop-in x402 helpers: `validateX402NetworkConfig` (boot-time guard), `verifyX402Request` (parse + validate inbound X-Payment), `processX402Settle` (verify-then-settle in one call), `classifyX402SettleResult` (maps the tagged settle result to a recommended HTTP status / code / next_steps so merchants get a controlled envelope without coupling to facilitator-specific error text), `classifyOrchestrationError` (same `ClassifiedX402Error` shape but for uncaught exceptions thrown elsewhere in the orchestration; conservative substring fallback returns `null` for unknown errors so merchants rethrow instead of swallowing); `zeroAmountCarveOut` (skip CDP / mppx upstream verify+settle for $0 settles where the upstream rejects value=0 payloads; parses the credential, lifts signer + network, returns a `ZeroSettleResult` shaped identically to the success path so callers branch on rail, not on result shape); `usdToAtomic` (BigInt-based USD → atomic value, ROUND\_HALF\_UP, rejects NaN / negative / infinite; for Tempo / Solana / Base USDC amount construction). |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `@agent-score/commerce/discovery`                                    | `isDiscoveryProbeRequest`, `buildDiscoveryProbeResponse` (with optional `x402Sample` for x402-aware crawlers), `sampleX402AcceptForNetwork`, `buildWellKnownMpp`, `buildWellKnownX402` (x402scan v1 `/.well-known/x402` shape: `{version: 1, resources: ["METHOD /path"]}`), `buildLlmsTxt`, `buildSkillMd` (Claude-Skill-compatible `/skill.md` agent-discovery manifest: strictly agent-facing data only, no internal posture), `buildRedemptionSkillMd` (delivery-neutral redemption-code template; printed mailers, emailed codes, API trial credits all covered; `endpointPath`/`deliveryIntro`/`bodyShape`/`bodyRules`/`extraRecoveryRows` overrides for non-goods shapes), `buildMerchantIndexJson` + `standardEndpointDescriptions({kind})` (canonical `/` discovery body for goods vs api merchants), `buildSuccessNextSteps` (universal Passport-active success block), `buildAgentscoreOnboardingSteps`, `agentscoreOpenApiSnippets`, `siwxSecurityScheme` + `xPaymentInfoExtension` + `xGuidanceExtension` per the x402scan OpenAPI spec, `createBazaarDiscovery`; `noindexNonDiscoveryPaths` (Hono middleware) + `noindexNonDiscoveryPathsExpress` + `noindexNonDiscoveryPathsFastify` + `wrapNoindexResponse` / `applyNoindexHeader` (Web Fetch + Next.js): emits `X-Robots-Tag: noindex` on every path except the agent-discovery surfaces. Plus the UCP/JWKS publish surface: `buildSignedUcpResponse`, `buildSignedJwksResponse`, `wellKnownPreflightResponse`, `defaultA2aServices`, `bootstrapUcpSigningKey`, framework-neutral `SignedDiscoveryResponse` + per-framework wrappers `signedResponse{Hono,Express,Fastify,Nextjs,Web}`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `@agent-score/commerce/challenge`                                    | `buildAcceptedMethods`, `buildIdentityMetadata` (auto-attached by `Checkout` when wallet header present), `buildHowToPay`, `buildAgentInstructions` (auto-emits per-rail `compatible_clients`; pure helper `compatibleClientsByRails(rails)` returns the same map for vendors building custom 402s), `build402Body` (pass `x402.resource` for x402 v2 `ResourceInfo` metadata, `url` plus optional `serviceName` / `tags` / `description` / `mimeType` / `iconUrl`, and `x402.extensions` for declared extensions; both surface on the 402 body for spec-compliant crawlers, and `respond402` mirrors `resource` into the PAYMENT-REQUIRED header), `buildPricingBlock` (cents → dollar-string; optional `shippingCents` + `discountCents`; pass `discountCents` for redemption codes / coupons so the 402 body surfaces `discount` alongside `subtotal` / `total` for agent-renderable savings; optional `decimals` for sub-cent precision so per-token / per-byte unit pricing advertises real amounts instead of rounding to two decimals), `firstEncounterAgentMemory`, `Receipt` type (canonical 200-receipt shape); `respond402`: drop-in 402 emit that preserves mppx's `WWW-Authenticate` and layers x402's `PAYMENT-REQUIRED`. `buildValidationError`: structured 4xx body builder (`{error: {code, message}, required_fields?, example_body?, next_steps?, ...extra}`) so vendors compose body shapes by name instead of inlining at every validation site.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `@agent-score/commerce/middleware/{hono,express,fastify,nextjs,web}` | Framework-specific rate-limit middleware. Hono / Express / Fastify expose middleware factories (`rateLimitHono`, `rateLimitExpress`, `rateLimitFastify`); Next.js exposes `withRateLimit(opts, handler)`; Web Fetch exposes `createRateLimit(opts) => guard(req)`. Shared options: `windowSeconds` (default 60), `maxRequests` (default 60), `keyResolver` (default first hop of `x-forwarded-for`), `redisUrl` (lazy-imports `ioredis` when set, in-memory `Map` fallback otherwise), `keyPrefix`. `ioredis` is an optional peer dep; install it only for distributed limiting.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `@agent-score/commerce/stripe-multichain`                            | `createMultichainPaymentIntent` (returns `{ paymentIntentId, depositAddresses }`; read `depositAddresses[network]` directly), `createPayToAddressFromStripePI({request, amountCents, stripe, piCache, networks?, staticRecipients?, metadata?, orderId?, preferredNetwork?})`: per-order payTo resolver matching `Checkout.mintRecipients`: on the settle leg, reuses the buyer's signed-against payTo from the MPP credential (after `piCache.hasAddress` check OR a `staticRecipients` match; the static address is always-accepted because the merchant owns it); on the discovery leg, mints a fresh PI for the rails NOT covered by `staticRecipients`, caches the merged map, registers static addresses with `piCache.cacheAddress` so verify-leg lookups pass. `mintMultichainRecipients({...same opts})`: structured variant returning `{ recipients, paymentIntentId?, reusedFromCredential }` for the full per-rail map (typical multi-rail merchant hook). Use `staticRecipients: { solana: '<wallet>' }` for low-margin endpoints where Solana per-call ATA rent (\~$0.50 against MPP spec §13.6) dominates revenue; the SDK skips Stripe minting on that network, reuses the static recipient forever, and (when paired with a one-time external pre-funding of the recipient's USDC ATA) lets every settle pay only the ~$0.001 per-tx fee. `simulateCryptoDeposit`, `createMppxStripe`; `createPiCache` (TTL'd PI / deposit-address cache, Redis-backed when `redisUrl` set), `simulateDepositIfTestMode` (gates on `sk_test_` and looks up the PI for you), `STRIPE_TEST_TX_HASH_SUCCESS` / `STRIPE_TEST_TX_HASH_FAILED` constants.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `@agent-score/commerce/api`                                          | Everything from `@agent-score/sdk` re-exported in one place: `AgentScore` + `AgentScoreError`, `AGENTSCORE_TEST_ADDRESSES` + `isAgentScoreTestAddress`. Don't add `@agent-score/sdk` as a separate dep: the two can drift versions.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `@agent-score/commerce` (top-level: publishers + key/token helpers)  | Identity-publishing helpers for cross-vendor standards: `buildA2AAgentCard` (Google A2A v1.0 Signed Agent Card, served at `/.well-known/agent-card.json`), `buildUCPProfile` (Google Universal Commerce Protocol, served at `/.well-known/ucp`). Both return unsigned payloads: vendor signs + publishes. Key + token helpers: `loadUCPSigningKeyFromEnv` (cached env-driven loader: reads `UCP_SIGNING_KEY_JWK_PRIVATE` JSON JWK, detects alg from shape, falls back to ephemeral when unset, sanitizes errors so key bytes never reach logs, concurrent-safe via Promise-pinned cache); `hashOperatorToken` (sha256 hex of plaintext `opc_...`; for merchants persisting `operator_token_id` to their own DB without ever storing the plaintext); `extractOwnerScope(headers)` (returns optional `walletAddress` + optional `operatorTokenHash`) (canonical owner-identity extractor for caller-scoped resource queries; reads `X-Wallet-Address` / `X-Operator-Token`, hashes the token so plaintext never leaves the request).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

## Identity model

Two identity types: wallet (`X-Wallet-Address`) and operator-token (`X-Operator-Token`). Default checks operator-token first, then wallet. Address normalization is network-aware: EVM lowercased, Solana base58 preserved verbatim.

`DenialReason` codes (`missing_identity`, `identity_verification_required`, `token_expired`, `invalid_credential`, `wallet_signer_mismatch`, `wallet_auth_requires_wallet_signing`, `wallet_not_trusted`, `api_error`, `payment_required`) each carry a structured `agent_instructions` JSON block describing concrete recovery actions.

`createSessionOnMissing` auto-mints a verification session for two paths: cold-start (no identity headers) AND `wallet_not_trusted` with fixable reasons (`kyc_required` / `kyc_pending` / `kyc_failed`). Both paths rewrite the denial to `identity_verification_required` before reaching `onDenied`, so merchants only handle one code. **When the merchant omits `createSessionOnMissing` from the gate config, `Checkout` auto-defaults it** from `gate.apiKey` + `gate.baseUrl` + `gate.context` + `gate.merchantName`; every gated route gets the bootstrap UX out of the box; merchants that need per-request session context or `onBeforeSession` side effects (goods merchants pre-minting an order\_id) supply their own config to override. `buildVerificationRequiredBody(reason, opts?)` collapses the per-merchant body-mapping boilerplate into one call (`status: 403, body: buildVerificationRequiredBody(reason, { message, agentInstructions, extra })`). The gate middleware extracts the payment signer pre-evaluate (`extractPaymentSigner(req, x402Header)` covers MPP `did:pkh:eip155` + Solana `did:pkh:solana` + Solana `TransferChecked` authority fallback + x402 EIP-3009) and passes `signer: { address, network }` to `/v1/assess`; one round trip now carries the gate verdict AND the wallet-signer-match outcome AND the `signer_sanctions` OFAC SDN wallet-address verdict. Merchants read both back synchronously via `getSignerVerdict(ctx)` (or the `gate.getSignerVerdict()` accessor on the wrapper adapters) off the gate's cache (no extra HTTP call). **Wallet-OFAC SDN enforcement is unconditional** whenever the signer is supplied; an SDN hit OR an unavailable wallet-sanctions lookup flips the gate decision to deny before the handler runs (fail-closed; OFAC strict-liability), without requiring `policy.require_sanctions_clear` to opt in. `policy.require_sanctions_clear` is the separate NAME-based screen on the operator's KYC identity. `captureWallet` is fire-and-forget; POSTs the signer to `/v1/credentials/wallets` so the operator's cross-merchant credential↔wallet profile builds up over time.

## Identity publishing (cross-vendor standards)

Two helpers compose AgentScore identity into the payload formats published to other agent-commerce ecosystems. Each returns an unsigned object; your service signs + serves it however its key infrastructure works.

```typescript theme={"dark"}
import { buildA2AAgentCard, buildUCPProfile, ucpA2AExtension } from '@agent-score/commerce';

// 1. Google A2A v1.0 Signed Agent Card, published at /.well-known/agent-card.json.
//    Per UCP §A2A binding (https://ucp.dev/specification/checkout-a2a/), agents
//    that serve UCP via the A2A transport MUST declare the canonical UCP extension
//    URI in `capabilities.extensions[]` so platforms arriving via A2A detect UCP
//    support without re-fetching the profile. Pass an empty capabilities map when
//    you serve UCP at the discovery layer but have no formal capability bindings
//    yet. Skills declare what the agent can do; they are AgentSkill objects
//    (top-level on the card). Identity claims live in a separate AgentCardSignature
//    (RFC 7515 JWS) wrapping the serialized card, NOT in the card body itself.
const card = buildA2AAgentCard({
  name: 'My Agent Service',
  description: 'Buy products via agent payments.',
  url: 'https://agents.example.com',
  version: '1.0.0',
  skills: [
    { id: 'purchase', name: 'Purchase', description: 'Buy products via agent payments.', tags: ['commerce', 'payment'] },
  ],
  extensions: [ucpA2AExtension()],
});

// 2. Google Universal Commerce Protocol profile, published at /.well-known/ucp
//    Output shape: { ucp: { version, services, capabilities, payment_handlers,
//    name?, supported_versions? }, signing_keys: [...] }; services /
//    capabilities / payment_handlers are MAPS keyed by reverse-DNS service /
//    capability / handler name (UCP spec §3 + §6).
const profile = buildUCPProfile({
  name: 'My Agent Service',
  services: {
    'dev.ucp.shopping': [
      {
        version: '2026-04-08',
        spec: 'https://ucp.dev/2026-04-08/specification/overview',
        transport: 'mcp',
        endpoint: 'https://agents.example.com/api/ucp/mcp',
        schema: 'https://ucp.dev/services/shopping/mcp.openrpc.json',
      },
    ],
  },
  payment_handlers: {
    ...mppPaymentHandler({ networks: [{ network: 'tempo-mainnet', chain_id: 4217, recipient: TEMPO_ADDR }] }),
    ...x402PaymentHandler({ networks: [{ network: 'base-8453', recipient: BASE_ADDR }] }),
    ...stripeSptPaymentHandler({ spec: { profileId: 'profile_5xKvNqM9BaH' } }),
  },
  signing_keys: yourJWKS,
  // Optional: declare merchant gate policy as a `com.agentscore.identity` capability
  // binding inside the public profile. Static policy declaration only; no per-operator
  // claims. Per-operator identity attestation flows through the AP2 risk-signal endpoint.
  agentscore_gate: { require_kyc: true, min_age: 21, allowed_jurisdictions: ['US'] },
});
```

Note: ACP (Stripe + OpenAI Agentic Commerce Protocol) is a transactional checkout protocol. Not an identity-publishing surface. ACP merchants integrate through the existing `build402Body` + `buildPaymentHeaders` + Stripe SPT rail.

### Signing UCP profiles (vendor extension; opt-in for trust-mode verifiers)

UCP §6 doesn't mandate profile-body JWS signing; production UCP merchants commonly ship unsigned. AgentScore's `agentscore-profile+jws` is a vendor extension layered on top of the unsigned UCP profile for trust-mode verifiers (regulated-commerce, AP2-aware) that opt into auditable cryptographic provenance. Vanilla UCP agents read the canonical body and ignore the `signature` field. Sign + verify via the optional `jose` peer dep (install via `bun add jose`):

```typescript theme={"dark"}
import {
  buildJWKSResponse,
  generateUCPSigningKey,
  signUCPProfile,
  verifyUCPProfile,
} from '@agent-score/commerce';

// One-time per merchant: generate or load a key. Persist privateJWK in your secrets manager.
const { privateKey, publicJWK } = await generateUCPSigningKey({ kid: 'merchant-2026-05' });

// On every /.well-known/ucp request:
const profile = buildUCPProfile({
  name: 'My Agent Service',
  services: { /* keyed by service name, see above */ },
  payment_handlers: { /* keyed by handler reverse-DNS name, see above */ },
  signing_keys: [publicJWK],
});
const signed = await signUCPProfile(profile, {
  signingKey: privateKey,
  kid: publicJWK.kid,
  alg: 'EdDSA',
});
return c.json(signed);

// On /.well-known/jwks.json:
return c.json(buildJWKSResponse([publicJWK]));
```

Verifiers reconstruct the canonical body (everything except `signature`, keys sorted at every level), look up the kid in JWKS, and check the JWS. `verifyUCPProfile(signed, jwks)` does this for you. It enforces the JWS protected header `typ: "agentscore-profile+jws"` (vendor-namespaced; UCP §6 doesn't define a profile-as-JWS typ), restricts `alg` to `EdDSA` / `ES256`, requires a `kid`, rejects duplicate kids, and compares canonical body bytes against the JWS payload. Failures throw `UCPVerificationError` with a discriminated `code` field. Both EdDSA (Ed25519) and ES256 are supported. EdDSA is the default and recommended.

`signUCPProfile` rejects profiles containing non-integer `Number` values: cross-language float canonicalization is not stable, so use decimal strings (e.g. `"9.99"`) for any monetary or fractional fields you put in `extras`.

**Persisting the private JWK.** Mint once via `generateUCPSigningKey()`, export with `jose.exportJWK(privateKey)`, store in your secret manager. On each container start, read the secret, `jose.importJWK(jwk, alg)` to re-hydrate. KMS-backed flows require an adapter that exposes a `KeyLike` jose can call; `jose` does not natively wrap KMS endpoints. See `examples/signed-ucp-merchant.ts` for the runtime-independent re-hydrate pattern.

**Key rotation.** Mint a new key with a new `kid`, add the public JWK to your JWKS endpoint alongside the old one, then sign new profiles with the new key. Drop the old JWK after your verifier-side cache TTL has elapsed.

**Inline JWK in the profile vs separate JWKS endpoint.** UCP §6 mandates the separate `/.well-known/jwks.json` endpoint as the canonical trust source. The profile's `signing_keys[]` is informational; verifiers MUST resolve the kid against the JWKS to prevent a swap-after-sign attack.

## Quick start: full merchant via the `Checkout` orchestrator

`Checkout` is the canonical merchant surface in 2.0 for **fixed-price one-shot** endpoints; one config object, hooks for the merchant-specific pieces, and the SDK handles 402 emit, identity gating, x402 verify+settle, mppx compose, \$0 carve-out, identity\_metadata auto-attach, and the per-framework adapter.

For **variable-cost pay-per-result** endpoints (per-result search, per-token LLM, per-byte transcoding), reach for `computeFirstCheckout`; same config shape, but the probe leg runs the work, caches the result by content-hash of the request body, and emits a 402 with the EXACT computed price. The retry pays that exact amount and the merchant returns the cached body. Works on every exact-mode rail (x402-exact Base, tempo/charge, solana/charge, Stripe SPT) without upto / Permit2 / Settlement-Overrides. Tradeoff: the work runs on the unpaid probe leg, so mount `rateLimitHono` (`@agent-score/commerce/middleware/hono`) globally; it's load-bearing.

```typescript theme={"dark"}
import { Hono } from 'hono';
import { Checkout, pricingResult, validateShippingAgainstPolicy } from '@agent-score/commerce';
import { defaultA2aServices } from '@agent-score/commerce/discovery';

const checkout = new Checkout({
  rails: {
    tempo:     { recipient: process.env.TEMPO_RECIPIENT! },
    x402_base: { recipient: process.env.X402_BASE_RECIPIENT!, network: 'eip155:8453' },
    solana_mpp:{ recipient: process.env.SOLANA_RECIPIENT!,    network: 'solana:mainnet' },
    stripe:    { profileId: process.env.STRIPE_PROFILE_ID! },
  },
  url: 'https://merchant.example/purchase',
  preValidate: async (ctx) => {
    const body = (ctx.request.body ?? {}) as { product_slug?: string; shipping?: { country?: string; state?: string } };
    const product = await lookupProduct(body.product_slug);
    validateShippingAgainstPolicy({ country: body.shipping?.country ?? '', state: body.shipping?.state ?? '', policy: product, productName: product.name });
    return { product };
  },
  computePricing: async (ctx) => pricingResult({
    subtotalCents: ctx.state.product.priceCents,
    taxCents: ctx.state.product.taxCents,
    taxRate: ctx.state.product.taxRate,
    taxState: ctx.state.product.taxState,
  }),
  onSettled: async (ctx, outcome) => ({ ok: true, order_id: ctx.referenceId, tx_hash: outcome.txHash }),
  cdpApiKeyId:     process.env.CDP_API_KEY_ID,
  cdpApiKeySecret: process.env.CDP_API_KEY_SECRET,
  mppxSecretKey:   process.env.MPP_SECRET_KEY,
  gate: {
    apiKey: process.env.AGENTSCORE_API_KEY!,
    merchantName: 'Merchant',
    requireKyc: true, requireSanctionsClear: true, minAge: 21, allowedJurisdictions: ['US'],
  },
  // Optional: empty-body POSTs without a payment header auto-route to a sample 402
  // so x402 crawlers (awal x402 details, x402-proxy, ...) can discover the surface.
  discoveryProbe: {
    realm: 'merchant.example',
    sampleRail: 'tempo-mainnet',
    sampleAmountUsd: 1.0,
    sampleRecipient: process.env.TEMPO_RECIPIENT!,
  },
});
```

<Warning>
  **Solana MPP requires a static recipient with a pre-funded token account.** Point the Solana rail at a fixed wallet you control (as with `SOLANA_RECIPIENT` above) and pre-fund that wallet's USDC associated token account (ATA) once. Per-order rotating Solana deposit addresses (for example Stripe-multichain minted addresses) do not settle on Solana MPP, because the settlement transaction does not create the recipient's token account. Tempo and x402 (Base) settle fine to per-order recipients; only Solana needs the static, pre-funded wallet. When you mint per-order recipients via `@agent-score/commerce/stripe-multichain`, pass `staticRecipients: { solana: '<wallet>' }` so Solana is served from your fixed wallet, or leave Solana out of the rail set.
</Warning>

```ts theme={"dark"}
const app = new Hono();

// One-call mount: GET /.well-known/ucp + GET /.well-known/jwks.json + OPTIONS preflights.
// Express / Fastify have the same helper (`mountUcpRoutesExpress` / `mountUcpRoutesFastify`).
// Next.js / Web Fetch use file-based routing; call `buildSignedUcpResponse` directly inside the route handler.
checkout.mountUcpRoutesHono(app, {
  name: 'Merchant',
  wellKnownUcpUrl: 'https://merchant.example/.well-known/ucp',
  services: defaultA2aServices({ agentCardUrl: 'https://merchant.example/.well-known/agent-card.json' }),
  signingKid: 'merchant-2026-05',
});

app.post('/purchase', (c) => checkout.handleHono(c));
```

The 402 body Checkout emits auto-attaches `identity_mode` + `required_signer` + `signer_constraint` (and `linked_wallets` when the gate populated them) when an inbound `X-Wallet-Address` header is present; so agents self-correct at discovery instead of at the 403 retry.

See the [compute-first merchant example](https://github.com/agentscore/node-commerce/blob/main/examples/compute-first-merchant.ts) for the canonical variable-cost pattern via `computeFirstCheckout`.

## Fail-open (opt-in)

By default AgentScore Gate fails closed on AgentScore-side infra failure (429 / 5xx / network timeout); buyer gets 503. Pass `failOpen: true` to opt in to graceful degradation, then read the per-request degraded state via `getGateDegradedState(c)`:

```ts theme={"dark"}
import { agentscoreGate, getGateDegradedState } from '@agent-score/commerce/identity/hono';

const gate = agentscoreGate({ apiKey: process.env.AGENTSCORE_API_KEY!, failOpen: true });
app.use('/purchase', gate);

app.post('/purchase', async (c) => {
  const { degraded, infraReason } = getGateDegradedState(c);
  if (degraded) console.warn(`[gate] degraded: ${infraReason}`);
  // ...
});
```

`getGateDegradedState` is exported by every Node adapter (Hono, Express, Fastify). For `withAgentScoreGate` (Next.js / Web Fetch), the `degraded` + `infraReason` fields land on the `gate` object passed to your handler. Compliance denials (sanctions, age, jurisdiction, signer-mismatch) still deny regardless of `failOpen`; see [compliance-gating › Fail-open behavior](/compliance-gating#fail-open-behavior-opt-in).

## Examples

The [examples/](https://github.com/agentscore/node-commerce/tree/main/examples) directory has runnable single-file Hono apps for each common merchant scenario:

| Example                                                                                                                           | Scenario                                                                                                                                                                                                                                                                                                              |
| --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`api-provider.ts`](https://github.com/agentscore/node-commerce/blob/main/examples/api-provider.ts)                               | Per-call API billing on multiple rails: Tempo MPP + x402 (Base) + Solana MPP; no compliance gate                                                                                                                                                                                                                      |
| [`identity-only.ts`](https://github.com/agentscore/node-commerce/blob/main/examples/identity-only.ts)                             | Compliance gate without payment (vendor handles their own)                                                                                                                                                                                                                                                            |
| [`multi-rail-merchant.ts`](https://github.com/agentscore/node-commerce/blob/main/examples/multi-rail-merchant.ts)                 | Full agent-commerce: identity + Tempo MPP + x402 + Stripe SPT                                                                                                                                                                                                                                                         |
| [`stripe-multichain-merchant.ts`](https://github.com/agentscore/node-commerce/blob/main/examples/stripe-multichain-merchant.ts)   | Stripe-anchored multichain (PaymentIntent → tempo/base/solana deposit addresses)                                                                                                                                                                                                                                      |
| [`compute-first-merchant.ts`](https://github.com/agentscore/node-commerce/blob/main/examples/compute-first-merchant.ts)           | Pay-per-result variable-cost merchant via `computeFirstCheckout`. Probe runs the work + caches by body content-hash; settle replays the cached result. Works on every exact-mode rail (no upto / Permit2 / Settlement-Overrides).                                                                                     |
| [`compliance-merchant.ts`](https://github.com/agentscore/node-commerce/blob/main/examples/compliance-merchant.ts)                 | Regulated-goods merchant: full compliance gate + custom `onDenied` composing the denial helpers (`verificationAgentInstructions`, `isFixableDenial`, `buildSignerMismatchBody`, `buildContactSupportNextSteps`, `denialReasonStatus` / `denialReasonToBody` to assemble the {status, body} pair for any DenialReason) |
| [`per-product-policy-merchant.ts`](https://github.com/agentscore/node-commerce/blob/main/examples/per-product-policy-merchant.ts) | Multi-product merchant where each row carries its own compliance policy (hard gate, soft, or none). Uses `PolicyBlock`, `buildGateFromPolicy`, `runGateWithEnforcement`, and the one-call `validateShippingAgainstPolicy`.                                                                                            |
| [`signed-ucp-merchant.ts`](https://github.com/agentscore/node-commerce/blob/main/examples/signed-ucp-merchant.ts)                 | Signed UCP profile + JWKS endpoint via the one-call `checkout.mountUcpRoutesHono(app, ...)`. Demonstrates ephemeral-for-dev / env-JWK-for-prod and `bootstrapUcpSigningKey` lifespan-hook usage.                                                                                                                      |

## Links

* [npm](https://www.npmjs.com/package/@agent-score/commerce)
* [GitHub](https://github.com/agentscore/node-commerce)
