# Net Payments

> 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` / `ExternalXrpl

- Skill: `ai-2070/net-payments` (Agent Skill, multi-file: 25 files)
- Install (CLI): `npx skillmds@latest add ai-2070/net-payments`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ai-2070/net-payments/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: ai-2070 (https://skillmd.com/u/ai-2070)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/ai-2070/net-payments

---


# 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:

1. **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.
2. **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.**
3. **Non-custodial by construction.** Identity keys ≠ settlement keys. The
   `SchemeSigner` takes *typed operations* and returns signatures; there is no
   raw-bytes signing method and no way for a binding or agent to reach a key.
4. **Verification is a tier, not a boolean:** `observed | confirmed(n) |
   final`. A facilitator receipt is **`observed`, full stop** — `confirmed(n)`
   and `final` come only from the independent on-chain `ChainChecker`, so the
   facilitator is never in the trust root. Reorg is a first-class outcome that
   freezes the quote; billing events are immutable.
5. **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.
6. **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 outside `src/x402/`.
7. **The engine store is bookkeeping; the billing log is the record.** Terminal
   quote records are compacted 6h past quote expiry by default, so
   `engine.status()` returns `None` for 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 pass `None`.

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

1. **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.toml` or `requirements.txt` → Python, `go.mod` → Go,
     `Makefile`/`CMakeLists.txt` beside `.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.md` is the
     per-operation matrix and the authoritative answer to "does this language
     have X".
   - **Payments is not in the ergonomic wrapper.** Neither `@net-mesh/sdk` nor
     `net_sdk` contains a line of it. Every payments symbol in Node and Python
     is in `@net-mesh/core` and `net` respectively, and there is no
     `@net-mesh/payments` package. 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.
2. **Read `concepts.md`** if this is your first invocation this session.
3. **Which side is the user on?**
   - *Charging for a capability* (provider) → `provider.md`. Price at publish
     (`net.pricing.terms@1`), run the `PaymentEngine` lifecycle, pass a
     `PaymentFlow` into `gated_invoke` so the payment gate runs before the
     handler.
   - *Paying to invoke* (caller) → `caller.md`. `CallerPaymentFlow` over a
     `ProviderChannel`, spend policy, the approval loop; branch on the
     `net.payment.failure@1` schematic 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 behind `serve_payments` and the admission gate, and the caller's
     attempt is durable on disk. Rust and Python only, both directions.
4. **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`.
5. **Set the required tier.** Receipt-trust (`observed`) or an independent
   check (`confirmed(n)`/`final` via `ChainChecker`)? `verification.md`.
6. **Wire the signer** if settling on a real network — `ExternalSigner`
   (eip155/EIP-3009; key never in Net), `ExternalSvmSigner` (solana/SPL,
   intent-in/blob-out), or `ExternalXrplSigner` (xrpl/presigned Payment blob),
   registered per namespace; `DevLocalSigner` for testnet only (behind
   `unsafe-dev-signer`). From Python, all three ride the `payment_signer*`
   kwargs. `signer.md`.
7. **Configure spend policy** — limits, allowed networks/assets, the approval
   surface. Real networks deny by default. `spend-policy.md`.
8. **Enabling a new network?** It's config + registry + conformance, never
   code. `networks.md`.
9. **Surface billing** via `BillingLog` (stream/export). `billing.md`.
10. **Test** against golden vectors + the mock conformance suite; keep the
    key-invariant negative test green. `testing.md`.
11. **Before merging**, run the change past the review invariant in
    `gotchas.md` — most payments mistakes are scope violations, not bugs.
12. **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.pyi` stub
    - Cross-lang vectors: `net/crates/net/tests/cross_lang_payments/`

## What this skill deliberately does not cover

- **The base mesh, nRPC, capabilities, MCP bridge, event bus** — that's the
  `net-event-bus` skill. This skill assumes the substrate and only covers the
  money layer on top.
- **Refund/dispute semantics** — the `net.payment.dispute@1` tag 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.

## Further reading

- [Payments documentation](https://ai2070.net/docs/payments)

