Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.x402.org/llms.txt

Use this file to discover all available pages before exploring further.

Hooks allow you to intercept and modify payment lifecycle events on clients, servers and facilitators.

Server Hooks

x402ResourceServer (Transport-agnostic)

Register hooks on the core resource server for verification and settlement lifecycle events. Use cases include logging payments, recording analytics, implementing custom access control or recovering from transient failures.
  • onBeforeVerify — Runs before payment verification. Return { abort: true, reason } to reject.
  • onAfterVerify — Runs after successful verification.
  • onVerifyFailure — Runs on verification failure. Return { recovered: true, result } to override.
  • onBeforeSettle — Runs before settlement. Return { abort: true, reason } to reject.
  • onAfterSettle — Runs after successful settlement.
  • onSettleFailure — Runs on settlement failure. Return { recovered: true, result } to override.
These server-level hooks run for every payment regardless of which extensions are active. Extensions can also register the same hooks scoped to their own key via the hooks property on ResourceServerExtension — those run only when the extension is declared on the route. See Extensions Overview for details.
import { x402ResourceServer } from "@x402/core";

const server = new x402ResourceServer(facilitatorClient);

server.onAfterSettle(async (context) => {
  await recordPayment({
    payer: context.result.payer,
    transaction: context.result.transaction,
    amount: context.requirements.amount,
    network: context.requirements.network,
  });
});

x402HTTPResourceServer (HTTP)

Register hooks for HTTP-specific request handling before payment processing. Use cases include bypassing payment for API key holders, granting access to subscribers or blocking specific clients.
  • onProtectedRequest — Runs on every request to a protected route.
    • Return { grantAccess: true } to bypass payment.
    • Return { abort: true, reason } to return 403.
    • Return void to continue to payment flow.
import { x402ResourceServer, x402HTTPResourceServer } from "@x402/core";

const server = new x402ResourceServer(facilitatorClient);
const httpServer = new x402HTTPResourceServer(server, routes);

httpServer.onProtectedRequest(async (context, routeConfig) => {
  const apiKey = context.adapter.getHeader("X-API-Key");

  if (apiKey && await isValidApiKey(apiKey)) {
    return { grantAccess: true };
  }

  // No valid API key — continue to payment flow
});

Client Hooks

x402Client (Transport-agnostic)

Register hooks on the core client for payment payload creation lifecycle events. Common use cases include enforcing spending limits, requiring approval for large payments or logging outgoing transactions.
  • onBeforePaymentCreation — Runs before creating a payment payload. Return { abort: true, reason } to cancel.
  • onAfterPaymentCreation — Runs after successful payload creation.
  • onPaymentCreationFailure — Runs on failure. Return { recovered: true, payload } to provide fallback.
import { x402Client } from "@x402/core";

const client = new x402Client();

client.onBeforePaymentCreation(async (context) => {
  const maxAmount = BigInt("10000000"); // 10 USDC
  const requestedAmount = BigInt(context.selectedRequirements.amount);

  if (requestedAmount > maxAmount) {
    return { abort: true, reason: "Payment exceeds spending limit" };
  }
});

x402HTTPClient (HTTP)

Register hooks for HTTP-specific payment required handling. Use cases include trying API key authentication before paying or prompting users for payment confirmation.
  • onPaymentRequired — Runs when a 402 response is received.
    • Return { headers } to retry with alternate headers before paying.
    • Return void to proceed directly to payment.
import { x402Client, x402HTTPClient } from "@x402/core";

const client = new x402Client();
const httpClient = new x402HTTPClient(client);

httpClient.onPaymentRequired(async ({ paymentRequired }) => {
  // Try API key authentication first
  const apiKey = process.env.API_KEY;
  if (apiKey) {
    return { headers: { "Authorization": `Bearer ${apiKey}` } };
  }
  // Return void to proceed with payment
});

Facilitator Hooks

x402Facilitator

Register hooks on the facilitator for verification and settlement lifecycle events. Use cases include populating a bazaar discovery catalog, compliance checks or collecting metrics across all processed payments.
  • onBeforeVerify / onAfterVerify / onVerifyFailure — Same pattern as server hooks.
  • onBeforeSettle / onAfterSettle / onSettleFailure — Same pattern as server hooks.
import { x402Facilitator } from "@x402/core";
import { extractDiscoveryInfo } from "@x402/extensions/bazaar";

const facilitator = new x402Facilitator();

facilitator.onAfterVerify(async (context) => {
  // Extract resource info from payment for bazaar catalog
  const discovered = extractDiscoveryInfo(
    context.paymentPayload,
    context.requirements,
    true, // validate
  );

  if (discovered) {
    bazaarCatalog.add({
      resource: discovered.resourceUrl,
      description: discovered.description,
      mimeType: discovered.mimeType,
      x402Version: discovered.x402Version,
      accepts: [context.requirements],
      lastUpdated: new Date().toISOString(),
    });
  }
});

Hook Chaining

All SDKs support method chaining for registering multiple hooks:
server
  .onBeforeVerify(validatePayment)
  .onAfterVerify(logVerification)
  .onBeforeSettle(checkBalance)
  .onAfterSettle(recordTransaction);

Next, explore: