Sending bitcoin is one of the most essential user activities in a bitcoin application, and also one of the least structured ones. People may want to send bitcoin to a known contact, transfer it to another wallet on a different device, or make a purchase via a payment processor.
Payment entry points #
The need to send bitcoin can be triggered by many different use cases, and initiated by both sender and receiver. Common entry points are:
- Manual entry of address and amount
- Sending to a previously saved contact
- Copy & pasting payment information
- Clicking a payment link
- Scanning a QR code
- Receiving a contactless payment request (using NFC or Bluetooth)
Below are visualizations of some of these entry points.
Since users cannot control how a payment request is presented to them, wallets should be highly flexible in terms of input options and interoperability. If your wallet does not support a particular payment request, users should be presented with a human readable error.
Payment information can be shared in many formats and over diverse communication channels. Each has its own advantages and limitations. More details on the payment request formats page.
Presenting payment requests #
Once the application has imported a payment request, it should provide clear instructions and options to the user.
Manual payment initiation #
When responding to an invoice that contains all relevent information, the user can quickly review and approve it. In other scenarios, it may be required to manually enter or edit various details.
The most convenient option for choosing a recipient is from a previously saved contact. Alternatively, users can enter Lightning addresses, Lightning node IDs, on-chain addresses, or other addresses that are supported by the wallet.
There are also static payment requests that can receive payments repeatedly. These are less intuitive overall due to their appearance, but could also be considered payment endpoints.
If no amount is provided via a payment request, manual entry should be simple and convenient so users don’t accidentally send an incorrect amount. The amount should be displayed in bitcoin or satoshi value, as well as the user’s local currency. Options to quickly toggle between them should be available. More on the Units & Symbols page.
A transaction history is hard to make sense of when it only shows amounts, dates, and identifiers. Users should be allowed to add descriptions, tags, and other metadata to add context. This context can separately be used for helpful tools like visual spending breakdowns.
Payment fees can drastically differ based on a few attributes:
Lightning routing fees
On the Lightning network, payments are passed between nodes to get from the sender to the receiver. Each of those nodes may charge a base fee and a second fee based on a percentage of the amount forwarded. Fees paid can vary, but are typically in the single-digit or double-digit Satoshi range (a small fraction of on-chain fees).
Lightning service fees
Lightning wallets may require additional services to solve certain usability issues. An example being a lightning service provider (LSP) opening payment channels and providing inbound liquidity for the user, so they can receive payments. As these services are offered by third parties, additional fees may be charged.
On-chain fees #
Unfortunately, it is common for users to overpay on-chain fees by mistake. Wallets should have mechanisms in place to avoid this happening.
If a user’s transaction amount is low compared to the fee they would pay to broadcast, warn them. There are no standards regarding the threshold percentage to trigger such an alert. A good benchmark is to warn the user if their fee is 50% or more than the value of the transaction itself. You might choose a different threshold for your app. Procedures like this should be enough to ensure users do not overpay on-chain fees unintentionally.
Review & approval #
Always give the user an opportunity to review and confirm the details of their payment before sending.
When a payment is initiated via an invoice or payment link and doesn’t require any additional input by the user, the whole user interaction is one of review and confirmation.
This can be a good place for an additional security step, depending on the security paradigm of your app. For example, a wallet might provide the security step if the payment amount hits a threshold or if the wallet has a spending limit defined. Some wallets forego a security step when opening the app, but require it when spending. For more information on the nuances of building your security model, see the Protecting a wallet page.
If using a security step here, it should come after the user has selected all other options regarding the payment. This final security step represents the user’s final consent to the payment they are making.
Transaction processing #
Processing times may also differ between on-chain and Lightning network payments. On-chain, pending transactions are bundled into a new block roughly every 10 minutes. On the Lightning network, payment routing happens instantly and is largely dependent on the number of nodes involved, as well as their liquidity and processing speeds.
When transactions take longer than expected, users need to be clearly informed about the status. In scenarios like in-store payments, speedy confirmation is of the essence, as the user wants to move on, and the merchant may have other customers waiting. In-app status updates can be coupled with notifications to ensure that both parties are confident that everything is in order. For a framework on timing, see this article on response time limits.
In case a user needs to briefly wait, the application should not block the interface, but offer other useful actions to perform, such as labelling and tagging the payment, or adding the recipient to the contact list.
On-chain, you may offer users the options to cancel (via replace-by-fee (RBF)) or speed-up (via child-pays-for-parent (CPFP)) a transaction that is taking too long to confirm. This is only possible after the transaction has been broadcast, but before it has been included in a block.
Completion of a payment should be clearly indicated to the user.
It should also be simple to share a proof that the payment was made. In-person, it may suffice to show the screen to the receiver. Additional options like sharing the confirmation via chat or email may also be useful.
As on-chain transactions can be globally verified by anyone, a link to a bitcoin explorer can be shared as a payment confirmation. For Lightning transactions, the so-called
preimage can be considered a proof of payment.
Handling problems gracefully is particularly important when it comes to payments, as users may be concerned about having lost funds. Clear communication may include:
- A brief explanation of what went wrong
- Status of the funds and payment to address user worries
- How the problem can be fixed or avoided
- What to do next
It is ideal when the application can automatically identify and fix or avoid the problem. This may not always be possible, or even wanted, if the solution incurs extra fees or takes time. For practical purposes, it can be helpful to group problems into categories, such as:
- The problem cannot be identified
- The problem can be identified and requires manual action by the user
- The problem can be automatically fixed, but the user needs to choose which solution to use
- The app can likely automatically fix the problem with negligible impact on the user
Effectively supporting users when problems occur can build trust and confidence, and essential aspect for financial applications.
Encouraging lightning network #
Lightning is likely to be the best option for the majority of payments a user makes. It will be faster, more private, and cost less. An ideal scenario would be where the user does not spend time considering whether to pay on-chain or Lightning — it’s all bitcoin to them.
However, this can be challenging with the variety of different payment formats between on-chain and Lightning. What happens when the user is trying to pay somebody, but the receiving party has given them an on-chain address instead of a Lightning invoice?
If your wallet is Lightning-only, the user will be unable to proceed with making payment. However, even if your wallet allows the user to send on-chain payments, this payment could still result in a higher transaction fee than they would have incurred over Lightning. If it’s in the user’s best interest to pay over Lightning, then let them know and help them determine what to do next.
In this example, the user scans a QR to make a payment. This wallet recognizes it as an on-chain address. It is capable of making the on-chain payment with submarine swaps. However, that would involve a longer confirmation time and a higher fee for such a small payment. It immediately pulls up a modal notification to warn the user that they will have to wait longer for the payment to settle and pay a higher fee. It informs them they can pay instantly if they can get a different type of QR code from the sender.
If the user has already had this problem, they will know to ask the recipient for a different type of QR code. If not, they can use the “help me” screen to get more information.
Advanced options #
There are situations in which users may want to make more complex adjustments to the payment.
Lightning routing options #
Routing is a probabilistic endeavor. For example, a routing algorithm may identify two routes. The first one has a low fee but is also less likely to succeed. The second route has a higher fee, but is more likely to succeed. Due to the technical complexity and unknowns, there is ongoing conversation whether routing options are relevant for users to be aware of and make decisions on.
Coin selection #
On-chain wallets may offer experienced users the option to choose which of their on-chain bitcoin (UTXOs to be precise) to send, in order to protect their privacy. More on this topic on the Coin selection page.
Now that we’ve tackled sending and receiving, let’s look at how we can summarize this activity and make it useful.