Skip to content

One-Time Payments

One-time payments enable pay-per-use API access through direct blockchain transactions. This method is perfect for occasional API usage when you don't want to manage ongoing subscriptions or payment channels. Simply make a blockchain payment and use the transaction hash as proof of payment for API requests within a configured time window.

How One-Time Payments Work

You make a regular blockchain transaction (like sending USDC) to the API provider's wallet address. After the transaction confirms, you can use the transaction hash to authenticate API requests for a limited time period. The API server verifies your payment on-chain and grants access to the requested endpoints.

Think of it like a digital ticket or coupon system: Your blockchain transaction acts as a ticket that you can redeem multiple times within a specific timeframe. Unlike traditional payment processors that charge per transaction, this gives you a flexible "credit" that can be used for several API calls - similar to buying a day pass that works for multiple entries.

Best Use Cases

  • Occasional API access: Perfect for infrequent API usage without ongoing commitments
  • Resource downloads: One-time payments for downloading datasets, reports, or files
  • Trial access: Limited-time access to premium API endpoints
  • Simple micropayments: Straightforward pay-per-call model without complex setup
  • Guest access: Allow non-subscribers to access specific endpoints
  • Promotional usage: Time-limited access for marketing or demonstration purposes
  • Ticket-based access: Buy a "day pass" or "credit bundle" that works for multiple API calls within a time window

How it works & Architecture

One Time flow

💡 Implementation Details

Summary

One-time payments enable pay-per-use API access through direct blockchain transactions. Users make a single payment transaction to the API provider's address and use the transaction hash as proof of payment for subsequent API requests within a configured time window.

Payment Flow

  1. Payment Creation: Consumer makes direct blockchain transaction to provider's address
  2. Transaction Confirmation: Payment confirmed on blockchain with transaction hash
  3. API Request: Consumer includes transaction hash in API request with cryptographic proof
  4. Payment Verification: Server verifies transaction validity, amount, and timing
  5. Session Creation: Successful verification creates time-limited access session
  6. API Access: Consumer can make API calls during the valid session period

X-Payment Header Payload

One-time payments use the one-time scheme with the x402 v1 format:

{
  "x402Version": 1,
  "network": "base",
  "scheme": "one-time",
  "payload": {
    "signature": "0x1234...",
    "tx_hash": "0xabcd..."
  }
}

Key components:

  • x402Version: Protocol version (1)
  • network: Blockchain network where payment was made
  • scheme: Payment method ("one-time")
  • signature: Consumer's cryptographic proof of transaction ownership
  • tx_hash: Hash of the payment transaction on the blockchain

Verification Process

The middleware performs verification in this order:

1. Header Validation

  • Parse and validate X-Payment JSON structure
  • Verify x402Version is 1 and scheme matches "one-time"
  • Extract transaction hash and signature from payload

2. Signature Verification

  • Verify signature proves ownership of the transaction
  • Ensure signature was created by the transaction sender
  • Validate signature authenticity using ECDSA recovery

3. Transaction Validation

  • Query blockchain to verify transaction exists and is confirmed
  • Check transaction amount meets minimum payment requirement
  • Validate transaction was sent to the configured recipient address
  • Ensure transaction timestamp is within the payment window

4. Session Management

  • Check if payment has already been redeemed and session limits
  • Create new session if within redemption limits
  • Update redemption count and session expiration time

State Management

One-time payments maintain session state for reuse control:

Server-Side State (In-Memory)

pub struct OneTimePaymentState {
    payments: HashMap<TxHash, PaymentSession>,
}

Session Tracking:

  • Transaction hash mapped to session information
  • Redemption count tracking to prevent overuse
  • Session expiration time management
  • First redemption timestamp recording

Payment Session Limits

  • Payment Window: Transaction must be within configured time window (e.g., 48 hours)
  • Session TTL: Access valid for configured duration after first use (e.g., 1 hour)
  • Max Redemptions: Optional limit on API calls per payment (e.g., 5 calls)

Expiration Handling:

  • Sessions automatically expire based on TTL configuration
  • Payment window validation prevents old transaction reuse
  • Redemption limits prevent payment overuse

Settlement Process

One-time payments are settled immediately on-chain:

1. Direct Settlement

  • Payment settled when transaction is confirmed on blockchain
  • No additional settlement process required
  • Provider receives funds immediately upon transaction confirmation

2. Session-Based Access

  • Verification creates time-limited access session
  • Multiple API calls possible within session limits
  • Session expires automatically based on configuration

3. Rate Limiting

  • Configurable limits prevent payment abuse
  • Window-based expiration ensures timely usage
  • Redemption counting tracks usage patterns

Smart Contract Integration

