Last updated 4 months ago

Multiple payment methods

Rebilly offers supports for more than fifty different payment methods and FramePay allows you to implement them all within a single form.

Using multiple methods

Implementing multiple methods within your form is as simple as adding more elements to mount when they require data input or providing the selected method name when creating the token if they do not require data.

Methods requiring mounting

Currently FramePay will generate fields for payment cards and bank accounts. These must be mounted in the form before the token can be created.

// mounting a single payment card field
Rebilly.card.mount('#payment-card');

// mounting the three separate bank account fields
Rebilly.bban.mount('#bank-account-type', 'accountType');
Rebilly.bban.mount('#bank-account-number', 'accountNumber');
Rebilly.bban.mount('#bank-routing-number', 'routingNumber');

Other methods

To use methods that do not require elements within the form, simply provide their name as the method parameter within the extraData option when creating a payment token.

var extraData = {
    method: 'paypal'
};
Rebilly.createToken(form, extraData);

Payment cards and bank accounts

To accept payment cards and bank accounts at the same time you will have to add mounting points in your form for both types.

Then when creating the token you will have to specify which method to use (payment-card or ach), otherwise FramePay will try to process the first one that was mounted.

A common way to handle the selection of the payment method is to toggle the view between the different fields. See example below which supports five payment methods in the same form.

HTMLJavaScriptCSS
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Example 1</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="https://framepay.rebilly.com/rebilly.css" rel="stylesheet">
        <script src="https://framepay.rebilly.com/rebilly.js"></script>
    </head>
    <body>
        <div class="container">
            <div class="example-8">
                <form>
                    <fieldset>
                        <div class="field">
                            <label>First Name</label>
                            <input data-rebilly="firstName" name="field1" placeholder="John" type="text">
                        </div>
                        <div class="field">
                            <label>Last Name</label>
                            <input data-rebilly="lastName" name="field1" placeholder="Denver" type="text">
                        </div>
                        <div class="field">
                            <label>Email</label>
                            <input data-rebilly="emails" name="field2" placeholder="john.denver@example.com" type="text">
                        </div>
                    </fieldset>
                    <fieldset>
                        <label>Select your payment method</label>
                        <ul class="tab">
                            <li class="tab-item">
                                <a class="tab-link is-active" data-method="payment-card" href="#content-1">Credit Card</a>
                                <div class="tab-content-item is-active" id="content-1">
                                    <div class="field">
                                        <label>Payment Card</label>
                                        <div id="mounting-point"></div>
                                    </div>
                                </div>
                            </li>
                            <li class="tab-item">
                                <a class="tab-link" data-method="ach" href="#content-2">Bank Account</a>
                                <div class="tab-content-item" id="content-2">
                                    <div class="field">
                                        <label>Account Type</label>
                                        <div id="bank-account-type"></div>
                                    </div>
                                    <div class="field">
                                        <label>Account Number</label>
                                        <div id="bank-account-number"></div>
                                    </div>
                                    <div class="field">
                                        <label>Routing Number</label>
                                        <div id="bank-routing-number"></div>
                                    </div>
                                </div>
                            </li>
                            <li class="tab-item">
                                <a class="tab-link" data-method="paypal" href="#content-3"><img
                                        alt="paypal" src="/paypal.svg"></a>
                            </li>
                            <li class="tab-item">
                                <a class="tab-link" data-method="bitcoin" href="#content-4"><img
                                        alt="bitcoin" src="/bitcoin.svg"></a>
                            </li>
                            <li class="tab-item">
                                <a class="tab-link" data-method="China UnionPay" href="#content-5">China UnionPay</a>
                            </li>
                        </ul>
                    </fieldset>
                    <button id="pay-now">Make Payment</button>
                </form>
            </div>
        </div>
        <link href="/examples/framepay-example-8-multiple.css" rel="stylesheet">
        <script src="/examples/framepay-example-8-multiple.js"></script>
    </body>
