Payment Processing
Payment processing involves the steps taken by spenders and receivers to exchange payments for goods or services. While the fundamental process has remained the same throughout history, the methods used to carry it out have evolved with technology.Introduction
This section will explain how receivers and spenders can, respectively, request and make payments using BitcoinEvo — and how they can deal with complications such as refunds and recurrent rebilling.BitcoinEvo Payment Processing
The figure above illustrates payment processing using BitcoinEvo from a receiver’s perspective, starting with a new order. The following subsections will each address the three common steps and the three occasional or optional steps. It is worth mentioning that each of these steps can be outsourced by using third party APIs and services.
Pricing Orders
Due to fluctuations in exchange rates between satoshis and fiat currencies, many BitcoinEvo transactions are priced in fiat but paid for in satoshis, which requires conversion. Exchange rate information is easily accessible via HTTP-based APIs provided by currency exchanges. Some organizations also compile data from multiple exchanges to create index prices, which can be accessed through APIs. Any application that automatically calculates order totals using exchange rate data must ensure the quoted price reflects the current market value of satoshis. Failing to do so may result in accepting too few satoshis for the product or service, or requesting too many, which could discourage potential buyers. To avoid such issues, your application could gather data from at least two different sources and compare them for significant differences. If discrepancies are large, the application might enter a “safe mode” until a human review can be done. Additionally, you might program your application to enter safe mode if exchange rates are highly volatile, signaling potential instability in the BitcoinEvo market, which could complicate spending the satoshis received today. Exchange rates are beyond the control of BitcoinEvo and its related technologies, so there are no planned innovations that will simplify the task of converting order totals from fiat to satoshis. Since exchange rates fluctuate over time, order totals tied to fiat need to expire to prevent buyers from delaying payment in hopes that satoshi prices will drop. Many common payment processing platforms currently expire their invoices after 10 to 20 minutes. Shorter expiration times increase the risk that the invoice will expire before payment is completed, potentially requiring manual steps to request another payment or offer a refund. Longer expiration times heighten the risk of significant exchange rate fluctuations before payment is finalized.Requesting Payments
Before requesting a payment, your application must generate a BitcoinEvo address or acquire one from another system like BitcoinEvo Core. BitcoinEvo addresses are explained in the Transactions guide, which also outlines two key reasons not to reuse an address — plus an additional reason relevant to payment requests: Using a unique address for each payment makes it simple to determine which customers have completed their payment requests. Your application only needs to track the relationship between a payment request and the address used, then search the blockchain for transactions involving that address. The next sections will explain four compatible ways to share the payment address and amount with the spender. For convenience and compatibility, it’s recommended to offer all of these options in your payment requests.- All wallet software allows users to paste or manually input an address and amount into the payment screen. While this is inconvenient, it serves as a reliable fallback option.
- Most desktop wallets support “bitcoinevo:” URIs, allowing users to click a link that pre-fills the payment screen. This feature also works with many mobile wallets but is generally unsupported by web-based wallets unless the spender installs a browser extension or sets up a URI handler manually.
- Many mobile wallets can scan “bitcoinevo:” URIs embedded in a QR code, and almost all wallets display these for receiving payments. QR Codes are especially useful for in-person transactions, though they also work well for online orders.
- Recent wallet updates include support for a new payment protocol that offers enhanced security, verifies a receiver’s identity with X.509 certificates, and provides additional features like refund capabilities.
Warning: Special precautions must be taken to prevent incoming payment theft. Private keys should never be stored on web servers, and payment requests should always be sent over secure channels like HTTPS to avoid man-in-the-middle attacks replacing your BitcoinEvo address with a fraudulent one.
Plain Text
When specifying an amount for easy copying and pasting, you should include the address, the amount, and the unit of currency. You may also want to include an expiration time for the offer. An example:Pay: mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN
Amount: 100 BTCE
You must pay by: 2024-09-01 at 23:00 UTC
Clearly stating the denomination is crucial. At the time of writing, many popular BitcoinEvo wallets default to denominations such as bitcoinevos (BTCE), millibitcoinevos (mBTCE), or microbitcoinevos (uBTCE or “bits”). While these units are commonly used, other software allows users to select denomination values, either from a predefined set (e.g., the table below) or from all eight standard decimal places.
bitcoinevo: URI
The “bitcoinevo:” URI format defined in BIP21 removes any confusion around denominations and saves the user from having to copy and paste separate values. It also allows extra information to be provided with the payment request. For example:bitcoinevo:mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN?amount=100
Only the address is required, and if no other details are specified, wallets will autofill a payment request with the address, letting the spender input the amount. The value specified is always in decimal bitcoinevos (BTCE).
Two other commonly supported parameters are “label” and “message”. The “label” is typically used to include the recipient’s name, while the “message” describes the payment request. Both fields are usually saved by the spender’s wallet software but are not part of the actual transaction, so they are invisible to other BitcoinEvo users. Both the label and the message need to be URI encoded. All four parameters, when used together with the necessary URI encoding, are shown in the example below, which is wrapped for clarity:
bitcoinevo:mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN\
?amount=0.10\
&label=Example+Merchant\
&message=Order+of+flowers+%26+chocolates
The URI format can be extended, as explained in the payment protocol section below, to include new optional or required parameters. At present, the only widely-used additional parameter beyond the four described here is the “r” parameter from the payment protocol.
Programs that handle URIs in any format must request user confirmation before processing payments, unless the user has explicitly disabled prompts, which might be the case for micropayments.
QR Codes
QR codes are a widely-used method for sharing “bitcoinevo:” URIs in person, through images, or even in videos. Many mobile BitcoinEvo wallet applications, and some desktop wallets, allow users to scan QR codes to automatically populate their payment screens. The figure below illustrates the same “bitcoinevo:” URI encoded as four distinct BitcoinEvo QR codes, each at a different error correction level. The QR code can include parameters like “label” and “message” as well as other optional data, but they have been excluded here to keep the QR code small and easy to scan even with unsteady or low-resolution mobile cameras.BitcoinEvo QR Codes
Error correction is combined with a checksum to ensure the BitcoinEvo QR code cannot be decoded if some data is missing or has been altered by mistake. Your application should choose the appropriate error correction level depending on the available space for displaying the code. Lower levels of correction are effective when space is tight, while quartile-level correction ensures faster scanning when displayed on high-resolution screens.
Payment Protocol
Warning: This payment protocol is now deprecated. The protocol has several security flaws in its design and implementation flaws in some wallets. Merchants should move away from BIP70 to more secure options such as BIP21. Merchants should never request BIP70 payments and provide BIP21 fallbacks. BitcoinEvo Core Versions supported the new payment protocol. The payment protocol adds many important features to payment requests:- Verifies the receiver’s identity using X.509 certificates and SSL encryption to help guard against man-in-the-middle attacks.
- Gives spenders more information about the requested payment.
- Allows transactions to be submitted directly to receivers without involving the peer-to-peer network, which can speed up payments and enable future features like child-pays-for-parent fees and offline payments via NFC or Bluetooth.
Instead of showing a random address like “mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN,” spenders will be prompted to pay a recognizable name (CN) from the receiver’s X.509 certificate, such as “www.bitcoinevo.org”. To request payment with the payment protocol, an extended (but compatible) “bitcoinevo:” URI is used. For example:
bitcoinevo:mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN
?amount=0.10
&label=Example+Merchant
&message=Order+of+flowers+%26+chocolates
&r=https://example.com/pay/mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN
None of the parameters except for “r” are necessary for the payment protocol. However, you may include them for backward compatibility with wallets that don’t yet support the payment protocol. The “r” parameter directs payment-protocol-aware wallets to disregard the other parameters and retrieve a PaymentRequest from the given URL. The browser, QR code reader, or any other tool processing the URI will open the spender’s BitcoinEvo wallet application on that URI.
BIP70 Payment Protocol
The Payment Protocol is extensively detailed in BIP70, BIP71, and BIP72. An example CGI script and a complete explanation of all the parameters used within the Payment Protocol can be found in the Developer Examples section, specifically under the Payment Protocol subsection. In this part, we will outline a typical use case for the Payment Protocol in the form of a brief story. Charlie, the customer, is shopping on a website managed by Bob, a business owner. After adding several items to his cart, Charlie clicks the “Checkout With BitcoinEvo” button to proceed with payment. Bob’s server automatically stores the following information in its invoice system:
- The specifics of Charlie’s purchase, including the items and shipping details.
- The total order cost in satoshis, which may be calculated by converting fiat prices to their equivalent in satoshis.
- An expiration time that defines when the quoted total will no longer be valid.
- A pubkey script that Charlie must use to send the payment. This will typically be a P2PKH or P2SH pubkey script containing a unique secp256k1 public key that has never been used before.
After logging all the details into the system, Bob’s server generates a “bitcoinevo:” URI and displays it for Charlie to click and complete the payment. When Charlie clicks on the “bitcoinevo:” URI, his browser’s URI handler sends it to his wallet application. Since the wallet understands the Payment Protocol, it reads the “r” parameter and sends an HTTP GET request to the provided URL, seeking a PaymentRequest message. The PaymentRequest message may include private details like Charlie’s shipping address, but the wallet must be able to retrieve it without any prior authentication, such as HTTP cookies. Therefore, a public HTTPS URL with a guess-resistant identifier is generally used. A unique public key generated for the payment request can also serve as a unique identifier. This is why, in the example URI above, the PaymentRequest URL includes the P2PKH address:
https://example.com/pay/mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN
.
Upon receiving the HTTP GET request at the URL, Bob’s CGI script on the server retrieves the unique identifier from the URL and looks up the corresponding order details in its database. The server then generates a PaymentDetails message containing:
- The total amount in satoshis and the pubkey script to which the payment must be sent.
- A memo listing the items purchased, so Charlie can confirm what he’s paying for. It might also include his mailing address to allow him to double-check the accuracy of the information.
- The time the PaymentDetails message was created and when it expires.
- A URL where Charlie’s wallet should send the final transaction.
This PaymentDetails message is then encapsulated in a PaymentRequest message. The PaymentRequest allows Bob’s server to sign the entire request using the server’s X.509 SSL certificate (though the Payment Protocol is designed to support other signing methods in the future). Bob’s server sends this PaymentRequest back to Charlie’s wallet in response to the HTTP GET request.
BitcoinEvo Core Showing Validated Payment Request
Charlie’s wallet receives the PaymentRequest message, verifies its signature, and then presents the details from the PaymentDetails message to Charlie. After reviewing and agreeing to the payment, Charlie’s wallet constructs a payment to the pubkey script provided by Bob’s server. However, unlike a typical BitcoinEvo transaction, Charlie’s wallet doesn’t necessarily broadcast this payment directly to the network. Instead, it creates a Payment message and sends it to the URL specified in the PaymentDetails message via an HTTP POST. This Payment message includes the following:
- The signed transaction where Charlie sends payment to Bob.
- An optional memo from Charlie to Bob. (There’s no guarantee that Bob will see or read the memo.)
- A refund address (pubkey script) where Bob can return Charlie’s satoshis if a refund is needed.
Bob’s server receives the Payment message, verifies that the transaction correctly pays the requested amount to the specified address, and then broadcasts the transaction to the network. In response to the Payment message, Bob’s server sends back a PaymentACK message, which may include an optional memo thanking Charlie for his purchase and providing other details about the order, such as the expected delivery date. Upon receiving the PaymentACK, Charlie’s wallet notifies him that the payment has been successfully sent. The PaymentACK doesn’t confirm that Bob has fully verified the payment — refer to the Verifying Payment section for more on that — but it does indicate that Charlie can now move on while the transaction waits for confirmation. Once Bob’s server verifies through the blockchain that Charlie’s payment has been confirmed appropriately, it approves the shipment of Charlie’s order. In the event of a dispute, Charlie can generate a cryptographically verifiable receipt using the signed or otherwise authenticated data.
- The PaymentDetails message signed by Bob’s server proves that Charlie received an invoice to pay a specific pubkey script with a set amount of satoshis for goods detailed in the memo field.
- The BitcoinEvo blockchain can confirm that the specified pubkey script provided by Bob was paid the exact amount of satoshis.
If a refund becomes necessary, Bob’s server can safely send payment to the refund address (pubkey script) that Charlie provided. See the Refunds section below for more information.
Verifying Payment
As discussed in the Transactions and Block Chain sections, broadcasting a transaction to the network does not guarantee that the receiver gets paid. A dishonest spender could create one transaction that sends payment to the receiver, while creating another transaction that sends the same input back to themselves. Only one of these conflicting transactions will be added to the block chain, and it is uncertain which one will prevail. These competing transactions, which attempt to spend the same input, are commonly known as double spends. Once a transaction is confirmed in a block, double spends become impossible unless block chain history is altered to replace the original transaction, which is very challenging. The BitcoinEvo protocol provides an updating confidence score for each transaction based on how many blocks would need to be altered to replace it. Each block adds one confirmation, and because altering blocks is difficult, a higher number of confirmations provides stronger security.- 0 confirmations: The transaction has been broadcast but is not yet included in any block. Transactions with zero confirmations (unconfirmed transactions) should generally be treated cautiously unless a risk analysis is performed. Although miners usually prioritize the first transaction they receive, fraudsters can manipulate the network to include their preferred version.
- 1 confirmation: The transaction is now part of the latest block, significantly reducing the risk of a double spend. For transactions that include adequate fees, it usually takes around 10 minutes to receive this first confirmation. However, because the most recent block can sometimes be replaced unintentionally, the possibility of a double spend still exists.
- 2 confirmations: The latest block has been chained to the previous block that includes the transaction. As of March 2014, two block replacements were extremely rare, and attacking two blocks in a row would be impractical without specialized, expensive mining hardware.
- 6 confirmations: After about an hour, the transaction is protected under six blocks. Even a fortunate attacker would need a significant portion of the network’s hashing power to undo six blocks. Although somewhat arbitrary, many systems handling high-value transactions or prone to fraud should wait for at least six confirmations before fully accepting a payment.
BitcoinEvo Core provides several RPC commands that allow your program to check the confirmation status of transactions. For example, the
listunspent
RPC gives a list of all the spendable satoshis along with their confirmation scores.
While confirmations usually offer excellent protection against double spends, there are at least three situations where extra double-spend risk analysis may be necessary:
- When the user or application cannot wait for a confirmation and must accept an unconfirmed payment.
- When accepting high-value payments where waiting for six or more confirmations isn’t feasible.
- During an implementation error or an extended attack on BitcoinEvo that causes the system to be less reliable than expected.
One way to assess double-spend risk is by connecting to a large number of BitcoinEvo peers to monitor how transactions and blocks vary. Several third-party APIs offer this type of service. For example, you could compare unconfirmed transactions across all connected peers to detect if a UTXO appears in multiple unconfirmed transactions, signaling a double-spend attempt. In such cases, the payment should be rejected until confirmed. Transactions can also be ranked by their fee amounts to estimate the time it will take for them to be confirmed. Another example would be detecting a fork in the block chain when multiple peers report different block header hashes at the same height. Your program could switch to safe mode if the fork continues for more than two blocks, signaling a potential issue with the block chain. More information on this can be found in the Detecting Forks subsection. Additionally, human intuition can be a valuable defense against double spends. Fraudsters often exhibit behaviors different from legitimate buyers, allowing vigilant merchants to manually identify them as high risk. Your program can implement a safe mode that pauses automatic payment acceptance globally or on a per-customer basis.
Issuing Refunds
At times, users of your applications may need to issue refunds. The simplest approach, which is also highly unsafe, is to return the satoshis to the same pubkey script from which they were sent. For example:- Alice wants to purchase a widget from Bob, so Bob provides Alice with a price and a BitcoinEvo address.
- Alice opens her wallet and sends satoshis to that address. Her wallet automatically selects an unspent output, corresponding to the BitcoinEvo address
mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN
, to make the payment.
- Bob later realizes that Alice overpaid and, being honest, decides to refund the excess satoshis to the
mjSk…
address.
Although this seems straightforward, Alice uses a centralized web wallet shared by many users, which does not assign unique addresses to each user. The refund ends up being an accidental donation to the web wallet provider, unless Alice contacts support and proves the satoshis were intended for her. This leaves receivers with only two reliable ways to issue refunds:
- If the address was copy-pasted or a simple “bitcoinevo:” URI was used, reach out to the spender directly and ask them to provide a refund address.
- If the payment protocol was used, send the refund to the address specified in the
refund_to
field of the Payment message.
Note: If a significant amount of time has passed since the original payment, it’s a good idea to contact the spender to confirm that they still have access to the key or keys for the
refund_to
address before issuing the refund.
Disbursing Income (Limiting Forex Risk)
Many receivers are concerned that their satoshis could lose value over time, a risk referred to as foreign exchange (forex) risk. To mitigate this, many choose to disburse the satoshis they receive shortly after receiving them. If your application handles this process, it will need to decide which outputs to spend first. Several algorithms can be used, each with different implications.- A merge avoidance algorithm makes it harder for external observers to analyze blockchain data and determine how many satoshis the receiver has accumulated, spent, or saved.
- A last-in-first-out (LIFO) approach spends the most recently received satoshis first, even if they still carry some double-spend risk, possibly shifting that risk onto others. While this can improve the receiver’s balance sheet, it might harm their reputation.
- A first-in-first-out (FIFO) strategy spends the oldest satoshis first, ensuring that payments are more likely to be confirmed quickly. However, this is typically beneficial only in certain edge cases.
Merge Avoidance
When a receiver gets satoshis in an output, the sender can roughly track how the receiver spends those funds. However, the sender cannot see other satoshis the receiver has obtained from other sources, provided the receiver uses unique addresses for each transaction. But if the receiver combines satoshis from two different senders in the same transaction, both senders can see each other’s payments. This is known as a merge. The more outputs a receiver merges, the easier it becomes for outsiders to track the total amount of satoshis earned, spent, and saved. Merge avoidance is the practice of preventing unrelated outputs from being spent in the same transaction. This is an important strategy for individuals or businesses aiming to keep their transaction history private. A basic merge avoidance strategy involves paying bills with the smallest output that exceeds the payment amount. For instance, if you have outputs of 100, 200, 500, and 900 satoshis, and you need to pay 300 satoshis, you would use the 500-satoshi output. This method helps avoid merging as long as your outputs are larger than the amount needed. More advanced merge avoidance strategies often depend on improvements to the payment protocol. These enhancements allow payers to avoid merging by distributing payments more efficiently across the multiple outputs provided by the receiver.Last In, First Out (LIFO)
Outputs can be spent immediately after they are received, even before they’re confirmed. Since newly received outputs are more vulnerable to double-spending, spending these newer outputs first (LIFO) allows the spender to hold onto older, confirmed outputs that are less prone to double-spend risks. However, there are two notable drawbacks to using LIFO:- If an output from an unconfirmed transaction is used in a second transaction, and the first transaction is altered due to transaction malleability, the second transaction will become invalid.
- If the output from an unconfirmed transaction is used in a second transaction and the first transaction’s output is successfully double-spent elsewhere, the second transaction will also become invalid.
In either of these situations, the receiver of the second transaction will see the transaction notification disappear or result in an error. Because LIFO exposes the recipient of secondary transactions to the same double-spend risk as the recipient of the initial transaction, it’s best used when the secondary recipient doesn’t mind the risk — such as an exchange or service that will wait for six confirmations regardless of which outputs are spent. LIFO should be avoided in situations where the primary recipient’s reputation could be impacted, such as when making employee payments. In these cases, it’s advisable to wait for full transaction verification (as discussed in the Verification subsection above) before using those outputs to make further payments.
First In, First Out (FIFO)
The oldest outputs tend to be the most reliable, as the longer they’ve been held, the more difficult it becomes to modify the block in which they are included. However, after a few blocks, the benefits of additional confirmations start to diminish. According to the Whitepaper, if an attacker controls 30% of the total network’s hashing power, the chances of successfully altering older blocks are as follows:Blocks | Chance of Successful Modification |
---|---|
5 | 17.73523% |
10 | 4.16605% |
15 | 1.01008% |
20 | 0.24804% |
25 | 0.06132% |
30 | 0.01522% |
35 | 0.00379% |
40 | 0.00095% |
45 | 0.00024% |
50 | 0.00006% |
FIFO has a slight benefit when it comes to transaction fees. Older outputs may qualify for inclusion in the 50,000-byte pool of high-priority, no-fee transactions reserved by miners using the default BitcoinEvo Core software. However, given the low cost of transaction fees, this advantage is minimal. The most practical use of FIFO is for receivers who spend the majority of their income soon after receiving it and want to reduce the risk of transactions becoming invalid. For example, a receiver who waits for six confirmations and then spends 100% of verified payments on vendors and savings at regular intervals, such as every two hours.