Since my last exploration of bitcoin, there are a lot of things happening in that topic, and the geekiness of it (among other things) didn’t let me go. There were a lot of talks about one more more Bitcoin ATMs (like Lamassu) coming here to Taiwan, but all of them are months in the future. I thought maybe it could be interesting to build my own – let’s call it – vending machine, for fiat-to-bitcoin transactions.
There were other people making similar effort, for example the Open Bitcoin ATM, but I felt they fall a bit short and unlikely that I can get the same parts over here.
For a vending machine like this to work, there’s really only one piece of equipment is needed, the bill acceptor. I have looked around on eBay, and Alibaba for a Taiwan Dollar (TWD) bill acceptor, but there’s little to none to be found. Looks like I still got lucky that one of the big vending machine manufacturers, International Currency Technologies (ICT) is actually local (less than 1 hour on public transport from here, maybe?).
Looking around their side, they have plenty of bill acceptors (many but not all can do TWD). They don’t have any local distributor, so I got in touch with their sales directly. The first guy didn’t speak any English, but somehow after a handful of emails I got to guy with pretty good English (which is unfortunately not as common as I’d like it to be). A few weeks (yes, weeks) of emailing, and some nudging phone calls I got some useful information out of them.
I asked, what do I need if I want to use a bill acceptor for “a digital goods vending machine”, and maybe a thermal printer (that’s cool, wanted to use one for a long time)? They had some advice which parts do I need, and how much would they cost. Their recommendation:
- XBA, the most advanced bill acceptor [US$340]
- GP-58IV thermal printer (an advanced, not yet announced version of GP-58III) [US$150]
- a payment system board to make it easier to use them together and with an external control board (no mention of it on the website) [US$140]
It does add up quite a bit before any housing, brains, and display – definitely more than the Open Bitcoin ATM’s supposed $165 tag. But it looked like it does worth it, I went ahead and ordered it (+5% VAT, since I’m not a company).
The parts arrived quite quickly (as a reference, 3 days ago), within less than a week of the order, because they were in stock. Unpacking is fun, though soon it was obvious that not everything is smoothly on track.
The guides attached were barely scratching the surface, contained no information on how to make the units work with the computer (i.e. no protocol, no nothing), maximum referring to some software that I didn’t have access to, and would run on Windows anyways as opposed to my Linux system.
Asking and re-asking a bunch of questions to the sales guy made it clear:
- the thermal printer does not need the payment system board, and indeed it cannot even talk to the printer (though an attached documentation says the opposite). Need a “main” board to print to it.
- the thermal printer on the order was 12V supply and RS232 connection, while mine is 9V and USB, and apparently the former does not even exist. It uses wallplug instead of shared power like the bill acceptor and the payment system board.
- the payment system board cannot control the bill acceptor with the current RS232 cable, because its single RS232 connector is for the external “main” board that I should make. If I plug in the bill acceptor in there, the payment system has to be stand-alone
- the bill acceptor comes with a power plug which is type 172340-1, that none of the local computer part stores know, so I cannot (easily) supply power to it. They will send me another adaptor cable to improve on this.
Based on all this it seems like that even if they knew my use-case correctly, the actual parts I got do not fit together the way they represented it, and there’s plenty of confusion about the specs. I really didn’t need the payment system board, for example…
All in all, my contact was quite helpful, and pretty quick to reply, though it is still quite painful first encounter with system integration, and there’s a lot more to fix with the hardware, though was good enough to start.
There was a lot more querying in the emails about related documentation. Got the description of the ICT-104 protocol to communicate with the bill acceptor (it’s not too bad). Got the windows printer driver for the thermal printer, though managed to use it without that (and installing Windows): it turns out that the printer implements the Epson ESC/POS protocol, for which there’s already a python library, the python-escpos. It seems to be pretty dead, but good enough for initial testing.
The test prints are “okay”: the text is fine (32 char/line), barcode and qr code should be usable but there seems to be some communication problem that breaks images (like the space shuttle on the above picture), that needs to be debugged (seems like not all gifs are created equal, for example, some are more reliable). Oh, I used Dallas Clayton’s poem, “Good/Bad” for the testing.
Played with the bill acceptor as well, using some pins and a bench power supply (set to 12V, the bill acceptor eats max ~0.6V when the motor is running), and hoped that I don’t blow the circuit… So far so good.
The vending machine flow is something like this:
- turn on
- read receive address of customer
- accept payment
- calculate outgoing bitcoin
- send payment
- print receipt
I was doing the printer testing in Python, and RS232 is pretty easy in Python, so just cobbled together a command line vending machine interface in Python.
Turn on, communicate with the bill acceptor, display some initial information that I know that it’s going well.
Start running zbar in the background to read qr codes from the computer’s webcam. Using the console to exchange information, didn’t have time to fix up the python-zbar integration, though it should work as the Electrum bitcoin client uses it as well.
After an address is read, read the notes of the bill acceptor, and update the sum of received pay. This is listening on the RS232 line for specific codes, and replying to tell the bill acceptor what to do (i.e. accept/reject).
When the user is finished and signaled that to the interface, calculate the outgoing value, send the payment through a payment server. The payment server is a nodejs script that accepts payment information through a REST API. It does it very badly, insecurely, using the wrong REST model (it should be “POST” to do anything with consequence, never “GET”), but it does work. It connects to a local bitcoind instance (over SSL at least, not that it matters in this case, but at least I know SSL will work for the “real” server), which at the moment is connected to the testnet, not the real one.
After the payment is sent, print the receipt with some useful information on it, and a bitcoin logo for good measure.
I hoped it would be in better stage before tomorrow’s Bitcoin with a Lawyer’s Eyes event in the Taipei Hackerspace, but either way it is good to think ahead further.
If I want to make it really useful, and a “real” machine (one that you can kick or pour beer over it and still keeps working, as one of my friends put it), there are some specific things I can improve:
- enclose it in a box: metal, laser cut acrylic, …?
- better bill acceptor: keep bills in escrow before the payment gets through, disable acceptance unless we are at that stage of the workflow, set maximum vending amount in one go.
- designa a better interface, that can do multiple payments before needing to restart
- price not hardcoded into the software but dynamically set
- print relevant links embedded in qr code, eg. transaction on blockchain.info
- make the payment server secure and improve the overall security, eg. have a code or activation for starting up
- hook it up to the proper bitcoin network (this is the scariest part)
- build a few more, fund them, and put somewhere accessible
Now back to work.
Ps: My purpose of building any such machine is to make it easier to acquire bitcoins, this spreading their usage and increasing their usefulness. If you feel like tipping, my address is 1GxSUTrw5onv9HbJhKN5PVhuyxm4j75X8d. Thanks!