Bitcoin is a rapidly rising digital currency that is quickly becoming a popular method to purchase goods and services on the Internet that requires no credit card, no bank account, and no personal information to be transmitted. Payments can be sent and received to a merchant from anywhere in the world in seconds, and there is no middleman sitting between the customer and the merchant.
SilverStripe is ideally suited for an application like this - the framework contains many useful libraries (such as RestfulService) that speak directly to the Bitcoin network or a payment gateway that forwards Bitcoin transactions for a miniscule fee, and has several modules that enable a business to set up and deploy an e-commerce website very quickly with minimal effort. What would it take to accept Bitcoin in a point-of-sale environment using SilverStripe? I’ve created a basic point-of-sale system named "Bitrito" to sell hypothetical homemade burritos using Bitcoin to demonstrate this possibility.
What is Bitcoin?
Bitcoin is a decentralised open-source payment system and digital currency that was created in early 2009 by the anonymous developer Satoshi Nakamoto. It was conceived as electronic cash, cryptographically protected from forgery and counterfeiting while not being controlled by any central government or authority. Transactions are executed with public-key cryptography, and participants in a peer-to-peer network verify these transactions. Bitcoin has attracted quite a lot of interest over the last year or so, skyrocketing in value from around $20 NZD to nearly $1500 before settling down to over $700 as of this writing. Market fluctuations aside, Bitcoin has many niche uses over the modern banking system, such as virtually non-existent transfer fees and being transmittable to anybody on the Internet nearly instantaneously. Travelers don’t need to convert it when crossing a border, it’s entirely programmable, and the network is easily accessible via an API.
How does it work?
Bitcoin uses public-key cryptography to send and receive payments, and all transactions are recorded publicly (but anonymously) on a networked data structure known as a blockchain to prevent double spending. These two keys, a public key and a private one, can respectively be thought of as an account number and proof of ownership. The merchant presents their public key to the customer (usually as a QR code) and the customer uses their own private key to encode a message and transmit funds to the merchant’s public key, which is broadcast to the entire network. Because of the nature of public key cryptography, the private key used to encrypt this message is not the same public key used to decrypt it. Miners on the bitcoin network use the customer’s public key to independently verify that the customer used their private key to encode the message; each miner that does this is said to confirm the transaction. A merchant can use the number of confirmations by the network to gain confidence that the customer authorised the transaction and has not attempted to spend their coins more than once; more confirmations decreases the likelihood of a double-spend. Once a threshold set by the merchant is reached, the transaction is considered to be complete.
Where do I get it, and what can I do with it?
While you used to be able to mine new Bitcoins with an ordinary computer, the process has become prohibitively expensive - it requires specialised hardware and is very competitive. Because of this, most people simply purchase Bitcoin on the open market using an exchange or from other people who already own some. In New Zealand, Bitcoins can be purchased from BitNZ by arranging an order on their website and following their payment instructions. For those with a smartphone, the Mycelium app for Android will facilitate local swaps for a small fee. Once you’ve acquired your coins, you can use them to buy actual goods and services. Bitcoins can be converted into cash using these same tools.
Some examples include:
- beer (and more beer*)
- Airline flights: cheapair.com and expedia.com
- Domain names
- Server hosting
- VPN service, and access to overseas IP addresses
- thousands more
* one day promotion, may return in the future
What have we done with SilverStripe?
Blockchain.info enables anyone on the Bitcoin network to receive payments and view transactions; while in this case they are being used as a payment processor, it is entirely possible (and often desireable) to run your own Bitcoin daemon on a server to interface with the network. However, to facilitate use with SilverStripe, I have created a module that utilises Blockchain.info’s Receive Payment API to present a disposable payment address to customers, and instantaneously forward that payment to an address controlled by Bitrito. It should be noted that due to the public nature of the Blockchain, this address is not a necessarily a secret - any user who knows the public address can inspect all transactions sent to (and from) that address using Blockchain’s search engine. This is not a bad thing at all, as the customer can use this information as proof that a sale occurred; for most vendors, it is the equivalent of a receipt. The transaction process is fairly straightforward - the customer adds their products to a shopping cart system, inspects their order, and proceeds to checkout. I present them with a QR code, and Blockchain will that monitor that address for payments. These payments are immediately forwarded to a Bitcoin address controlled by the merchant.
SwipeStripe does not support digital currencies out of the box, so some minor database changes were needed to my project to make it work.
- All Price fields now use eight digits of precision instead of the current four.
- Change to the Order::process function, which uses a hardcoded precision of two before handing the order Total over to the payment module. [pull request]
- The third is a change to the Price field within SwipeStripe to allow the class to be extended then overridden by my module. [pull request]
- A change to the SilverStripe framework itself - the Amount field in Money.php needs to be changed from Decimal(19,4) to Decimal(19,8). The reason for this is due to the way Bitcoin converts into normal currency - at current prices the difference between ฿0.0001 and ฿0.0002 is roughly $0.07 NZD, which is fine for big ticket items but not so great for cheap items like burritos and other foodstuffs. It would be great to override this change from within the module, but a method that works has yet to be found. [diff]
Once the ordering system has been modified to handle a greater amount of precision and the module has been installed, customers can begin to pay you with Bitcoin. Since the currency is able to be treated in the same way as cash, logging in is not necessary. For our purposes, a single “customer” account has been created to handle all orders - there is no personal information whatsoever required from the user to make a transaction. Once the customer sends payment to the presented address, Blockchain.info will forward it back to Bitrito almost immediately; it will periodically update Bitrito with confirmations that the transaction occurred.
Where do we go from here?
Bitrito is a basic example of using SilverStripe to accept Bitcoin in lieu of any other payment system; while I am using it to sell burritos here, you can sell anything from physical goods to digital downloads. You can see the module in action by visiting the Bitrito shop, which has been setup to demonstrate its ability to accept Bitcoin as payment. It is also available on Github (https://github.com/silverstripe-elliot/bitrito), as is the payment-bitcoin module (https://github.com/silverstripe-elliot/payment-bitcoin). I hope that with a wider audience using the module, I can eventually improve it, add new features, and perhaps accept other alternative currencies such as Litecoin or Dogecoin. Let us know what you think of it in the comments below.
Impressed with our work? Shout us a beer by sending some Bitcoin to 187FPjt1sL9QujhZzpcw1zH5vHF1afhTq1!
Bitcoin image source: http://commons.wikimedia.org/wiki/File:Bitcoin_logo.svg