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.
<!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);
});
});