Bitcoin protocol for e-commerce

Vault0x
Vault0x
Published in
7 min readDec 5, 2017

The growing number of online merchants and suppliers has lead us to adopt alternate payment gateways, and the universal acceptance of the cryptocurrencies worldwide has led to the use of Blockchain as payment gateways by many merchants but there is still some reservations about the process, and it is not highly secure and adaptive for the community. The current process works on the core principle of wallets which are either manually or automatically handled by the user.

The current process for payments using Blockchain works as follows:

  1. Customer purchases some items from an online seller and decides to pay using Cryptocurrency.
  2. Merchant generates a unique payment address for his wallet and provides that address to the customer to pay.
  3. Customer copies the address from the merchant’s portal and pastes it into his wallet or follows the link to launch their wallet with the amount to be paid.
  4. Customer authorizes payment to the merchant’s address and broadcasts the transaction through the p2p network.
  5. Merchant’s server detects the payment by validating the transaction against sufficient transaction confirmations and considers the transaction as final.

BIP-0070 defines the communication protocol between merchants and their customer, enabling both the parties to have a better experience and security against attackers/hackers. This protocol can easily be applied to production systems and be used by masses.

We can extend the above flow to behave like a secure protocol by adding several new features:

  1. Implementation of Human-readable, safe payment destinations — Instead of using 34-character address, customers will be asked to authorize payment to “example.com.”
  2. Providing a secure proof of payment, which can be further utilized by the customer in case of a dispute with the merchant.
  3. Resistance from man-in-the-middle attacks which tends to replace the merchant’s address with attacker’s address.
  4. Payment received messages are also provided which confirms the customer that the merchant has received, and has processed (or is processing) their payment.
  5. Refund addresses are automatically generated and are provided to the merchant by the user’s wallet software; this enables merchants to refund payments without asking the customer for another address, in case of failure or overpayments.

This payment protocol utilizes the Google’s Protocol Buffers and is authenticated using X.509 certificates to be communicated over HTTP/https. We can further enhance the security of protocol by using PKI and encodings.

Source:https://raw.githubusercontent.com/bitcoin/bips/master/bip-0070/Protocol_Sequence.png

The payment protocol defined by the use of three messages: PaymentRequest, Payment, and PaymentACK.

Messages defined for Protocol

When the customer confirms that he/she is ready to pay a PaymentRequest is send to the merchant.

PaymentRequest

Payment requests are the initial message sent to the merchant, it is similar to what we do in an SSL handshake and sets the parameters to conduct the payment. The PaymentRequest message is further split into two messages. The bulk of the information for this protocol is contained in the PaymentDetails message. It is wrapped inside a PaymentRequest message, with the meta-information about the merchant and a digital signature. An example PaymentDetails message is as follows:

message PaymentDetails {
optional string network = 1 [default = "main"];
repeated Output outputs = 2;
required uint64 time = 3;
optional uint64 expires = 4;
optional string memo = 5;
optional string payment_url = 6;
optional bytes merchant_data = 7;
}

network: We either chose “main” for payments on the production, or “test” for payments on the test networks. If a network is not supported then the request is rejected.

outputs: These are the outputs where currencies are to be sent. The customer is prompted with input “how much to pay?”, Or the merchant’s amount is chosen then the bitcoin client choose any or all of the outputs for payment such that sum is equal to the payment to be paid. Output also holds the script for the address where payment is to be sent.

time: These are the Unix timestamp (seconds since 1-Jan-1970 UTC) when the request is created.

expires: These are the Unix timestamp (UTC) after which the payment request should be considered invalid.

memo: This describes the explanation of the PaymentRequest in UTF-8 encoded, plain-text (no formatting).

payment_url: This is the secure location where a Payment message may be sent to obtain a Payment acknowledgment.

merchant_data: This is the arbitrary data that will be used by the merchant to identify the PaymentRequest.

The payment_url specified above in the PaymentDetails should remain valid at least until the PaymentDetails expires. If the payment is canceled for an order than it should not invalidate the payment_url, as it is vital to record miss-payments in order to refund the amount.