</html>
(function () {
    let selectedMethod;

    var tabListItems = document.querySelectorAll('.tab-link');
    var tabContent = document.querySelectorAll('.tab-content-item');

    var resetTabs = function resetTabs() {
        for (var i = 0; i < tabListItems.length; i++) {
            tabListItems[i].className = 'tab-link';
            if (tabContent[i]) {
                tabContent[i].className = 'tab-content-item';
            }
        }
    };

    var toggleTab = function tabs(event) {
        event.preventDefault();
        resetTabs();

        var target = event.target;
        var content = document.querySelector(target.getAttribute('href'));

        target.classList.add('is-active');
        if (content) {
            content.classList.add('is-active');
        }

        selectedMethod = target.getAttribute('data-method');
    };

    for (var i = 0; i < tabListItems.length; i++) {
        tabListItems[i].addEventListener('click', toggleTab, false);
    }

    var config = {
        publishableKey: 'pk_sandbox_Lvl5rm8lLrtAV6iSL3CIdYLAburumF4Ld8b1KDs',
        style: {
            buttons: {
                base: {
                    color: '#363636',
                    background: '#ffffff',
                    fontSize: '14px',
                    borderColor: '#dbdbdb',
                    height: '36px',
                    ':hover': {
                        background: '#ffffff',
                        borderColor: '#b5b5b5',
                    },
                },
                focus: {
                    background: '#ffffff',
                    borderColor: '#000000',
                },
                active: {
                    background: '#209cee',
                    borderColor: '#209cee',
                },
            },
        },
    };
    Rebilly.initialize(config);

    Rebilly.on('ready', function () {

        // mount framepay
        var card = Rebilly.card.mount('#mounting-point');
        var type = Rebilly.bankAccount.mount('#bank-account-type', 'bankAccountType');
        var number = Rebilly.bankAccount.mount('#bank-account-number', 'bankAccountNumber');
        var routing = Rebilly.bankAccount.mount('#bank-routing-number', 'bankRoutingNumber');
    });

    var form = document.querySelector('form');

    form.addEventListener('submit', function (e) {
        e.preventDefault();
        e.stopPropagation();

        var extraData = {
            // use the method selected by the customer
            method: selectedMethod,
        };

        Rebilly.createToken(form, extraData)
            .then(function (resp) {
                // we have a token field in the form
                // thus we can submit directly
                alert(JSON.stringify(resp, null, 2));
            })
            .catch(function (err) {
                alert(JSON.stringify(err, null, 2));
            });
    });
})();
html {
    height: 100%;
}

body {
    background-color: #ffffff;
    height: 100%;
    margin: 0;
}

.container {
    width: 100%;
    height: 100%;
    display: flex;
    border-radius: 8px;
    -webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset;
    -moz-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.example-8 {
    max-width: 500px;
    width: 100%;
    font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
    padding: 20px;
    box-sizing: border-box;
    border-radius: 8px;
}

.example-8 * {
    font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.example-8 fieldset {
    border: none;
    margin: 0 0 40px 0;
    padding: 0;
}

.example-8 .field + .field {
    margin-top: 18px;
}

.example-8 label {
    display: block;
    margin-bottom: 12px;
    font-weight: bold;
}

.example-8 input,
.example-8 button {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    outline: none;
    border-style: none;
}

.example-8 input {
    border: 1px solid #dbdbdb;
    border-radius: 4px;
    font-size: 15px;
    margin: 0;
    outline: 0;
    padding: 10px;
    width: 100%;
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    background-color: #ffffff;
    color: #8a97a0;
    -webkit-box-shadow: inset 0 1px 2px rgba(10, 10, 10, .1);
    -moz-box-shadow: inset 0 1px 2px rgba(10, 10, 10, .1);
    box-shadow: inset 0 1px 2px rgba(10, 10, 10, .1);
    -webkit-transition: all 0.4s;
    -o-transition: all 0.4s;
    -moz-transition: all 0.4s;
    transition: all 0.4s;
}

.example-8 input:focus {
    border-color: #3273dc;
    -webkit-box-shadow: 0 0 0 0.125em rgba(50, 115, 220, .25);
    -moz-box-shadow: 0 0 0 0.125em rgba(50, 115, 220, .25);
    box-shadow: 0 0 0 0.125em rgba(50, 115, 220, .25);
    color: #363636;
}

.example-8 input:-webkit-autofill {
    -webkit-text-fill-color: #000;
    transition: background-color 100000000s;
    -webkit-animation: 1ms void-animation-out;
}


.example-8 input::-webkit-input-placeholder {
    color: #8a97a0;
}

.example-8 input::-moz-placeholder {
    color: #8a97a0;
}

.example-8 input:-ms-input-placeholder {
    color: #8a97a0;
}

.tab {
    display: block;
}

.tab {
    margin: 0;
    padding: 0;
}

.tab .tab-item {
    width: 100%;
    list-style: none;
}

.tab .tab-item + .tab-item {
    margin-top: 4px;
}

.tab .tab-item .tab-link {
    display: block;
    background: #8a97a0;
    padding: 11px;
    color: #ffffff;
    text-decoration: none;
    text-align: center;
    border-radius: 4px;
    -webkit-transition: all 0.4s;
    -o-transition: all 0.4s;
    -moz-transition: all 0.4s;
    transition: all 0.4s;
}

.tab .tab-item .tab-link:hover {
    background: #2C3E50;
}

.tab .tab-item .tab-link.is-active {
    background: #2C3E50;
}

.tab .tab-item img {
    margin-top: 4px;
    max-height: 18px;
}

.tab-content-item {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    overflow: hidden;
    position: absolute;
    opacity: 0;
    width: 1px;
    -webkit-transition: all 0.4s;
    -o-transition: all 0.4s;
    -moz-transition: all 0.4s;
    transition: all 0.4s;
}

.tab-content-item.is-active {
    clip: auto;
    height: auto;
    margin: auto;
    opacity: 1;
    overflow: visible;
    padding: 20px 0;
    position: relative;
    width: auto;
}

.example-8 button {
    position: relative;
    display: block;
    padding: 19px 39px 18px 39px;
    color: #FFF;
    margin: 0 auto;
    border-radius: 4px;
    background: #23d160;
    font-size: 18px;
    text-align: center;
    font-style: normal;
    width: 100%;
    -webkit-transition: all 0.4s;
    -o-transition: all 0.4s;
    -moz-transition: all 0.4s;
    transition: all 0.4s;
}

.example-8 button:hover {
    background: #20bc56;
    cursor: pointer;
}

.example-8 .rebilly-framepay {
    background: #ffffff;
    height: 40px;
    border: 1px solid #dbdbdb;
    padding: 0 10px;
    -webkit-box-shadow: inset 0 1px 2px rgba(10, 10, 10, .1);
    -moz-box-shadow: inset 0 1px 2px rgba(10, 10, 10, .1);
    box-shadow: inset 0 1px 2px rgba(10, 10, 10, .1);
    -webkit-transition: all 0.4s;
    -o-transition: all 0.4s;
    -moz-transition: all 0.4s;
    transition: all 0.4s;
}

.example-8 .rebilly-framepay.rebilly-framepay-focus {
    border-color: #3273dc;
    -webkit-box-shadow: 0 0 0 0.125em rgba(50, 115, 220, .25);
    -moz-box-shadow: 0 0 0 0.125em rgba(50, 115, 220, .25);
    box-shadow: 0 0 0 0.125em rgba(50, 115, 220, .25);
}

.example-8 .rebilly-framepay.rebilly-framepay-buttons {
    border: none;
    box-shadow: none;
    padding: 0;
}

Form

Both types of fields are defined in the form simultaneously. In order to make the interface more user friendly it is recommended to display only one method at a time and let the user toggle between them.

<form method="post" action="/process">
    <!-- payment card field -->
    <fieldset>
        <div class="field">
            <label>Payment Card</label>
            <div id="payment-card"></div>
        </div>
    </fieldset>
    <!-- bank account fields -->
    <fieldset>
        <div class="field">
            <label>Bank Account Type</label>
            <div id="bank-account-type"></div>
        </div>
        <div class="field">
            <label>Bank Account Number</label>
            <div id="bank-account-number"></div>
        </div>
        <div class="field">
            <label>Bank Routing Number</label>
            <div id="bank-routing-number"></div>
        </div>
    </fieldset>
    <input type="hidden" data-rebilly="token" name="rebilly-token">
    <button>Checkout</button>
</form>

Script

In this example the payment card field is mounted first and will be the default payment method if not specified.

// mount all fields
Rebilly.card.mount('#payment-card', 'card');
Rebilly.bban.mount('#bank-account-type', 'accountType');
Rebilly.bban.mount('#bank-account-number', 'accountNumber');
Rebilly.bban.mount('#bank-routing-number', 'routingNumber');


var form = document.querySelector('form');
var extraData = {
    // define which method to use
    // between `payment-card` and `ach`
    method: 'payment-card'
};

form.addEventListener('submit', function (event) {
    event.preventDefault();
    Rebilly.createToken(form, extraData)
        .then(function (token) {
            // we have a token field in the form
            // thus we can submit directly
            form.submit();
        })
        .catch(function (error) {
            console.error(error);
        });
});

Other methods

To use any other method supported by Rebilly just define its value when creating the payment token.

var extraData = {
    method: 'echeck'
};

Rebilly.createToken(form, extraData);

PayPal

To accept PayPal create a form as usual and provide paypal as the method when creating the token.

Form

No special form fields are required.

<form>
    <fieldset>
        <div class="field">
            <input type="text" data-rebilly="firstName" placeholder="First Name">
        </div>
        <div class="field">
            <input type="text" data-rebilly="lastName" placeholder="Last Name">
        </div>
        <div class="field">
            <input type="text" name="email" placeholder="Email">
        </div>
        <input type="hidden" data-rebilly="token" name="rebilly-token">
    </fieldset>
    <button>Pay using PayPal</button>
</form>

Script

See the method value in extraData.

var form = document.querySelector('form');
var extraData = {
    method: 'paypal'
};

form.addEventListener('submit', function (event) {
    event.preventDefault();
    Rebilly.createToken(form, extraData)
        .then(function (token) {
            // we have a token field in the form
            // thus we can submit directly
            form.submit();
        })
        .catch(function (error) {
            console.error(error);
        });
});

Bitcoin

To accept Bitcoin create a form as usual and provide bitcoin as the method when creating the token.

Form

No special form fields are required.

<form>
    <fieldset>
        <div class="field">
            <input type="text" data-rebilly="firstName" placeholder="First Name">
        </div>
        <div class="field">
            <input type="text" data-rebilly="lastName" placeholder="Last Name">
        </div>
        <div class="field">
            <input type="text" name="email" placeholder="Email">
        </div>
        <input type="hidden" data-rebilly="token" name="rebilly-token">
    </fieldset>
    <button>Pay with Bitcoin</button>
</form>

Script

See the method value in extraData.

var form = document.querySelector('form');
var extraData = {
    method: 'bitcoin'
};

form.addEventListener('submit', function (event) {
    event.preventDefault();
    Rebilly.createToken(form, extraData)
        .then(function (token) {
            // we have a token field in the form
            // thus we can submit directly
            form.submit();
        })
        .catch(function (error) {
            console.error(error);
        });
});