Customization tutorial

In this tutorial, we will customize default gateway to our needs. We will continue working with our tutorial app from previous page.

Template file

We can easily write templates inline to our sci.html template, but we will use separate javascript file, since it's cleaner and we can later share it accross our other sites for instance.

First, we need to create folder for our static files. It will be called static and it will contain one file, bitcoinpay-templates.js. Our directory structure should look like this:

bitcoinpay-tutorial/
    app.py
    templates/
        checkout.html
        sci.html
    static/
        bitcoinpay-templates.js

Now we just need to make slight modifications in our templates/sci.html. First we will include React JSX Transformer, so our templates are compiled directly in the browser and we also need to tell the library to use our brand new templates.

This is our file with all the changes:

<!-- templates/sci.html -->
<!doctype html>
<html>
  <head>
    <meta charset="utf-8"/>
    <script src="https://bitcoinpay.com/static/js/bitcoinpay-bundle.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.2/JSXTransformer.js"></script>
    <script type="text/jsx" src="/static/bitcoinpay-templates.js"></script>
  </head>
  <body>
    <h1>Sample SCI page</h1>
    <div id="bitcoinpay"></div>
    <script type="text/jsx">
      var settings = {paymentId: '{{ payment_id }}', elementId: 'bitcoinpay', templates: bitcoinpayTemplates};
      BitcoinPay.api.payment(settings);
    </script>
  </body>
</html>

Custom templates

Now we can start to modify our template file.

We will start with creating bitcoinpayTemplates object, which we added to the library in previous step:

// /static/bitcoinpay-templates.js
var bitcoinpayTemplates = {};

First template we want to override will be template for pending state, since it's the first thing our client see.

var bitcoinpayTemplates = {

    'pending': React.createClass({
        render: function() {
            return (
                <div>
                    <h1>Our custom pending template</h1>
                </div>
            )
        }
    }),

};

As you can see, the template itself is almost pure HTML. You don't have to worry about React.createClass. It is just boilerplate code. You can read more about React compontents here. You can do almost anything in your custom component using React. We will focus just on the HTML part inside return function in this tutorial.

Using predefined components

Except standard HTML tags, you can also use prefenider components, which represent common objects appearing on the invoice page, such as qr codes, bitcoin addresses, etc. You can see full list of predefined components here

We will add QrCode and ReceivingAddress to our custom pending template, so our clients can make payments

var bitcoinpayTemplates = {

    'pending': React.createClass({
        render: function() {
            return (
                <div>
                    <h1>Our custom pending template</h1>
                    <BitcoinPay.api.components.QrCode/>
                    <BitcoinPay.api.components.ReceivingAddress/>
                </div>
            )
        }
    }),

};

Using invoice attributes

In example above, we used BitcoinPay.api.components.ReceivingAddress to render address for the payment. This address is rendered like HTML span elements, but we want to have address in the div with our custom HTML class. We can use invoice attributes and rewrite example above as following

var bitcoinpayTemplates = {

    'pending': React.createClass({
        render: function() {
            return (
                <div>
                    <h1>Our custom pending template</h1>
                    <BitcoinPay.api.components.QrCode/>
                    <div className="our-custom-class">{this.props.invoice.data.address}</div>
                </div>
            )
        }
    }),

};

Please note, that only difference from standard HTML notation is className instead of class. This is due to class being reserved javascript keyword.

For full list of attributes see list of available attributes

Our clients also need to know how much they need to pay in fiat and bitcoin, so lets add this information

var bitcoinpayTemplates = {

    'pending': React.createClass({
        render: function() {
            return (
                <div>
                    <h1>Payment id: {this.props.invoice.data.payment_id}</h1>
                    <h2>Waiting for your payment</h2>
                    <BitcoinPay.api.components.QrCode/>
                    <div className="our-custom-class">{this.props.invoice.data.address}</div>
                    <div>Amount to be paid: {this.props.invoice.data.missing} BTC</div>
                </div>
            )
        }
    }),

};

We can add amount in FIAT currency and countdown till invoice expiration time, so our users know how much time do they have to pay for invoice. We will use predefined CountDown component for countdown and ToBePaidFiat for the fiat amount, but we could use invoice attributes as well.

var bitcoinpayTemplates = {

    'pending': React.createClass({
        render: function() {
            return (
                <div>
                    <h1>Payment id: {this.props.invoice.data.payment_id}</h1>
                    <h2>Waiting for your payment</h2>
                    <BitcoinPay.api.components.QrCode/>
                    <div className="our-custom-class">{this.props.invoice.data.address}</div>
                    <div>Amount to be paid: {this.props.invoice.data.missing} BTC</div>
                    <BitcoinPay.api.components.ToBePaidFiat/>
                    <BitcoinPay.api.components.CountDown/>
                </div>
            )
        }
    }),

};

This should be enough for user to be able to pay for invoice. We will also override default template for timeout state (see list of all possible payment states). We will add very simple template, just to inform user that payment has expired.

var bitcoinpayTemplates = {

    'pending': React.createClass({
        render: function() {
            return (
                <div>
                    <h1>Payment id: {this.props.invoice.data.payment_id}</h1>
                    <h2>Waiting for your payment</h2>
                    <BitcoinPay.api.components.QrCode/>
                    <div className="our-custom-class">{this.props.invoice.data.address}</div>
                    <div>Amount to be paid: {this.props.invoice.data.missing} BTC</div>
                    <BitcoinPay.api.components.ToBePaidFiat/>
                    <BitcoinPay.api.components.CountDown/>
                </div>
            )
        }
    }),

    'timeout': React.createClass({
        render: function() {
            return (
                <div>
                    <h1>Payment {this.props.invoice.data.payment_id} has expired.</h1>
                </div>
            )
        }
    }),

};

Now you should be able to fully customize gateway to your needs. You migh also want to checkout how to apply inline styling with React here. If you have any questions regarding implementation, do not hesitate to contact us any time on tech@bitcoinpay.com.