Launching the Checkout Experience
How to create a customer/consumer and cart prior to creating a charge.
After loading the SDK, you can launch the Checkout UI with the ChargeAfter.payments.present('checkout', opt)
function.
Script Loading
To avoid any impact to the performance of your website, the script is loaded asynchronously. This means that the ChargeAfter.payments.present('checkout', opt) function might not be available immediately after script load.
You must provide the customer information (via the consumerDetails
object) and cart information (via the cartDetails
object) in a JSON format. Jump to the code sample .
consumerDetails Object
It is recommended to provide all the available customer information when launching the ChargeAfter Checkout UI.
Depending on the specific financial products used, the consumerDetails
object can be optional or required. If any of the consumer details are not provided when launching the Checkout UI, ChargeAfter will collect it from the consumer and inform the merchant via the onDataUpdate
callback.
The consumerDetails
object contains the following fields:
Name | Type | Description | Required/Optional | Validations |
---|---|---|---|---|
firstName | string | Consumer first name. For example: "John" | Required, except when onDataUpdate function is used. | All letters, spaces and hyphens. |
lastName | string | Consumer last name. For example: "Doe" | Required, except when onDataUpdate function is used. | All letters, spaces and hyphens. |
string | Consumer email. Should be a valid email format. For example: "[email protected]" | Required, except when onDataUpdate function is used. | All letters, hyphens, numbers, symbols, of periods. | |
mobilePhoneNumber | string | Consumer phone number. For example: "2124454545" | Required, except when onDataUpdate function is used. | Numbers. No spaces, periods, or symbols are allowed. |
merchantConsumerId | string | The merchant identifier for the consumer. | Required, except when onDataUpdate function is used. | |
shippingAddress | object | The shipping address object. See address Object. | Required, except when onDataUpdate function is used. | See address Object. |
billingAddress | object | The billing address object. See address Object. | Required, except when onDataUpdate function is used. | See address Object. |
shippingAddress and billingAddress Objects
Name | Type | Description | Required/Optional | Validations |
---|---|---|---|---|
line1 | string | Address line 1 | Required | All letters, spaces, numbers, hyphen, hash symbol (#) and periods. |
line2 | string | Address line 2 | Optional | All letters, spaces, numbers, hyphen, hash symbol (#) and periods. |
city | string | City name. For example: "New York" (US) or “Edmonton” (CA) | Required | All letters, spaces, numbers and hyphens. |
zipCode | string | ZipCode / Postal Code. For example: "10019" or "10019-1232" / “A1A 1A1” | Required | |
state | string | State/Province. The value to be set is either 2 character state code or State/Province name. For example: "NY" or "New York"/“Alberta” | Required |
Billing and Shipping Address
As an anti-fraud measure, billingAddress and shippingAddress (if provided) must be the same, otherwise, the checkout will not work.
In-store Pickups
If the response object to the onDataUpdate callback is provided and the order is an in-store pickup, then provide only the billing address.
cartDetails Object
cartDetails
is an array that contains various elements of the cart:
Name | Type | Required/Optional |
---|---|---|
items | array | Required |
discounts | array | Optional |
merchantOrderId | string | Optional |
taxAmount | number | Required |
shippingAmount | number | Required |
totalAmount | number | Required |
items Object
items
is an array that contains the details of every item in the cart:
Name | Type | Required/Optional |
---|---|---|
name | string | Required |
price | number | Required |
sku | string | Required |
quantity | number | Required, integer |
leasable | boolean | True if the specific item is leasable. False or undefined if not leasable. If an item is not leasable, some leasing options will not be available to pay for the order. |
productCategory | string | Product category or full taxonomy path |
warranty | object | Optional (See warranty Object.) |
Code Sample
f// Present the checkout modal box and pass it an options object
ChargeAfter.checkout.present({
// Consumer information
consumerDetails: {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
mobilePhoneNumber: "2124454545",
merchantConsumerId: "<consumer-id-by-merchant>",
shippingAddress: {
line1: "3 My Street",
line2: "My Building, 4th floor",
city: "New York",
zipCode: "10019",
state: "NY",
},
billingAddress: {
line1: "3 My Street",
line2: "My Building, 4th floor",
city: "New York",
zipCode: "10019",
state: "NY",
}
},
// Cart information
cartDetails: {
items: [{
name: "Awesome Product",
price: 1999.0,
sku: "AWSMPRDCT",
quantity: 2,
leasable: true,
productCategory: "Product category",
warranty: {
name: "Awesome Warranty",
price: 100.0,
sku: "AWSMWRNTY"
}
}],
discounts: [{
name: "Birthday discount",
amount: 20
}],
merchantOrderId: "<order-id-by-merchant>", // OPTIONAL. Passed to interested lenders
taxAmount: 199.0,
shippingAmount: 19.0,
totalAmount: 4296.0
},
// This callback allows you to process the result of customers data update
onDataUpdate: function(updatedData, callback) {
callback({
taxAmount: CALCULATED_TAX_AMOUNT,
shippingAmount: CALCULATED_SHIPPING_AMOUNT,
totalAmount: UPDATED_TOTAL_AMOUNT
});
},
// This callback allows you to process the result of the checkout process
// if onComplete function is provided on sdk init, both will fire
callback: function(token, data, status) {
},
// Available values: E_COMMERCE / IN_STORE / CALL_CENTER / IN_HOME
channel: "E_COMMERCE",
// This string is OPTIONAL. Will continue the prequalification to checkout.
sessionToken: "<id received from apply (prequalify)>",
// This object is OPTIONAL
filter: {
creditTiers: ["SubPrime"], //possible value Prime, NearPrime, SubPrime
}
// optional string-string/number/Boolean/Date map
// tags: {property: 'value'}
// This parameter is OPTIONAL. This is used to load the Checkout UI directly to a specific lender
// lenderId : XXXXXXXXX,
// This parameter is OPTIONAL. Used to specify an existing HTML container to contain the checkout
// UI
// containerSelector: '#container-id'
// This parameter is OPTIONAL. Used to specify the promo code that will be used for checkout
// experience.
// promoCode: 'ASDAASD'
});
import { prequalify, checkout } from "@chargeafter/payment-sdk";
await checkout({
config: {
env: {
name?: "production" | "sandbox", // defaults to "production"
apiKey: "<your api key>",
}
},
// This callback allows you to process the result of customers data update
onDataUpdate: async (updatedData, callback) => {
// process updated data and trigger callback with updated cart amount
// see "OnDataUpdate" section below.
callback({
taxAmount: CALCULATED_TAX_AMOUNT,
shippingAmount: CALCULATED_SHIPPING_AMOUNT,
totalAmount: UPDATED_TOTAL_AMOUNT
});
},
// Consumer information
consumerDetails: {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
mobilePhoneNumber: "2124454545",
merchantConsumerId: "merchant-internal-consumer-id",
shippingAddress: {
line1: "3 My Street",
line2: "My Building, 4th floor",
city: "New York",
zipCode: "10019",
state: "NY",
},
billingAddress: {
line1: "3 My Street",
line2: "My Building, 4th floor",
city: "New York",
zipCode: "10019",
state: "NY",
}
},
// Cart information
cartDetails: {
items: [
{
name: "Awesome Product",
price: 1999.0,
sku: "AWSMPRDCT",
quantity: 2,
leasable: true,
productCategory: "Product category",
warranty: {
name: "Awesome Warranty",
price: 100.0,
sku: "AWSMWRNTY"
}
}
],
discounts: [
{
name: "Birthday discount",
amount: 20
}
],
merchantOrderId: "<order id>", // OPTIONAL. Passed to interested lenders
taxAmount: 199.0,
shippingAmount: 19.0,
totalAmount: 4296.0
},
// Available values: E_COMMERCE / IN_STORE / CALL_CENTER / IN_HOME
channel: "E_COMMERCE",
// This object is OPTIONAL
currency : "USD",
// This string is OPTIONAL. Will continue the prequalification to checkout.
applicationId : "<id received from apply (prequalify)>",
// This object is OPTIONAL
// appSettings: {
// containerSelector: "#my-container-selector",
// },
// This parameter is OPTIONAL. This is used to load the Checkout UI directly to a specific lender
// lenderId : XXXXXXXXX,
});
Optional Fields
discounts Object
The discounts
object is an optional array that consists of one or more applied discounts:
Name | Type | Required/Optional |
---|---|---|
name | string | Required |
amount | number | Required |
warranty Object
Optionally nested within each item
object, is the warranty
object. If added, then all fields below are required as shown:
Name | Type | Required/Optional |
---|---|---|
name | string | Required |
price | number | Required |
sku | string | Required |
channel Object
The channel
object is an optional parameter that indicates from where the merchant initiated the flow.
Possible values:
E_COMMERCE
IN_STORE
CALL_CENTER
IN_HOME
Formatting channel Object Values
The values must be entered exactly as above in all uppercase letters.
preferences Object
The preferences
object is optional, and has the following fields:
Name | Type | Description | Required/Optional |
---|---|---|---|
language | string | Specifies the language in which the Checkout UI will be launched. The value consists of two letters representing the language. Default value: En Other languages: Fr | Optional |
currency | string | Specifies currencies in fields and variables. Default value: USD Other values: CAD , AUD | Optional |
country | string | Specifies countries and regions supported by ChargeAfter in fields and variables. Default value: US Other values: CA , AU | Optional |
totalAmount Object
All items from your website's cart must be included in the cartDetails
and must be equal to the total amount of the cart. This may include warranty, discounts, and fees (recycling, installation, delivery, etc.). The totalAmount
field represents the bottom line for this checkout, after adding tax and shipping cost and subtracting any discounts.
Currency for these fields is determined by merchant country or configuration.
Amount/price fields are restricted to present up to two decimal places. In cases where a number has more than two decimal places, ChargeAfter will automatically round it up to the nearest whole cent.
Formatting Amounts
Remember to pass the correct data types. For example, amount fields (like
totalAmount
) are typically numbers, and not strings (i.e. 45.9 rather than “45.9”).
onDataUpdate function
If cart information is changed during the checkout flow, such as adjustments for shipping or discounts, the onDataUpdate
function is invoked.
The onDataUpdate
function can be invoked in three ways:
- Synchronously
- Asynchronously with
await
- Asynchronously with
promise
Synchronous onDataUpdate function
If the consumer makes changes to their personal information, such as their shipping address state in the ChargeAfter modal, then:
- ChargeAfter sends the updated details in the updatedData object to the merchant.
- The merchant calculates the new cart, which triggers and returns an object response in the
onDataUpdate
function.
Synchronous Code Samples
If the onDataUpdate
function returns a value immediately, there’s no need to use the callback function. For example, if the updated checkout details are available immediately, then simply return it:
function(updatedData, callback) {
var zipCode = updatedData.consumerDetails.billingAddress.zipCode;
if (zipCode) {
// calculate updated shipping and tax amount and return it
return {
taxAmount: CALCULATED_TAX_AMOUNT,
shippingAmount: CALCULATED_SHIPPING_AMOUNT,
totalAmount: UPDATED_TOTAL_AMOUNT
};
} else {
// nothing to update, but making sure to return an object
return {};
}
}
This code sample demonstrates a common use case of the automatic application of California state sales tax:
// synchronized function
function onDataUpdate(updatedData, callback) {
var taxAmount = 10;
if (updatedData.consumerDetails.billingAddress.state === 'CA') {
taxAmount = 15;
}
return {
taxAmount,
shippingAmount: 0,
totalAmount: 215, <- Should be totalAmount that includes the new tax e.g if all items sum to $200, then totalAmount should be $215.
};
}
Asynchronous onDataUpdate function with await
In Step 2 above , if you do not immediately return a value via the object response in the onDataUpdate
function, the callback
argument will be triggered to pass the updated information to ChargeAfter.
Asynchronous Code Sample with await
This code sample demonstrates how you can use await
to fetch additional information before returning an object response in the OnDataUpdate
function:
// this is async await function
async function onDataUpdate(updatedData, callback) {
return await fetch('some url');
}
Asynchronous onDataUpdate function with promise
In Step 2 above , if you do not immediately return a value via the object response in the onDataUpdate
function, the callback
argument will be triggered to pass the updated information to ChargeAfter.
The promise
function can also be used to fetch additional information before returning an object response in the OnDataUpdate
function.
Code Sample with promise
// this is promise function
function onDataUpdate(updatedData, callback) {
return new Promise((resolve, reject) => {});
}
updatedData Object
The updatedData
object is very similar to the cartDetails
object that is provided initially in the ChargeAfter.checkout.present()
function. It contains the updated checkout details and is composed of the following fields:
Name | Type |
---|---|
totalAmount | Number |
taxAmount | Number |
shippingAmount | Number |
items | Array |
consumerDetails | Object |
discounts | Array |
Object Response in the onDataUpdate function
The object returned in the onDataUpdate
function has the following structure:
Name | Required/Optional |
---|---|
shippingAmount | Required |
taxAmount | Required |
totalAmount | Required |
Continuing in the Checkout Flow
Do not forget to either immediately return an object in the onDataUpdate function or invoke the callback function. The merchant’s website response is a condition for moving forward in the Checkout flow.
Enabling inline mode
If you prefer to bypass the launching of the ChargeAfter modal so that the consumer experiences all ChargeAfter functionality within your own website, you must enable inline mode.
To enable inline mode, you must specify the containerSelector
property in the present function. The value passed should be a valid HTML selector as specified by W3C.
ChargeAfter.payments.present('checkout/apply',{
// …,
containerSelector:"some container selector", // can be also the dom element
})
Updated 16 days ago