BTCPay Server is a free, open-source, self-hosted payment processor for Bitcoin (and other cryptocurrencies). No fees, no KYC, no middleman. Here's how to use it.
Why BTCPay Over Hosted Alternatives
- Zero fees: No percentage cuts on transactions
- No KYC: You control your own keys and payment processing
- Privacy: No third-party tracking of your business revenue
- Lightning Network: Instant settlements with minimal fees
- Self-hosted: Can't be shut down or have your account frozen
Setup Overview
BTCPay requires a VPS with Docker. Official recommended setup:
# On a Ubuntu 22.04 VPS with 2GB RAM minimum
git clone https://github.com/btcpayserver/btcpayserver-docker
cd btcpayserver-docker
export BTCPAY_HOST="pay.yourdomain.com"
export NBITCOIN_NETWORK="mainnet"
export BTCPAYGEN_CRYPTO1="btc"
export BTCPAYGEN_ADDITIONAL_FRAGMENTS=""
. ./btcpay-setup.sh -i
Flask Integration
import requests
BTCPAY_URL = 'https://pay.yourdomain.com'
BTCPAY_API_KEY = 'your_api_key'
STORE_ID = 'your_store_id'
def create_invoice(amount_usd, order_id, email):
resp = requests.post(
f'{BTCPAY_URL}/api/v1/stores/{STORE_ID}/invoices',
headers={'Authorization': f'token {BTCPAY_API_KEY}'},
json={
'amount': str(amount_usd),
'currency': 'USD',
'metadata': {'orderId': order_id, 'buyerEmail': email},
'checkout': {'expirationMinutes': 30}
}
)
return resp.json()
Webhook Handling
@app.route('/btcpay/webhook', methods=['POST'])
def btcpay_webhook():
event = request.json
if event.get('type') == 'InvoiceSettled':
invoice_id = event['invoiceId']
# Mark order as paid in your DB
fulfill_order(invoice_id)
return '', 200
Invoice States to Handle
- New → Waiting for payment
- Processing → Payment received, awaiting confirmation
- Settled → Confirmed, fulfill order
- Expired → Payment window passed
- Invalid → Underpaid or other issue
ZeroPhantom's tool suite uses BTCPay Server for all crypto payments.