Direct Token Transfers

  • Supports any ERC-20 token transfer transaction
  • No specialized smart contracts required
  • Works with standard wallet transactions

Network Support

  • Available on all EVM-compatible networks
  • Mainnet support across major blockchains
  • Configurable for any network with RPC access

Security Features

  • Transaction verification: On-chain proof of payment
  • Signature authentication: Cryptographic ownership proof
  • Time-window validation: Prevents stale transaction reuse
  • Redemption limits: Controls payment overuse
  • Session expiration: Automatic access termination

v0.6.0+ Unified Approach (Recommended)

For API Consumers

import { withPaymentInterceptor } from "pipegate-sdk";
 
// Make payment and get transaction hash
const txHash = "0x...";
 
// Single unified interceptor
const client = withPaymentInterceptor(
  axios.create({ baseURL: "https://api.example.com" }),
  PRIVATE_KEY,
  { oneTimePaymentTxHash: txHash }
);
 
// Automatic payment handling
const response = await client.get("/endpoint");

For API Providers

use pipegate::middleware::{PaymentsLayer, PaymentsState, Scheme, SchemeConfig};
 
// Configure one-time payments
let one_time_config = SchemeConfig::new(
    Scheme::OneTimePayments,
    "https://base-rpc.publicnode.com".to_string(),
    token_address,
    recipient_address,
    "1".to_string(), // 1 token per call
).await;
 
// Single middleware for all schemes
let app = Router::new()
    .route("/api", get(handler))
    .layer(PaymentsLayer::new(
        PaymentsState::new(),
        MiddlewareConfig::new(vec![one_time_config])
    ));

Rate Limitations (v0.6.0+)

One-time payments now adds rate limitations:

  • Payment Window: Payment must have been made within a specified time window (e.g., 48 hours)
  • Session TTL: Payment remains valid for a configured duration after first redemption (e.g., 1 hour)
  • Max Redemptions: Optional limit on how many times the payment can be reused (e.g., 5 calls)

These parameters are returned in the 402 Payment Required response:

{
  "extra": {
    "absWindowSeconds": 172800, // 48 hours payment window
    "sessionTTLSeconds": 3600, // 1 hour session validity
    "maxRedemptions": 5 // Maximum 5 API calls per payment
  }
}

Legacy Implementation

For API Consumers

Make Payment

// Make direct payment using your wallet to the provider
// Store transaction hash for API call
const txHash = "0x...";

or You can subscribe to the provider using Pipegate Hub

or Just use the cast CLI tool to send a transaction, no need to use any platform

terminal
# Send 1 USDC to the provider
cast send $USDC_ADDRESS "transfer(address,uint256)" $0xPROVIDER 1000000 --rpc-url $RPC_URL --private-key $PRIVATE_KEY

Setup API Client

Using axios interceptors:

import { ClientInterceptor } from "pipegate-sdk";
 
const pipeGate = new ClientInterceptor();
 
const api = axios.create({
  baseURL: "https://api.example.com",
});
 
api.interceptors.request.use(
  pipeGate.createOneTimePaymentRequestInterceptor(txHash).request
);

Or Manually signing the request and adding the required headers in the request:

const signedHeaders = await pipegate.signOneTimePaymentRequest(txHash);
 
const response = await fetch("/endpoint", {
  headers: {
    "X-Transaction": txHash,
    "X-Signature": signature,
  },
});

Make API Call

try {
  const response = await api.get("/endpoint");
} catch (error) {
  if (error.message.includes("invalid payment")) {
    // Handle payment verification error
  }
}

For API Providers

Configure Payment Settings

Set the token you want to recieve and the amount you want to charge for each call. User will be allowed to access the API for a certain period of time after payment which can be configured

use pipegate::middleware::one_time_payment::{types::OneTimePaymentConfig};
use pipegate::utils::{Address, Url, U256};
 
let rpc_url: Url = "https://base-rpc.publicnode.com".parse().unwrap();
 
let onetime_payment_config = OneTimePaymentConfig {
    recipient: Address::from_str("YOUR_ADDRESS").unwrap(),
    token_address: Address::from_str("USDC_ADDRESS").unwrap(),
    amount: U256::from(1000000), // 1 USDC each call
    period: U256::from(3600), // Access until 1 hour post payment
    rpc_url: rpc_url.to_string(),
};

Setup Middleware

use pipegate::middleware::one_time_payment::{OneTimePaymentMiddlewareLayer};
 
let app = Router::new()
    .route("/", get(root))
    .layer(OnetimePaymentMiddlewareLayer::new(onetime_payment_config));

Best Practices

  • Verify transaction confirmations
  • Handle payment expiration
  • Implement rate limiting
  • Store transaction hashes to prevent reuse