The PaymentInfo struct uniquely identifies a payment and contains all its parameters:
Copy
interface PaymentInfo { operator: `0x${string}`; // PaymentOperator contract address payer: `0x${string}`; // Payer's address receiver: `0x${string}`; // Merchant's address token: `0x${string}`; // Payment token (e.g., USDC) maxAmount: bigint; // Maximum payment amount preApprovalExpiry: bigint; // Pre-approval expiry timestamp (0n if not used) authorizationExpiry: bigint; // When payer can reclaim funds refundExpiry: bigint; // Deadline for refund requests minFeeBps: number; // Minimum fee in basis points maxFeeBps: number; // Maximum fee in basis points feeReceiver: `0x${string}`; // Address that receives fees salt: bigint; // Unique salt for this payment}
Use computePaymentInfoHash() from @x402r/core to compute the unique hash of a payment. Use parsePaymentInfo() to deserialize a JSON PaymentInfo back into the typed struct.
The EscrowPeriod contract tracks when a payment was authorized and enforces a configurable waiting period before funds can be released. During the escrow period:
Payers can request refunds or freeze the payment
Merchants can refund but cannot release
After the period — merchants can release funds to themselves
Copy
import { X402rClient } from '@x402r/client';// Check when payment was authorizedconst authTime = await client.getAuthorizationTime(paymentInfo, escrowPeriodAddress);// Check if still within escrow periodconst inEscrow = await client.isDuringEscrowPeriod(paymentInfo, escrowPeriodAddress);if (!inEscrow) { console.log('Escrow period has passed - funds can be released');}
All refund methods require a nonce parameter. This is the record index from the PaymentIndexRecorder that identifies which charge the refund request applies to. For the first charge, use 0n.
Copy
// Request refund for the first chargeawait client.requestRefund(paymentInfo, amount, 0n);// Check status for the first chargeconst status = await client.getRefundStatus(paymentInfo, 0n);