Accept payments from any blockchain. Settle in USDh. Built for AI agents and applications.
The Stacks Payment Router enables you to accept cryptocurrency payments from Ethereum, Arbitrum, Base, Polygon, and other chains, automatically converting them to USDh (yield-bearing stablecoin) on Stacks. Perfect for AI agents, SaaS applications, and any service that needs cross-chain payment acceptance.
Stacks Payment Router is a cross-chain payment system that:
- β Accepts payments from multiple blockchains (Ethereum, Arbitrum, Base, Polygon, Optimism, Stacks, Solana, Bitcoin)
- β Automatically converts all payments to USDh stablecoin on Stacks
- β Earns yield on your deposits (20% APY)
- β Generates unique addresses for each payment (one Stacks address β addresses on all chains)
- β Detects payments automatically and settles them within minutes
- β Provides APIs for easy integration into your application
First, you need a Stacks wallet address. If you don't have one:
- Install Hiro Wallet: https://www.hiro.so/wallet/install
- Create a new wallet or import an existing one
- Copy your Stacks address (starts with
ST1...orST2...)
Option A: Using the Web Dashboard
- Visit:
https://payment-router.com/dashboard - Click "Connect Wallet" and connect your Hiro Wallet
- Your agent is automatically registered!
Option B: Using the API
curl -X POST https://api.payment-router.com/api/v1/agents/register \
-H "Content-Type: application/json" \
-d '{
"stacksAddress": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"agentId": "my-agent-001",
"enabledChains": ["ethereum", "arbitrum", "base"],
"autoWithdraw": false
}'Response:
{
"success": true,
"data": {
"id": "agent-001",
"stacksAddress": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"enabledChains": ["ethereum", "arbitrum", "base"],
"paymentAddresses": {
"ethereum": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"arbitrum": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"base": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
},
"registeredAt": "2024-12-13T10:00:00Z"
}
}When you want to accept a payment, create a payment intent:
curl -X POST https://api.payment-router.com/api/v1/payments/intent \
-H "Content-Type: application/json" \
-d '{
"agentAddress": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"amount": "100.00",
"chain": "ethereum"
}'Response:
{
"success": true,
"data": {
"id": "intent-abc123",
"agentAddress": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"amount": "100.00",
"expectedAmount": "0.05",
"chain": "ethereum",
"paymentAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"status": "pending",
"expiresAt": "2024-12-14T10:00:00Z",
"paymentUrl": "https://payment-router.com/pay/intent-abc123"
}
}Share the paymentUrl with your customer. They can:
- Scan QR code with their wallet
- Copy the payment address
- Send the exact amount in the specified token
- β Payment is detected within ~15 seconds
- β Automatically converted to USDh
- β Deposited to your yield vault
- β You earn 20% APY automatically
1. Payment Management
- View all payment intents
- See payment status in real-time
- Track settlement history
2. Vault Management
- View your USDh balance
- See accrued yield
- Withdraw funds (with optional delay for security)
3. Agent Settings
- Configure supported chains
- Set payment limits
- Enable auto-withdraw (instant settlement with fee)
- Manage webhooks
4. Analytics
- Payment volume charts
- Success rates
- Revenue tracking
- Visit:
https://payment-router.com/dashboard - Connect Wallet: Click "Connect Wallet" β Select Hiro Wallet
- Authorize: Approve the connection
- Start Accepting Payments: Create your first payment intent!
Production: https://api.payment-router.com/api/v1
Testnet: https://api-testnet.payment-router.com/api/v1
Most endpoints don't require authentication. For admin operations, use API keys:
X-API-Key: your-api-key-hereRegister your Stacks address to start accepting payments.
POST /api/v1/agents/register
Content-Type: application/json
{
"stacksAddress": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"agentId": "my-unique-agent-id",
"enabledChains": ["ethereum", "arbitrum", "base"],
"autoWithdraw": false,
"settlementPreference": "usdh"
}Parameters:
stacksAddress(required): Your Stacks wallet addressagentId(required): Unique identifier for your agent (max 64 chars)enabledChains(required): Array of chains you want to accept payments onautoWithdraw(optional): Iftrue, funds are instantly withdrawn (with fee). Default:falsesettlementPreference(optional):"usdh"or"stx". Default:"usdh"
Supported Chains:
ethereum- Ethereum Mainnetarbitrum- Arbitrum Onebase- Basepolygon- Polygonoptimism- Optimismstacks- Stackssolana- Solanabitcoin- Bitcoin
Create a payment request and get a unique payment address.
POST /api/v1/payments/intent
Content-Type: application/json
{
"agentAddress": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"amount": "100.00",
"chain": "ethereum",
"metadata": {
"orderId": "order-123",
"customerEmail": "customer@example.com"
}
}Parameters:
agentAddress(required): Your registered Stacks addressamount(required): Payment amount in USDchain(required): Blockchain to accept payment onmetadata(optional): Custom data attached to payment
Response:
{
"success": true,
"data": {
"id": "intent-abc123",
"agentAddress": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"amount": "100.00",
"expectedAmount": "0.05",
"expectedToken": "ETH",
"chain": "ethereum",
"paymentAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"status": "pending",
"createdAt": "2024-12-13T10:00:00Z",
"expiresAt": "2024-12-14T10:00:00Z",
"paymentUrl": "https://payment-router.com/pay/intent-abc123"
}
}Check the status of a payment intent.
GET /api/v1/payments/intent/{intentId}/statusResponse:
{
"success": true,
"data": {
"status": "settled",
"detectedAt": "2024-12-13T10:05:00Z",
"settledAt": "2024-12-13T10:06:00Z",
"txHash": "0x123...",
"settlementTxHash": "0x456...",
"netAmount": "99.50",
"feesPaid": "0.50"
}
}Payment Statuses:
pending- Waiting for paymentdetected- Payment detected, routing in progresssettled- Payment converted to USDh and depositedexpired- Payment expired (default: 24 hours)failed- Payment failed (insufficient amount, etc.)
Check your USDh balance in the yield vault.
GET /api/v1/agents/{agentAddress}/balanceResponse:
{
"success": true,
"data": {
"balance": "1250.50",
"principal": "1000.00",
"accruedYield": "250.50",
"totalYieldEarned": "500.00",
"lastYieldClaim": "2024-12-13T09:00:00Z"
}
}Get your agent registration information.
GET /api/v1/agents/{agentAddress}Response:
{
"success": true,
"data": {
"address": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"agentId": "my-agent-001",
"enabledChains": ["ethereum", "arbitrum", "base"],
"paymentAddresses": {
"ethereum": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"arbitrum": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"base": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
},
"autoWithdraw": false,
"settlementPreference": "usdh",
"totalVolume": "50000.00",
"totalPayments": 150,
"registeredAt": "2024-12-01T00:00:00Z"
}
}The Payment Router is built on Stacks blockchain and uses Clarity smart contracts:
- Agent Registry Contract: Manages agent registration and payment tracking
- Payment Router Contract: Orchestrates payment intents and settlement
- Yield Vault Contract: Manages USDh deposits and yield accrual
Your Stacks address is your identity in the system:
- Format:
ST1...orST2...(mainnet) orST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K(testnet) - Used to: Register as an agent, receive settlements, manage vault
Agent Registry: ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K.agent-registry
Payment Router: ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K.payment-router
Yield Vault: ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K.yield-vault
Token USDh: ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K.token-usdh
- Testnet Explorer: https://explorer.hiro.so/?chain=testnet
- Mainnet Explorer: https://explorer.hiro.so/
Search for your contract address to see:
- Contract source code
- Function calls
- Transaction history
- Contract state
Using Hiro Wallet:
- Open Hiro Wallet extension
- Go to "Contract Call" tab
- Enter contract address (e.g.,
ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K.payment-router) - Select function (e.g.,
get-payment-intent) - Enter parameters
- Submit transaction
Using Stacks.js:
import { callReadOnlyFunction } from '@stacks/transactions';
import { StacksTestnet } from '@stacks/network';
const network = new StacksTestnet();
// Read payment intent
const result = await callReadOnlyFunction({
network,
contractAddress: 'ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K',
contractName: 'payment-router',
functionName: 'get-payment-intent',
functionArgs: [stringAsciiCV('intent-abc123')],
senderAddress: 'ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K',
});1. You create payment intent β Get unique payment address
2. Customer sends crypto to address β Payment detected (~15 seconds)
3. System routes payment β Swaps/bridges to USDh
4. Settlement executed β USDh deposited to your vault
5. You earn yield β 20% APY automatically
- Standard Settlement: 0.5% fee (paid from payment amount)
- Auto-Withdraw: 0.5% settlement fee + 1% instant withdrawal fee
Example:
- Payment: $100 USD
- Settlement fee: $0.50
- Net deposited: $99.50 USDh
- After 1 year at 20% APY: ~$119.40 USDh
All payments are automatically deposited into the Yield Vault:
- APY: 20% (configurable by protocol)
- Compounding: Yield accrues continuously
- Withdrawal: Standard withdrawal (144 blocks delay) or instant (with fee)
- Minimum Deposit: 1 USDh
- No Lockup: Withdraw anytime
Standard Withdrawal (Recommended):
- Request withdrawal from dashboard or API
- Wait 144 blocks (~24 hours) for security
- Execute withdrawal (no fee)
- Funds sent to your Stacks address
Instant Withdrawal:
- Request instant withdrawal
- Pay 1% fee
- Funds sent immediately
// Install: npm install @payment-router/api-client
import { ApiClient } from '@payment-router/api-client';
const api = new ApiClient({
baseUrl: 'https://api.payment-router.com/api/v1'
});
// 1. Register agent (one-time)
const agent = await api.registerAgent({
address: 'ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K',
name: 'My AI Agent',
enabledChains: ['ethereum', 'arbitrum'],
autoWithdraw: false
});
// 2. Create payment intent
const payment = await api.createPaymentIntent({
agentAddress: 'ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K',
amount: '100.00',
chain: 'ethereum',
metadata: { orderId: 'order-123' }
});
// Share payment.paymentUrl with customer
// 3. Poll for payment status
const checkStatus = setInterval(async () => {
const status = await api.getPaymentStatus(payment.id);
if (status.data.status === 'settled') {
console.log('Payment settled!', status.data);
clearInterval(checkStatus);
}
}, 5000); // Check every 5 seconds
// 4. Check balance
const balance = await api.getAgentBalance('ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K');
console.log('Your balance:', balance.data.balance, 'USDh');import requests
import time
API_BASE = "https://api.payment-router.com/api/v1"
# 1. Register agent
response = requests.post(f"{API_BASE}/agents/register", json={
"stacksAddress": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"agentId": "my-python-agent",
"enabledChains": ["ethereum", "arbitrum"]
})
agent = response.json()["data"]
# 2. Create payment intent
response = requests.post(f"{API_BASE}/payments/intent", json={
"agentAddress": "ST2N6HZJPPQ8VGJZGPPP8754CFNGWKBHVAZ85QB6K",
"amount": "100.00",
"chain": "ethereum"
})
payment = response.json()["data"]
print(f"Payment URL: {payment['paymentUrl']}")
# 3. Poll for status
while True:
response = requests.get(f"{API_BASE}/payments/intent/{payment['id']}/status")
status = response.json()["data"]
if status["status"] == "settled":
print("Payment settled!")
break
time.sleep(5)Receive real-time notifications when payments are detected and settled:
// Set webhook URL in agent settings
await api.updateAgent(agentAddress, {
webhookUrl: 'https://your-app.com/webhooks/payment'
});
// Your webhook endpoint
app.post('/webhooks/payment', (req, res) => {
const { type, data } = req.body;
if (type === 'payment.detected') {
console.log('Payment detected:', data.intentId);
}
if (type === 'payment.settled') {
console.log('Payment settled:', data.intentId, data.netAmount);
}
res.json({ received: true });
});Accept payments for AI services (ChatGPT plugins, AI tools, etc.):
// User requests AI service
const payment = await createPaymentIntent({
agentAddress: YOUR_STACKS_ADDRESS,
amount: '10.00',
chain: 'ethereum'
});
// Show payment link to user
// After payment settles, provide AI serviceAccept monthly subscriptions from any chain:
// Create monthly subscription payment
const subscription = await createPaymentIntent({
agentAddress: YOUR_STACKS_ADDRESS,
amount: '29.99',
chain: 'arbitrum', // User's preferred chain
metadata: {
subscriptionId: 'sub-123',
plan: 'pro',
period: 'monthly'
}
});Accept crypto payments for products:
// Customer checkout
const order = await createPaymentIntent({
agentAddress: YOUR_STACKS_ADDRESS,
amount: orderTotal.toString(),
chain: customerPreferredChain,
metadata: {
orderId: order.id,
items: order.items
}
});
// Redirect to payment page
window.location.href = order.paymentUrl;Accept payments for services:
// Create invoice payment
const invoice = await createPaymentIntent({
agentAddress: YOUR_STACKS_ADDRESS,
amount: invoiceAmount.toString(),
chain: 'ethereum',
metadata: {
invoiceId: invoice.id,
clientId: client.id
}
});- β Never share your Stacks private key - Only your public address is needed
- β Use webhooks - Don't poll excessively, use webhooks for real-time updates
- β Verify payments - Always verify payment status before providing service
- β Set payment limits - Configure min/max amounts in agent settings
- β Monitor transactions - Check Stacks explorer regularly
- Store Intent IDs: Save payment intent IDs in your database
- Handle Expiry: Payment intents expire after 24 hours (configurable)
- Error Handling: Always handle API errors gracefully
- Rate Limiting: API has rate limits (100 requests/minute)
- Webhooks: Use webhooks instead of polling when possible
Access your dashboard at https://payment-router.com/dashboard to see:
- Total Volume: All-time payment volume
- Success Rate: Percentage of successful payments
- Average Amount: Average payment size
- Recent Payments: Last 24 hours, 7 days, 30 days
- Vault Stats: Balance, yield earned, deposits, withdrawals
// Get payment statistics
const stats = await api.getPaymentStats(agentAddress);
console.log('Total payments:', stats.data.totalPayments);
console.log('Total volume:', stats.data.totalVolume);
console.log('Success rate:', stats.data.successRate + '%');- API Reference: https://docs.payment-router.com/api
- Stacks Documentation: https://docs.stacks.co
- Clarity Language: https://docs.stacks.co/learn/clarity
- Discord: Join our Discord
- GitHub: https://github.com/Officialhomie/stacks-payment-router
- Twitter: @StacksPaymentRouter
- Email: support@payment-router.com
- Status Page: https://status.payment-router.com
1. Get a Stacks Wallet
- Install Hiro Wallet: https://www.hiro.so/wallet/install
- Create new wallet
- Copy your Stacks address (ST1... or ST2...)
2. Register Your Agent
curl -X POST https://api.payment-router.com/api/v1/agents/register \
-H "Content-Type: application/json" \
-d '{
"stacksAddress": "YOUR_STACKS_ADDRESS",
"agentId": "my-first-agent",
"enabledChains": ["ethereum"]
}'3. Create a Test Payment
curl -X POST https://api.payment-router.com/api/v1/payments/intent \
-H "Content-Type: application/json" \
-d '{
"agentAddress": "YOUR_STACKS_ADDRESS",
"amount": "10.00",
"chain": "ethereum"
}'4. Share Payment Link
Copy the "paymentUrl" from the response
Share it with a test customer
5. Monitor Payment
# Check status
curl https://api.payment-router.com/api/v1/payments/intent/{INTENT_ID}/status
# When status = "settled", payment is complete!6. Check Your Balance
curl https://api.payment-router.com/api/v1/agents/YOUR_STACKS_ADDRESS/balance- API:
https://api-testnet.payment-router.com - Dashboard:
https://testnet.payment-router.com - Stacks Explorer: https://explorer.hiro.so/?chain=testnet
- Get Testnet STX: https://explorer.hiro.so/sandbox/faucet?chain=testnet
- API:
https://api.payment-router.com - Dashboard:
https://payment-router.com - Stacks Explorer: https://explorer.hiro.so
Enable autoWithdraw: true when registering to get instant access to funds (with 1% fee):
await api.registerAgent({
address: YOUR_ADDRESS,
autoWithdraw: true // Instant settlement
});Configure min/max amounts to prevent errors:
await api.updateAgent(YOUR_ADDRESS, {
minPaymentAmount: '1.00', // Minimum $1
maxPaymentAmount: '10000.00' // Maximum $10,000
});Attach custom data to payments for your internal tracking:
await api.createPaymentIntent({
agentAddress: YOUR_ADDRESS,
amount: '100.00',
chain: 'ethereum',
metadata: {
orderId: 'order-123',
customerId: 'cust-456',
productId: 'prod-789'
}
});Set up webhooks to get real-time notifications:
// In your agent settings
webhookUrl: 'https://your-app.com/webhooks/payment'Q: What is USDh? A: USDh is a yield-bearing stablecoin on Stacks. All payments are converted to USDh and earn 20% APY automatically.
Q: How long does settlement take? A: Payment detection: ~15 seconds. Settlement: 2-5 minutes depending on chain congestion.
Q: What chains are supported? A: Ethereum, Arbitrum, Base, Polygon, Optimism, Stacks, Solana, Bitcoin.
Q: What tokens can I accept? A: ETH, USDC, USDT, WETH, WBTC, SOL, STX, and more. All are automatically converted to USDh.
Q: Is there a minimum payment amount? A: Yes, minimum is $1 USD equivalent. Maximum is configurable.
Q: How do I withdraw my funds? A: Use the dashboard or API to request withdrawal. Standard withdrawal takes ~24 hours. Instant withdrawal (with fee) is immediate.
Q: What are the fees? A: Settlement fee: 0.5%. Instant withdrawal fee: 1%. No fees for standard withdrawals.
Q: Do I need to know blockchain programming? A: No! The API handles everything. Just use the REST API or web dashboard.
Q: Is this secure? A: Yes! Built on Stacks blockchain with audited Clarity smart contracts. Your funds are secured by blockchain cryptography.
Q: Can I use this for production? A: Yes! The system is production-ready. Start with testnet to familiarize yourself.
- Get a Stacks Wallet: https://www.hiro.so/wallet/install
- Visit Dashboard: https://payment-router.com/dashboard
- Connect Wallet: Click "Connect Wallet"
- Create Payment: Click "Create Payment Intent"
- Share Link: Send payment URL to customer
- Get Paid: Payment settles automatically!
MIT License - Use freely for your projects!
Built with β€οΈ on Stacks blockchain
Last Updated: December 13, 2025