Skip to main content

Custom Checkout Form

To build and set up a custom checkout form these general steps must be completed:

  1. Create a Lightning Web Component
  2. Add fields to the Checkout form HTML
  3. Load the JS library and the CSS file
  4. Build the configuration object

Create a Lightning Web Component

Create a component with basic and empty structure.

Add fields to the Checkout form HTML

All input fields are going to be dynamically generated by the Javascript Library in the LWC. For this, div tags decorated with lwc:dom="manual" and identified with data-id property will be needed in the HTML. These two properties are mandatory in each field for DOM manipulation purposes. Everything that follows, except the div tags with the two mandatory properties (label, other divs, etc.), is part of the customization:

force-app/main/default/lwc/customCheckoutExample/customCheckoutExample.html
<template>
<lightning-card>
<div class="slds-grid slds-gutters">
<div class="slds-m-around_large">

<!-- Billing Info Form Section -->
<div>
<p class="slds-text-heading_small slds-text-align_center">Enter your Billing Info</p>
<div class="slds-grid slds-gutters">
<div class="slds-col">
<label>Street Addres 1</label>
<div lwc:dom="manual" data-id="billingAddressLine"></div>
</div>
<div class="slds-col">
<label>Street Addres 2</label>
<div lwc:dom="manual" data-id="billingAddressLine2"></div>
</div>
</div>
<div class="slds-grid slds-gutters">
<div class="slds-col slds-size_1-of-2">
<label>City</label>
<div lwc:dom="manual" data-id="billingCity"></div>
</div>
<div class="slds-col slds-size_1-of-2">
<label>State</label>
<div lwc:dom="manual" data-id="billingState"></div>
</div>
</div>
<div class="slds-grid slds-gutters">
<div class="slds-col slds-size_1-of-2">
<label>Country</label>
<div lwc:dom="manual" data-id="billingCountry"></div>
</div>
<div class="slds-col slds-size_1-of-2">
<label>Email</label>
<div lwc:dom="manual" data-id="billingEmail"></div>
</div>
</div>
<div class="slds-grid slds-gutters">
<div class="slds-col">
<label>Zip</label>
<div lwc:dom="manual" data-id="billingZip"></div>
</div>
<div class="slds-col">
<label>Phone</label>
<div lwc:dom="manual" data-id="billingPhone"></div>
</div>
</div>
</div>

<hr/>
<!-- Credit Card Form Section -->
<div data-id="card-form">
<p class="slds-text-heading_small slds-text-align_center">Enter your Card Info</p>
<div class="slds-grid">
<div class="slds-col">
<div lwc:dom="manual" data-id="cardTypeImg"></div>
<label>Card Name</label>
<div lwc:dom="manual" data-id="nameOnCard"></div>
</div>
</div>
<div class="slds-grid slds-gutters">
<div class="slds-col slds-size_1-of-2 slds-m-left_small">
<label>Credit / Debit Card Number</label>
<div lwc:dom="manual" data-id="cardNumber"></div>
</div>
<div class="slds-col slds-m-right_small">
<div class="slds-grid slds-gutters">
<div class="slds-col">
<label>Expiration</label>
<div lwc:dom="manual" data-id="cardExp"></div>
</div>
<div class="slds-col">
<label>CVC</label>
<div lwc:dom="manual" data-id="cardCVC"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</lightning-card>
</template>

These are the available Billing info fields that, if provided, will be display by the library:

data-idDefinitionInput Type
countryCaptures the billing country informationpicklist
stateCaptures the billing state informationpicklist
zipHolds the billing zip code informationtel
cityCaptures the billing city informationtext
addressLineCaptures the main billing addresstext
addressLine2Captures the second billing addresstext
emailCaptures the billing emailtext
phoneCaptures the billing phonetel

These are the available Credit Card fields that, if provided, will be display by the library:

data-idDefinitionInput Type
nameOnCardCaptures the name on the credit cardtext
cardNumberCaptures the credit card numbertext
cardExpCaptures the expiration date of the credit cardtext
cardCVCCaptures the CVV/CVC codepassword

These are the available Bank Account fields that, if provided, will be display by the library

data-idDefinitionInput Type
nameOnAccountCaptures the name on accounttext
accountNumberCaptures the bank account numbertext
accountNumber2Captures Second field that captures the bank account number (for confirmation purposes)text
routingNumberCaptures the bank routing numbertext
bankNameHolds the name of the bank associated with the transaction.text
bankAccountTypeCaptures the type of bank account used. (Checking, Savings or Business Checking)picklist

NOTE: All the data-id properties must have the exact values indicated in the tables above.

