"Use this skill when the user is integrating the Net Payments SDK (`net-payments` Rust crate, `net_payments` lib, or the Python/Node `CapabilityGateway` + `PaymentProvider` payment surface) — x402-native payments for the Net mesh. Covers pricing a capability at discovery (`net.pricing.terms@1`), issuing signed quotes (`net.payment.quote@1`), the provider lifecycle engine (`PaymentEngine`: quote → verify → settle → tiered verification → billing), the caller flow (`CallerPaymentFlow` / `ProviderChannel`: pricing → spend policy → payload → pay), paid agent-to-agent tasks (prepare → purchase → submit: `serve_a2a_configured`, `redeem_for_task` on a reservation-bound quote, `A2aCallerFlow` + a durable `A2aPurchaseStore`), facilitators (mock + the real HTTP `verify`/`settle` client, config packs, auth), tiered verification (`observed | confirmed(n) | final`) with the independent on-chain `ChainChecker`, reorg handling, the settlement signer seam (`SchemeSigner` / `ExternalSigner` / `ExternalSvmSigner` / `ExternalXrplSigner` — EIP-3009 exact-EVM, SPL exact-SVM, exact-XRPL; keys never cross the boundary), the spend policy engine (budgets, delegation inheritance, `requires_payment_approval`), immutable billing events + the billing stream, network enablement (CAIP-2/CAIP-19, the signed asset registry, Base/Solana/xrpl config-not-code ladder), the outbound HTTP 402 two-way door, the failure schematic (`net.payment.failure@1`) that rides denials beside the human error, the multi-language SDK surfaces (Python AND Node/TS at full demand+supply parity with Rust — `CapabilityGateway`, paid `PaymentProvider` + `buildPricingTerms`, HTTP-402 client, eip155/svm/xrpl signers, approval verbs, free `publishTools`; paid A2A is Rust + Python only), and cross-language golden vectors + conformance. Triggers on imports of `net-payments` / `net_payments`; on `x402`, `PaymentEngine`, `PaymentQuote`, `PricingTerms`, `net.payment.*` / `net.billing.* / net.settlement.*`, `X402Carry`, `VerificationTier`, `confirmed(n)`, `reorg`, `SchemeSigner`, `ExternalSigner`, `ExternalSvmSigner`, `SvmTransferIntent`, SPL/Solana settlement, `SpendPolicyEngine`, `BillingEvent`, `MeshPaymentChannel`, `serve_payments`, `serve_a2a_configured`, `redeem_for_task`, `A2aCallerFlow`, `prepare_task`/`purchase_task`/`submit_task`, `gated_invoke`, `requires_payment_approval`, `CAIP-2`/`CAIP-19`, `HttpFacilitator`, `EIP-3009`, HTTP 402; and on phrases like 'price a capability', 'charge for a tool', 'charge for an agent task', 'sell bounded work to another agent', 'paid A2A', 'pay to invoke', 'settle on Base/Solana', 'verify a payment on-chain', 'spend limit / budget', 'approve a payment', 'pay an x402 API'. Net signs the commercial facts around invocation; it does NOT custody funds, process payments, issue invoices, or move money. Skip for unrelated event-bus / mesh work (the `net-event-bus` skill) or for editing payments' own internals unless the task is payments integration."
Resources
19Install
npx skillscat add ai-2070/net/net-payments Install via the SkillsCat registry.
Net Payments SDK (x402-native)
net-payments is not a payment processor. It does not custody funds,
process payments, issue invoices, determine taxes, or clear transactions.
x402 v2 moves the money; Net signs the commercial facts around it —
provider identity, discovery-time pricing, tiered verification, immutable
billing, and spend policy.
Before you write or edit any payment code, read concepts.md in this skill
directory. It is the conceptual prerequisite for everything else. The API
templates will look like a dozen payment SDKs and you will write something that
compiles, runs, and is a rejected PR — because the constraints here
(non-custodial, byte-preserved x402, no parallel wire format, tiers not
booleans) are not the constraints of a normal payments library.
How to use this skill
Load reference files on demand — do not read them all up front.
| File | Read when |
|---|---|
concepts.md |
Always first. The mental model, the category line, the eight doctrines, the object model at a glance, the data boundary (what "commercial facts" may and may not carry — no PII, by construction), "no HTTP endpoint required," the review invariant. ~5 min. |
bindings/coverage.md |
Before promising payments works in a given language. Payments is a three-binding subsystem: Rust, Node and Python only, and Node/Python reach it solely through the low-level package. Go and C have no payments API at all. |
object-model.md |
When touching the five Net envelopes — exact fields, the canonical signing regime, versioning, idempotency, amounts. |
x402.md |
When touching x402 structures — X402Carry byte-preservation, PaymentRequirements/PaymentPayload/settlement views, CAIP ids, the exact EVM scheme. |
provider.md |
When the user charges for a capability — PaymentEngine lifecycle (quote → verify → settle → serve → bill), provider admission policy, pricing at publish, serve_payments over the mesh, and terminal-record compaction (default-on at 6h; why status() is not an audit surface). |
caller.md |
When the user pays to invoke — CallerPaymentFlow, ProviderChannel (InProcessProvider / MeshPaymentChannel), spend check, the approval loop, the MCP gateway path. |
a2a.md |
When the user charges for an agent task — paid A2A from the money side: pricing <node>/net.a2a.task/<service>, one PaymentEngine behind both serve_payments and EngineTaskAdmissionGate, redeem_for_task against the reservation-bound input_hash, A2aCallerFlow over a durable A2aPurchaseStore, the purchase-state table (unknown vs denied{funds_ambiguous} vs paid_unexecutable), and the operator queue that accumulates by design. |
facilitator.md |
When wiring the verify/settle boundary — the Facilitator trait, the mock + its injectable modes, the real HttpFacilitator, GET /supported validation, auth, config packs. |
verification.md |
When the question is about confidence — the observed / confirmed(n) / final tiers, the independent ChainChecker, reorg freeze, the immutable chain, idempotency/replay, and the deadline on re-verification (the retention horizon). |
signer.md |
When touching settlement signing — the SchemeSigner seam, ExternalSigner (production) vs DevLocalSigner (testnet), EIP-3009 authoring, the no-raw-signing invariant. |
spend-policy.md |
When the user wants limits, budgets, or approvals — SpendPolicyEngine, SpendLimits, the fail-closed default posture, the operator approval surface, delegation inheritance. |
networks.md |
When enabling a network — CAIP-2/CAIP-19, the signed asset registry, the Base Sepolia → Base → Solana → xrpl ladder, "config, not code," the live testnet runbook. |
billing.md |
When the user wants usage records / a billing stream — BillingLog (subscribe/read/export), immutability, the lifecycle-hooks doctrine, what billing is NOT. |
http402.md |
When a Net agent pays an external x402 HTTP API — the outbound X402HttpFlow + the Python / Node PaymentHttpClient, the header-only v2 transport, why it's the same objects (the two-way door). |
failure-schematic.md |
When handling denials / refusals — the net.payment.failure@1 object that rides beside the human error, the reason→recovery mapping, the header discipline, its payment-only scope (code: "payment"; non-payment admission failures don't ride it), and how each surface (MCP / Python failure field / tracing) projects it. |
bindings.md |
First, when any code is going to be written. The routing page: which companion to load, and the two facts that decide whether there is code to write at all — payments is Rust/Python/Node only, and in Node and Python it lives in the low-level package (@net-mesh/core, net), never the wrapper. Then load exactly one of bindings/{rust,typescript,python,go,c}.md. |
testing.md |
When writing/running tests — cross-language golden vectors, the mock conformance suite, the key-invariant negative test, feature-gated suites, the env-gated live run. |
gotchas.md |
When the user's framing carries a wrong mental model, when migrating, or before merging — the review invariant, "what not to build," the byte-preservation trap, common mistakes. |
source-access.md |
When you need to read the payments source and you are not inside the Net repository. Two cases: opening a file this skill cites, and answering something this skill does not cover — the exact serialized shape of an object, how verification or settlement actually proceeds, whether a surface exists in the binding being written. One opensrc command fetches the whole tree; the page carries the root map that makes shorthand citations (core/quote.rs, x402/mod.rs) resolvable, why crates:net-payments returns "not found" (the crate is unpublished — that is not a missing feature), what the checkout will not contain, why a line anchor is a hint rather than an address, and where the golden vectors and conformance tests are. Read concepts.md for the model first; source settles mechanism, not what may be built. |
TL;DR mental model (the absolute minimum)
If you remember nothing else from concepts.md, remember these:
- x402 is the payment wire; Net signs around it. Net envelopes wrap x402
structures; they never replace, translate, or re-encode them. Chain
specifics live in x402 schemes + facilitator config — never in Net core. - Byte-preservation is law. x402 documents are carried as base64 of their
original bytes (X402Carry), never re-serialized through Net types.
Re-serializing a received x402 doc (envelope drift) is a rejected PR. - Non-custodial by construction. Identity keys ≠ settlement keys. The
SchemeSignertakes typed operations and returns signatures; there is no
raw-bytes signing method and no way for a binding or agent to reach a key. - Verification is a tier, not a boolean:
observed | confirmed(n) | final. A facilitator receipt isobserved, full stop —confirmed(n)
andfinalcome only from the independent on-chainChainChecker, so the
facilitator is never in the trust root. Reorg is a first-class outcome that
freezes the quote; billing events are immutable. - The policy engine decides, not the model. Spend policy runs caller-side
before anything leaves; provider policy runs at quote issuance and
re-checks before the handler. Handlers never see unpaid calls. Approvals
render in UX; the decision lives in shared policy state. - Enabling a network is config, not code. Facilitator pack + registry
entries + a conformance run — no new envelope types, no core changes, no
per-network branches outsidesrc/x402/. - The engine store is bookkeeping; the billing log is the record. Terminal
quote records are compacted 6h past quote expiry by default, soengine.status()returnsNonefor a payment that completed fine — build
reconciliation on the billing stream. Replay protection is never compacted:
settlement-transaction tombstones are permanent at every setting, and nothing
unredeemed or frozen is retired. The horizon is also your re-verification
window; if you re-verify out of band, widen it or passNone.
The category line, verbatim: Net standardizes the commercial facts around
capability invocation; it does not intermediate the money.
If the user's language conflicts with any of these ("Net wallet", "generate an
invoice", "sign these bytes", "translate x402", "the facilitator confirmed
finality", "auto-refund the overpayment"), stop and read gotchas.md — they're
carrying a mental model that produces compiling-but-rejected code.
Workflow when integrating
- Select the binding, then load exactly one — and answer "is there a payments
API at all" before anything else. Payments is a three-binding subsystem.- Read the language off the project:
Cargo.toml→ Rust,package.json
→ Node/TS,pyproject.tomlorrequirements.txt→ Python,go.mod→ Go,Makefile/CMakeLists.txtbeside.c/.h→ C. - Rust, Python and Node/TS have a full native demand + supply flow.
Go and C have no payments API at all — not partial, not reduced. Go has
a golden-vector conformance test and nothing else; C does not even have
that. If the task is "add x402 payments to our Go service", that is a
language choice or a feature request, not a coding task. Say so first. - Then read
bindings.md(routing) and exactly one companion —bindings/rust.md,bindings/typescript.md,bindings/python.md,bindings/go.md,bindings/c.md.bindings/coverage.mdis the
per-operation matrix and the authoritative answer to "does this language
have X". - Payments is not in the ergonomic wrapper. Neither
@net-mesh/sdknornet_sdkcontains a line of it. Every payments symbol in Node and Python
is in@net-mesh/coreandnetrespectively, and there is no@net-mesh/paymentspackage. An import from the wrapper fails in a way
that looks like a missing feature. - Never default to Rust because the substrate is Rust. With no project
context and no language named, ask — the answer decides whether there is
any code to write.
- Read the language off the project:
- Read
concepts.mdif this is your first invocation this session. - Which side is the user on?
- Charging for a capability (provider) →
provider.md. Price at publish
(net.pricing.terms@1), run thePaymentEnginelifecycle, pass aPaymentFlowintogated_invokeso the payment gate runs before the
handler. - Paying to invoke (caller) →
caller.md.CallerPaymentFlowover aProviderChannel, spend policy, the approval loop; branch on thenet.payment.failure@1schematic that rides a denial (failure-schematic.md). - Paying an external x402 HTTP API →
http402.md(X402HttpFlow/PaymentHttpClient). - Charging for, or buying, an agent task →
a2a.md. Paid A2A is
prepare → purchase → submit, not a one-shot invoke: the same engine must
sit behindserve_paymentsand the admission gate, and the caller's
attempt is durable on disk. Rust and Python only, both directions.
- Charging for a capability (provider) →
- Pick the facilitator. Default to
MockFacilitator(the conformance
backbone) for anything not touching real money;HttpFacilitator+ a
config pack for a real network.facilitator.md. - Set the required tier. Receipt-trust (
observed) or an independent
check (confirmed(n)/finalviaChainChecker)?verification.md. - Wire the signer if settling on a real network —
ExternalSigner
(eip155/EIP-3009; key never in Net),ExternalSvmSigner(solana/SPL,
intent-in/blob-out), orExternalXrplSigner(xrpl/presigned Payment blob),
registered per namespace;DevLocalSignerfor testnet only (behindunsafe-dev-signer). From Python, all three ride thepayment_signer*
kwargs.signer.md. - Configure spend policy — limits, allowed networks/assets, the approval
surface. Real networks deny by default.spend-policy.md. - Enabling a new network? It's config + registry + conformance, never
code.networks.md. - Surface billing via
BillingLog(stream/export).billing.md. - Test against golden vectors + the mock conformance suite; keep the
key-invariant negative test green.testing.md. - Before merging, run the change past the review invariant in
gotchas.md— most payments mistakes are scope violations, not bugs. - If you're unsure about an API, read the source — it's ground truth:
- Rust core:
net/crates/net/payments/src/(engine/,flow/,facilitator/,core/,x402/,policy/,checker/,billing/) - Failure schematic (SDK wire object):
net/crates/net/sdk/src/tool_payment.rs - Rust examples/tests:
payments/examples/,payments/tests/ - Python surface:
net/crates/net/bindings/python/src/capability_gateway.rs,payment_http.rs, and the_net.pyistub - Cross-lang vectors:
net/crates/net/tests/cross_lang_payments/
- Rust core:
What this skill deliberately does not cover
- The base mesh, nRPC, capabilities, MCP bridge, event bus — that's the
net-event-busskill. This skill assumes the substrate and only covers the
money layer on top. - Refund/dispute semantics — the
net.payment.dispute@1tag is reserved;
no semantics ship today. - RFQ / dynamic pricing — waits on x402 v2 dynamic-pricing maturity; no
parallel dynamic flow, no counter-offer object (that absence is the rule). - Accounts / postpaid / prepaid — bilateral, provider-scoped, and not
shipped; company-held credits only via licensed partners. - Inbound HTTP 402 serving — deferred, demand-driven.
If the user asks about these, say where they stand rather than inventing an
API.