Hooks are the core extension mechanism of the x402 settlement system. By implementing the ISettlementHook interface, you can execute arbitrary business logic after payment completion, such as:
- 💰 Revenue splitting
- 🎨 NFT minting
- 🎁 Reward points
- 📦 Automatic fulfillment
The x402 settlement framework provides two types of Hooks:
Protocol-level Hooks deployed once per network for universal use:
| Hook | Location | Purpose | Usage |
|---|---|---|---|
| TransferHook | src/hooks/ |
Simple transfers with facilitator fee | Production-ready, shared deployment |
Characteristics:
- ✅ Production-ready and optimized
- ✅ Deployed once per network
- ✅ Universal addresses for all projects
- ✅ Minimal gas overhead
- ✅ Battle-tested and audited
📖 Learn more about Built-in Hooks →
Educational templates and reference implementations:
| Hook | Location | Purpose |
|---|---|---|
| TransferHook | Built-in (no separate contract) | Simple transfers and revenue splitting |
| NFTMintHook | examples/nft-mint/ |
Atomic NFT minting with payment |
| RewardHook | examples/reward-points/ |
Loyalty points distribution |
Characteristics:
- 📖 Learning and customization templates
- 🔧 Per-application deployment
- 🎯 Scenario-specific implementations
- 🔄 Starting points for custom Hooks
Use Built-in Hooks when:
- ✅ You need simple token transfers
- ✅ You want facilitator fee support
- ✅ You value minimal gas costs
- ✅ You don't need custom business logic
Use or Create Custom Hooks when:
- 🎯 You need revenue splitting
- 🎯 You need NFT minting
- 🎯 You need custom business logic
- 🎯 You need Hook-specific state
interface ISettlementHook {
function execute(
bytes32 contextKey, // Settlement context ID
address payer, // Payer address
address token, // Token contract address
uint256 amount, // Amount
bytes calldata data // Business data
) external returns (bytes memory);
}We provide complete implementations for three common scenarios. Choose the one that best fits your needs:
| Scenario | Description | Example Directory |
|---|---|---|
| 💰 Revenue Split | Automatically distribute revenue among multiple parties | examples/revenue-split/ |
| 🎨 NFT Minting | Automatically mint NFT to user after payment | examples/nft-mint/ |
| 🎁 Reward Points | Pay merchant while distributing reward points to user | examples/reward-points/ |
contract MyHook is ISettlementHook {
using SafeERC20 for IERC20;
address public immutable settlementRouter;
modifier onlyHub() {
require(msg.sender == settlementRouter, "Only hub");
_;
}
constructor(address _settlementHub) {
settlementRouter = _settlementHub;
}
function execute(
bytes32 contextKey,
address payer,
address token,
uint256 amount,
bytes calldata data
) external onlyHub returns (bytes memory) {
// 1. Parse business data
address recipient = abi.decode(data, (address));
// 2. Execute business logic
// TODO: Your business logic here
// 3. Transfer funds (must consume all amount)
IERC20(token).safeTransferFrom(settlementRouter, recipient, amount);
return abi.encode(recipient);
}
}- Only Hub can call - Use
onlyHubmodifier to prevent unauthorized access - Consume all funds from Hub - Must transfer out the entire
amountfrom SettlementRouter
// ✅ Correct: Consume all amount from Hub
IERC20(token).safeTransferFrom(settlementRouter, recipient, amount);
// ✅ Also correct: Hook can hold funds if needed for business logic
IERC20(token).safeTransferFrom(settlementRouter, address(this), amount);
// ... later business logic to distribute funds
// ❌ Wrong: Leaving funds in Hub
IERC20(token).safeTransferFrom(settlementRouter, recipient, amount / 2);
// This will cause "HubShouldNotHoldFunds" error- Hooks CAN hold funds - Useful for escrow, batching, or delayed payments
- Hub CANNOT hold funds - This is enforced by the SettlementRouter contract
- Business logic is flexible - Design your Hook according to your use case
Each example includes complete contract code, deployment scripts, and test cases:
💰 Revenue Split - examples/revenue-split/
Scenario: E-commerce platform with automatic commission
- Merchant receives 95% of payment
- Platform automatically collects 5% commission
- Supports any number of split parties
🎨 NFT Minting - examples/nft-mint/
Scenario: Digital artwork purchase
- User automatically receives NFT after payment
- Supports NFT minting + revenue split combination
- Includes complete NFT contract example
🎁 Reward Points - examples/reward-points/
Scenario: Member loyalty system
- Merchant receives full payment
- User gets reward points (1000 points per $0.1)
- Includes ERC20 reward token contract
- Explore Examples: Browse the
examples/directory for complete implementations - Run Tests: Execute
forge testto see all examples in action - Deploy: Use the deployment scripts in each example directory
- Customize: Modify the examples to fit your specific use case
- API Documentation - Complete API reference
- Security Guide - Security best practices
- Facilitator Guide - Integration guide for facilitators
- Always use
SafeERC20for token transfers - Add event logging for important actions
- Validate all input parameters
- Consider gas optimization for complex logic
- Test thoroughly with edge cases
Q: Hook execution fails with "balance not zero"
A: Ensure your Hook consumes the entire amount parameter
Q: "Only hub" error when testing
A: Make sure to call from the SettlementRouter address in tests
Q: Gas limit exceeded
A: Optimize your Hook logic or split complex operations