About Me
Ash's Logo
Portfolio

Pay with Crypto

A compact utility for acceptance

Up until 2019, the BitPay Invoice only had to support Payment Protocol for Bitcoin and Bitcoin Cash. Payment protocol essentially is a way for BitPay to communicate directly with a user's wallet and lock in the amount, address, fee, and expiration time. This allowed instant, error-free payments; the catch here is that only a handful of the most popular crypto platforms actually support the protocol.

By the end of 2020, it became a company wide initiative to open the Invoice back up and accept peer-to-peer payment in addition to PayPro. With Wallet Selection opening the doors for custom payment flows, I immediately got to work leveraging and extending the Invoice's design system to address all the issues we faced over the last 2 years.

Key Takeaways

  1. 1
    Launching / Triggering Wallet is ideal
  2. Being able to directly launch an app or communicate with the wallet is ideal and a user may even change their behavior to achieve this. (MetaMask, Coinbase, BIP21, PayPro)

  3. 2
    Copying is highly used but error prone
  4. Copying fields is the primary way to pay in 3/6 situations and is the fallback in the other 3. This means that copying can be 1 layer deep when it is a secondary action but has to be immediately accessible otherwise. (Amount + Address, PayPro)

  5. 3
    Scanning is ideal but has narrow usage
  6. Similar to Open in Wallet, scanning is an accurate way to populate payment details but is only available in 1/6 situations with 2 degrees of precision. (Address, BIP21, PayPro)

From Exchanges

Universal interface for blockchain payments

When paying using an app that cannot read BIP21 URIs, really all you want is the Address + Amount so you can copy and verify the strings. The previous incarnation of the invoice was QR optimized as it assumed Exchange users would not be able to pay without first transferring to a wallet.

The simplest solution proved to be pulling the Copy Fields out of the Sheet and place them pinned to the bottom of the card. The BitPay Details bar is crucial element to completing the look of the Invoice and maintaining consistency across the other states.

Additionally, based on the wallet selected, we can auto-toggle the QR code. For example. Cash App would have the Address QR automatically toggled open because mobile scanning ensures an accurate transmission of the address. In the case of desktop-first service like Kraken or Gemini for example, the QR would start out collapsed.

V4 Reference Implementation

Invoice TimerInvoice expires in 15:00
View details
Total Price
135.00 USD
Exchange Rate
267.93 USD
Amount Due
0.286929 BCH
$135.00
QR
Amount Due
0.286929 BCH
Address
bitcoincash:...vhtva9z26awa

3 Flows for Exchanges

  1. 1
    On Desktop paying with Exchange on Desktop
  2. Primarily copying & pasting fields.

  3. 2
    On Desktop paying with Exchange on Mobile
  4. Primarily copying & pasting amount, then scanning address.

  5. 3
    On Mobile paying with Exchange on Mobile
  6. Primarily copying fields.

P2P No URI MobileP2P No URI Mobile Toast

From Wallets

Optimizing precision for P2P payments

The key advantage of using a non-custodial wallet is that these wallets often support URI decoding allowing us to pre-fill the amount and address. In this case, the way we do this is via "Open in Wallet" which manually triggers the respective BIP21 URI from the browser. The operating system then handles which application to actually launch. This is great if you 1 wallet installed on your device but quickly breaks down otherwise.

Based on selection, we can optimize for either Scan or Launch by collapsing the QR if we can assume the user will be paying with a wallet on the same device. However, because Launching a wallet is a nondeterministic action, we have to keep the Copy functionality on par with Launch hence the linear "Pay Bar" design.

V4 Reference Implementation

Invoice TimerInvoice expires in 15:00
View details
Total Price
135.00 USD
Exchange Rate
185.18 USD
Amount Due
0.729002 BCH
0.729002 BCH
QR
Open in Wallet
Copy Payment

And 3 Flows for Wallets

  1. 4
    On Desktop paying with Wallet on Desktop
  2. Ideally will try to launch wallet, falling back to copying fields or PayPro link.

  3. 5
    On Desktop paying with Wallet on Mobile
  4. Ideally will try to scan QR, falling back to copying fields or PayPro link.

  5. 6
    On Mobile paying with Wallet on Mobile
  6. Ideally will try to launch wallet, falling back to copying fields or PayPro Link.

P2P URI MobileP2P URI Mobile Toast

With Payment Protocol

Consistent experience for BIP72

The consistency of the upgrade / downgrade experience between PayPro and P2P was essential so the main form the Invoice takes is largely identical. We can trim off certain layer however; in this case because only 1 string can be copied, the Copy Sheet is removed entirely in favor of a simple toast that displays the full string.

On mobile, this transforms the experience into a compact interface that can be paid with a few taps. Additionally, we can also detect when a PayPro link is actually hit by the wallet; so in the case "Open in Wallet" does not work as expected, we can auto-trigger a Helper Toast to guide the user.

