*Last updated: July 2026*
Accepting Bitcoin payments in your Python application is straightforward with the right tools. This guide shows you how to integrate BTC payments that work globally, with no middlemen.
The simplest approach - accept BTC directly to your wallet:
import requests
import time
def get_btc_balance(address):
"""Check BTC balance using Blockstream API."""
url = f"https://blockstream.info/api/address/{address}"
resp = requests.get(url, timeout=10)
data = resp.json()
# Calculate balance from UTXOs
balance = 0
for tx in data.get("chain_stats", []):
balance += tx.get("funded_txo_sum", 0)
balance -= tx.get("spent_txo_sum", 0)
return balance / 100_000_000 # Convert from satoshis
def create_invoice(amount_btc, product_id):
"""Create a payment invoice."""
return {
"invoice_id": f"inv_{int(time.time())}",
"amount": amount_btc,
"product": product_id,
"status": "pending",
"created_at": time.time()
}
def check_payment(invoice_id, address):
"""Check if invoice has been paid."""
balance = get_btc_balance(address)
return balance > 0
BTCPay Server is free, open-source, and self-hosted:
import requests
BTCPAY_URL = "https://your-btcpay-server.com"
BTCPAY_TOKEN = "your_api_token"
def create_btcpay_invoice(amount_sats, product_id):
"""Create invoice via BTCPay Server."""
resp = requests.post(
f"{BTCPAY_URL}/api/v1/invoices",
headers={"Authorization": f"token {BTCPAY_TOKEN}"},
json={
"amount": amount_sats,
"currency": "BTC",
"metadata": {"product_id": product_id}
}
)
return resp.json()
def check_btcpay_status(invoice_id):
"""Check invoice status."""
resp = requests.get(
f"{BTCPAY_URL}/api/v1/invoices/{invoice_id}",
headers={"Authorization": f"token {BTCPAY_TOKEN}"}
)
return resp.json()["status"] == "complete"
Services like BitPay or CoinGate handle everything:
# Example with a generic processor
def create_processor_invoice(amount_usd, product_id):
"""Create invoice via payment processor."""
resp = requests.post(
"https://api.processor.com/invoices",
headers={"Authorization": "Bearer your_key"},
json={
"price_amount": amount_usd,
"price_currency": "USD",
"receive_currency": "BTC",
"order_id": product_id
}
)
return resp.json()
import hashlib
class BitcoinPaymentHandler:
def __init__(self, btc_address):
self.btc_address = btc_address
self.payments = {}
def create_payment(self, user_id, amount_btc, product_id):
"""Create a new payment request."""
payment_id = hashlib.sha256(
f"{user_id}-{product_id}-{int(time.time())}".encode()
).hexdigest()[:16]
self.payments[payment_id] = {
"user_id": user_id,
"amount": amount_btc,
"product": product_id,
"address": self.btc_address,
"status": "pending",
"created_at": time.time()
}
return payment_id
def check_payment(self, payment_id):
"""Check if payment was received."""
payment = self.payments.get(payment_id)
if not payment:
return False
# Check blockchain
balance = get_btc_balance(payment["address"])
if balance >= payment["amount"]:
payment["status"] = "paid"
return True
return False
def get_payment_status(self, payment_id):
"""Get current payment status."""
payment = self.payments.get(payment_id)
if not payment:
return "not_found"
# Auto-expire after 24 hours
if time.time() - payment["created_at"] > 86400:
payment["status"] = "expired"
return payment["status"]
1. Never reuse addresses: Generate a new address for each payment
2. Wait for confirmations: At least 1 confirmation for small amounts, 3+ for large
3. Validate amounts: Check the exact amount sent, not just "any" payment
4. Log everything: Keep detailed records for accounting
5. Use HTTPS: Never transmit payment info over HTTP
We have a complete Bitcoin payment integration at [our store](https://petroleum-board-hawaii-lol.trycloudflare.com).
What's included:
[Browse the collection โ](https://petroleum-board-hawaii-lol.trycloudflare.com)
Browse 120+ Python tools with crypto payments and instant delivery.
Browse Products โ