Requesting bitcoin involves creating and sharing a payment request with a sender. A payment request is a piece of information that tells a sender where and how much bitcoin to send someone. This page covers design considerations when requesting bitcoin with a daily spending wallet.
Payment request formats
Payment requests come in many different formats. Each has unique properties and use cases. To learn more about these formats, see the payment request formats page.
The wallet described in this reference design is for daily spending. That means creating payments should be simple and fast. As a result, this wallet lets the user send bitcoin directly from the home screen.
Avoid showing the user’s balance on the home or requesting page. When requesting payments in person, this could reveal the user’s balance to nearby on-lookers, negatively affecting the user’s privacy. More on this here.
From the requesting page, the user types in an amount. This wallet allows the user to easily toggle between entering amounts in sats, bitcoin, or their local currency. If the user has an amount entered and switches units, it clears the input field. This prevents the user from requesting an amount they didn’t intend. Read more on entering amounts on our Units & Symbols page.
Users can also skip entering an amount, as there are scenarios where the user may want the sender to decide the amount. Zero-amount requests also limit both parties exposure to price volatility as the bitcoin price in fiat terms could change between requesting and the payment being sent.
Unified requests remove the friction of users having to choose between requesting with lightning or on-chain, which can be confusing, especially for new users.
This wallet’s on-chain addresses are all swap addresses. These help with moving received bitcoin into the user’s lightning balance. This results in a single lightning balance and avoids a separate on-chain balance. This simplified experience is trust-minimized and non-custodial thanks to submarine swaps. We cover these more in our lightning services and receiving pages.
As unified requests aren’t widely supported yet, and users may want to request just from lightning or on-chain, they have options to share the lightning invoice or on-chain address independently.
Receiving payments to this wallet requires users to be online. This wallet notifies users that their wallet should remain open until the payment is received. We cover this more on our receiving and lighting services pages.
Metadata is additional information that is part of or can be added to a payment request. This can include an amount, note, or name for the sender. Or for the requester, labels, or assigning a contact.
Expiration times are something unique to lightning invoices. We cover modifying these here.
Ensure users can back up this metadata to prevent them from losing their transaction history.
Any fees the user may incur should be communicated alongside payment requests so users will know in advance if they will be charged before receiving a payment. What these fees are for will vary from app to app but they a generally for opening channels. Below are common fee scenarios this wallet will face:
A fee is charged if the user has no open channels and needs one opened on-demand when the payment is received.
A fee may be charged when requesting a zero-amount invoice if the received amount is higher than their inbound liquidity, also known as their receive limit.
A fee is charged if the user is requesting an amount higher than their receive limit.
No fee is charged if the user is requesting an amount lower than their receive limit.
Quick response codes (QR) encode a payment request into a scannable graphic. QR codes should be large enough and have high contrast with your application’s background so they can be easily scanned.
Uppercasing bech32 strings in the payment request data will result in less complex, more easily scannable QR codes. Automatically increasing screen brightness when displaying the QR code further improves scannability.
Payment links use a BIP21 URIbitcoin: which makes these readable by other bitcoin applications. These can be included as part of a button or hyperlink. Also see the wallet selector UI pattern.
Lightning invoices aren’t permanent; they expire over time. However, this expiration time can be modified, unlocking unique use cases and improving usability in some situations.
When denominating invoices in fiat, custom expiries should be used to prevent exposure to price volatility.
If requesting a specific amount denominated in fiat, use a shorter expiry and have the invoice refresh each time it expires. For a wallet designed for in-person payments, a 30 - 60 second expiry works well.
If there is no amount defined on the invoice, the invoice is denominated in bitcoin, or the invoice needs to be shared in a message, then use a longer expiry, like 24 hours.
While it is good to allow users to define their own custom expiries, remember that only advanced users will do this. Choose a sensible default that makes sense for your user-base and how the wallet is intended to be used.
For some background on situations the user might encounter with different invoice expiries, see this blog post from designer Stephen DeLorme.
Next, we go over the design considerations for receiving bitcoin bitcoin.