Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.agentscore.sh/llms.txt

Use this file to discover all available pages before exploring further.

agentscore-commerce is the full merchant-side SDK for agent commerce in Python. One install bundles identity gating, payment-protocol helpers, 402 challenge builders, discovery doc generators, and Stripe multichain support. Submodule imports keep dependencies focused.

Installation

pip install agentscore-commerce[fastapi]   # or [flask], [django], [aiohttp], [sanic], [starlette], [stripe]
Accept x402 payments through the Coinbase facilitator (mints per-endpoint CDP JWTs via cdp-sdk):
pip install 'agentscore-commerce[fastapi,x402,coinbase]'
# Set CDP_API_KEY_ID and CDP_API_KEY_SECRET in the environment.
The [mppx] extra adds Tempo MPP + Stripe SPT helpers.

Build the x402 accepts entry for a 402 challenge

from agentscore_commerce.payment import build_x402_accepts_for_402, create_x402_server

x402_server = await create_x402_server(facilitator="coinbase", rails=["x402-base-mainnet"])

x402_accepts = build_x402_accepts_for_402(
    x402_server,
    network="eip155:8453",
    price=f"${total_usd}",
    pay_to=os.environ["TREASURY_BASE_RECIPIENT"],
    max_timeout_seconds=300,
)
Returns a list of plain dicts ready for the 402 body’s accepts[]. extra.name is derived from the registered scheme metadata so the EIP-712 domain matches the on-chain USDC contract.

Submodules

ImportWhat it gives you
agentscore_commerce.identity.{fastapi,flask,django,aiohttp,sanic,middleware}Trust gate middleware: KYC, age, sanctions, jurisdiction. AgentScoreGate(...) (or agentscore_gate(app, ...) on Flask/Sanic), capture_wallet(...), verify_wallet_signer_match(...), get_assess_data(...).
agentscore_commerce.identity (publishers)Cross-vendor identity-publishing helpers: build_a2a_agent_card (Google A2A v1.0 Signed Agent Card, served at /.well-known/agent-card.json), build_ucp_profile (Google Universal Commerce Protocol, served at /.well-known/ucp). Both return unsigned dataclasses with to_dict() — vendor signs + publishes.
agentscore_commerce.paymentnetworks, USDC, rails registries; payment_directive, build_payment_headers (one-call WWW-Authenticate + PAYMENT-REQUIRED bundle), www_authenticate_header, payment_required_header, alias_amount_fields (v1↔v2 amount field shim for v1-only x402 parser compat), settlement_override_header, dispatch_settlement_by_network, extract_payment_signer, build_idempotency_key; create_x402_server, create_mppx_server; drop-in x402 helpers: validate_x402_network_config (boot-time guard), verify_x402_request (parse + validate inbound X-Payment), process_x402_settle (verify-then-settle in one call), classify_x402_settle_result (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).
agentscore_commerce.discoveryis_discovery_probe_request, build_discovery_probe_response (with optional x402_sample for x402-aware crawlers), sample_x402_accept_for_network, build_well_known_mpp, build_well_known_x402 (x402scan v1 /.well-known/x402 shape: {version: 1, resources: ["METHOD /path"]}), build_llms_txt, build_skill_md (Claude-Skill-compatible /skill.md agent-discovery manifest — strictly agent-facing data only, no internal posture), agentscore_openapi_snippets, siwx_security_scheme + x_payment_info_extension (fixed/dynamic price + multi-protocol) + x_guidance_extension per the x402scan OpenAPI spec, build_bazaar_discovery_payload; NoindexNonDiscoveryMiddleware (ASGI — covers FastAPI/Starlette/aiohttp/Sanic) + install_flask_noindex(app, ...) (Flask) + DjangoNoindexMiddleware (Django) — emit X-Robots-Tag: noindex on every path except the agent-discovery surfaces (/openapi.json, /llms.txt, /skill.md, /.well-known/{mpp.json,x402,agent-card.json,ucp}, /favicon.{png,ico}); pure helpers is_discovery_path + DEFAULT_DISCOVERY_PATHS for any framework not listed.
agentscore_commerce.challengebuild_accepted_methods, build_identity_metadata, build_how_to_pay, build_agent_instructions, build_402_body, build_pricing_block (cents → dollar-string with shipping support), first_encounter_agent_memory, OrderReceipt dataclass; respond_402 — drop-in 402 emit that preserves pympp’s WWW-Authenticate and layers x402’s PAYMENT-REQUIRED. build_validation_error — 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.
agentscore_commerce.stripe_multichaincreate_multichain_payment_intent, get_deposit_address, simulate_crypto_deposit, create_mppx_stripe; create_pi_cache (TTL’d PI / deposit-address cache, Redis-backed when redis_url set), simulate_deposit_if_test_mode (gates on sk_test_ and looks up the PI for you), STRIPE_TEST_TX_HASH_SUCCESS / STRIPE_TEST_TX_HASH_FAILED constants.
agentscore_commerce.apiEverything from agentscore-py re-exported in one place: AgentScore + AgentScoreError, AGENTSCORE_TEST_ADDRESSES + is_agentscore_test_address. Don’t add agentscore-py as a separate dep — the two can drift versions.

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. create_session_on_missing auto-mints a verification session when no identity is present. verify_wallet_signer_match routes the verdict through the API’s server-side resolve_signer mode — one /v1/assess round trip carries both the gate verdict and the wallet-signer-match outcome. Repeat lookups for the same (claimed, signer) pair hit a per-entry cache so repeat payments under the same operator cost zero extra API calls. capture_wallet 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 dataclass — your service signs + serves it however its key infrastructure works.
from agentscore_commerce.identity import (
    UCPService,
    UCPSigningKey,
    UCPPaymentHandler,
    A2AAgentCardCapabilities,
    build_a2a_agent_card,
    build_ucp_profile,
)

