Payments
Tenzro provides multi-protocol payment support for HTTP 402-based machine payments, including MPP (Machine Payments Protocol), x402 (Coinbase), and Tempo network integration.
Overview
The payment system implements five primary payment protocols designed for AI agents and machine-to-machine transactions:
- MPP — Machine Payments Protocol
- x402 — Coinbase's HTTP 402 payment protocol
- Tempo — Direct participation in Tempo network for stablecoin settlement
- Visa TAP — Visa Trusted Agent Protocol with RFC 9421 HTTP message signatures
- Mastercard Agent Pay — Know Your Agent (KYA) verification with agentic tokens
All protocols are integrated with TDIP identity for delegation scope enforcement and automatic payment routing through the PaymentGateway.
MPP (Machine Payments Protocol)
MPP is a standardized protocol for machine-to-machine payments. It uses HTTP 402 challenge/credential/receipt flow with session management.
MPP Flow
- Request — Client requests a resource
- Challenge — Server responds with 402 Payment Required + MppChallenge
- Credential — Client creates MppCredential with payment proof
- Verification — Server verifies credential and creates session
- Receipt — Server returns MppReceipt confirming payment
- Access — Client can access resource with session token
MPP Challenge
{
"challenge_id": "chal_abc123",
"amount": "0.05 TNZO",
"currency": "TNZO",
"recipient": "tenzro1abc...xyz",
"expires_at": "2026-03-20T13:00:00Z",
"payment_methods": ["direct", "channel"],
"metadata": {
"resource": "/api/inference",
"model": "gemma4-9b"
}
}MPP Credential
{
"challenge_id": "chal_abc123",
"payer": "did:tenzro:human:550e8400...",
"amount": "0.05 TNZO",
"payment_proof": "0xabc123...",
"signature": "0xdef456...",
"timestamp": "2026-03-20T12:30:00Z"
}MPP Receipt
{
"receipt_id": "rcpt_xyz789",
"challenge_id": "chal_abc123",
"amount": "0.05 TNZO",
"settlement_tx": "0x789abc...",
"session_token": "sess_mno345",
"session_expires_at": "2026-03-20T14:00:00Z"
}MPP Sessions
MPP supports session-based access where a single payment grants access for a duration:
- Session tokens are cryptographically secure (UUID v4)
- Sessions track usage (requests, tokens consumed)
- Vouchers enable session credit top-ups without new challenges
- Sessions automatically expire after configured duration
x402 Protocol
x402 is Coinbase's HTTP 402 payment protocol designed for cryptocurrency payments over HTTP.
x402 Flow
# 1. Request resource
GET /api/inference HTTP/1.1
Host: provider.tenzro.network
# 2. Server responds with 402
HTTP/1.1 402 Payment Required
X-Payment-Required: {
"amount": "0.05",
"currency": "TNZO",
"recipient": "tenzro1abc...xyz",
"payment_id": "pay_abc123"
}
# 3. Client pays
POST /api/x402/pay HTTP/1.1
Content-Type: application/json
{
"payment_id": "pay_abc123",
"payer": "did:tenzro:human:550e8400...",
"amount": "0.05",
"tx_hash": "0x789abc..."
}
# 4. Server verifies and grants access
HTTP/1.1 200 OK
X-Payment-Receipt: {
"payment_id": "pay_abc123",
"confirmed": true
}Tempo Integration
Tempo is a stablecoin network enabling instant, low-cost transfers. Tenzro integrates directly with Tempo for cross-chain stablecoin settlement.
Tempo Features
- TIP-20 Tokens — Stablecoins (USDC, USDT, etc.) on Tempo network
- Instant Settlement — Sub-second finality for payments
- Low Fees — Minimal transaction costs
- Bridge Adapter — Seamless transfers between Tenzro and Tempo
Tempo Transfer
# Transfer USDC via Tempo
{
"from": "tenzro1abc...xyz",
"to": "tenzro1def...uvw",
"amount": "100.00",
"token": {
"symbol": "USDC",
"decimals": 6,
"contract": "tempo:usdc:0x..."
},
"memo": "AI inference payment"
}
# Result
{
"tx_hash": "tempo:0x789abc...",
"finality": "Finalized",
"timestamp": "2026-03-20T12:30:15Z"
}Visa Trusted Agent Protocol (TAP)
Visa TAP enables verified AI agents to make purchases using RFC 9421 HTTP Message Signatures. Tenzro replaces Visa's centralized agent registry with on-chain TDIP identities for decentralized agent verification.
Visa TAP Flow
- Request — Agent requests resource from merchant
- Challenge — Merchant responds with HTTP 402 + TAP challenge
- Sign — Agent signs request with RFC 9421 (Signature-Input + Signature headers)
- Verify — Merchant verifies via 7-stage pipeline: extract headers → resolve agent key from TDIP → check timestamp → verify nonce → check domain → verify signature → build result
See the full Visa TAP documentation for implementation details, security considerations, and code examples.
Visa TAP SDK Example
// Rust
let credential = serde_json::json!({/* visa tap credential */});
let receipt = client.payment().pay_visa_tap(credential).await?;// TypeScript
const receipt = await client.payment.payVisaTap({/* visa tap credential */});Mastercard Agent Pay
Mastercard Agent Pay provides a comprehensive framework for agentic commerce with Know Your Agent (KYA) verification levels and agentic tokens for controlled, delegated purchasing. Tenzro maps KYA levels to TDIP identity verification tiers.
KYA Levels
- Level 0: Unverified — No verification, read-only access
- Level 1: Basic — Verified controller, ≤$100 per transaction
- Level 2: Enhanced — Enhanced KYC + TEE keys, ≤$1,000 per transaction
- Level 3: Full — Full KYC/KYB + remote attestation, ≤$100,000 per transaction
Agent Pay Flow
- KYA Verification — Merchant verifies agent's KYA level via TDIP identity registry
- Token Issuance — Controller issues agentic token (SingleUse/SessionBound/Recurring)
- Purchase Intent — Agent declares what it intends to buy with items and total amount
- Payment — Merchant validates intent, verifies token, settles payment on Tenzro Ledger
See the full Mastercard Agent Pay documentation for KYA mapping, token lifecycle, and implementation examples.
Mastercard Agent Pay SDK Example
// Rust
let credential = serde_json::json!({/* mastercard credential */});
let receipt = client.payment().pay_mastercard(credential).await?;// TypeScript
const receipt = await client.payment.payMastercard({/* mastercard credential */});Identity-Bound Payments
All payment protocols integrate with TDIP for identity-based access control and delegation scope enforcement:
Delegation Enforcement
# Payment request validation
{
"payer": "did:tenzro:machine:did:tenzro:human:550e8400...:agent123",
"amount": "50.0 TNZO",
"delegation_scope": {
"max_transaction_value": "100.0 TNZO",
"allowed_payment_protocols": ["Mpp", "X402"],
"allowed_chains": [1337]
}
}
# Validation checks:
# ✓ Amount (50.0) <= max_transaction_value (100.0)
# ✓ Protocol (Mpp) in allowed_payment_protocols
# ✓ Chain (1337) in allowed_chains
# ✓ Daily spend limit not exceeded
# → Payment authorizedExample Scenarios
Scenario 1: Agent Exceeds Limit
Agent attempts payment above max_transaction_value. Payment rejected, requiring human approval.
Scenario 2: Unauthorized Protocol
Agent attempts payment via Tempo, but delegation scope only allows MPP and x402.
Scenario 3: Valid Payment
Payment within all limits, protocol allowed, daily spend updated to 100/500 TNZO.
Payment Gateway
The PaymentGateway provides unified routing across all payment protocols:
# Create payment via gateway
let gateway = PaymentGateway::new();
let challenge = gateway.create_challenge(
PaymentProtocolId::Mpp,
&payer_did,
&recipient_address,
amount,
"TNZO",
).await?;
# Verify payment credential
let receipt = gateway.verify_credential(
PaymentProtocolId::Mpp,
&challenge_id,
&credential,
).await?;
# Settlement happens automatically on verificationClose Payment Channel
// Rust
let result = client.settlement().close_payment_channel("channel-123").await?;// TypeScript
const result = await client.settlement.closePaymentChannel("channel-123");Agent Pay for Inference
End-to-end payment flow for agent inference requests, combining identity verification, payment challenge, and settlement in a single call:
// Rust - end-to-end agent inference payment
let result = client.agent().agent_pay_for_inference(
"my-agent", "gemma4-9b", "What is Tenzro?", Some(100),
).await?;// TypeScript
const result = await client.agent.agentPayForInference(
"my-agent", "gemma4-9b", "What is Tenzro?", 100
);HTTP Middleware
Tenzro provides axum middleware for automatic payment challenge/verification:
use tenzro_payments::middleware::PaymentMiddleware;
let app = Router::new()
.route("/api/inference", post(inference_handler))
.layer(PaymentMiddleware::new(
payment_gateway,
PaymentProtocolId::Mpp,
));
# Requests automatically challenged with 402
# Valid credentials verified and passed to handlerAP2 (Agentic Payment Protocol)
AP2 enables autonomous agent-to-agent payment sessions, allowing AI agents to negotiate, authorize, and execute payments without human intervention. Sessions are bound to TDIP delegation scopes, ensuring agents can only spend within their authorized limits.
Session Lifecycle
- createSession — Agent initiates a payment session with a provider, specifying purpose and maximum budget
- authorizePayment — Session validates the payment against the agent's SpendingPolicy and TDIP delegation scope
- executePayment — Payment is executed on-chain or via micropayment channel, with atomic settlement
- closeSession — Session is finalized, remaining budget released, and settlement receipt issued
SpendingPolicy Enforcement
Every AP2 session is governed by a SpendingPolicy that enforces real-time constraints on agent spending:
{
"maxPerTransaction": "10.0 TNZO",
"maxDailyTotal": "500.0 TNZO",
"allowedRecipients": [
"did:tenzro:machine:provider-gemma4-9b",
"did:tenzro:machine:provider-mistral-8x7b"
],
"requireTeeAttestation": true
}The SpendingPolicy integrates with TDIP delegation scopes — the effective limits are the intersection of the AP2 session policy and the agent's identity-level delegation scope. If either constraint is violated, the payment is rejected.
Rust SDK
// Create an AP2 session between agent and provider
let session = client.ap2().create_session(
agent_did,
provider_did,
"inference",
max_amount,
).await?;
// Authorize and execute a payment within the session
let receipt = session.authorize_payment(amount).await?;
let result = session.execute_payment(&receipt).await?;
// Close session when done
session.close().await?;TypeScript SDK
// Create an AP2 session between agent and provider
const session = await client.ap2().createSession(
agentDid, providerDid, "inference", maxAmount
);
// Authorize and execute a payment within the session
const receipt = await session.authorizePayment(amount);
const result = await session.executePayment(receipt);
// Close session when done
await session.close();Nanopayment Batching
The NanopaymentBatcher enables high-frequency micro-settlements for per-token billing, streaming inference, and continuous data feeds. Instead of settling each micropayment individually on-chain, payments are accumulated in off-chain channels and flushed in batches.
Channel Lifecycle
- openChannel — Payer deposits collateral into a payment channel with a specific payee
- sendNanopayment — Individual micro-payments are sent off-chain (can be called thousands of times)
- flushBatch — Accumulated payments are batched and settled on-chain in a single transaction
- closeChannel — Channel is closed, final settlement executed, and remaining deposit returned
Gas Savings
Nanopayment batching achieves a 97.9% gas reduction compared to individual on-chain settlements. A batch of 1,000 nanopayments settles in a single transaction, reducing per-payment gas cost from ~21,000 to ~440 gas units.
Rust SDK
// Open a nanopayment channel with deposit
let channel = client.nanopayment().open_channel(
payer, payee, deposit,
).await?;
// Send many individual nanopayments off-chain
for token in tokens {
channel.send_nanopayment(token_cost).await?;
}
// Flush accumulated payments to chain
let batch_receipt = channel.flush_batch().await?;
// Close channel and settle remaining balance
channel.close().await?;TypeScript SDK
// Open a nanopayment channel with deposit
const ch = await client.nanopayment().openChannel(payer, payee, deposit);
// Send many individual nanopayments off-chain
for (const token of tokens) {
await ch.sendNanopayment(tokenCost);
}
// Flush accumulated payments to chain
const batchReceipt = await ch.flushBatch();
// Close channel and settle remaining balance
await ch.close();Circuit Breaker Integration
Circuit breakers monitor provider health during payment flows to protect agents from paying for unreliable or degraded services. When a provider's error rate exceeds the configured threshold, the circuit breaker trips and the provider is excluded from payment routing until it recovers.
- Health Monitoring — Tracks success/failure rates, latency, and availability per provider
- Automatic Exclusion — Tripped providers are removed from PaymentGateway routing and AP2 session creation
- Gradual Recovery — Half-open state allows test requests before fully restoring a provider
// Rust
let health = client.circuit_breaker().get_provider_health(provider_id).await?;
// health.state: Closed (healthy) | Open (tripped) | HalfOpen (recovering)
// health.error_rate: 0.02
// health.latency_p99_ms: 145// TypeScript
const health = await client.circuitBreaker().getProviderHealth(providerId);
// health.state: "closed" | "open" | "half-open"
// health.errorRate: 0.02
// health.latencyP99Ms: 145