Bitcoin Payment Processing with BitPay

2014-08-10 09:42
Written by
andyw - member of the CiviCRM community - view blog guidelines

What is Bitcoin?

So you may have heard about Bitcoin, some of you might be quite familiar with it - but for those who aren't, it is a digital currency - a form of electronic cash which can be used to make online payments, transfer money to friends - in theory, anything that you can do with traditional money, you can equally do with Bitcoin.

Bitcoin uses many of the ideas initially developed for peer-to-peer file sharing networks to create a decentralized system, ie: one that is not controlled and cannot be manipulated by any person, organization or government. The software it runs on is open source and can be viewed by anyone, and so in this sense, it is very much considered to be in the public domain, both in terms of the network itself, and the software running on it.

I hope that is an ok explanation for the purposes of this post - but for those who'd like to find out more, there are some links below to some good sources who can explain it much better and in a bit more detail than I can:

So What is BitPay Then?

BitPay is a payment processing service for Bitcoin payments - they are kind of aiming to be the Paypal of the Bitcoin world. Whilst Bitcoin is a public network, and you can theoretically broadcast transactions to the network yourself without having to rely on a third-party to do that for you (we are working on a payment processor for that too, but more on that coming soon), it requires a lot of setup, your own server, a fair bit of background knowledge - it's probably not for most people.

So BitPay aims to simplify the process of accepting Bitcoin payments by providing a gateway interface similar to any other payment processor. It's worth noting there are plenty of alternative payment processing providers for Bitcoin payments out there, but BitPay is one of the most popular, and it's the one we've decided to implement for now.


You can currently get hold of the extension from the Github url below - although we'll make it available through the public extensions directory once it's been better tested and is considered stable:

Place that in your extensions directory (either by cloning through git, or by downloading the zip file), and then enable the extension. This will make two new payment processors available - 'Bitcoin' and 'BitPay'. Ignore the 'Bitcoin' one for now.

Also, be sure to configure your extension resource URL (will try to add a warning for that in due course), as the extension will not work correctly if this is not done.

To add the BitPay processor, go to Administer -> System Settings -> Payment Processors and click 'Add New Payment Processor', then select 'BitPay' on the next page.

You should see a screen like the one below:

All you should need to do is name your processor, enter an optional description, and enter your BitPay api key. An API key can be generated through your account dashboard on the BitPay site.

You may also see the following warning:

See the section below marked 'Payment Notifications' for more info on this, but in short, we have designed the processor to work with or without SSL, so if you get this warning, you should make sure cron is running, and configure it to run as often as you think sensible - we would recommend at least every 15 minutes, but preferably every 5-10 minutes to ensure payments are completed as promptly as possible after confirmation is received.


So here is a test event page with the BitPay processor enabled, along with some others:

You'll see it converts the prices to BTC at the current exchange rate when you have BitPay selected as the processor. So you set the prices in your local currency, and the price in BTC is calculated at the time of signing up. And that is also displayed on the confirmation screen before checking out, here:


To make payment, the user will be redirected to the following page on the site:

You can make payment either by using a mobile wallet app to scan the QR code, clicking the 'Pay with Bitcoin' button - this will open up a wallet app on your computer which is configured to handle Bitcoin links, with the amount prefilled - or you can manually send the amount on the invoice to the address at the bottom.

For now, we're going to use a mobile wallet app to demonstrate - so scanning the QR code with your app prefills the receiving address and amount, like so:

Then all that is required is to click the 'Send Payment' button. When you've done that, the on-screen invoice should display a status of paid:

.. and then redirect to the usual 'Thankyou' page which we're all familiar with.


There will be a delay before the transaction is fully completed, as at the moment, the processor uses the default behaviour of requiring 6 network confirmations before considering the transaction as completed, at which point the contribution will be marked as complete in Civi, and confirmations emails sent (if configured).

This is to guard against fraud and something known as 'double spending', and is quite important when exchanging Bitcoin for physical goods, as you don't want to be in a situation where you've sent out the goods, then later discover the transaction to be fraudulent.

However, with the type of transactions Civi handles (contributions, event registrations, memberships), it is not so important, as with contributions, you don't generally get anything in return - and with memberships and event registrations, these are things that can be revoked or cancelled if the confirmation process subsequently fails.

