Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Fulfillment channels (x402) · Boson Protocol
Skip to content

Fulfillment channels (x402)

After the facilitator confirms on-chain settlement, the seller's server delivers the asset. The x402 challenge advertised which channels are available; the buyer picked one.

For the canonical reference (channels and trade-offs), see Concepts → Fulfillment channels.

Built-in channels

ChannelDelivery
InlineSeller's HTTP response carries the asset directly
EmailServer sends an email to a buyer-supplied address
XMTPServer posts to the buyer's XMTP identity
WebhookServer POSTs to a buyer-supplied URL
IPFS pointerServer returns an IPFS CID; buyer fetches separately

Implementing a channel

import type { FulfillmentChannel } from "@bosonprotocol/x402-fulfillment"
 
const inline: FulfillmentChannel = {
  id: "inline",
  async fulfill({ asset, request, response }) {
    response.json(asset)
  },
}

Register the channel with the server:

import { ChannelRegistry } from "@bosonprotocol/x402-fulfillment"
 
const registry = new ChannelRegistry([inline, email, xmtp])
const x402 = createX402bServerExpress({ /* …, */ channelRegistry: registry })

Buyer-chosen, seller-bound

The buyer's client picks the channel; the seller's server must support it. Negotiation happens at the 402 step — the server advertises only channels it implements.

Custom channels

The FulfillmentChannel interface is open. Add your own (Slack DM, on-chain log, in-game inventory) by implementing fulfill().

Common gotchas

  • The buyer's contact info comes in the X-PAYMENT envelope (for email/XMTP). Validate / sanitize before using.
  • Inline channel can't deliver large assets. Use IPFS pointer for >1 MB payloads.
  • Webhook handlers must be authenticated — HMAC-sign the payload.

Next