Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Payment Configuration

The payment configuration module (server/src/payment_config.rs) is the central place where pricing rules are defined and x402 V2 payment requirements are generated. It determines how much each query costs and what payment options the server offers to clients.

GlobalPaymentConfig

GlobalPaymentConfig holds everything the server needs to price queries and communicate payment options:

#![allow(unused)]
fn main() {
pub struct GlobalPaymentConfig {
    pub facilitator: Arc<FacilitatorClient>,
    pub mime_type: String,               // default: "application/vnd.apache.arrow.stream"
    pub max_timeout_seconds: u64,        // default: 300
    pub default_description: String,     // default: "Query execution payment"
    pub offers_tables: HashMap<String, TablePaymentOffers>,
}
}
  • facilitator — The client used to verify and settle payments with the x402 facilitator.
  • mime_type — The response format advertised to clients (defaults to "application/vnd.apache.arrow.stream").
  • max_timeout_seconds — How long a payment remains valid before expiring (defaults to 300 seconds).
  • default_description — Fallback description when a table doesn’t have its own (defaults to "Query execution payment").
  • offers_tables — A map of table names to their payment offers (pricing tiers, schemas, descriptions).

Construction

All fields except facilitator are optional and fall back to sensible defaults.

#![allow(unused)]
fn main() {
// Rust - with defaults
let config = GlobalPaymentConfig::default(Arc::new(facilitator));

// Rust - with custom values
let config = GlobalPaymentConfig::new(
    Arc::new(facilitator),
    Some("text/csv".to_string()),
    Some(600),
    Some("Custom description".to_string()),
    None,
);
}
# Python - with defaults
config = GlobalPaymentConfig(facilitator)

# Python - with custom values
config = GlobalPaymentConfig(
    facilitator,
    mime_type="text/csv",
    max_timeout_seconds=600,
    default_description="Custom description",
)

Getters

GetterRustPythonReturns
MIME typeconfig.mime_type (pub field)config.mime_typeString / str
Max timeoutconfig.max_timeout_seconds (pub field)config.max_timeout_secondsu64 / int
Default descriptionconfig.default_description (pub field)config.default_descriptionString / str
Get table offersconfig.get_offers_table("table")Option<&TablePaymentOffers>
Table requires paymentconfig.table_requires_payment("table")config.table_requires_payment("table")Option<bool>

Setters

SetterRustPython
Set facilitatorconfig.set_facilitator(arc_client)config.set_facilitator(facilitator)
Set MIME typeconfig.set_mime_type("text/csv".to_string())config.set_mime_type("text/csv")
Set max timeoutconfig.set_max_timeout_seconds(600)config.set_max_timeout_seconds(600)
Set default descriptionconfig.set_default_description("...".to_string())config.set_default_description("...")
Add table offersconfig.add_offers_table(offer)config.add_offers_table(offer)

See the Configuration Reference for the full API.

What It Does

The module answers four questions for the query handler:

  1. Does this table require payment?table_requires_payment returns whether a table is free, paid, or unknown.

  2. What are the payment options for this query?get_all_payment_requirements takes a table name and estimated row count, then returns all applicable payment requirements. Each price tag is checked against its min_items/max_items range to determine if it applies.

  3. Does the client’s payment match what we expect?find_matching_payment_requirements compares the PaymentRequirements the client echoed back (in PaymentPayload.accepted) against the server-generated requirements using direct equality.

  4. What should the 402 response look like?create_payment_required_response assembles the full PaymentRequired response body including the error message, resource info, and all applicable payment options.

Price Calculation

The price calculation depends on the pricing model:

Per-row pricing:

total = amount_per_item * item_count
charge = max(total, min_total_amount)   // if min_total_amount is set

Fixed pricing:

charge = amount

Payment Requirements

Each applicable price tag produces a x402 PaymentRequirements entry sent to the client in the 402 response. The key fields are:

FieldDescription
schemePayment scheme style. Always "exact" — the client must pay the exact amount
networkThe blockchain network (e.g., "base-sepolia")
amountTotal price in the token’s smallest unit
pay_toThe recipient wallet address
max_timeout_secondsHow long the payment offer is valid
assetThe token contract address
extraToken metadata (e.g., name, version)