So we will probably introduce an additional setting for this on the payment processor configuration page, whereby you can choose to complete the transaction immediately, as soon as it is marked as paid - however, you should be aware of the potential dangers of doing this.

In short though, there is currently a delay of 30 mins to 1 hour while confirmations are received, before the transaction is marked as complete in Civi.

Payment Notifications

For security reasons, BitPay will only send payment notifications to an SSL (https) url - this is when the BitPay site contacts your site to provide updates on the status of the invoice - basically, whether the payment has gone through or has failed.

So if your site has an SSL certificate installed, you shouldn't need to read any further - everything should just work as if by magic. Just be sure to check that anonymous users have the 'Profile listings and forms' permission, which I think is the case for all processors that implement payment notifications.

However, we're aware that the majority of CiviCRM sites don't have SSL certificates, and thought this might be a bit of a drawback for a lot of users / potentially limit the audience somewhat, so have designed in a fallback system for those cases.

There is a Scheduled Task (cron job) which should enable itself automatically if it detects you don't have an SSL certificate - all you need to do is configure cron to run as often as you can. Be careful with this, as it does have a potential impact on the performance of your site - but as stated above, at least every 15 minutes would be good, every 5-10 minutes would be better, but it's up to you to decide what's best for your use case - the less often it runs, the longer payments will take to be marked as complete in Civi after BitPay has received the necessary confirmations.

That is all

I hope the extension proves useful - please try it out, let me know about any bugs or problems. There is a forum thread here for the moment where you can do that, although I will probably start a new one just for this extension if it proves popular / if there are a lot of issues.,30532.0.html

Also, many thanks to Circle Interactive, who let me spend a fair bit of work time doing this. It wasn't written for any particular client - we just did it because we wanted to, and thought it might be a nice addition to Civi.

Filed under


All went well unti I went to try it out.

At the confirmation screen I click "Continue" and it brings me to a page where it shows: "DB Error: no such table". I then repeated with civicrm debugging turned on and found that I'm missing a table civicrm_bitpay_transaction. I'll try crawling through the code to find the installSchema proc - hopefully this will help me manually create this table.

Any other insights? Why did this table not get installed? I didn't see any errors when I installed the payment processor.

I'm using Joomla 2.5.24 with civicrm 4.4.6.

It is supposed to install the schema when the payment processor settings form is saved for the first time - have done it that way as the extension may include a few different payment processors (that share a lot of common functionality) eventually, but we only want to install a schema for the one being used.

That has obviously failed to work on your Joomla for some reason, but I'll take a look into that, find out why that is.

In the meantime though, yes - if you manually run the query from the installSchema function on your Civi database, that should sort the problem out.


I manually installed the table and all is almost perfect.

I setup the cron job for civicrm and I do get an error:

Fatal error: Class 'Bitcoin_Utils_BTCUpdater' not found in /home/XXX/public_html/media/civicrm/extensions/ on line 630

I get this in the email sent from the cron run. I think I can fix it by adding a require once statement to the above file?

If I run the Update BTC Exchange Rate manually from the Scheduled Jobs page I don't get any errors and the log show it ran properly.

Does this cron also change the contribution from Pending to Completed? I did a test transaction and the contribution was left as pending, I manually set the contribution to completed. But this was before I enabled the civicrm cron, I need to do another transaction now that the cron is running.

Great job on this by the way!

I didn't have the invoice updater job enabled. I just enabled it and have an additional cron error:

Fatal error: Class 'BitPay_Invoice_Status_Updater' not found in /home/njlp/public_html/media/civicrm/extensions/ on line 653

Again this is probably something I can fix by adding a require once to bitcoin.php.

Note that I do NOT get these errors when I run the job from the admin area (more -> Execute Now) - but only when the cron kicks off the job.

Thanks! - The BTC exchange rate updater isn't required - I decided it would be better to query the exchange rate when the (event or contribution) page is loaded, so I'll get that taken out, so it's not confusing.

Re: the missing classes - they should be being loaded automatically by a custom class loader, but it sounds like that's not getting initialized when run via cron (I must admit, I was running it through the admin interface too, so may have missed that one).

