How it works

FunkPay involves three independent actors. Each controls their own keys and infrastructure — no shared custody, no central service.

🏪
Merchant side
Merchant

The merchant sells goods or services and wants to accept Bitcoin payments — on-chain, self-custodial, no payment processor.

What the merchant runs

  • btcfunkpay — a Python/FastAPI server self-hosted on their own infrastructure
  • Their own Bitcoin node (or trusted node) to monitor the mempool and confirmed blocks
  • A product catalog with SKUs and fiat prices (USD, EUR…) — converted to satoshis at the live rate when an invoice is created
  • Webhook endpoints on their backend to fulfill orders on payment confirmation

Keys & security

  • The merchant provides an xpub (extended public key) from their cold wallet — btcfunkpay derives a fresh address for every invoice without ever holding a private key
  • Private keys stay in cold storage, completely offline and out of reach of the server
  • Even if the server is compromised, funds cannot be moved — only incoming addresses are known
  • Payment data and order logic never leave the merchant's own server
🔑 xpub only — no private key on server 🛡 Self-hosted infrastructure ⛓ Own node — no third party
👤
Payer side — human
Customer

The customer visits the merchant's website, sees a Bitcoin checkout widget, and pays with their own wallet.

What the customer does

  • Opens the merchant's website — the funkpay.js widget loads inline, shows price in fiat and satoshis
  • Scans the QR code with any Bitcoin wallet (mobile, hardware, desktop)
  • Or copies the BIP-21 payment URI and pastes into their wallet
  • The widget monitors the address and shows confirmation in real time — no page reload needed

Keys & privacy

  • The customer pays with their own wallet — FunkPay never has access to their keys or seed phrase
  • No account, no sign-up, no KYC — just a Bitcoin address and a payment
  • The funkpay.js widget runs entirely in the browser; it only knows the payment address and the amount
  • FunkPay has no visibility into the customer's wallet balance or transaction history
🔑 Customer keeps their own keys 🚫 No account — no KYC 🌐 Any Bitcoin wallet
🤖
Payer side — AI agent
AI Agent — FunkPayAI user

The agent is a developer or power user who wants their AI (Claude, Cursor, or any MCP client) to make Bitcoin payments autonomously on their behalf.

What the agent user runs

  • FunkPayAI — an Electron desktop app installed on their own PC (Mac, Windows, Linux)
  • A local Bitcoin Core node (pruned, ~10 GB) — downloaded and managed automatically by the app
  • An MCP stdio proxy (~/.funkpay/mcp-stdio.mjs) that exposes 11 tools to the AI client
  • An approval policy: always ask, never ask, or ask only above a sat threshold

Keys & security

  • Private keys are generated locally inside FunkPayAI and never leave the machine — not even to FunkPay servers
  • Transactions are signed and broadcast via the local Bitcoin Core node — no third-party node, no API key
  • The agent operates within the limits set by the user — the approval policy is the last line of defence before any payment
  • The payer's wallet is fully private — balance, private keys, and unrelated transaction history never leave the user's machine. The merchant only sees the payment address and amount for invoices they created, nothing more.
🔑 Local keys — never transmitted ⛓ Local node — fully sovereign ⚙ Approval policy — user controls autonomy

From invoice to fulfillment

The same four steps apply whether the payer is a human using the widget or an AI agent using MCP tools.

1

Invoice created

btcfunkpay derives a fresh Bitcoin address from the merchant's xpub and returns a BIP-21 payment URI with amount and label.

2

Payment sent

The customer scans the QR, or the AI agent calls send_payment. The transaction is broadcast to the Bitcoin network.

3

On-chain detection

btcfunkpay detects the transaction in the mempool and fires a webhook. Another webhook fires on each confirmation milestone.

4

Order fulfilled

The merchant's backend receives the webhook and completes the order — ship goods, unlock content, provision a service.

System diagram

Two parallel paths converge at the Bitcoin network and the merchant server.

── AI agent path ───────────────────────────────────────── Claude Code / MCP client │ MCP stdio ▼ ~/.funkpay/mcp-stdio.mjs stdio proxy — 11 tools │ HTTP localhost:3282 ▼ FunkPayAI (Electron, user's PC) wallet API · approval policy · ledger │ JSON-RPC ▼ Bitcoin Core (local, pruned) private keys stay on device │ │ broadcast ▼ Bitcoin network │ on-chain tx ▼ btcfunkpay (merchant's server) xpub → derives addresses · monitors mempool │ webhook POST ▼ Merchant backend → fulfill order ── Customer / widget path ──────────────────────────────── Customer browser ← funkpay.js widget QR · BIP-21 · fiat price │ scan / paste ▼ Customer's wallet (any Bitcoin wallet) │ broadcast ▼ Bitcoin network → btcfunkpay → webhook → fulfill order