A PaymentRequest is PaymentDetails which may be associated with a merchant’s identity:

message PaymentRequest {
optional uint32 payment_details_version = 1 [default = 1];
optional string pki_type = 2 [default = "none"];
optional bytes pki_data = 3;
required bytes serialized_payment_details = 4;
optional bytes signature = 5;
}

payment_details_version A version for the payment details is specified.

pki_type: public-key infrastructure (PKI) system being used to identify the merchant. BIP-0070 supports three options: “none”, “x509+sha256” and “x509+sha1”.

pki_data: PKI-system data is used to identify the merchant and can be used to create a digital signature.

serialized_payment_details: This defines a protocol-buffer serialized for PaymentDetails message.

signature: This is the digital signature over a hash of the protocol buffer which is serialized variation of the PaymentRequest message.

A Bitcoin wallet application performs the following tasks, when it receives a PaymentRequest:

  1. Wallet will validate the merchant’s identity and signature using the PKI system.
  2. Wallet will validate the customer’s UTC before PaymentDetails expires. If it is not present, then the payment request must be rejected.
  3. Wallet will display the merchant’s identity and check with the customer if they would like to submit payment or not.

PaymentRequest messages larger than 50,000 bytes will be rejected by the wallet application, this will protect the system against denial of service attacks.

Payment

Payment messages are ones which are sent to the customer and shows that the customer has authorized payment:

message Payment {
optional bytes merchant_data = 1;
repeated bytes transactions = 2;
repeated Output refund_to = 3;
optional string memo = 4;
}

merchant_data: This is copied from PaymentDetails. Merchants may use invoice numbers or similar data which can be used to match Payments to PaymentRequests. It is possible that malicious clients may modify the merchant_data, so it should be authenticated for example signed with a merchant-only key.

transactions: This is the valid transactions that entirely pay the PaymentRequest.

refund_to: This is the address where the merchant may return funds, if necessary. BIPS-0070 defines the return period up to 2 months after the time of the payment request. If longer than that then the parties must negotiate.

memo: This is the UTF-8 encoded, plain-text note send from the customer to the merchant.

If the customer authorizes payment, the following tasks are performed by the Bitcoin client:

  1. The client creates and signs the transactions that pay the full amount.
  2. Client validates the customer’s timestamp, and if it expires, then the payment should be canceled.
  3. Finally, the client broadcast the transactions on the p2p network.
  4. If the payment_url is specified, then it posts a Payment message to that URL.

Errors communicating with the payment_url server should always be sent to the user. If the case arises that the merchant’s server receives multiple Payment messages for an individual request, it must acknowledge each request individually. The messages sent by the merchant’s server should indicate the current state of the payment. This ensures that in case of a transport level failure, recovery is possible by re-sending the Payment message.

Some important points about Payments:

  1. Payment URL should be secured with TLS.
  2. Wallet should use appropriate Content-Type and Accept headers, as specified in BIP-0071, Content-Type: application/bitcoin-paymentAccept: application/bitcoin-paymentack.
  3. Merchant’s server should verify whether the transactions satisfy conditions of payment or not. If and only if they do meet then it should broadcast the transactions.
  4. All payment messages larger than 50,000 bytes should be rejected by the merchant’s server.

PaymentACK

PaymentACK is the final acknowledgement in the payment protocol; it is sent to confirm the payment.

message PaymentACK {
required Payment payment = 1;
optional string memo = 2;
}

payment: This is the copy of the message that triggered PaymentACK.

memo: This provides the status of the transaction.

In the PaymentACK messages also, the messages larger than 60,000 bytes should be rejected by the user’s wallet application, this will help to prevent denial-of-service attacks. This is more substantial Payment and PaymentRequest messages as this message contain a full Payment message.

This is only a base implementation of the protocol for Blockchain based payment systems. Further security can be enhanced using the PKI algorithms and also secure the transport layer. We can specify the versions of the protocols in the payment request which will create a similar channel like TLS. We can also enhance this to a language-specific payment gateway.

--

--