StablePay

API Reference

Everything you need to accept stablecoin payments. Base URL: https://wetakestables.shop

How It Works Auth Checkout Orders Webhooks Widget Invoices Treasury Compliance Managed Wallets Payment Links Receipts AI Agent Pricing

Authentication

All authenticated endpoints require a Bearer token in the Authorization header. Get your token from the dashboard or login response.

Authorization: Bearer your-merchant-token
POST /api/v1/signup

Create a new merchant account. Returns a merchant ID and sends a verification email.

Body:

{
  "email": "merchant@example.com",
  "companyName": "My Store",
  "contactName": "John",
  "password": "min8chars",
  "plan": "FREE"
}

Response:

{
  "success": true,
  "message": "Check your email for the verification code.",
  "merchantId": "cmXXXXXXXX"
}
POST /api/verify-email

Verify email with the 6-digit code. Auto-activates FREE tier accounts.

{ "email": "merchant@example.com", "code": "123456" }

Response:

{ "success": true, "token": "your-bearer-token", "merchantId": "cmXXXX", "isActive": true }
POST /api/login

Login with email + password. Returns a Bearer token for API calls.

{ "email": "merchant@example.com", "password": "your-password" }

Response:

{ "success": true, "token": "your-bearer-token", "merchantId": "cmXXXX", "isActive": true }
POST /api/forgot-password

Request a password reset code. Sends a 6-digit code to the email.

{ "email": "merchant@example.com" }
POST /api/reset-password

Reset password using the 6-digit code from email.

{ "email": "merchant@example.com", "code": "123456", "newPassword": "min8chars" }

Checkout (Create Payment)

This is the main endpoint your checkout flow calls. Creates an order and returns a payment address.

POST /api/embed/checkout

Create a payment order. No auth required — uses merchantId to identify the account.

Body:

{
  "merchantId": "your-merchant-id",    // Required
  "amount": 99.99,                     // Required — in USD
  "chain": "BASE_MAINNET",            // Optional — customer picks if omitted
  "token": "USDC",                    // Optional — defaults to USDC
  "customerEmail": "buyer@email.com", // Optional
  "customerWallet": "0xabc...",       // Optional — customer's wallet for precise matching
  "productName": "Order #1234"        // Optional
}

Response:

{
  "success": true,
  "order": {
    "id": "cmXXXXXX",
    "amount": 99.99,
    "token": "USDC",
    "chain": "BASE_MAINNET",
    "paymentAddress": "0x...",    // Send stablecoins HERE
    "expiresAt": "2026-03-28T..."
  }
}
Flow: Your checkout calls this → customer sends stablecoins to paymentAddress → we detect the transfer on-chain → webhook fires to your server → order confirmed.
After creating the order, redirect the customer to:
https://wetakestables.shop/checkout?orderId=ORDER_ID

This resolves the order and loads the full checkout UI (chain selector, wallet connect, QR code, manual send).

GET /checkout?orderId=ORDER_ID

Checkout page for an existing order. Resolves the order, validates it's still pending and not expired, then redirects to the payment UI with the correct merchant/amount/chain.

Errors:

404 — Order not found
400 — Order is confirmed/expired/cancelled — cannot checkout

Orders

GET /api/orders

List your orders. Requires Bearer token. Returns only orders belonging to the authenticated merchant.

Authorization: Bearer your-token

// Response:
{ "orders": [...], "total": 42, "page": 1, "limit": 50 }
GET /api/orders/:orderId

Get a single order by ID. Returns full order details including transaction info.

POST /api/orders/:orderId/confirm

Manually confirm an order (admin). Normally handled automatically by on-chain detection.

Webhooks

Configure your webhook URL in the dashboard or via the agent. We POST to your endpoint when payment events occur.

How It Works

When a customer pays, we send a POST request to your server so you know it happened. You don't need to check — we tell you.

Your webhook URL: https://YOUR-DOMAIN/api/webhooks/stablepay

Set this in your dashboard or tell the AI agent your domain and it'll configure everything + write the handler code for you.

Example: Next.js Webhook Handler

// pages/api/webhooks/stablepay.js
export default async function handler(req, res) {
  if (req.method !== 'POST') return res.status(405).end();

  const { event, orderId, amount, txHash, chain } = req.body;

  if (event === 'order.confirmed') {
    // Payment confirmed! Do your thing:
    // - Update your database
    // - Send confirmation email
    // - Fulfill the order
    console.log(`Payment: $${amount} on ${chain}, tx: ${txHash}`);
  }

  res.status(200).json({ received: true });
}

Webhook Payload (order.confirmed)

When a payment confirms, we POST this to your webhook URL:

{
  "event": "order.confirmed",
  "orderId": "cmXXXXXX",
  "amount": 99.99,
  "token": "USDC",
  "chain": "BASE_MAINNET",
  "status": "CONFIRMED",
  "txHash": "0xabc123...",
  "explorerLink": "https://basescan.org/tx/0xabc123...",
  "customerEmail": "buyer@email.com",
  "customerWallet": "0x742d...",
  "paymentAddress": "0x42f8...",
  "feePercent": 0.01,
  "feeAmount": 0.99,
  "netAmount": 99.00,
  "confirmedAt": "2026-03-29T14:30:00Z"
}

The explorerLink lets you verify the transaction on-chain (BaseScan, Etherscan, etc.)

Events:

  • order.created — New payment order created
  • order.confirmed — Payment confirmed on-chain
  • order.refunded — Refund processed
  • invoice.paid — Invoice payment received
  • receipt.sent — Receipt email delivered
Your webhook should respond with 200 OK. We retry up to 3 times with exponential backoff on failure.

How It Works

Setup (3 steps)

1
Create wallet — bring your own (MetaMask, Phantom) or we create a managed one instantly. One address works on all EVM chains.
2
Add your domain — we auto-configure your webhook URL and redirect URLs. AI agent handles everything.
3
Add the widget — one script tag + one line of code. Customers can pay immediately.

Payment Flow

Customer clicks "Pay with Crypto" on your site
        |
StablePay checkout opens (modal or hosted page)
        |
Customer picks chain (Base, Ethereum, Polygon, Arbitrum, Solana)
        |
Customer picks stablecoin (USDC, USDT, EURC — varies by chain)
        |
Customer picks HOW to pay:
   +-- Connect Wallet — MetaMask/Rainbow/Coinbase/Phantom, one-click approve
   +-- QR Code — scan with mobile wallet app
   +-- Copy Address — paste into any wallet or exchange
        |
Payment lands in YOUR wallet (direct, non-custodial)
        |
Our scanner detects the on-chain transfer (15-30 seconds)
        |
Webhook fires to your server with:
  orderId, amount, token, txHash, explorerLink, netAmount, confirmedAt
        |
Customer sees success screen

How Each Payment Method Works

1. Connect Wallet

Customer clicks "Connect Wallet"
  → Widget detects installed wallets (MetaMask, Rainbow, etc.)
  → If multiple: shows wallet picker
  → Wallet connects, customer address captured
  → Order created in our DB (with customerWallet)
  → Widget calls ERC20 transfer() directly through wallet
  → Wallet popup → customer approves → tx submitted
  → txHash registered with our API immediately
  → Scanner also confirms as backup
  → Webhook fires with txHash + explorerLink

2. QR Code

Customer switches to "QR Code" tab
  → Enters their wallet address (for matching)
  → Order created in our DB
  → QR code generated with merchant's payment address
  → Customer scans QR with mobile wallet app
  → Sends payment from their wallet
  → Widget polls GET /api/embed/order/:id every 5 seconds
  → Scanner detects Transfer event on-chain
  → Matches by FROM + TO + amount → confirms order
  → Poll picks up CONFIRMED → shows success
  → Webhook fires

3. Copy Address

Customer switches to "Copy Address" tab
  → Enters their wallet address (for matching)
  → Order created in our DB
  → Shows: merchant address (with Copy button) + exact amount
  → Customer copies address → opens Coinbase/Binance/any wallet
  → Sends exact amount on the correct chain
  → Scanner detects → matches → confirms
  → Widget polling picks up confirmation
  → Webhook fires

What Your Customers See

The checkout widget gives every customer 3 ways to pay — no config needed:

Connect Wallet

MetaMask, Rainbow, Coinbase Wallet, Phantom. One-click approve. Best for desktop.

QR Code

Scan with any mobile wallet app. Pre-filled transaction. Best for phones.

Copy Address

Copy wallet address + exact amount. Send from any wallet or exchange (Coinbase, Binance).

Customers choose their chain and stablecoin. The widget shows only what you have configured. If you accept USDC on Base and Ethereum, that's what they see — nothing more.

Checkout Widget

Drop-in checkout for any website. One script tag + one function call.

Quick Start

<script src="https://wetakestables.shop/checkout-widget.js"></script>

<button onclick="StablePay.checkout({
  merchantId: 'your-merchant-id',
  amount: 49.99,
  onSuccess: (data) => {
    console.log('Paid!', data.orderId, data.txHash);
    window.location.href = '/thank-you';
  },
  onCancel: () => console.log('Cancelled')
})">Pay with Crypto</button>

All Options:

ParameterTypeDescription
merchantIdstringRequired. Your merchant ID.
amountnumberPayment amount in USD.
productNamestringShown in header. Default: "Pay with Stablecoins"
customerEmailstringPre-fill customer email.
allowedChainsstring[]Restrict chains shown at checkout.
allowedTokensstring[]Restrict tokens shown.
onSuccessfunctionCallback: { orderId, txHash, amount }
onCancelfunctionCalled when customer closes checkout.

Customization Options:

ParameterTypeDescription
theme'dark' | 'light'Color scheme. Default: 'light'
borderStyle'brutal' | 'rounded' | 'minimal'Border style. Default: 'brutal' (thick borders + shadow)
accentColorstringAccent color (hex). Default: '#00E5FF'
headerColorstringHeader background color. Default: '#00E5FF'
buttonTextstringCustom pay button text. Overrides default.
logoUrlstringURL to your logo. Displayed in header.
fontFamilystringCustom font (must be loaded on your page).
customCSSstringAdditional CSS rules scoped to .sp-widget
hideFooterbooleanHide "Powered by StablePay" footer.
Example: Custom styled checkout
StablePay.checkout({
  merchantId: 'your-id',
  amount: 25.00,
  // Style it your way:
  theme: 'dark',
  borderStyle: 'rounded',
  headerColor: '#8B5CF6',
  accentColor: '#8B5CF6',
  logoUrl: 'https://yoursite.com/logo.png',
  buttonText: 'Complete Purchase',
  fontFamily: 'Inter',
  hideFooter: true,
  customCSS: 'border-radius: 20px; box-shadow: 0 8px 32px rgba(0,0,0,0.2);',
  onSuccess: (data) => window.location.href = '/thanks'
});

Supported Chains & Tokens

BaseUSDC, USDT, EURC
EthereumUSDC, USDT, EURC
PolygonUSDC, USDT, EURC
ArbitrumUSDC, USDT, EURC
SolanaUSDC, USDT, EURC
View contract addresses

Base

USDC: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

USDT: 0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2

EURC: 0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42

Ethereum

USDC: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48

USDT: 0xdAC17F958D2ee523a2206206994597C13D831ec7

EURC: 0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c

Polygon

USDC: 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359

USDT: 0xc2132D05D31c914a87C6611C10748AEb04B58e8F

EURC: 0x390f28e7b2a5Ce76b67F0cD10EA0950A3a19F803

Arbitrum

USDC: 0xaf88d065e77c8cC2239327C5EDb3A432268e5831

USDT: 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9

EURC: 0x7Cb7cA2D5c848a1b3e6eCc8De1d8E4F79dAF96c8

Solana

USDC: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

USDT: Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB

EURC: HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr

3 Payment Methods (built-in)

Every checkout automatically shows 3 ways to pay. No config needed.

Connect WalletOne-click with MetaMask, Rainbow, Coinbase, Phantom. Best for desktop.
QR CodeScan with any mobile wallet app. Best for phones.
Copy AddressCopy wallet address + amount. Send from any wallet or exchange.

Supported Wallets

EVM ChainsMetaMask, Rainbow, Coinbase Wallet, Rabby
SolanaPhantom, Solflare, Backpack

Multiple wallets? Customer sees a picker. Single wallet connects automatically.

Invoices & Receipts

POST /api/invoices

Create and send an invoice. Requires Bearer token.

{
  "merchantId": "cmXXXX",
  "customerEmail": "client@email.com",
  "customerName": "Client Name",
  "subtotal": 500.00,
  "lineItems": [
    { "description": "Web Design", "quantity": 1, "unitPrice": 500.00 }
  ],
  "dueDate": "2026-04-15",
  "notes": "Thank you for your business"
}
GET /api/receipts?merchantId=X

List all receipts. Auto-generated when payments confirm.

Treasury

View your stablecoin balances across all chains in real-time.

GET /api/treasury/balances

Get USDC/USDT/EURC balances for all your wallets across every chain. Queries the blockchain in real-time.

Response:

{
  "wallets": [
    {
      "chain": "BASE_MAINNET",
      "address": "0x42f8...",
      "tokens": [
        { "token": "USDC", "balance": "8200.00", "balanceUSD": 8200 }
      ],
      "totalUSD": 8200
    }
  ],
  "totalUSD": 12340.00,
  "feesDue": 89.20,
  "netAvailable": 12250.80
}
GET /api/treasury/incoming?days=7

Recent confirmed payments. Defaults to 7 days, max 90.

Compliance & AML

Every payment is automatically screened against OFAC sanctions lists and known bad actors. Risk scores are assigned to every transaction.

How Screening Works

When a customer pays, we check their wallet address against:

  • OFAC sanctions list — U.S. Treasury sanctioned addresses (Tornado Cash, etc.)
  • Known mixers — Privacy protocols used for laundering
  • Known exploits — Addresses linked to hacks
  • Transaction patterns — Large amounts, burst detection, repeat senders