# 1. Google A2A v1.0 Signed Agent Card — published at /.well-known/agent-card.json
card = build_a2a_agent_card(
    name="My Agent Service",
    url="https://agents.example.com",
    capabilities=A2AAgentCardCapabilities(endpoints=[{"name": "purchase", "method": "POST"}]),
    data=assess_result,
)

# 2. Google Universal Commerce Protocol profile — published at /.well-known/ucp
profile = build_ucp_profile(
    name="My Agent Service",
    services=[UCPService(type="rest", url="https://agents.example.com")],
    payment_handlers=[UCPPaymentHandler(name="tempo", config={"recipient": TEMPO_ADDR})],
    signing_keys=[UCPSigningKey(kid="me", kty="EC", alg="ES256")],
    data=assess_result,
)
Note: ACP (Stripe + OpenAI Agentic Commerce Protocol) is a transactional checkout protocol — not an identity-publishing surface. ACP merchants integrate through the existing build_402_body + build_payment_headers + Stripe SPT rail.

Quick start (FastAPI)

from fastapi import Depends, FastAPI, Request
from agentscore_commerce.identity.fastapi import AgentScoreGate, get_assess_data
from agentscore_commerce.payment import (
    PaymentDirectiveInput,
    payment_directive,
    www_authenticate_header,
)
from agentscore_commerce.challenge import (
    Build402BodyInput,
    BuildAcceptedMethodsInput,
    BuildAgentInstructionsInput,
    BuildHowToPayInput,
    HowToPayRails,
    TempoConfig,
    TempoRailConfig,
    build_402_body,
    build_accepted_methods,
    build_agent_instructions,
    build_how_to_pay,
)

app = FastAPI()
_gate = AgentScoreGate(api_key="ask_...", require_kyc=True, min_age=21)


# Gate runs CONDITIONALLY — fires only when a payment credential is attached so
# anonymous discovery returns a 402 challenge with rails + pricing. Identity is
# verified at settle time on the retry leg.
async def gate_on_settle(request: Request) -> None:
    has_payment_header = bool(
        request.headers.get("payment-signature")
        or request.headers.get("x-payment")
        or (request.headers.get("authorization") or "").startswith("Payment ")
    )
    if not has_payment_header:
        return None
    return await _gate(request)


@app.post("/purchase", dependencies=[Depends(gate_on_settle)])
async def purchase(assess=Depends(get_assess_data)):
    # ... identity + payment processing ...
    ...

Fail-open (opt-in)

By default AgentScore Gate fails closed on AgentScore-side infra failure (429 / 5xx / network timeout) — buyer gets 503. Pass fail_open=True to opt in to graceful degradation, then read the per-request degraded state via get_gate_degraded_state(request):
from fastapi import Depends, FastAPI, Request
from agentscore_commerce.identity.fastapi import AgentScoreGate, get_gate_degraded_state

app = FastAPI()
gate = AgentScoreGate(api_key=os.environ["AGENTSCORE_API_KEY"], fail_open=True)

@app.post("/purchase", dependencies=[Depends(gate)])
async def purchase(request: Request):
    state = get_gate_degraded_state(request)
    if state["degraded"]:
        logger.warning("gate degraded: %s", state["infra_reason"])
    # ...
get_gate_degraded_state is exported by every Python adapter (FastAPI, Flask, Django, AIOHTTP, Sanic, ASGI middleware) and reads the framework-appropriate request state. Signatures take a request argument on every adapter except Flask, which reads from g and takes no arguments (get_gate_degraded_state()). Compliance denials (sanctions, age, jurisdiction, signer-mismatch) still deny regardless of fail_open — see compliance-gating › Fail-open behavior.

Examples

The examples/ directory has runnable single-file FastAPI apps for each common merchant scenario:
ExampleScenario
api_provider.pyPer-call API billing on multiple rails: Tempo MPP + x402 (Base + Solana); no compliance gate
identity_only.pyCompliance gate without payment (vendor handles their own)
multi_rail_merchant.pyFull agent-commerce: identity + Tempo MPP + x402 + Stripe SPT
stripe_multichain_merchant.pyStripe-anchored multichain (PaymentIntent → tempo/base/solana deposit addresses)
variable_cost_merchant.pyPay-per-actual-usage on two protocols: x402 upto + MPP tempo session
compliance_merchant.pyRegulated-goods merchant — full compliance gate + custom on_denied composing the denial helpers (verification_agent_instructions, is_fixable_denial, build_signer_mismatch_body, build_contact_support_next_steps)
per_product_policy_merchant.pyMulti-product merchant where each row carries its own compliance policy (hard gate, soft, or none). Uses PolicyBlock, build_gate_from_policy, run_gate_with_enforcement, shipping_country_allowed, shipping_state_allowed.