BR-DGE Hosted Fields
You can use BR-DGE Hosted Fields to fully outsource all your cardholder data functions to BR-DGE so that your platform qualifies for the simplest PCI-DSS SAQ level.
This is achieved by collecting the most sensitive cardholder data via inline frames (iframes) hosted by BR-DGE domains. BR-DGE PCI-DSS SAQ-D compliant systems then translate the data into a single-use token that can be safely handled by your PCI-DSS SAQ-A platform. The token can be used by your back-end services to generate a payment via the BR-DGE REST API.
Add BR-DGE Hosted Fields Module to your App
After you have set up the Comcarde JavaScript Client, you can add a hosted-fields
module to your website source.
<script src="https://sandbox-assets.comcarde.com/web/v2/js/hosted-fields.min.js"></script>
<script src="https://assets.comcarde.com/web/v2/js/hosted-fields.min.js"></script>
Insert placeholder elements with special IDs into your website. These can be positioned to fit in with your website/app design. The hosted-fields
module will find the elements based on their ID, and replace them with <iframe>
elements.
Hosted Field element IDs
card-number
cvv
expiration-date
Example:
<div id="card-number"></div>
<div id="cvv"></div>
<div id="expiration-date"></div>
You can also provide labels for the hosted fields, the same as if it were a field hosted by the parent website/app.
<label for="expiration-date">Expiration Date</label>
<div id="expiration-date"></div>
Finally, add hosted fields functionality to your Comcarde JavaScript Client:
comcarde.client.create(
{
authorization: client - api - key, // your client API Key
},
function (clientErr, clientInstance) {
// optionally configure other plugin modules...
/*
* Create BR-DGE Hosted Fields Plugin Module Component
*/
comcarde.hostedFields.create(
{
client: clientInstance,
styles: {
// Style all elements
input: {
'font-size': '16px',
color: '#3A3A3A',
'font-family': 'monospace',
},
// Styling element state
':focus': {
color: 'blue',
},
'.valid': {
color: 'green',
},
'.invalid': {
color: 'red',
},
// Media queries
// Note that these apply to the iframe, not the root window.
'@media screen and (max-width: 700px)': {
input: {
'font-size': '16px',
},
},
},
fields: {
number: {
selector: '#card-number',
placeholder: 'xxxx xxxx xxxx xxxx',
},
cvv: {
selector: '#cvv',
placeholder: 'xxx',
},
expirationDate: {
selector: '#expiration-date',
placeholder: 'MM/YYYY',
},
},
},
function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr)
return
}
hostedFieldsInstance.on('validityChange', function (event) {
var field = event.fields[event.emittedBy]
if (field.isValid) {
// handle valid case
} else if (field.isPotentiallyValid) {
// handle potentially valid case
} else {
// handle invalid case
}
})
/*
* Hosted Fields can also listen on the following events
*/
form.addEventListener(
'submit',
function (event) {
event.preventDefault()
/*
* Cardholder name, issue number, and start date can optionally also be
* passed to the tokenize operation. This data can safely be collected
* via fields hosted by merchants without requiring more than PCI DSS SAQ A
* accreditation.
*
* This can be useful if your BR-DGE account is configured with Payment
* Service Provider connections that require cardholder names etc.
*/
hostedFieldsInstance.tokenize(
{
cardholderName: 'X Ample',
issueNumber: '01',
startDate: '01/19',
},
function (tokenizeErr, payload) {
if (tokenizeErr) {
console.error(tokenizeErr)
return
}
// send payload.token to your server to be used as a tokenized payment
// instrument in a payment request.
// If BR-DGE is able to provide metadata about the card then
// payload.metadata will be provided. This field will be returned as
// null if no card information is available.
//
// Note: All text field values will be UPPERCASE, and any field could
// be returned as null if its value could not be determined.
if (payload.metadata) {
var metadata = payload.metadata
/*
* metadata.cardBrand: MASTERCARD, VISA, etc (free text)
* metadata.issuer: Name of issuing bank (free text)
* metadata.type: DEBIT, CREDIT or CHARGE_CARD (enum)
* metadata.category: CLASSIC, BUSINESS, MIXED_PRODUCT, etc
* (free text)
* metadata.countryIsoA2: ISO 3166 Alpha-2 country code
* metadata.commercial: indicates if card is corporate or retail
* (Boolean)
*/
}
}
)
},
false
)
}
)
}
)
To can customise your Hosted Fields, please see the Hosted Fields Styling documentation.
Hosted Fields Events
You can subscribe to Hosted Fields events using an event listener. This allows you to update the UI of your form based on the state of the fields. These events include:
Event Name | Description |
---|---|
focus | Emitted when a field gains focus. |
blur | Emitted when a field loses focus. |
empty | Emitted when a field transitions from having data to being empty. |
notEmpty | Emitted when a field transitions from being empty to having data. |
cardTypeChange | Emitted when the possible card type has changed. |
validityChange | Emitted when the validity of a field changes. |
Example:
hostedFieldsInstance.on('validityChange', function (event) {
console.log(event.emittedBy, 'validity')
})
hostedFieldsInstance.on('focus', function (event) {
console.log(event.emittedBy, 'has been focused')
})
hostedFieldsInstance.on('blur', function (event) {
console.log(event.emittedBy, 'has been burred')
})
BIN/IIN Lookup
The Hosted Fields module supports on-the-fly Bank/Issuer Identification Number (BIN/IIN) lookup when the first nine digits of a card PAN are entered into BR-DGE Hosted Fields. The information returned will match the CardMetadata
schema of the BR-DGE REST API OpenAPI specification.
This feature can be enabled via the binLookup
flag when configuring the Hosted Fields module:
comcarde.hostedFields.create({
...
binLookup: true, // enable BIN/IIN lookup
...
});
A callback can then be configured which will be provided with a card metadata object every time a PAN is entered into BR-DGE Hosted Fields:
hostedFieldsInstance.on('binLookup', (cardMetadata) => {
// cardMetadata will contain information about the card
var cardType = cardMetadata.type
})
For more information, please see the CardMetadata schema in the BR-DGE REST API OpenAPI specification.
Card on File
Card on File can further streamline your online checkout experience. We recommend reading about the BR-DGE Vault before continuing.
Creating a Card on File
Once Credentials On File Mandate requirements relating to cardholder consent has been met, the tokenize
method can be configured to create a Card on File.
hostedFieldsInstance.tokenize({
'customerAgreedToSaveCard': true,
'customerId': ..., // optional identifier for customer
...
}, function(tokenizeErr, payload) {
/*
* payload.token contains a single-use token associated with a CVV if collected
* payload.savedCard.token: multi-use token that can be used to represent the
* card in future payments
* payload.savedCard.cardType: E.g. VISA/MASTERCARD
* payload.savedCard.nameOnCard: "John F Doe",
* payload.savedCard.pan: Obfuscated card PAN to help shoppers identify cards
* e.g. "**** **** **** 1111"
* payload.savedCard.expiryDate: E.g. "06-30",
* payload.savedCard.startDate: If available, e.g. "01-20"
* payload.savedCard.issueNumber: if available, e.g. 1
*/
}
});
Using a Card on File
When using a Card on File in payments we recommend exchanging the multi-use token for the Card on File for a single-use token in your client application, then using the single-use token in payment requests.
Multi-Use Token to Single-Use Token
Call tokenizeSavedCard
with the multi-use token for the saved card your customer selects.
comcarde.client.create({
authorization: client-api-key // your client API Key
}, function(clientErr, clientInstance) {
...
comcarde.hostedFields.create({
client: clientInstance,
...
}, function(hostedFieldsErr, hostedFieldsInstance) {
...
// for example, using a form to initiate tokenization
form.addEventListener('submit', function(event) {
event.preventDefault();
event.preventDefault();
hostedFieldsInstance.tokenizeSavedCard({
'token': multi-use-token // for selected saved card
}, function(tokenizeErr, payload) {
// send payload.token to your server to be used as a tokenized payment
// instrument in a payment request.
});
}
})
};
Multi-Use Token to Single-Use Token with CVV
For security reasons, we do not store card verification values (CVVs), but you can optionally collect CVVs and temporarily associate them with single-use tokens.
If you wish to collect CVVs, first add a div to contain a CVV field hosted by BR-DGE:
<label for="save-card-cvv">CVV</label>
<div id="save-card-cvv"></div>
Then configure the hosted fields module to collect CVVs, and call tokenizeSavedCard
with the multi-use token for the saved card your customer selects:
comcarde.client.create({
authorization: client-api-key // your client API Key
}, function(clientErr, clientInstance) {
...
comcarde.hostedFields.create({
client: clientInstance,
...
fields: {
...
saveCardCvv: {
selector: '#save-card-cvv',
placeholder: 'xxx'
}
}
}, function(hostedFieldsErr, hostedFieldsInstance) {
...
// for example, using a form to initiate tokenization
form.addEventListener('submit', function(event) {
event.preventDefault();
hostedFieldsInstance.tokenizeSavedCard({
'token': multi-use-token // for selected Card on File
}, function(tokenizeErr, payload) {
// send payload.token to your server to be used as a tokenized payment
// instrument in a payment request.
});
}
});
});
Visa Installments
Visa Installments is an optional extension to our hosted fields module that allows issuers to offer installment plans to their cardholders.
At a high level this works by:
- A customer enters their card details
- If Visa Installments is enabled on your BR-DGE account and your customer uses a Visa card we may return an array of Visa Installment plans you can offer to your customer.
- Please get in contact with support to enable Visa Installments on your account
- Use the data provided within the
visaInstallmentPlans
array to build a UI to display different plan options to their customers. - If your customer selects a plan and agrees to the terms and conditions you can call
hostedFieldsInstance.tokenizeVisPlan
to generate a token that can be used as a payment instrument in payment requests by your server. - You will receive a settlement for the full amount similar to a card payment.
- The Installments agreement and the servicing of that agreement are between the issuer and their cardholder and does not involve the merchant.
Enable Visa Installments
Add additional configuration to your hostedFields
configuration, comcarde.hostedFields.create
should be extended with a visaInstallments
object that contains an amount
and currencyCode
:
// Configure hostedFields
comcarde.hostedFields.create({
...
visaInstallments: {
amount: "10000", // example of the amount to be paid (in cents)
currencyCode: "USD" // example of transaction's currency
}
...
});
Tokenize your Customer's card
Installment Plans will only be returned for eligible VISA customers.
Use our hosted fields tokenize
functionality as you would normally. If the card is eligible you may receive an array of visaInstallmentPlans
in the response to calling hostedFieldsInstance.tokenize
.
Please get in contact with support for information on how to present Visa Installment plans to your customers.
Example array of visaInstallmentPlans
:
[
{
"planId": "3fa...a6",
"name": "Plan name",
"type": "ISSUER_PROMOTION",
"numberOfInstallments": 0,
"installmentFrequency": "WEEKLY",
"termsAndConditions": [
{
"url": "https://dev...sa.com/support",
"version": 0,
"text": "Sample terms and conditions text",
"languageCode": "eng"
}
],
"promotionInfo": {
"promotionCode": "A2",
"promotionID": "MBANK12"
},
"costInfo": {
"annualPercentageRate": 320,
"feeInfo": [
{
"type": "CONSUMER",
"ratePercentage": 150,
"flatFee": 1000
},
{
"type": "UPFRONT_FEES",
"ratePercentage": 150
}
],
"totalPlanCost": 61299,
"totalFees": 500,
"totalUpfrontFees": 100,
"totalRecurringFees": 20,
"firstInstallment": {
"installmentFee": 123112,
"amount": 123112,
"upfrontFee": 123112
},
"lastInstallment": {
"installmentFee": 123112,
"amount": 123112
},
"currency": "USD"
}
},
{
"planId": "f73676d0-999d-09b7-3581-1963c7c63d02",
"name": "TestX",
"type": "ISSUER_DEFAULT",
"numberOfInstallments": 3,
"installmentFrequency": "MONTHLY",
"termsAndConditions": [
{
"url": "",
"version": 6,
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"languageCode": "eng"
}
],
"promotionInfo": {
"promotionCode": "",
"promotionID": ""
},
"costInfo": {
"annualPercentageRate": 0,
"feeInfo": [
{
"type": "CONSUMER",
"ratePercentage": 0,
"flatFee": 0
},
{
"type": "CONSUMER_UPFRONT",
"ratePercentage": 200,
"flatFee": 0
}
],
"totalPlanCost": 12592,
"totalFees": 247,
"totalUpfrontFees": 247,
"totalRecurringFees": 0,
"firstInstallment": {
"installmentFee": 0,
"amount": 4115,
"upfrontFee": 247
},
"lastInstallment": {
"installmentFee": 0,
"amount": 4115
},
"currency": "USD"
}
}
]
For more information, please see the VisaInstallmentMatchedPlan schema in the BR-DGE REST API OpenAPI specification.
Tokenize Selected Installment Plan
Once the customer has selected and accepted the terms and conditions of an installment plan we then create a new token that can be used as by your server as a Payment Instrument in a payment request.
To do this we have extended hosted fields with a tokenizeVisPlan
function, this should be called with:
- The
token
from the original card tokenization - The selected
planId
- The
version
of thetermsAndConditions
that the customer has accepted
const token = '95ea954e-e02b-4275-a614-fe4ef55c510e' // Token from card tokenization
const planId = 'f73676d0-999d-09b7-3581-1963c7c63d02' // Visa Installment Plan ID
const termsAndConditionsVersionNumber = 6 // Version of accepted terms and conditions
hostedFieldsInstance.tokenizeVisPlan(
{ token, planId, termsAndConditionsVersionNumber },
function (tokenizeErr, tokenizePayload) {
if (tokenizeErr) {
throw tokenizeErr
}
// send tokenizePayload.token to your server to be used as a tokenized payment
// instrument in a payment request.
}
)
Updated about 1 month ago