Advertisement

Adding Bitcoin Payment Processing to Your Website

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

Bitcoin has definitely started to become more mainstream, and with its global reach and minimal fees, it is a payment method worth considering.

In this article, we will take a look at what Bitcoin is, as well as how to start accepting them in your applications.


What Is Bitcoin?

First things first, what is Bitcoin? For the un-familiar, Bitcoin is a peer-to-peer currency, developed to remove the need for a third party trusted authority, and instead rely on intrinsic security by means of cryptographic hashes.

By removing a central authority (A government, bank, etc..) you reduce fees and lower requirements. There is no need to fill out forms or pay people's salaries, so in a sense, the money secures itself.

I'm not going to get into the specifics, but essentially each time a transfer of currency takes place, the money is signed with the two parties keys and then hashed, and these transactions are appended to the global log. This allows coins to be publicly traced back, and to see if the money really belongs to someone or not.


Advantages & Disadvantages

Now let's take a look at some of the advantages and disadvantages associated with using Bitcoin:

Advantages:

  • Anyone can use it globally.
  • Somewhat anonymous.
  • Minimal fees.
  • No setup required.

Disadvantages:

  • The worth of the coins fluctuates.
  • Not as mainstream as other options (CC, Paypal).

The advantages all follow a similar pattern, in that because there is no central authority, anyone can use it at any time without needing any confirmations or acceptance, plus the fees are pretty low.

Now the disadvantages are varied. Since it is not as mainstream as other payment options, I don't think it is quite where it needs to be, in order to make it your only payment option. But by all means, if you are a huge supporter and want this to grow, you can be a Bitcoin-only service, but I would suggest, for now, using it alongside another service, which accepts credit card.

The other disadvantage is the stability of Bitcoin's value; at the beginning of this year, the worth of one bitcoin was around 12-14$ each, in just a couple of months the coins went up to almost 240$ in April and are currently worth around 110-115$ each. This is in huge contrast to traditional currencies, for your money to have a 2000% increase in worth and then a 50% decrease, all within a few months seems like it should be a red flag.

courtesy of blockchain.info

It's hard to say for sure, if this is just a bi-product of having a decentralized currency, or if it is due to the infancy of the program, but it is definitely a concern.

Luckily most Bitcoin processors, like the one I will be using in this article, allows you to instantly convert the Bitcoins or a portion of them into regular currency, like dollars, right away. You can for instance setup that 80% of the Bitcoins that come in should be immediately converted and transferred to your bank account, removing this risk element.

Ultimately, you can both gain and lose from these fluctuations, so it's up to you to decide whether you want to gamble and leave more of it in Bitcoins, or remove all the risk and convert all of it.

Their are a couple popular services around that work like Coinbase, BitPay, etc. but the one I will be using in this article is BIPS.


The Premise

In this article we will be building a simple landing page, where you can enter in your email and click 'purchase' which will take you to the payment page. On the payment page, you will be given a Bitcoin wallet address which you can send the money to, and once you pay, you will receive the item you purchased via email.

These three stages are completely separate, as in all payment options, but it stands out more here, since you can't pay directly from the purchase form and need to pay from your own personal Bitcoin wallet.

For this app, I will be using Slim to provide a little structure, Mandrill for sending the product and, like I mentioned, BIPS as the payment processor to implement the Bitcoin side of things.


The Setup

So to install Slim, create a composer.json file with the following:

{
   "name": "bitcoin app",
   "require": {
       "slim/slim": "2.2.0"
   }
}

Then run composer install (assuming you have composer installed) to install the dependencies.

Next, create a public folder with an index.php file inside of it, and a views folder.

Your structure should look something like this:

public/
    -> index.php
vendor/
views/  
composer.json

Now open the index.php file and let's setup the Slim app:

<?php
   require "../vendor/autoload.php";

   $app = new \Slim\Slim(array(
       "templates.path" => "../views"
   ));

We are requiring the autoloader, and then instantiating the Slim library, so far just boilerplate. Next, let's add the home route which will be a standard HTML page with the form to start a purchase:

$app->get('/', function() use ($app) {
   $app->render('home.php');
});

And then we need to add the home.php view file itself to the views folder:

<!DOCTYPE HTML>
<html>
<head>
    <title>Bitcoin App</title>
    <style>
        body {
            font-size: 1.6em;
            text-align: center;
            padding: 130px;
            font-family: sans-serif;
        }
    </style>
</head>
<body>
    <h1>Buy This</h1>
    <p>This is a great offer you should purchase this thing</p>
    <form action="/" method="POST">
        <input type="text" placeholder="Enter your E-mail" name="email"/>
        <input type="submit" value="Purchase !">
    </form>
</body>
</html>

Nothing too fancy, basically just a form to submit the user's email.

The last piece of setup we need to complete is to sign up for both BIPS and Mandrill (if you are using it) and generate API keys for both. In BIPS, you go to the Merchant tab and generate an invoice API key, and for Mandrill you go to the SMTP & API Credentials page to generate a new API key.


Creating an Invoice

So far we have a basic form which will submit a user's email via a POST request, the next step is to take that email and generate an invoice for it.

Let's add a post route to the index.php file, which will generate an API call to create a new invoice and redirect the user to it:

