Skip to content
Integra Agentic Connectors

x402 beside a seller's stack

Serve an x402 resource with your own server and facilitator, and the seller door for the ATR and the check.

This guide serves an x402 resource from your own server, with your own facilitator, and uses the seller door for the ATR and the check. The pairing is x402/exact/eip155/eip3009: H is the nonce of the EIP-3009 authorization the payer signs.

sequenceDiagram
    participant B as Buyer's agent
    participant R as Your resource server
    participant D as Seller door
    participant F as Your facilitator
    B->>R: GET /v1/report
    R->>D: issue (accepts, request, content)
    D-->>R: atrHash, link, carriers
    R-->>B: 402 PaymentRequired with extensions.legalContext
    B->>R: GET /v1/report with PAYMENT-SIGNATURE
    R->>D: claim (payment, chosen = accepted)
    D-->>R: settling
    R->>F: verify, settle
    F-->>R: transaction
    R->>D: report (reference = transaction)
    R-->>B: 200 and the resource

What each call sends

CallFieldValue
issueoffersEach PaymentRequirements exactly as the 402 will carry it, with pairing x402/exact/eip155/eip3009.
requestThe commitment to the request the 402 answers.
lifetimeSecondsThe largest maxTimeoutSeconds.
claimpaymentThe PaymentPayload, exactly as received.
chosenIts accepted.
networkaccepted.network.
requestThe same commitment.
settleByThe authorization's validBefore.
reportreferenceThe facilitator's transaction.
chosenaccepted, when the payment was not claimed.

The whole flow

This program issues the ATR, builds the 402 with the LCP package's x402 entry point, and claims the payment the buyer presents. The door is the stand-in (see Getting started), so the buyer's payment is vector CV6's. Your facilitator would verify and settle between the claim and the report.

x402.ts
import type { ClaimResponse, IssueRequest, IssueResponse, Refusal } from "@integraledger/agentic-connectors";
import {  } from "@integraledger/agentic-connectors";
import { , type , type  } from "@integraledger/lcp/x402";

const  = .. ?? "https://seller.example/door";
const  = .. ?? "";

async function <>(: string, : unknown): <> {
  const  = await (`${}${}`, {
    : "POST",
    : { : `Bearer ${}`, "content-type": "application/json" },
    : .(),
  });
  const  = (await .()) as  | Refusal;
  if (!.) throw new (`${}: ${.} ${( as Refusal).}`);
  return  as ;
}

const :  = {
  : "exact",
  : "eip155:84532",
  : "10000",
  : "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
  : "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
  : 60,
  : { : "USDC", : "2" },
};
const  = {
  : "GET",
  : "/v1/report",
  : "",
  : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
} as ;

// 1. Issue the ATR before the 402 goes out.
const : IssueRequest = {
  : "chk_7Q2:v1",
  : "quote",
  : .,
  : [{ : "x402/exact/eip155/eip3009",  }],
  ,
  : [{ : "terms", : .('"Pay 10000 base units of USDC for one report."').("base64") }],
};
const  = await <IssueResponse>("/issue", );

// 2. Place H and the link in the 402, through the LCP package's entry point for the pairing.
const :  = {
  : 2,
  : { : "https://api.seller.example/v1/report" },
  : [],
};
const  = .(, ., ., );
if ("refused" in ) throw new (.);
const  = .?.["legalContext"]?.;
.("402 carries H:", .() === .(..));

// 3. The buyer pays. Claim the payment before the facilitator sees it.
const  = (["CV6"]!.[1]!.. as { : { :  } }).;
const  = ( as unknown as { : { : { : string } } })...;
const  = await <ClaimResponse>("/claim", {
  : "quote",
  : "x402/exact/eip155/eip3009",
  ,
  : .,
  : ..,
  ,
  : (),
});
.("claim:", ., "claimed:", ..);

// 4. Verify and settle with your facilitator, then report its `transaction` to the door.
402 carries H: true
claim: settling claimed: true

After your facilitator settles, report {atrHash, pairing, outcome: "paid", reference: <transaction>, network} (see the report operation).

Where H is on chain

The facilitator submits the payer's authorization to the token contract, which verifies the signature when it executes the transfer. H is then on chain as the nonce topic of the contract's AuthorizationUsed event in the settlement transaction. Anyone holding the ATR can hash it and find that event; the chain alone does not reveal the ATR's content.

Other x402 pairings

Every x402 pairing uses the same calls; what differs is where H rides and what the record proves. The pairings reference lists them, and the LCP package's documentation at lcp.integraledger.com describes each binding. For Tron and Polkadot, the profile facilitator is a facilitator you can run.

Edit on GitHub

Last updated on

On this page