V4 Reference Implementation

Invoice TimerInvoice expires in 15:00
View details
Total Price
135.00 USD
Exchange Rate
11,382.15 USD
Network Cost
0.000172 BTC
Amount Due
0.011861 BTC
$135.00
QR
Open in Wallet
Copy Payment

2 Types of Scanning

  1. 1
    Plain String: Address or Tag Only
  2. Type 1 scanning must make clear to the user what exactly they are scanning in the case of 2 strings being scannable i.e Address & Destination Tag for XRP. Additionally, Type 1 scanning is typically optional so a toggle is required considering we should expect low usage of this capability. For example, the Gemini mobile app has the capability of scanning an address when withdrawing but on average, exchange mobile apps have a lower userbase than their desktop counterpart with notable exceptions like Cash App, Paxful, etc.

  3. 2
    URI: BIP21 / BIP72 / PayPro
  4. Type 2 scanning is more functional and does not necessarily have a specific field that corresponds to it. For example, a BIP21 URI has a specific encoding that we wouldn’t display, we would instead show the Address & Amount separately with their own copy buttons. This is not true however for a BIP72 URI where the contents of the QR code is the same as the copy field.

    BIP72 URIs are unique because wallets have to generally optimize for PayPro’s behavior of locking the amount and address. Copay does this by reading the user’s clipboard and allowing them to open the payment. Other wallets simply have a “Open URI” button, allow the user to paste the link into the Address field if it is before Amount, or only work with “Open in Wallet” or scanning. Thus, the user usually has to be aware to some degree of their wallet’s flow for PayPro versus the universal support for Address & Amount. This theory leads me to believe that the contents of a PayPro link are not very important to the user.

PayPro MobilePayPro Mobile Toast

Direct Connection

Pull payments with account pairing

Web3 Wallets (MetaMask)

Direct Connection payment experiences are essentially our custom integrations for specific wallets. In the case of Ethereum and ERC20 payments, the connection itself is generalized allowing the Invoice to connect to any Web3 wallet.

When I first created this design for ETH payments in 2019, I knew we needed the interface generalized enough to support any arbitrary feed of balances. The result is 0x-like UI for initiating "withdrawals". Definitely better than dealing with Addresses, Amount, and Miner Fees!

V4 Reference Implementation

Invoice TimerInvoice expires in 15:00
View details
Total Price
135.00 USD
Exchange Rate
441.78 USD
Amount Due
0.334764 ETH
$135.00
Connected Wallet
MetaMask
Ethereum
32.307812 ETH
USD Coin
1216.38 USDC
Gemini Dollars
112.35 GUSD
Paxos Standard
2391.42 PAX
Binance Dollar
174.38 BUSD
Dai
132.250711 DAI
Chainlink
67.081309 LINK
Polkadot
103.204117 DOT
Uniswap
304.001903 UNI
Compound
7.256102 COMP
Maker
3.020168 MKR
OmiseGo
112.506117 OMG
Basic Attention Token
1105.9201 BAT
0x
45789.026913 ZRX
Make Payment

OAuth Exchanges (Coinbase)

OAuth was BitPay's first major shift from purely dealing with blockchain payments. These payments work by directly connecting BitPay's Coinbase account with the user's and initiating an account-to-account transfer between the two at time of payment (off-chain).

The result is a feeless, instant payment that feels more like PayPal than crypto. You can read more about the Coinbase user experience I created here.

V4 Reference Implementation

Invoice TimerInvoice expires in 15:00
View details
Total Price
135.00 USD
Exchange Rate
13,386.54 USD
Amount Due
0.010229 BTC
$135.00
Connected Wallet
Coinbase
Bitcoin
5.789012 BTC
Bitcoin Cash
14.369019 BCH
Ethereum
32.307812 ETH
Ripple
784.701385 XRP
Litecoin
24.950163 LTC
Zcash
8.078102 ZEC
Stellar Lumens
3098.2210 XLM
Make Payment

Hardware Wallets (Ledger)

We can take the same concept from Web3 and apply it to custom integrations for hardware wallets. See compound.finance for an example of how this would work.

From BitPay Wallet

One-tap payments for our ecosystem

Finally, the last configuration of the Invoice is what I call "Universal Mode". The purpose of Universal Mode is to provide a fully optimized payment experience for BitPay App users that bypasses authentication, email, and currency selection. We can take it step further by automatically sending a push notification with the payment details to a user's paired device. On mobile, we can skip the Invoice directly and bounce the user to their wallet as soon as they select it.

This creates an extremely unique and seamless crypto payment experience that cannot easily be recreated with third-party wallets.

V4 Reference Implementation

Invoice TimerInvoice expires in 15:00
View details
Total Price
135.00 USD
$135.00
QR
Open in Wallet
Copy Payment
Universal Mode Mobile Toast