$app->post('/', function () use ($app) {
    $email = $req = $app->request()->post('email');
    
    if ($email) {
        $token = "BIPS_API_KEY";
        
        $ch = curl_init("https://bips.me/api/v1/invoice");
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($ch, CURLOPT_USERPWD, $token . ":");
        curl_setopt($ch, CURLOPT_SSLVERSION,3);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_POSTFIELDS, array(
            "price" => 20,
            "currency" => "USD",
            "item" => "PDF Book",
            "custom" => json_encode(array(
                "users_email" => $email
            ))
        ));
        $invoiceUrl = curl_exec($ch);
        $app->redirect($invoiceUrl);
    }
});

There are a couple of things to notice here, for one, the API token you generated for creating invoices, is the 'username' in the HTTP authentication. The POST fields we are sending are as follows:

  • price - the price of the object (an int or float value).
  • currency - a currency abbreviation like USD, GBP, EUR or BTC for prices in Bitcoin itself.
  • item - the item's name, this is optional but it will show up on the invoice.
  • custom - a JSON encoded string containing any custom data you want attached to the invoice. Whatever gets specified here will be passed back once the user pays, so you can put internal reference numbers or keys to a database, in our example I just put the email in since we aren't storing any other data.

The API call will return just the URL to the invoice itself, so we can just get the response and redirect straight to it.

Now unlike other payment options, like a credit card or PayPal, there is no third party who handles the charge, so you can't just enter your number or login to pay. Instead, it creates a custom wallet per transaction, and gives you 15 minutes to transfer the amount specified into that account. This is what I was talking about earlier, that with Bitcoin, you notice the different steps during the payment process more, then you would with something like the one-click purchase on Amazon.

On the other hand, the advantage to a system like this is the innate security that comes without you needing to do anything. You don't deal with credit card numbers or processing payments, so the site doesn't need to be as secure, you just create a new 'identity' or wallet, and if the money is transfered there, then the payment is completed successfully.


Completing the Purchase

The last step is to handle the actual purchase, once the payment has been completed. To do this you need to add a callback URL and a secret key on the merchant tab of the BIPS panel. I am just going to direct it to the /ipn route, with a secret key of SECRETKEY.

The callback is a POST request which contains all the info from the purchase along with the custom data you passed in and a hash to verify that it is authentic. You verify the purchase by SHA-512 hashing the transaction key along with the secret you setup in the admin panel, and verify that it matches the computed 'hash' in the callback's request:

$app->post('/ipn', function () use ($app) {
    //Slim Request object
    $req = $app->request();

    //Get some variables from the request
    $email = $req->post('custom')['email'];
    $transactionKey = $req->post('transaction')['hash'];
    $invoiceHash = $req->post('hash');
    $status = $req->post('status');
    
    //Hash the transaction key with the secret
    $secret = 'SECRETKEY';
    $hash = hash("sha512", $transactionKey . $secret);
    
    //Verify it
    if ($invoiceHash === $hash && $status == 1) {
        //Paid
    }
});

The transaction key and secret are just appended to one another and then we hash them together. The last bit just checks if the status is 1 (which means the payment came in) and checking the authenticity of the notification.

We now have the user's address and we have a payment confirmation, so the last step is to send the user some sort of item. If you are building a subscription service, or some kind of physical item, you can just log the user's payment into a database, but to wrap up this article, let's take a brief look at sending an item with Mandrill.

if ($invoiceHash === $hash && $status == 1) {
    //Mandrill URL + API key
    $url = "https://mandrillapp.com/api/1.0/messages/send.json";
    $apiKey = "MANDRILL_API_KEY";

    //Get Email Template
    $view = $app->view();
    $template = $view->fetch("email.php");

    //Message POST data
    $messageData = array(
        "key" => $apiKey,
        "message" => array(
            "html" => $template,
            "subject" => "Thank you for your Purchase :)",
            "from_email" => "demo@email.com",
            "from_name" => "Your Name",
            "to" => array(
                array(
                    "email" => $email
                )
            )
        )
    );

    //Send Request
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($messageData));
    curl_setopt($ch, CURLOPT_SSLVERSION,3);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_exec($ch);
}

In the above code, all we're doing is preparing all of the data and building the JSON message request to be sent to the Mandrill API; you need to send the API key, the email's subject and message, the from email/name and who the email is for.

For the message, we are using Slim's built in template commands, and then we POST the request using curl and json_encode to compile the data into JSON.

Next, let's create the template file email.php (inside the views folder). You can put just about anything you want in here, as it is parsed as a normal Slim template, and we just return the rendered HTML:

<h1>Thank you for your Purchase</h1>

<p>You can download the file <a href="http://link-to-file">here</a>.</p>

I just added a heading with a link to the file. If all went well, your site should be fully working.


Conclusion

In this article we went through the process of both creating an invoice as well as handling payments. Bitcoin can seem a bit daunting to get started with, but as you can see, it is much simpler then one would think, even simpler then other payment options in most cases.

I know this may be one of the most expensive demos to try out, so I have gotten an exclusive photo by the talented web designer Melissa Keizer which you can purchase in the demo if you so wish.

I hope you enjoyed this article, and thank you for reading. Like always, if you have any questions feel free to leave me a comment below, on twitter, or in the Nettuts+ IRC channel on freenode.

Advertisement