There is a function called bitcoin_init() which should sort all that out though - I would put a call to that at the top of civicrm_api3_job_update_bitpay_invoices() - but I'll do some more work on this during the week, sort these problems out and update the Github repo.

I did exactly that (added call to bitcoin_init to civicrm_api3_job_update_bitpay_invoices) and I don't get any errors.

I also added it to civicrm_api3_job_update_btc_exchange_rate and that cron doesn't throw any errors (I understand that you want to remove this job)

All seems to be working perfect now. Now I just need to find people to donate or join via bitcoin!



Great, thanks for letting me know - I'll get the Github repo updated, so people don't have the same problems in future, and thanks very much for trying it out / letting me know about those problems.

And good luck finding users who want to donate using Bitcoin .. they might be a little thin on the ground at the moment :) - but it's something I hope will gain some traction in the future - but if you don't give them that option in the first place, that's probably never going to happen.

All the best!


This worked the one time I tried it - however another problem has come up. When the invoice page loads the html returned from bitpay is blank? By this I mean I see the following html on the invoice page (hopefully this comment system doesn't strip out all the html!).

<div id="bitpay-payment-block">
<iframe src="">

The invoice page returned from bitpay is blank?? However if I type the address into a browser it shows up just fine.

I did the following and it appears to have fixed the problem. I added &view=iframe to the address shown in custom/templates/BitPay/Payments/page.tpl. I tested this twice and it shows that it now works ok. I then went back to the old tpl file and it didn't work again. (Despite this tesing, I'm not absolutely convinced I fixed anything - perhaps bitpay is screwing with me!!!)

I also tried modifying the bitpay address using firebug and the same thing happened. (removing the &view=iframe showed a blank frame).

Yes, I'm getting that too now - I think they have changed some stuff. Typical, I must have run like 100 payments through this while testing it - the minute you turn your back, they change everything. Adding &view=iframe seems to fix it though, as you suggest.

Also, one of the reasons I put it on a separate page is that it was quite a big iframe, now it seems to have shrunk, so have got this tiny little thing sitting on a page on its own.

Oh well, will have a think about what to do about that.

Thanks for passing that on though - I've updated the repo with that change, and the fix to the cron job - still need to sit down  and investigate what went wrong on the installation, but will get round to that.

I just installed it on another site and did a complete test. Everything worked great. The only nitpick that I have is that BitPay contributions are hard to find from the civicrm contributions page. They are listed as Paid By: "Credit Card", and Received Into: "Deposit Bank Account". This is exactly how PayPal transactions are listed. It would be nice to be able to identify just the BitPay transactions somehow. I presume the list of Payment Methods on the contribution find screen is a civicrm list and is not this extension though. (I only wish I was getting so many donations that not being able to find/identify them was a bigger problem!)

Sorry for the delayed reply - was going to do some more to this during the week, hopefully get it into a suitable state to go on the extensions directory.

With regard to identifying the transactions, I think we should probably add a new payment instrument when the extension is installed, I think it would make more sense to label that 'Digital currency' than 'Bitcoin' - but let me know your thoughts on that - will try and get something implemented.

The 'Received Into' part I think you could solve by adding a new financial account at:


then configuring the payment processor to use it.

Will also try to add a couple of new features, test in some more complicated situations (contribution pages with memberships, pricesets etc), which I suspect might need some work, and will also troubleshoot that installation issue you had.


I ended up rolling my install back to 4.4.7 and haven't really spent much time trying to get this to work under 4.5.0.

I did have some success by adding:

require_once "media/civicrm/extensions/";

to custom/php/CRM/Core/Payment/BitPay.php. It allowed the transactions to go through, but the display of the prices in bitcoin on donation pages was still broken. I'm sure this isn't the proper fix.

(I think I submitted a prior comment that included the error messages I was getting with running this under 4.5.0. In case that comment didn't really get posted - it was having trouble finding the class \Guzzle\Service\Client();)


Is anyone using this with civicrm version 4.6? Last I tried (which was a long time ago with 4.5!) I had problems. I'm going to be upgrading a site from 4.4 this week. I'll give it a try, but would like to know if anyone else has had luck.