BitPay is an example of a Bitcoin service where you take something fantastic and render it nearly unusable through aggressive insolence. They take the concept of bitcoin addresses wrapped in QR codes which everybody understands, and replace them with a different kind of code that wraps the bitcoin address with some additional data (order number, order total in fiat currency and the email address of the payer) into a so-called ‘invoice’ that the user is then supposed to pay. This different format is standardized under the so-called ‘Payment Protocol’ specified under BIP-0070.
The problem is that support for BIP-70 is next to non-existent, especially on desktops and particularly when using a hardware wallet such as Trezor or Ledger Nano S. The companion apps for these wallets recognize standard Bitcoin URIs that are given in the format known as BIP-0021:
However BitPay uses a URL that looks like this:
What makes it even more annoying is that when you initiate a payment, the BitPay website offers directions to pay with a hardware wallet, but these directions are incomplete. My post outlines the complete process you need to follow if you want to pay via Trezor or Ledger.
Step 1. Start Electrum and create a new wallet based on a hardware device
You can download the portable version of Electrum from the official website. As your keys are stored on your HW wallet and you’re using Electrum only for sending, the warning about portable versions is irrelevant. Your funds are safu 😉
Now here is where things get a little interesting. Electrum supports 3 types of wallets:
- P2KH — called ‘Legacy accounts’ insider Trezor Wallet: these are your good old 1-type Bitcoin addresses
- P2SH — called ‘Accounts’ inside Trezor Wallet: these are the 3-type Bitcoin addresses
- P2WPKH — these are not yet officially supported in Trezor Wallet or Ledger Live even though the firmware support is there. These are the ‘Native SegWit’ addresses known as bech32 that occupy even less space than P2SH SegWit addresses.
For the purpose of our guide, you should select either ‘Legacy’ or ‘P2SH-SegWit’, depending on whether your Trezor or Ledger is configured to use 1-type or 3-type addresses.
If you click on each of the radio buttons, you will notice that the derivation path below changes between m/44'/0'/0' , m/49'/0'/0' , and m/84'/0'/0'. If you use a single account within the Trezor Wallet app or Ledger Live, you are OK to leave it as is. But chances are you are an organized person like me and you have multiple wallets (‘accounts’ in Trezor parlance).
If you want to spend from a different account than the first one, you need to change the last digit of the derivation to select the account you want. First account is number 0, second account is number 1 and so on.
In my case, I wanted to pay using funds in my Account #5 and I use SegWit 3-type addresses, so I changed the derivation to m/49'/0'/4'. And I am now almost done:
Step 2. Send payment to BitPay
All of this is a preamble to the single, least logical part of the BitPay payment process, and the part that is missing from their instruction.
Here is what you get when you check out on a website that uses Bitpay:
Here, you need to click on ‘Copy payment URL’ and paste that URL inside the ‘Pay to’ field in Electrum:
This is what annoys me most about this whole thing: it requires a big leap of logic from the user to paste a payment URL that looks like this: bitcoin:?r=https://bitpay.com/i/Q5KzreX5GfFtZu4fp2Gm4n into a field that expects a plain old Bitcoin address.
After you do this, your adventures are nearly over. However your Electrum wallet has ‘Replace by Fee’ enabled by default. Check under Tools → Preferences:
If you leave Replace by Fee enabled and send the transaction, as soon as Bitpay sees it in the mempool, it will complain and will put the payment on hold with the merchant until the TX gets confirmed. In my opinion, disabling RBF is stupid, because it leaves you no way to unstick a transaction that has been posted with low fee for whatever reason. Yet the Bitpay engineers think differently and their website complains as if you’ve done something wrong. Anyway everything should be fine at the moment your transaction is mined into a block.
3. Multiple Reasons for Payment Failure
If you are lucky, you paid successfully for the stuff you wanted and you are now eagerly waiting to get it. However be warned that the payment may fail for different reason and that you may not know what these reasons are. Here is the message you will get when you paste a bitpay payment URL into Electrum after the 15 minute payment window has expired:
Not very clear, is it? Also, you will get the same error if you paste a payment URL with a mangled payment ID. Or, if you are behind TOR or an IP address that Cloudflare does not like. In that case, Cloudflare — who do DDoS protection for BitPay — will throw a blocking page with CAPTCHA which the Electrum wallet can’t handle.
The only recourse you have is to try later and, if possible, from another IP address (and with TOR disabled).
I don’t know about you, but I wasted about 3o minutes today figuring out how to pay for some stuff using BitPay. The process they have designed is annoying, misleading, and contriving. At every step of the process they are pushing you to create a wallet with blockchain.com. Please do not do that. If you can’t make the payment, just move on. BitPay deserve to die.
If you are a merchant, please do not use BitPay. On their website, they maintain a KB article called ‘Common Errors When Trying to Pay BitPay Invoices‘. Go ahead, read it. See how many different issues with how many different wallets are described there. Offer a workaround? Nope… Use the wallets they tell you or GTFO.
If you want a better alternative, check out BTCPay. It was born out of sheer frustration with BitPay.
Let me know about your experiences with BitPay in the comments below!