Payment Requests
Requesting and receiving Bitcoin payments in applications involves generating a address (or reusing a dedicated one per invoice), communicating amount and recipient to the payer (e.g. via a bitcoin: URI or QR code), and verifying that payment was received. This guide covers BIP 21 bitcoin: URIs, generating and parsing payment requests, and handling verification and refunds. For fiat conversion on invoices, see Price Tracking. For watching addresses, see Blockchain Monitoring.
Use a unique address per payment request so you can match incoming transactions to the correct order or customer. Do not reuse a single address for multiple invoices if you need to know who paid what.
BIP 21 defines the bitcoin: URI scheme so wallets can pre-fill address and amount.
Format:
bitcoin:<address>?amount=<amount_btc>&label=<label>&message=<message>
- address: Required; Bitcoin address (e.g. P2WPKH, P2TR).
- amount: Optional; decimal BTC (e.g.
0.001for 100,000 sats). - label: Optional; recipient or purpose (for payer's wallet only; not on-chain).
- message: Optional; description (for payer's wallet only; not on-chain).
All query parameters must be URI-encoded.
Encode the bitcoin: URI in a QR code so mobile wallets can scan it. Use a QR library for your language (e.g. qrcode in Rust, qrcode in Python, go-qrcode in Go). The payload is the URI string; error correction level is optional (e.g. medium for small codes, high for noisy environments).
- Unconfirmed: The transaction is in the mempool; it can be replaced (RBF) or double-spent. Do not treat as final for high-value or physical goods unless you accept the risk.
- Confirmations: Each block on top of the block that includes the tx adds one confirmation. Many applications wait for 1–6 confirmations before considering payment final. See Transaction Lifecycle.
- Watching: Use Blockchain Monitoring (e.g. address watch, ZMQ, or API) to detect when a payment to your invoice address is included in a block and reaches the desired confirmation depth.
- Never refund to "the address that sent" by default: that address may belong to an exchange or shared wallet, not the customer. Either ask the customer for a refund address or use a refund address they provided at payment time (e.g. in a payment protocol flow).
- If you used a plain
bitcoin:URI or copy-paste, contact the payer and ask for a refund address, then send a normal transaction to that address. - BIP 70 (payment protocol) is deprecated; prefer BIP 21 and your own backend for verification and refund handling.
- Address Generation - Generating unique addresses per invoice
- Blockchain Monitoring - Watching for incoming payments
- Price Tracking - Converting fiat to satoshis for invoice amount
- Transaction Lifecycle - Confirmations and finality
- Transaction Fees - RBF and accepting unconfirmed payments