Payment Methods

One-Time Payment#

Overview#

One-Time Payment is the most fundamental payment mode in OKX Onchain OS Payment: each time a buyer requests a paid resource, a complete payment flow is executed independently. One request, instant settlement, instant delivery.

Use Cases#

  • Each API call has a clear price and delivery is irreversible once completed (e.g., report generation, file download)
  • Resources should only be delivered after on-chain confirmation (txHash) is received
  • High-value API calls that require the certainty of immediate on-chain settlement

Seller Integration#

Node.js

Typescript
import { x402ResourceServer } from "@okxweb3/x402-core/server";
import { ExactEvmScheme } from "@okxweb3/x402-evm/exact/server";
import { OKXFacilitatorClient } from "@okxweb3/x402-core";

const facilitator = new OKXFacilitatorClient({
    apiKey: "xxx",
    secretKey: "xxx",
    passphrase: "xxx",
    syncSettle: false,
});

const server = new x402ResourceServer(facilitator);
// Register one-time payment scheme
server.register("eip155:196", new ExactEvmScheme());
// Configure payment routes
const routes = {
    "GET /api/data": {
      accepts: [{
        scheme: "exact",
        network: "eip155:196",
        payTo: "0xSellerWallet",
        price: "$0.01",
      }],
      description: "Premium data endpoint",
      mimeType: "application/json",
    },
  };

app.use(paymentMiddleware(routes, server));

Go

Go
package main

import (
    "fmt"
    "net/http"
    "os"
    "time"

    x402http "github.com/okx/payments/go/http"
    ginmw "github.com/okx/payments/go/http/gin"
    exact "github.com/okx/payments/go/mechanisms/evm/exact/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://web3.okx.com",
    })
    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: "exact", Price: "$0.01", Network: "eip155:196", PayTo: "SellerWallet"},
            },
            Description: "Premium data endpoint",
            MimeType:    "application/json",
        },
    }

    schemes := []ginmw.SchemeConfig{
        {Network: "eip155:196", Server: exact.NewExactEvmScheme()},
    }

    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

Rust
use std::collections::HashMap;
use axum::{routing::get, Json, Router};
use serde_json::{json, Value};

use x402_axum::{payment_middleware, AcceptConfig, RoutePaymentConfig};
use x402_core::http::OkxHttpFacilitatorClient;
use x402_core::server::X402ResourceServer;
use x402_evm::ExactEvmScheme;

#[tokio::main]
async fn main() {
    let facilitator = OkxHttpFacilitatorClient::new(
        "https://web3.okx.com",
        "OKX_API_KEY",
        "OKX_SECRET_KEY",
        "OKX_PASSPHRASE",
    );

    let server = X402ResourceServer::new(facilitator)
        .register("eip155:196", ExactEvmScheme::new());

    let routes = HashMap::from([(
        "GET /api/data".to_string(),
        RoutePaymentConfig {
            accepts: vec![AcceptConfig {
                scheme: "exact".into(),
                price: "$0.01".into(),
                network: "eip155:196".into(),
                pay_to: "SellerWallet".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"})) }))
        .layer(payment_middleware(routes, server));

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Synchronous Settlement vs Asynchronous Settlement#

After calling /settle, the Facilitator submits the transaction on-chain. The syncSettle field in the route configuration controls the settlement behavior:

ModeParameter ValueFacilitator BehaviorUse Case
SynchronoustrueSubmits the transaction and waits for on-chain confirmation before returning txHashHigh-value transactions where resources should only be delivered after payment is confirmed
AsynchronousfalseReturns txHash immediately after submitting the transaction, without waiting for confirmationMedium-value transactions where response speed matters
Note

Asynchronous Settlement carries timing risk: resources may be delivered before on-chain payment is finalized. Synchronous Settlement is recommended for high-value transactions.

Buyer Integration#

After installing the OKX Agentic Wallet, the Agent automatically handles the 402 negotiation and payment signing. For details, see Buyer Quickstart.