Skip to content

Merchant API

Reference for x402-paysdk/merchant authentication, refs, orders, refunds, receipts, notify, tx history, and reconciliation.

TypeScript
import { MerchantClient } from 'x402-paysdk/merchant';

This entry point is backend-only. It handles bearer credentials, notify HMAC keys, merchant-controlled wallet signers, and business evidence.

MerchantClient

TypeScript
const client = new MerchantClient({ gateway: 'https://pay.example.com', apiKey: process.env.X402_API_KEY!, notifyHmacKey: process.env.X402_NOTIFY_KEY, notifyHmacKeyId: process.env.X402_NOTIFY_KEY_ID, notifyNonceStore, merchantWalletSigner, payTo, network: 'base'});
OptionPurpose
gatewayCanonical gateway origin
apiKeyRequired bearer key for authenticated requests
notifyHmacKey, notifyHmacKeyIdOptional current notify credential
notifyNonceStoreAtomic replay store used by high-level notify verification
merchantWalletSignerOptional merchant-controlled signer for reverse x402 refunds
payTo, networkOptional defaults for merchant operations and refunds

client.request<T>(path, init?) sends an authenticated same-origin request. Paths must begin with one / and cannot escape the configured origin.

Merchant registration and keys

FunctionPurpose
createMerchantChallenge(gateway, request)Request payTo ownership challenge
merchantChallengeSigningMessage(message)Build canonical EIP-191 challenge text
merchantChallengeTypedData(message)Build EVM EIP-712 ownership typed data
registerMerchant(gateway, request)Submit signature and receive one-time credentials
getMerchantProfile(client)Read authenticated profile
rotateMerchantKey(client, { keyType })Rotate apiKey or notifyHmacKey with overlap expiry
revokeOldMerchantKey(client, options)Revoke the old tenant-scoped key

Registration returns merchantId, apiKey, notifyHmacKey, notifyHmacKeyId, and payTo. Store raw keys immediately; do not expect to read them again.

Reference management

FunctionPurpose
createPaymentRef(client, options)Create an authenticated fixed or open ref
getRef(client, refId)Read public snapshot
listRefs(client, options)List tenant refs by payTo with bounded pagination
revokePaymentRef(client, options)Revoke a ref with optional bounded reason
revokePayTo(client, options)Retire a payTo address

Merchant create options match the receiver API but omit gateway and apiKey, which come from the client.

Optional order mode

FunctionSignature summary
createOrder(client, { payTo, amount, asset?, network?, orderId?, description?, metadata?, expirySecs? })
getOrder(client, orderId)
listOrders(client, { status?, limit?, cursor? }?)
cancelOrder(client, orderId)
createOrderRefund(client, { orderId, amount, refundId?, originalPaymentRef, expiresInSecs? })
getRefundStatus(client, orderId, refundId)
listRefunds(client, orderId)

Order status is unpaid | pending | paid | confirmed | failed | cancelled | partially_refunded | fully_refunded. Routes may be unavailable when gateway order mode is disabled.

Refunds

refund(client, options) performs a reverse x402 payment with the merchant wallet. Order mode creates a bound refund intent first; stateless mode requires originalPayer, refundId, network, original receipt hash, original amount, cumulative refunded amount, sequence, and FULL | PARTIAL result.

Use rejectRefund(client, options) for a signed REJECTED refund receipt. It does not move funds or call the facilitator.

Receipt and tx verification

FunctionPurpose
verifyReceipt(client, options)Verify signed payment receipt and chain transfer
verifyRefundReceipt(client, options)Verify signed refund receipt and reverse transfer
verifySignedPaymentReceipt(options)Local signature and expected-field verification
verifySignedRefundReceipt(options)Local refund signature and expected-field verification
paymentReceiptContentHash(receipt)Canonical payment receipt reference
refundReceiptContentHash(receipt)Canonical refund receipt reference
getTxStatus(gateway, txHash)Bounded transaction status
getPaymentHistory(gateway, options)Bounded Transfer log history

Local signature verification establishes gateway attestation. Network verification establishes chain finality.

Notify verification

FunctionReplay-safe?Use
verifySettlementNotify(headers, rawBody, keys, nonceStore, ...)YesVerify HMAC, headers, body binding, event schema, timestamp, and nonce
verifyNotifySignature(headers, rawBody, keys, nonceStore, ...)YesVerify envelope without parsing event body
notifyMiddleware(options)YesExpress-compatible middleware using raw body access
createMemoryNotifyNonceStore()One process onlyTests and local development
verifyNotifySignatureWithoutReplayProtection(...)NoDiagnostics only; never guard side effects

Production multi-instance systems need a shared atomic NotifyNonceStore.putIfAbsent(key, expiresAt) implementation.

Reconciliation

TypeScript
const report = await reconcile(client, { payTo, fromBlock, limit: 200, receipts, refundReceipts, trustedSigners, minConfirmations: 3, verifyChain: true});

The result contains incoming and outgoing transfer evidence, anomalies, the last observed block, and optional cursors. Reconciliation reports mismatches; it never mutates merchant orders automatically.

Anomalies include transfers without receipts, receipts without transfers, signature/chain verification failures, duplicates, refund evidence mismatches, cumulative mismatches, and refunds exceeding the original amount.