Risk Levels

LOW (0-30)Payment proceeds normally
MEDIUM (31-60)Payment proceeds, flagged for review
HIGH (61-80)Payment confirmed but flagged for merchant review
BLOCKED (81-100)Payment rejected, not confirmed
GET /api/compliance/status

Your compliance overview — KYC status, total screened, flagged count, blocked count.

POST /api/compliance/screen-wallet

Manually screen any wallet address.

{ "address": "0x...", "chain": "BASE_MAINNET" }

// Response:
{ "riskScore": 0, "riskLevel": "LOW", "flags": [] }
// or
{ "riskScore": 100, "riskLevel": "BLOCKED", "flags": ["OFAC_SANCTIONED"] }
GET /api/compliance/screenings

Screening history with risk scores, flags, and timestamps.

GET /api/compliance/export

Download CSV export of all screenings for compliance audits.

Managed Wallets

Don't have a crypto wallet? We create and manage one for you.

How It Works

During onboarding, if you don't have a wallet, our AI agent creates one instantly:

  • EVM wallet — works on Base, Ethereum, Polygon, Arbitrum (one address)
  • Solana wallet — separate keypair for Solana
  • Encrypted storage — private keys encrypted with AES-256

Important: StablePay holds the keys for managed wallets. You can withdraw anytime, but we strongly recommend setting up your own wallet (MetaMask, Phantom) for full control of your funds.

Custody Model

Own Wallet

You hold the keys. We never touch your funds. Payments go directly to you.

Managed Wallet

We hold the keys (AES-256 encrypted). You can withdraw anytime or migrate to your own wallet.

Auto-Migration

When you provide your own wallet address (via the agent or dashboard), we automatically:

  1. Set your new address as the payment destination
  2. Check the managed wallet balance
  3. Transfer all funds to your new address
  4. Mark the managed wallet as migrated

Zero manual steps. Just tell the agent your new address and funds move automatically.

Widget Smart Features

Balance Check

After connecting a wallet, the widget checks the customer's token balance on-chain. If insufficient, the pay button shows "Insufficient USDC (0.00 available)" and is disabled. Re-checks when chain or token changes.

EURC Conversion

When a customer selects EURC, the widget fetches the live EUR/USD rate from CoinGecko and converts the USD amount. Header shows €8.70 EURC ($10.00 USD). Transaction sends the converted EUR amount.

Chain Auto-Switching

Before every payment, the widget calls wallet_switchEthereumChain to ensure MetaMask is on the correct network. If switching from an EVM chain to Solana (or vice versa), the widget auto-disconnects the current wallet and prompts for the correct one.

Solana Payments

Full SPL token transfer support via Phantom, Solflare, or Backpack. Loads @solana/web3.js from CDN, constructs associated token accounts, signs via wallet provider, and confirms on-chain.

AI Agent

Built-in AI assistant that configures your account, writes integration code, and handles support.

What It Can Do

  • Create and configure wallets (EVM + Solana)
  • Set up webhooks and redirect URLs from your domain
  • Generate integration code for React, Shopify, WordPress, etc.
  • Screen wallet addresses for AML/sanctions risk
  • Check your treasury balances across chains
  • Explain fees, billing cycles, and pricing
  • Remember your business context across sessions
  • Withdraw from managed wallets
POST /api/agent/chat

Send a message to the AI agent. Requires Bearer token.

{ "message": "What's my balance on Base?" }

// Response:
{ "success": true, "response": "Your Base wallet has $8,200 USDC." }
GET /api/agent/history

Get chat history. Returns last 50 messages by default.

DELETE /api/agent/history

Clear chat history.

Pricing

Volume-based fees. No subscriptions. No setup costs.

Under $10k/month2.0%
$10k - $50k/month1.5%
$50k - $250k/month1.2%
$250k+/month1.0%

100% of payments go directly to your wallet. Fees are invoiced separately per billing cycle.

Customer Receipts

GET /receipt/:receiptId Public

Customer-facing receipt page. Shows amount, merchant, chain, tx explorer link, PDF download. Also accepts orderId (auto-resolves to receipt).

GET /api/receipts/:receiptId/pdf Public

Download receipt as PDF

Pricing

Volume-based fees for everyone:

$0 - $10k/month2.0%
$10k - $50k/month1.5%
$50k - $250k/month1.2%
$250k+/month1.0%

PRO features (refunds, receipts, custom branding, unlimited links) unlock at $5k/mo volume or $19/mo paid in crypto via StablePay.

Supported chains: Base, Ethereum, Polygon, Arbitrum, BNB Chain, Solana, TRON

Supported tokens: USDC, USDT, EURC