Website administrators/developers looking to accept bitcoin payments are overwhelmed by terms like blocks, txid, address, HD wallet, private keys, etc. In this post we try to give a 101 on this process by showing the basic workflow:
- Price: Calculate total amount of the order in BTC. This can be done by dividing the order/cart value by current bitcoin price. Since bitcoin price is fluctuating, there is time window within which we want to customer to pay these bitcoins. Most merchants provide a window of 10–15 minutes
- New Address: Generate a new bitcoin address. This is used to receive payments. Must be unique per order
- Prompt the User: Show the customer bitcoin address with qrcode/btc amount to which he can make the payment. Show a timer to indicate time left to make payment
- Socket: Webbrowser opens a websocket connection to server to listen to realtime notification of bitcoin payment and redirects customer to order confirmation page on notification.
- Payment: Customer makes payments through his/her bitcoin wallet
- Callbacks: Server gets notifications of payment confirmation and status of order is updated
Setting Up
- Click on Get Started For Free on Merchants Page .
- You will be shown a Settings Page like the below one
- Click on Stores and you will get your API. Use the API Key to authenticate API calls to blockonomics.co
- Click on Add a new store
- After this you will be asked to enter xpub key of wallet. This is the wallet that will be used receive your funds. To know how to create a bitcoin wallet and get xpub, feel free to see this video
- You can optionally add tag for each store that can help you differentiate each store as seen in the image above
- You should set HTTP callback URL to a callback endpoint on your website. For example something like https://btcshirtshop.com/callback.php?secret=verylongsecret. You can choose any secret phrase that you like. The purpose of the secret is to safeguard against any attacker directly calling your callback endpoint. When blockonomics.co sends callback parameters it will sent along the secret, so you are sure that the caller is authentic.
Integration Tips
- Order Information — Blockonomics doesn’t send order information/extra custom data in HTTP callback. You must keep track of order information in database by associating each order with a unique bitcoin address. This way when you get payment callback, you know which order you got payment for.
- Here is an example of order table schema in DB:
order_id (integer): Keeps track of order id tx_id(long int): Transaction id of received payment address(string): Unique bitcoin address for receiving payment value(long int): Expected bitcoin amount in satoshis
- Address Reuse / Expiry — In Blockonomics addresses never expire. You can receive unlimited amount of BTC/transaction to a single address. You will keep receiving callbacks to address, even if payment is done days/months after the address is generated. Also, Blockonomics can handle 1000s of addresses and there is no need for you to add complex logic to reuse addresses. If you are a large shop with thousands of orders per day, it is only recommended to increase gap limit to avoid fee
- Payment Timer — It is a recommend practice to show payment timer during checkout. Payment timer is used to lock in the bitcoin price for sometime so that customer can pay exact bitcoin amount. A time from 10–30 minutes is recommend. It is not recommend to have large time periods. Sometimes bitcoin price may fall by 20–30% in 12 hours which will result in losses for you. So, if the invoice hasn’t been payed for a while you should refresh the invoice so that it reflects the updated USD/BTC price
- Invoice Status — When you receive HTTP callbacks for payment, you should update invoice status on your server accordingly. On client/customer side, a simple way to do is to keep polling server invoice endpoint for status.
GET btcshop.com/api/status?invoiceid=8123 GET btcshop.com/api/status?invoiceid=8123 GET btcshop.com/api/status?invoiceid=8123 Busy polling on browser for invoice status
- Polling works however is resource intensive. A better way is to use our websocket API. Invoice status from server can be fetched again only when realtime payment notification is received
var socket = new WebSocket(“wss://www.blockonomics.co/payment/"+ address);
socket.onmessage = function(event){
response = JSON.parse(event.data);
//This condition ensures that we reload only when we get a
//new payment status and don't go into a loop
if (response.status > invoice_status)
setTimeout(function(){window.location.reload() }, 1000); }
}
//The current location (invoice page) is reload only upon websocket //notification of payment.There is timeout to let the invoice status //update on server via HTTP callback
- Payment Confirmations — Always wait for one or two payment confirmation before delivering your product
Don’t accept zero confirmation/unconfirmed payments as they can be easily cancelled or reversed
If you still need to accept unconfirmed payments, accept non RBF payments.
Resources
- Blockonomics Payments API
- Angular library to generate QR Codes
- BitcoinJS — Bitcoin-related functions implemented in pure JavaScript