Load the JS library and the CSS file

force-app/main/default/lwc/customCheckoutExample/customCheckoutExample.js
import customCheckout from "@salesforce/resourceUrl/ChargentCustomCheckout";
import { loadStyle, loadScript } from 'lightning/platformResourceLoader';

export default class CustomCheckoutExample extends LightningElement {

connectedCallback() {
Promise.all([
loadStyle(this, customCheckout + "/v1/css/chargentPayform.css"),
loadScript(this, customCheckout + "/v1/js/chargentCustomCheckout.js")
])
.then(() => {
chargentFields.createPayform(
// Initialize the Library with the Configuration Object.
);
});
}
}

The method to initialize and configure the Chargent JS Library is chargentFields.createPayform(ConfigurationObjectHere). This method receives a json which have all the information the library needs to render the input fields in the DOM. Also note that the javascript library will be located in the ChargentCustomCheckout static resources folder.

Build the configuration object

The library needs a Configuration Object to make it work. The configuration object has inside a hierarchy of fields divided in 4 essential parts:

  • cardformFields
  • bankFields
  • billingFields
  • currencyField

This is the general structure of the configuration object:

{
assets: appFrontier_AssetsResource,
cardTypes: ["visa", "mastercard"],
paymentMethods: ["Credit Card", "Bank Account"],
cardformFields: {...},
bankFields: {...},
billingFields: {...},
currencyField: {...},
}

Each of this hierarchy fields has similar structure and parameters. Next, the main 4 sections of the Configuration Object will be detailed.

cardformFields

All the configuration of the credit card input fields goes here:

cardformFields: {
nameOnCard: {
selector: this.template.querySelector('[data-id="nameOnCard"]'),
placeholder: 'Name as it appears on your card',
value: 'Juan Alcantara',
size: 25,
class: "slds-input",
requiredMessage: "This field cannot be empty",
required: true,
disablePaste: false,
},
cardNumber: {
selector: this.template.querySelector('[data-id="cardNumber"]'),
placeholder: '{{cardNumberPlaceHolder}}',
class: "slds-input",
requiredMessage: "This field cannot be empty",
required: true,
img: { selector: this.template.querySelector('[data-id="cardTypeImg"]'), default: appFrontier_AssetsResource +"/svg/no_image.png", class:"slds-img"},
style: {success : "slds-success", error: "slds-has-error"}
},
cardExp: {
selector: this.template.querySelector('[data-id="cardExp"]'),
placeholder: 'MM / YY',
class: "slds-input",
requiredMessage: "This field cannot be empty",
required: true,
disablePaste: false,
style: {success : "slds-success", error: "slds-has-error"}
},
cardCVC: {
selector: this.template.querySelector('[data-id="cardCVC"]'),
placeholder: '{{cvcPlaceHolder}}',
class: "slds-input",
requiredMessage: "This field cannot be empty",
required: true,
disablePaste: false
},
nameOnAccount: {
selector: this.template.querySelector('[data-id="nameOnAccount"]'),
placeholder: 'Name on Account',
size: 25,
class: "slds-input",
requiredMessage: "This field cannot be empty",
required: true,
disablePaste: false,
},
}
ParameterDescription
selectorThis parameter is needed for the library to locate in which part of the HTML DOM the field will be rendered.
placeholderThis value is used if the customer wants the field to have a placeholder value.
classThis value is used to add the specified name class to the input for styling purposes.
requiredThis value is used to validate the field completion.
requiredMessageThis value is used to replace the Error Label when a field is empty. If no value is passed, the default message will be: "Complete this field."
valueThis value will be used to prepopulate the Input Information with the designated value
styleThis value is used to add classes for success or error validations on the input fields.
imgThis parameter controls the display of the Credit Card image. You can change the default image value.
sizeThe maximum input character count on the input field.
disablePasteWhen present, it indicates that it cannot be pasted in the field.

bankFields

All the configuration of the bank account input fields goes here:

