| layout | guide | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| title | Sending bitcoin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description | Best practices and design guidelines for designing user experiences for sending bitcoin in daily spending wallet application. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| has_children | true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nav_order | 4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parent | Daily spending wallet | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permalink | /guide/daily-spending-wallet/sending/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| redirect_from |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| main_classes | -no-top-padding | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| image | /assets/images/guide/daily-spending-wallet/sending/bitcoin-payments-social.jpg | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| image_base | /assets/images/guide/daily-spending-wallet/sending/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| imagesEntryPoints |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| imagesEntryScreens |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| imagesInfo |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| imagesProcessing |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| imagesErrors |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| imagesReview |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| imagesLightning |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| imagesTestTransactions |
|
{% include picture.html image = "/assets/images/guide/daily-spending-wallet/sending/bitcoin-payments.jpg" retina = "/assets/images/guide/daily-spending-wallet/sending/bitcoin-payments@2x.jpg" mobile = "/assets/images/guide/daily-spending-wallet/sending/bitcoin-payments-mobile.jpg" mobileRetina = "/assets/images/guide/daily-spending-wallet/sending/bitcoin-payments-mobile@2x.jpg" alt-text = "Illustration of a man and woman exchanging a bitcoin" width = 1600 height = 600 layout = "full-width" %}
{:.no_toc}
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]({{ '/guide/daily-spending-wallet/contacts/' | relative_url }}), transfer it to another wallet on a different device, or make a purchase via a [payment processor]({{ '/guide/getting-started/software/#payment-processors' | relative_url }}).
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.
{% include image-gallery.html pages = page.imagesEntryPoints %}
Since users cannot control how a payment request is presented to them, wallets should be highly flexible in terms of input options and [interoperability]({{ '/guide/designing-products/interoperability/' | relative_url }}). If your wallet does not support a particular payment request, users should be presented with a human readable [error]({{ '/guide/daily-spending-wallet/sending/#errors' | relative_url }}).
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]({{ '/guide/how-it-works/payment-request-formats/' | relative_url }}) page.
Once the application has imported a payment request, it should provide clear instructions and options to the user.
{% include image-gallery.html pages = page.imagesEntryScreens %}
When responding to an invoice that contains all relevant information, the user can quickly review and approve it. In other scenarios, it may be required to manually enter or edit various details.
{% include image-gallery.html pages = page.imagesInfo %}
Recipient
The most convenient option for choosing a recipient is from a previously saved [contact]({{ '/guide/daily-spending-wallet/contacts/' | relative_url }}). 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]({{ '/guide/how-it-works/payment-request-formats/' | relative_url }}) that can receive payments repeatedly. These are less intuitive overall due to their appearance, but could also be considered payment endpoints.
Amount
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]({{ '/guide/designing-products/units-and-symbols/' | relative_url }}).
Metadata
A [transaction history]({{ '/guide/daily-spending-wallet/activity/' | relative_url }}) 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.
Fees are a sensitive topic for users and should always be presented transparently with appropriate information and options for users to choose what works for them. The network itself charges fees for payment processing, and a service provider might also charge fees for additional services they provide such as lightning liquidity. For more details, see the [send fees page]({{ '/guide/daily-spending-wallet/sending/send-fees/' | relative_url }}).
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]({{'/guide/onboarding/protecting-a-wallet/' | relative_url}}) 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.
{% include image-gallery.html pages = page.imagesReview %}
Users often experience anxiety when transacting with large amounts, or using new payment methods/information. This anxiety can be higher with bitcoin payments due to its novelty, irreversible nature and the possibility of permanent loss if funds are sent to an invalid address. One way users manage this is by sending a small payment first, and have the recipient confirm they received it.
Offering an automated test transactions feature can help users minimise the risk as well as manual effort. This feature can be useful in the case of on-chain as well as lightning payments, provided that the transacting parties can communicate with one another.
Technically, this feature can utilise replace-by-fee (RBF) or a simple small-value transaction.
There are three main interactions in this feature:
- application presents this option user on review screen: in the appropriate scenario, such as large amount or new silent payments address is being used.
- user chooses & sends the test transaction: they may ignore it if they have no way of communicating with the receiver. Inform users about relevant fees, if any.
- user finalises the original payment: allow the user to easily find and finalise the transaction. Applications can even remind the user about this after appropriate time.
{% include image-gallery.html pages = page.imagesTestTransactions %}
Processing times may also differ between on-chain and lightning network payments. On-chain, pending transactions are bundled into a [new block]({{ '/guide/getting-started/technology-primer/#what-is-a-blockchain' | relative_url }}) roughly every 10 minutes. On the lightning network, [payment routing]({{ '/guide/getting-started/technology-primer/#how-are-payments-routed' | relative_url }}) 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.
{% include image-gallery.html pages = page.imagesProcessing %}
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.
{% include picture.html image = "/assets/images/guide/daily-spending-wallet/sending/success.png" retina = "/assets/images/guide/daily-spending-wallet/sending/success@2x.png" modalImage = "/assets/images/guide/daily-spending-wallet/sending/success-big.png" alt-text = "Screen showing a completed transaction" caption = "A brief transaction summary with access to further details." width = 250 height = 541 layout = "float-right-desktop -background -shadow" %}
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]({{ '/guide/getting-started/software/#explorers' | relative_url }}) 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
{% include image-gallery.html pages = page.imagesErrors %}
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, an essential aspect for financial applications.
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.
{% include image-gallery.html pages = page.imagesLightning %}
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.
There are situations in which users may want to make more complex adjustments to the payment.
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.
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]({{ '/guide/how-it-works/coin-selection/' | relative_url }}).
Let's look a closer look at [send fees]({{ '/guide/daily-spending-wallet/sending/send-fees/' | relative_url }}).
{% include next-previous.html previousUrl = "/guide/daily-spending-wallet/requesting/receiving/" previousName = "Receiving bitcoin" nextUrl = "/guide/daily-spending-wallet/sending/send-fees" nextName = "Send fees" %}