Batch Payment#
Overview#
Batch Payment is a payment mode designed by OKX Onchain OS Payment for high-frequency, low-value scenarios. Unlike One-Time Payment, Batch Payment does not require each transaction to be settled on-chain immediately -- after the buyer signs, the seller receives confirmation and delivers the resource right away, while on-chain settlement is completed asynchronously in batches by OKX in the background.
Why Batch Payment#
In One-Time Payment, every transaction must go through the full "verify -> on-chain settlement -> delivery" flow. This is reasonable for high-value transactions, but in scenarios where AI Agents make high-frequency calls, settling each transaction individually on-chain introduces two problems:
- Latency: Even with asynchronous settlement, the Facilitator still needs extra time to submit transactions
- Throughput: In high-frequency scenarios, per-transaction on-chain settlement is limited by on-chain confirmation speed, and a large number of concurrent requests creates a settlement bottleneck
Batch Payment specifically addresses both issues: the settle call returns confirmation immediately (solving the latency problem), and multiple transactions are compressed into a single on-chain transaction (solving the throughput problem).
Prerequisites#
Batch Payment requires the buyer to install and use the OKX Agentic Wallet. Regular EVM wallets cannot use this mode.
This is because Batch Payment relies on two key pieces of infrastructure:
- Session Key: A temporary signing key generated by the Agentic Wallet that allows the Agent to sign autonomously within the authorized scope, without invoking the primary private key each time
- TEE (Trusted Execution Environment): A hardware-level security isolation technology. OKX performs batch settlement inside a TEE, ensuring that signing data cannot be tampered with or stolen -- even if the server is compromised, settlement transactions cannot be forged
Use Cases#
- Continuous AI Agent calls: An Agent frequently calls multiple paid APIs during a single task (e.g., search -> analyze -> generate)
- Streaming billing: High-frequency micropayments charged per token, per character, or per request
- Bulk data queries: A large volume of on-chain data or market data queries in a short period
- Tool-chain orchestration: An Agent automatically orchestrates multiple tool calls, each with a very small amount
Seller Integration#
Node.js
import { OKXFacilitatorClient } from "@okxweb3/x402-core";
import { x402ResourceServer } from "@okxweb3/x402-core/server";
import { AggrDeferredEvmScheme } from "@okxweb3/x402-evm/deferred/server";
const facilitator = new OKXFacilitatorClient({
apiKey: "xxx",
secretKey: "xxx",
passphrase: "xxx",
});
const server = new x402ResourceServer(facilitator);
server.register("eip155:196", new AggrDeferredEvmScheme());
const routes = {
"GET /api/data": {
accepts: [{
scheme: "aggr_deferred",
network: "eip155:196",
payTo: "0xSellerWallet",
price: "$0.001",
}],
description: "Data endpoint with deferred settlement",
mimeType: "application/json",
},
};
app.use(paymentMiddleware(routes, server));
Go
package main
import (
"fmt"
"net/http"
"os"
"time"
x402http "github.com/okx/payments/go/http"
ginmw "github.com/okx/payments/go/http/gin"
deferred "github.com/okx/payments/go/mechanisms/evm/deferred/server"
ginfw "github.com/gin-gonic/gin"
)
func main() {
syncClient, err := x402http.NewOKXFacilitatorClient(&x402http.OKXFacilitatorConfig{
Auth: x402http.OKXAuthConfig{
APIKey: "OKX_API_KEY",
SecretKey: "OKX_SECRET_KEY",
Passphrase: "OKX_PASSPHRASE",
},
BaseURL: "https://beta.okex.org",
})
if err != nil {
fmt.Printf("Failed to create client: %v\n", err)
os.Exit(1)
}
routes := x402http.RoutesConfig{
"GET /api/data": {
Accepts: x402http.PaymentOptions{
{Scheme: "aggr_deferred", Price: "$0.01", Network: "eip155:196", PayTo: "SellerWallet"},
},
Description: "Premium data endpoint",
MimeType: "application/json",
},
}
schemes := []ginmw.SchemeConfig{
{Network: "eip155:196", Server: deferred.NewAggrDeferredEvmScheme()},
}
r := ginfw.Default()
apiGroup := r.Group("/")
apiGroup.Use(ginmw.X402Payment(ginmw.Config{
Routes: routes,
Facilitator: syncClient,
Schemes: schemes,
Timeout: 30 * time.Second,
}))
apiGroup.GET("/api/data", func(c *ginfw.Context) {
c.JSON(http.StatusOK, ginfw.H{
"data": "premium content",
"price": "$0.01",
})
})
r.Run(":3000")
}
Rust
use axum::{Router, Json, routing::get};
use serde_json::json;
use std::collections::HashMap;
use x402_axum::{payment_middleware, RoutePaymentConfig, AcceptConfig};
use x402_core::http::OkxHttpFacilitatorClient;
use x402_core::server::X402ResourceServer;
use x402_evm::AggrDeferredEvmScheme;
#[tokio::main]
async fn main() {
let facilitator = OkxHttpFacilitatorClient::new(
"https://beta.okex.org",
&std::env::var("OKX_API_KEY").unwrap(),
&std::env::var("OKX_SECRET_KEY").unwrap(),
&std::env::var("OKX_PASSPHRASE").unwrap(),
);
let server = X402ResourceServer::new(facilitator)
.register("eip155:196", AggrDeferredEvmScheme::new());
let routes = HashMap::from([(
"GET /api/data".to_string(),
RoutePaymentConfig {
accepts: vec![AcceptConfig {
scheme: "aggr_deferred".into(),
price: "$0.01".into(),
network: "eip155:196".into(),
pay_to: "0xSellerWallet".into(),
}],
description: "Premium data endpoint".into(),
mime_type: "application/json".into(),
sync_settle: None,
},
)]);
let app = Router::new()
.route("/api/data", get(|| async { Json(json!({"data": "premium content"})) }))
.layer(payment_middleware(routes, server));
let listener = tokio::net::TcpListener::bind("0.0.0.0:4021").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
Buyer Integration#
After the buyer installs the OKX Agentic Wallet, the Agent automatically handles the 402 negotiation and signed payment. For details, please refer to Buyer Quickstart.