Skip to content

docs: clarify fiat vs crypto payments and fix stale x402 token examples#226

Merged
aaitor merged 3 commits into
mainfrom
docs/issue-1076-fiat-crypto-clarity
Jun 17, 2026
Merged

docs: clarify fiat vs crypto payments and fix stale x402 token examples#226
aaitor merged 3 commits into
mainfrom
docs/issue-1076-fiat-crypto-clarity

Conversation

@aaitor

@aaitor aaitor commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

Refreshes the docs to address hackathon feedback in nevermined-io/nvm-monorepo#1076"subscribers can't tell whether a plan is fiat or crypto upfront, and get blocked when they lack the required payment method."

The review found the issue partially addressed: the SDK primitives now exist (resolveScheme/resolve_scheme, dedicated error codes), but the buyer-facing docs over-claimed scheme auto-detection and contained stale, non-runnable token examples. This PR fixes two problems.

1. Correctness — stale x402 buyer-token examples

The direct getX402AccessToken / get_x402_access_token call now requires a create-first delegationConfig (TS throws locally; Python is rejected by the backend). 24 examples still used the bare two-arg form, so they don't run. Updated them to create a delegation first, then mint the token by delegationId:

  • Buyer flow: query-agents, process-requests
  • Quickstarts: getting-started/quickstart (Python), integrate/quickstart/python
  • Agent integrations: langchain (×4), express, fastapi, agentcore, strands
  • Platform integrations: google-a2a, mcp, nevermined-x402-ap2
  • products/nevermined-app/overview

2. Clarity — fiat vs crypto

  • order-plans — new "Which payment type does this plan need?" section with resolveScheme / resolve_scheme detection.
  • core-concepts — side-by-side fiat-vs-crypto prerequisites table.
  • nevermined-x402 — corrected the buyer-side Note: the direct token call does not auto-detect the scheme (defaults to nvm:erc4337); middleware and A2A clients do.
  • integration-faq — payment-method-mismatch troubleshooting (maps BCK.X402.0027, BCK.PROTOCOL.0050, and "No enrolled card found" to fixes).
  • card-enrollment / card-delegation — detect the required provider with resolveNetwork / resolve_network before enrolling.

Status of issue #1076's proposals

# Proposal Status Note
1 Auto-detect token method Partial helpers exist + used in middleware/A2A/CLI; the direct call still defaults to crypto (clarified here)
2 Plan-type badges in UI Open product/UX
3 Pre-purchase method check Open product/UX
4 Dual-payment plans Not possible isCrypto is a single boolean — a plan is strictly one type
5 Actionable error on mismatch Partial good "no card" errors exist; documented here

