Skip to main content

Documentation Index

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

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

The @x402r/sdk package covers the merchant’s post-payment lifecycle: capturing escrowed funds, charging directly, processing refunds, and querying operator state.
Looking for server setup? The Merchant Server Quickstart shows how to accept escrow payments via Express middleware. This page covers the createMerchantClient factory for managing payments after they arrive.

Installation

npm install @x402r/sdk viem

Setup

import { createMerchantClient } from '@x402r/sdk'
import { createPublicClient, createWalletClient, http } from 'viem'
import { baseSepolia } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)

const merchant = createMerchantClient({
  publicClient: createPublicClient({ chain: baseSepolia, transport: http() }),
  walletClient: createWalletClient({
    account,
    chain: baseSepolia,
    transport: http(),
  }),
  operatorAddress: '0x...',
  escrowPeriodAddress: '0x...',
  refundRequestAddress: '0x...',
  refundRequestEvidenceAddress: '0x...',
  freezeAddress: '0x...',
})

payment.capture

Transfer escrowed funds to the receiver. Specify a smaller amount than paymentInfo.maxAmount for a partial capture; the rest stays in escrow.
const tx = await merchant.payment.capture(paymentInfo, 10_000_000n)
Parameters
NameTypeDescription
paymentInfoPaymentInfoFull struct identifying the payment
amountbigintAtomic units to capture (must be ≤ paymentInfo.maxAmount)
dataHex (optional)Pass-through data for the operator’s pre/post action plugins
Returns Promise<Hash>, the settlement transaction hash.
Always query payment.getAmounts() first to determine the available capturable amount.

payment.voidPayment

Return all escrowed funds to the payer before capture. Full-only: void() empties the authorization in one transaction. For a partial return, capture the share you want to keep first, then void the rest (or let it expire at captureDeadline).
const tx = await merchant.payment.voidPayment(paymentInfo)
Parameters
NameTypeDescription
paymentInfoPaymentInfoFull struct identifying the payment
dataHex (optional)Pass-through data for the operator’s pre/post action plugins
Returns Promise<Hash>, the void transaction hash.

payment.charge

Non-escrow settlement for subscriptions or session-based payments. Pulls funds directly from the payer via a token collector (no escrow hold).
const tx = await merchant.payment.charge(
  paymentInfo,
  5_000_000n,
  '0xTokenCollector...' as `0x${string}`,
  '0xSignatureData...' as `0x${string}`,
)
Parameters
NameTypeDescription
paymentInfoPaymentInfoFull struct identifying the payment
amountbigintAtomic units to charge
tokenCollectorAddressCanonical token collector for the chosen assetTransferMethod
collectorDataHexRaw ERC-3009 signature or ABI-encoded Permit2 signature
Returns Promise<Hash>, the charge transaction hash.

payment.refund

Refund funds the merchant has already captured. Requires a token collector to pull funds from the merchant’s balance.
const tx = await merchant.payment.refund(
  paymentInfo,
  5_000_000n,
  '0xTokenCollector...' as `0x${string}`,
  '0xSignatureData...' as `0x${string}`,
)
Parameters
NameTypeDescription
paymentInfoPaymentInfoFull struct identifying the payment
amountbigintAtomic units to refund to the payer
tokenCollectorAddressToken collector that sources the refund (typically ReceiverRefundCollector)
collectorDataHexData passed to the collector (for example, the receiver signature)
Returns Promise<Hash>, the refund transaction hash.
Refunds after capture require the merchant to hold enough token balance and to grant an allowance on the refund collector.

payment.getAmounts

Query the current capturable and refundable amounts for a payment.
const amounts = await merchant.payment.getAmounts(paymentInfo)
Parameters
NameTypeDescription
paymentInfoPaymentInfoFull struct identifying the payment
Returns Promise<PaymentAmounts>:
FieldTypeDescription
hasCollectedPaymentbooleanWhether the on-chain escrow holds the payment
capturableAmountbigintAtomic units still capturable from escrow
refundableAmountbigintAtomic units still refundable

payment.getState

Returns the payment’s lifecycle position as a tuple. The SDK exposes no PaymentState enum.
const [hasCollectedPayment, capturableAmount, refundableAmount] =
  await merchant.payment.getState(paymentInfo)
Parameters
NameTypeDescription
paymentInfoPaymentInfoFull struct identifying the payment
Returns Promise<readonly [boolean, bigint, bigint]>, [hasCollectedPayment, capturableAmount, refundableAmount].

operator.getConfig

Retrieve all slot addresses from the PaymentOperator contract.
const config = await merchant.operator.getConfig()
Returns Promise<OperatorSlots>, see packages/core/src/actions/operator/types.ts. Key fields:
FieldTypeDescription
escrowAddressCanonical AuthCaptureEscrow
authorizeCondition / authorizeHookAddressPre/post slots for authorize
chargeCondition / chargeHookAddressPre/post slots for charge
captureCondition / captureHookAddressPre/post slots for capture
voidCondition / voidHookAddressPre/post slots for void
refundCondition / refundHookAddressPre/post slots for refund
feeCalculatorAddressPer-operator fee calculator
feeReceiverAddressOperator fee recipient
protocolFeeConfigAddressProtocol fee config contract

operator.getFeeAddresses

Fetch the fee-related addresses (subset of getConfig with both operator and protocol resolved).
const fees = await merchant.operator.getFeeAddresses()
Returns Promise<FeeAddresses>:
FieldTypeDescription
operatorFeeCalculatorAddressPer-operator calculator
protocolFeeConfigAddressProtocol fee config contract
protocolFeeCalculatorAddressProtocol-level calculator
operatorFeeRecipientAddressWhere operator fees flow
protocolFeeRecipientAddressWhere protocol fees flow

operator.calculateFees

Calculate the full fee breakdown for a payment amount.
const fees = await merchant.operator.calculateFees(paymentInfo, 1_000_000n)
Parameters
NameTypeDescription
paymentInfoPaymentInfoFull struct identifying the payment
amountbigintAtomic units to compute fees for
Returns Promise<FeeCalculationResult>:
FieldTypeDescription
protocolFeeBpsbigintProtocol fee in basis points
operatorFeeBpsbigintOperator fee in basis points
totalFeeBpsbigintSum of the two
protocolFeeAmountbigintAtomic units of protocol fee
operatorFeeAmountbigintAtomic units of operator fee
totalFeeAmountbigintAtomic units of total fee
netAmountbigintAmount remaining after fees

Capture vs refund decision flow

Next steps

Refund Handling

Process incoming refund requests with deny workflows.

forwardToArbiter()

Forward escrow settlements to an arbiter service.

PaymentOperator

Understand the underlying PaymentOperator contract methods.