bankFields: {
nameOnAccount: {
selector: this.template.querySelector('[data-id="nameOnAccount"]'),
placeholder: 'Name on Account',
class: "slds-input",
required: true,
style: {success : "slds-success", error: "slds-has-error"}
},
accountNumber: {
selector: this.template.querySelector('[data-id="accountNumber"]'),
placeholder: 'Account Number',
class: "slds-input",
required: true,
style: {success : "slds-success", error: "slds-has-error"}
},
accountNumber2: {
selector: this.template.querySelector('[data-id="accountNumber"]'),
placeholder: 'Re-enter Account Number',
class: "slds-input",
required: true,
style: {success : "slds-success", error: "slds-has-error"}
},
routingNumber: {
selector: this.template.querySelector('[data-id="routingNumber"]'),
placeholder: 'Routing Number',
class: "slds-input",
required: true,
style: {success : "slds-success", error: "slds-has-error"}
},
bankName: {
selector: this.template.querySelector('[data-id="bankName"]'),
placeholder: 'Bank Name',
class: "slds-input",
required: true,
},
bankAccountType: {
selector: this.template.querySelector('[data-id="bankAccountType"]'),
placeholder: 'Bank Type',
class: "slds-input",
required: true,
disablePaste: false
}
}
ParameterDescription
selectorThis parameter is needed for the library to locate in which part of the HTML DOM the field will be rendered.
placeholderThis value is used if the customer wants the field to have a placeholder value.
classThis value is used to add the specified name class to the input for styling purposes.
requiredThis value is used to validate the field completion.
requiredMessageThis value is used to replace the Error Label when a field is empty. If no value is passed, the default message will be: "Complete this field."
valueThis value will be used to prepopulate the Input Information with the designated value
styleThis value is used to add classes for success or error validations on the input fields.
imgThis parameter controls the display of the Credit Card image. You can change the default image value.
sizeThe maximum input character count on the input field.
disablePasteWhen present, it indicates that it cannot be pasted in the field.

billingFields

All the configuration of the billing input fields goes here:

billingFields: {
addressLine: {
selector: this.template.querySelector('[data-id="billingAddressLine"]'),
placeholder: 'Enter Your Address',
size: 50,
value: 'Main Street',
class: "slds-input",
requiredMessage: "Use your home address here.",
required: true,
readOnly: true
},
addressLine2: {
selector: this.template.querySelector('[data-id="billingAddressLine2"]'),
placeholder: 'Enter Your Address 2',
size: 50,
value: 'Second Street',
class: "slds-input",
},
city: {
selector: this.template.querySelector('[data-id="billingCity"]'),
placeholder: 'Enter Your City',
size: 20,
value: 'Miami',
class: "slds-input",
required: true
},
state: {
selector: this.template.querySelector('[data-id="billingState"]'),
class: "slds-input",
required: true
},
zip: {
selector: this.template.querySelector('[data-id="billingZip"]'),
placeholder: 'Enter Your Zip Code',
size: 5,
class: "slds-input",
value: '12345',
required: true
},
country: {
selector: this.template.querySelector('[data-id="billingCountry"]'),
placeholder: 'Enter Your Country',
size: 5,
value: '',
class: "slds-input",
required: true
},
email: {
selector: this.template.querySelector('[data-id="billingEmail"]'),
placeholder: 'Enter Your Email',
size: 5,
value: '[email protected]',
class: "slds-input",
required: true
},
phone: {
selector: this.template.querySelector('[data-id="billingPhone"]'),
placeholder: 'Enter Your Phone Number',
size: 5,
value: '9955559965',
class: "slds-input",
required: true,

},
}
ParameterDescription
selectorThis parameter is needed for the library to locate in which part of the HTML DOM the field will be rendered.
placeholderThis value is used if the customer wants the field to have a placeholder value.
classThis value is used to add the specified name class to the input for styling purposes.
valueThis value will be used to prepopulate the Input Information with the designated value.
requiredThis value is used to validate the field completion.
styleThis value is used to add classes for success or error validations on the input fields.
sizeThe maximum input character on the input field.
requiredMessageThis value is used to replace the Error Label when a field is empty. If no value is passed, the default message will be: "Complete this field."
disablePasteWhen present it indicates if it cannot be pasted in the field
readOnlyWhen the field has this property is not editable

currencyField

All the configuration of the currency input field goes here:

currencyField: {
selector: this.template.querySelector('[data-id="amount"]'),
decimal: 2,
value: 33,
placeholder: '$0.00',
class: "slds-input",
currency: "USD",
required: true
}
NameDescription
selectorThis parameter is needed for the library to locate in which part of the HTML DOM the field will be rendered.
decimalThis value is used to format the amount to a fixed position.
valueThis is the default charge amount value (must be an integer).
placeholderThis value is used if the customer wants the field to have a placeholder value.
classThis value is used to add the specified name class to the input for styling purposes.
currencyThis value will be used to format the amount to a currency (USD for this release).
requiredThis value is used to validate the field completion.

Every selector must match with the corresponding data-id used in the HTML.

Even though these steps are only related to the Javascript Library, the implementation of the scaComponent (LWC) component will also be necessary to be able to perform any payment operation. (see following pages).