The docs/SDK-facing portion is addressed by this PR; remaining items (#2/#3/#4) are product/UX/protocol work, tracked via a status comment on #1076.

Not changed

  • docs/api-reference/** — generated/mirrored from the SDK repos.
  • skills/nevermined-payments/** — already uses the correct create-first pattern.

Test plan

  • mintlify broken-links — no broken links found
  • mintlify validate — build validation passed
  • Snippets verified against current SDK signatures on origin/main of payments / payments-py (import paths, arg order, delegationConfig, fiat scheme)
  • Reviewer: confirm the Mintlify preview renders the new tables/Notes correctly
  • Reviewer: sanity-check the fiat-vs-crypto guidance reads clearly for a first-time subscriber

🤖 Generated with Claude Code

Addresses hackathon feedback in nvm-monorepo#1076 — subscribers can't tell
a plan's payment type (fiat vs crypto) upfront and get blocked when they
lack the required method.

Correctness — the buyer-side getX402AccessToken / get_x402_access_token call
now requires a create-first delegationConfig (bare 2-arg calls throw or are
rejected). Update the stale examples to create a delegation first, then mint
the token by delegationId, across query-agents, process-requests, the
quickstarts, langchain, express, fastapi, agentcore, strands, the google-a2a
/ mcp / x402-ap2 integration guides, and the app overview.

Clarity (fiat vs crypto):
- order-plans: add "Which payment type does this plan need?" with
  resolveScheme / resolve_scheme detection.
- core-concepts: add a fiat-vs-crypto prerequisites comparison table.
- nevermined-x402: correct the buyer-side Note — the direct token call does
  NOT auto-detect; it defaults to nvm:erc4337. Middleware / A2A clients do.
- integration-faq: add a payment-method-mismatch troubleshooting entry.
- card-enrollment / card-delegation: add provider detection via
  resolveNetwork / resolve_network before enrolling.

Skill references under skills/nevermined-payments/ already use the correct
create-first pattern and were left unchanged. api-reference/ is generated and
untouched. Verified with mintlify broken-links and mintlify validate.
Copilot AI review requested due to automatic review settings June 16, 2026 16:24
@aaitor aaitor requested a review from a team as a code owner June 16, 2026 16:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Nevermined documentation to (1) fix stale/non-runnable x402 buyer-token examples by adopting the delegation-first flow, and (2) clarify up-front whether a plan requires fiat (card) or crypto, including how to detect the correct scheme/provider via SDK helpers.

Changes:

  • Replaced direct getX402AccessToken / get_x402_access_token examples with “create delegation first, then mint token by delegationId” patterns across guides and integrations.
  • Added/expanded fiat-vs-crypto guidance (tables, notes, troubleshooting) and documented scheme/provider detection with resolveScheme / resolve_scheme and resolveNetwork / resolve_network.
  • Updated integration docs (MCP, A2A, framework examples) to reflect the corrected token/delegation flow and scheme defaults.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/solutions/card-delegation.mdx Clarifies that the enrollment provider must match the plan; links to provider detection guidance.
docs/products/payments/card-enrollment.mdx Adds resolveNetwork / resolve_network snippet to determine the correct card provider before enrolling.
docs/products/nevermined-app/overview.mdx Updates the SDK integration snippet to use delegation-first token minting (but currently has undefined variables; see comment).
docs/integrations/nevermined-x402-ap2.mdx Fixes Python subscriber token example to use create-delegation-first + delegation_id.
docs/integrations/mcp.mdx Updates subscriber token minting example to include delegation creation and pass delegationId.
docs/integrations/google-a2a.mdx Adds note about fiat vs crypto handling and updates TypeScript token example to delegation-first.
docs/integrate/quickstart/python.mdx Fixes quickstart buyer flow to create delegation first and mint token with X402TokenOptions.
docs/integrate/add-to-your-agent/strands.mdx Updates client example to create delegation first and pass delegation config when minting tokens.
docs/integrate/add-to-your-agent/langchain.mdx Updates both TS/Python client snippets to the delegation-first token flow.
docs/integrate/add-to-your-agent/fastapi.mdx Fixes Python client example to create delegation first and pass explicit scheme + delegation id.
docs/integrate/add-to-your-agent/express.mdx Fixes TypeScript client example to create delegation first and pass scheme + delegationId.
docs/integrate/add-to-your-agent/agentcore.mdx Updates Python client snippet to include delegation-first token minting and cleans up imports.
docs/getting-started/quickstart.mdx Updates subscriber SDK examples (Python) to use delegation-first token minting; adds fiat option comments.
docs/getting-started/core-concepts.mdx Adds a fiat-vs-crypto prerequisites table and points readers to scheme detection guidance.
docs/getting-started/ai-agent-purchase.mdx Clarifies that plans are strictly fiat or crypto and links to detection section.
docs/development-guide/query-agents.mdx Reworks buyer-token section to explain delegations and updates TS/Python snippets accordingly.
docs/development-guide/process-requests.mdx Adds delegation-first note and updates TS/Python examples to mint tokens against delegationId.
docs/development-guide/order-plans.mdx Adds “Which payment type…” section with resolveScheme / resolve_scheme and scheme-default clarification.
docs/development-guide/nevermined-x402.mdx Corrects guidance: direct buyer token minting does not auto-detect scheme; middleware/A2A do.
docs/development-guide/integration-faq.mdx Adds troubleshooting table mapping common mismatch errors to concrete fixes.

Comment thread docs/development-guide/order-plans.mdx Outdated
Comment thread docs/products/nevermined-app/overview.mdx
@mintlify

mintlify Bot commented Jun 16, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
Nevermined 🟢 Ready View Preview Jun 16, 2026, 4:31 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

…iew snippet

- order-plans: import resolve_scheme from payments_py.x402.resolve_scheme
  (submodule path, consistent with the x402 api-reference and resolve_network)
- nevermined-app/overview: define agentId/planId so the SDK snippet is
  copy/paste runnable (was referencing undefined planId/agentId)

@r-marques r-marques left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated PR review — ✅ Ready to merge

Reviewed origin/main...HEAD (20 files) with the pr-review-toolkit panel: docs-quality reviewer + two dedicated fact-checkers (SDK API accuracy against @nevermined-io/payments / payments_py, and error-code + internal-link integrity against nvm-monorepo + the docs tree).

This is a documentation-only PR whose value rests entirely on the factual accuracy of its SDK examples, error codes, and cross-links. All three were verified against source — and they hold up. No blockers, no should-fix items; a few optional polish nits below.

Verification performed (all ✅)

  • Every SDK signature in the diff is real and copy-paste-safe. The central claim — getX402AccessToken / get_x402_access_token default to nvm:erc4337 and do not auto-detect the scheme — is confirmed (payments/src/x402/token.ts:69, payments-py/payments_py/x402/token.py:177). createDelegation/create_delegation field names, the delegationConfig/scheme token options, the resolveScheme/resolveNetwork (+ Python resolve_scheme/resolve_network) exports, and the X402TokenOptions/DelegationConfig/CreateDelegationPayload import paths all match the current SDK source. The "create a delegation first, then mint against it" narrative is exactly the SDK's now-preferred path (the old inline form emits a FutureWarning).
  • Both troubleshooting error codes are real — verified against origin/main (note: they are recently added; a stale local checkout won't have them, but origin/main does):
    • BCK.X402.0027api-errors.ts:1410 ("Payment method not found or unusable"), thrown at apps/api/src/x402/handlers/card-delegation-scheme.handler.ts:219 with the literal message "No accessible payment method found for this API Key" — matching the FAQ's paraphrase.
    • BCK.PROTOCOL.0050api-errors.ts:1212 ("Fiat plans cannot be ordered through this endpoint. Use the x402 card-delegation settle flow (POST /api/v1/x402/settle)…"), and it is thrown for fiat plans on the order path (apps/api/src/protocol/protocol.service.ts:1223, covered by protocol.service.fiat-rejection.spec.ts). The FAQ's "use orderFiatPlan() / POST /api/v1/x402/settle" guidance is correct.
  • Plan-type source verified: registry.price.isCrypto (ContractsTypes.ts:36) and metadata.plan.fiatPaymentProvider (DDOTypes.ts:77) both exist.
  • All 7 internal cross-links/anchors resolve, including the ones that looked risky: card-enrollment#choosing-a-provider (heading "## Choosing a Provider" at line 194), /docs/products/payments/mandates, and top-up#when-top-ups-stop.
  • Style/terminology on-spec: second person, active voice, "plan" (never "subscription"), payment-signature header, x402 v2 schemes, no legacy isValidRequest, no staging_* environment names. The repeated delegation snippet is consistent (same field names/comments/values) across TS and Python in all files.

🔴 Blockers (0)

None.

🟡 Should fix (0)

None.

💡 Good to have (4, all optional)

  • Mixed scheme inclusion across the new delegation examples. Four examples pass scheme explicitly (express.mdx, fastapi.mdx, quickstart.mdx, integrate/quickstart/python.mdx) while the rest omit it. Functionally fine (nvm:erc4337 is the default), but a reader copying two adjacent guides sees the call shaped differently for no stated reason. Consider standardising on the express/fastapi style — the commented scheme: 'nvm:erc4337', // 'nvm:card-delegation' for fiat plans line is the single best in-context reminder of the fiat path. (docs-quality, confidence 75)
  • docs/development-guide/integration-faq.mdx still has no trailing newline (the edit appends content but leaves \ No newline at end of file). Harmless to Mintlify; worth adding while the file is open to keep future diffs clean. (docs-quality, confidence 80)
  • process-requests.mdx is the one page in the set that doesn't get the closing "detect a plan's type → order-plans#which-payment-type-does-this-plan-need" pointer the others received. It already links there in its top <Note>, so this is purely about making the set fully parallel. (docs-quality, confidence 60)
  • resolveNetwork / fiatPaymentProvider typing nuance. resolveNetwork() actually returns string | undefined (the raw fiatPaymentProvider value), not a constrained 'stripe' | 'braintree' | 'visa' union — the documented values are correct in practice but not type-enforced. Separately, the backend DDOTypes.fiatPaymentProvider enumerates only 'stripe' | 'braintree' while the docs (and the SDK delegation provider union) include 'visa'; likely just a backend type lag, but worth a quick confirm that visa flows through fiatPaymentProvider the same way. (api-accuracy, confidence 60)

✅ Strengths

  • Fixes a genuinely misleading stale example. The old getX402AccessToken(planId, agentId) one-liner silently defaulted to crypto; the new "create a delegation first, then mint against it" flow matches the SDK's current preferred path and prevents the exact fiat-vs-crypto mismatch the PR sets out to clarify.
  • Accurate, actionable troubleshooting. The new FAQ maps real, recently-added backend error codes to concrete fixes — the kind of problem-aware, practical content the repo's style guide asks for.
  • Strong cross-file consistency and terminology discipline, with clean comparison tables in core-concepts.mdx and order-plans.mdx and correct Mintlify component usage throughout.

r-marques
r-marques previously approved these changes Jun 17, 2026
…line

- Add the commented `scheme: 'nvm:erc4337' // 'nvm:card-delegation' for fiat`
  reminder to the buyer-token examples that omitted it (query-agents,
  process-requests, langchain, agentcore, strands, google-a2a, mcp, app
  overview), matching the express/fastapi style so the fiat path is signalled
  uniformly at the token call.
- integration-faq: add trailing newline.

Left pre-existing canonical examples (top-up, x402-facilitator, products/
payments/overview, mandate-selection) as-is to keep the PR scoped.
@aaitor

aaitor commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

Thanks for the thorough fact-check — addressed the optional nits in e7f5172:

  1. Mixed scheme inclusion — standardized on the express/fastapi style: added the commented scheme: 'nvm:erc4337' // 'nvm:card-delegation' for fiat plans reminder to the buyer-token calls that omitted it (query-agents, process-requests, langchain pattern-B, agentcore, strands, google-a2a, mcp, app overview). Left the dynamic-scheme discovery-first blocks (scheme: accept.scheme) and the pre-existing canonical examples (top-up, x402-facilitator, products/payments/overview, mandate-selection) untouched to keep the PR scoped — happy to do a follow-up sweep across those if you'd prefer full repo-wide uniformity.
  2. Trailing newline on integration-faq.mdx — fixed.
  3. process-requests closing pointer — it already links to order-plans#which-payment-type-does-this-plan-need in its top <Note>, so the detection pointer is present; left as-is rather than duplicating it at the bottom.
  4. resolveNetwork typing / visa — good catch. The doc comments describe the values ('stripe' | 'braintree' | 'visa'), which are correct in practice even though the return type is string | undefined, so I left them as a value hint. On visa: it's a first-class provider in the card-enrollment "Choosing a Provider" table and the SDK delegation provider union, so the docs are right — the backend DDOTypes.fiatPaymentProvider enum looks like type lag (worth a backend tidy-up, but out of scope here).

mintlify validate + broken-links both still green.

@aaitor aaitor merged commit d2b9d01 into main Jun 17, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants