BazaarLinkBazaarLink
로그인
문서API 레퍼런스SDK 레퍼런스에이전트 사용법AI 스킬

OKX x402 결제: 에이전트 등록 및 충전

x402를 사용하면 클라이언트가 스테이블코인으로 요청에 결제할 수 있습니다. BazaarLink는 X Layer에서 OKX의 x402 facilitator를 통해 정산되는 x402 결제로 에이전트 계정을 등록하고 기존 잔액을 충전할 수 있습니다. 이 페이지는 두 경로의 실제 동작을 설명합니다.

402 흐름

두 경로 모두 같은 세 단계로 진행됩니다: 요청, 서명, 재전송.

  1. 결제 없이 요청을 보냅니다. 서버는 402 Payment Required와 x402Version, resource, accepts(network, asset, amount, payTo, maxTimeoutSeconds)를 담은 JSON을 반환합니다.
  2. 자신의 지갑 키로 accepts의 한 항목에 대한 결제 승인을 서명합니다.
  3. 같은 요청을 다시 보내고 base64로 인코딩한 결제 페이로드를 X-PAYMENT 헤더에 넣습니다. payment-signature 헤더 이름도 별칭으로 허용됩니다.
응답의 요구사항 확인
network, asset, amount는 하드코딩하지 말고 402 응답에서 가져오세요. amount는 자산의 최소 단위입니다(USDT0은 소수점 이하 6자리). 두 요청에 같은 JSON 본문을 보내세요.

에이전트 등록

POSThttps://bazaarlink.ai/api/v1/agents/register/x402

POST /api/v1/agents/register/x402는 한 번의 결제 요청으로 에이전트 계정, API key, 초기 잔액을 만듭니다. API key와 로그인이 필요하지 않습니다.

요청 본문

name필수
string
에이전트 이름, 1~100자.
description
string
선택 설명, 최대 4000자.
amountUsd필수
number
결제할 금액(미국 달러), 양수여야 합니다. 402를 만들기 전에 허용 범위(현재 $1~$50)로 제한되므로 응답의 금액을 사용하세요.

알 수 없는 필드는 400 bad_request로 거부됩니다.

1. 결제 없이 요청

응답은 결제 요구사항이 담긴 402입니다. 아직 아무것도 생성되지 않습니다.

curl -i -X POST https://bazaarlink.ai/api/v1/agents/register/x402 \
  -H "Content-Type: application/json" \
  -d '{"name":"my-agent","amountUsd":1.1}'
HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "x402Version": 2,
  "resource": {
    "url": "https://bazaarlink.ai/api/v1/agents/register/x402",
    "description": "BazaarLink paid agent registration",
    "mimeType": "application/json"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:196",
      "payTo": "0xPAY_TO_ADDRESS",
      "asset": "0xASSET_CONTRACT",
      "amount": "1100000",
      "maxTimeoutSeconds": 300,
      "extra": { "name": "USD₮0", "version": "1" }
    }
  ]
}

2. 서명하고 재전송

자신의 지갑으로 서명한 뒤 X-PAYMENT 헤더와 함께 같은 요청을 보냅니다. curl 명령은 요청을 보여 주며, 아래 TypeScript 예제가 헤더 값을 만듭니다.

curl -i -X POST https://bazaarlink.ai/api/v1/agents/register/x402 \
  -H "Content-Type: application/json" \
  -H "X-PAYMENT: <base64 payment payload>" \
  -d '{"name":"my-agent","amountUsd":1.1}'

TypeScript 예제

이 예제는 @okxweb3/x402 클라이언트 패키지와 viem을 사용합니다. OKX Wallet 또는 어떤 지갑 키로도 서명할 수 있습니다. 개인 키는 자신의 컴퓨터에 남고 서명된 승인만 전송됩니다.

import { x402Client } from "@okxweb3/x402-core/client";
import type { Network } from "@okxweb3/x402-core/types";
import { toClientEvmSigner } from "@okxweb3/x402-evm";
import { ExactEvmScheme } from "@okxweb3/x402-evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const URL = "https://bazaarlink.ai/api/v1/agents/register/x402";
const HEADERS = { "content-type": "application/json" };
const BODY = JSON.stringify({ name: "my-agent", amountUsd: 1.1 });

// 1. Ask without paying. The 402 body lists what the server accepts.
const challenge = await fetch(URL, { method: "POST", headers: HEADERS, body: BODY });
if (challenge.status !== 402) throw new Error("unexpected status " + challenge.status);
const paymentRequired = await challenge.json();

// 2. Sign the payment authorization with your own wallet key.
const privateKey = readSecret("payer-private-key") as `0x${string}`; // from your own secret store, never from source code
const signer = toClientEvmSigner(privateKeyToAccount(privateKey));
const client = new x402Client().register(
  paymentRequired.accepts[0].network as Network,
  new ExactEvmScheme(signer),
);
const payload = await client.createPaymentPayload(paymentRequired);
const xPayment = Buffer.from(JSON.stringify(payload), "utf8").toString("base64");

// 3. Send the same request again with the signed payment.
const res = await fetch(URL, { method: "POST", headers: { ...HEADERS, "x-payment": xPayment }, body: BODY });
const account = await res.json(); // 201: api_key, credits, claim_token, payment ...
console.log(res.status, account.credits_usd);

지갑 개인 키는 환경 변수나 시크릿 저장소에 보관하고 소스 코드에는 넣지 마세요.

등록 응답

등록에 성공하면 다음 필드와 함께 201이 반환됩니다. API key는 여기에서 한 번만 표시되므로 바로 저장하세요.

HTTP/1.1 201 Created
Content-Type: application/json

{
  "api_key": "sk-bl-...",
  "credits": 1,
  "credits_usd": "$1.0000",
  "claim_token": "...",
  "claim_expires": "2026-10-08T00:00:00.000Z",
  "upgrade_url": "https://bazaarlink.ai/claim?token=...",
  "referral_code": "...",
  "free_model": "auto:free",
  "message": "...",
  "referral_message": "...",
  "base_url": "https://bazaarlink.ai/api/v1",
  "docs": "https://bazaarlink.ai/llms.txt",
  "payment": {
    "txHash": "0xTX_HASH",
    "network": "eip155:196",
    "amountUsd": 1.1,
    "paidUsd": 1.1,
    "creditedUsd": 1,
    "serviceFeeUsd": 0.1
  }
}
api_key
string
새 API key.
credits
number
추가되는 잔액(미국 달러): 결제 금액에서 플랫폼 충전 수수료를 뺀 금액.
credits_usd
string
같은 잔액을 형식화한 문자열.
claim_token
string
사람이 계정을 인수하는 데 사용할 토큰.
claim_expires
string
계정 인수 기한(ISO 8601).
upgrade_url
string
사람이 사용하는 인수 링크이며 /claim?token=으로 끝납니다.
referral_code
string
새 에이전트 계정의 추천 코드.
free_model
string
항상 auto:free이며 잔액 없이 사용할 수 있는 모델.
message
string
에이전트가 소유자에게 보여 줄 수 있는 준비된 문구.
referral_message
string
추천 코드에 관한 문구.
base_url
string
새 key와 함께 사용할 API base URL.
docs
string
기계가 읽을 수 있는 문서 진입점.
payment
object
결제된 지불의 txHash, network, amountUsd와 함께 paidUsd, creditedUsd, serviceFeeUsd를 담은 객체.

기존 잔액 충전

POSThttps://bazaarlink.ai/api/x402/topup

POST /api/x402/topup은 API key를 소유한 계정 또는 로그인된 session의 잔액을 충전합니다. 402 흐름은 같고 본문에는 amountUsd만 있습니다.

Authorization: Bearer와 API key로 인증하거나 로그인된 브라우저 session을 사용하세요.

curl -i -X POST https://bazaarlink.ai/api/x402/topup \
  -H "Authorization: Bearer $BAZAARLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-PAYMENT: <base64 payment payload>" \
  -d '{"amountUsd":1.1}'

충전에 성공하면 200을 반환하며 status가 credited이고, 미국 달러 기준 새 잔액, txHash, 그리고 paidUsd, creditedUsd, serviceFeeUsd(결제 금액, 입금된 금액, 플랫폼 충전 수수료)가 포함됩니다.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "credited",
  "balance": 12.5,
  "txHash": "0xTX_HASH",
  "paidUsd": 1.1,
  "creditedUsd": 1,
  "serviceFeeUsd": 0.1
}
// Same three steps against /api/x402/topup; only the URL, body and auth header change.
const URL = "https://bazaarlink.ai/api/x402/topup";
const HEADERS = {
  "content-type": "application/json",
  authorization: "Bearer " + process.env.BAZAARLINK_API_KEY,
};
const BODY = JSON.stringify({ amountUsd: 1.1 });
// ...reuse the challenge / sign / resend code from the registration example.
// 200 -> { "status": "credited", "balance": 12.5, "txHash": "0x...", "paidUsd": 1.1, "creditedUsd": 1, "serviceFeeUsd": 0.1 }

현재 한도 확인

GEThttps://bazaarlink.ai/api/x402/topup

GET /api/x402/topup은 인증 없이 minUsd, maxUsd, network를 반환합니다.

curl https://bazaarlink.ai/api/x402/topup
{ "minUsd": 1, "maxUsd": 50, "network": "eip155:196" }

중복 결제 및 재전송

서명된 승인은 한 번만 사용할 수 있습니다. 서버는 결제 네트워크에 연결하기 전에 중복 결제를 인식하므로 재시도해도 두 번 결제되지 않습니다.

충전: 이미 credited 처리된 결제를 다시 보내면 status가 already_credited인 200이 반환됩니다.

등록: 15분 동안 같은 서명 결제에는 API key가 포함된 동일한 201 응답이 반환되므로 네트워크 실패 시 안전하게 재시도할 수 있습니다. 그 후에는 status가 already_registered인 200과 결제 txHash가 반환되고 API key는 다시 표시되지 않습니다.

오류 응답

x402 경로는 { "error": { "message", "code" } } 형식으로 오류를 반환합니다. 다른 두 응답이 있습니다: 410은 { "error", "code" }, 429는 Retry-After 헤더가 있는 { "error" }입니다.

HTTP
코드
의미
400bad_request
본문이 올바르지 않습니다: 유형이 잘못되었거나 name이 없거나 알 수 없는 필드가 있습니다.
400topup_unavailable
이 계정에서는 충전할 수 없습니다.
401unauthenticated
충전 전용: 유효한 API key 또는 session이 없습니다.
402(payment requirements body)
사용 가능한 결제가 아직 없습니다. 본문의 요구사항에 서명하고 재전송하세요. 결제가 요구사항과 일치하지 않거나 검증에 실패해도 반환됩니다.
402payment_amount_too_low
정산된 금액이 요청한 금액보다 적습니다.
403geo_blocked
현재 지역에서는 x402를 사용할 수 없습니다.
410agent_register_discontinued
에이전트 등록이 꺼져 있습니다.
429(Retry-After header)
같은 네트워크 출처에서 등록이 너무 많습니다. Retry-After에 표시된 초만큼 기다리세요.
502facilitator_error
결제를 검증하거나 정산할 수 없습니다. 나중에 다시 시도하세요.
502settlement_error
결제를 받았지만 잔액에 반영하지 못했습니다. 새 결제에 서명하지 말고 같은 결제를 다시 보내세요.
502registration_error
결제를 받았지만 계정을 만들지 못했습니다. 새 결제에 서명하지 말고 같은 결제를 다시 보내세요.
503disabled / runtime_disabled
x402가 현재 꺼져 있거나 설정되지 않았습니다.
503asset_unavailable / dedup_unavailable
의존 항목(자산 설정, 중복 확인 또는 충전 확인)에 연결할 수 없습니다. 나중에 다시 시도하세요.
503signup_disabled / agent_register_unavailable
등록이 일시 중지되었거나 사용할 수 없습니다.

계정을 사람에게 전달

응답의 upgrade_url을 계정 소유자에게 보내세요. 소유자가 로그인해 인수하면 API key와 잔액이 소유자의 계정으로 이동합니다. claim_expires 전에 인수해야 합니다.

https://bazaarlink.ai/claim?token=<claim_token>

네트워크와 자산

현재는 X Layer의 USDT0이며 OKX의 x402 facilitator를 통해 정산됩니다. 플랫폼 충전 수수료가 적용되므로 받는 잔액은 결제 금액보다 적습니다(요금 안내 참조). 결제는 온체인으로 정산되며 되돌릴 수 없으니 서명 전에 금액과 네트워크를 확인하세요.

개요는 x402 에이전트 결제 페이지를 참조하세요.

Support
Support
Hi! How can we help you?
Send a message and we'll get back to you soon.