Launch the Checkout UI

After loading the SDK, you may use it to launch the checkout UI, using the ChargeAfter.checkout.present function.

UI Configuration

To ensure a seamless customer experience, you will need to provide the customer and cart information in a JSON format to launch the checkout UI. An example can be found below:

// 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: "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
    },

    // 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
    callback: function(token, data, error) {
      
    },
  
    // Available values: E_COMMERCE / IN_STORE / CALL_CENTER
    channel: "E_COMMERCE",
  
    // This object is OPTIONAL
    preferences: { 
      language: 'En',
      country: 'US'
    },
  
    // 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. This is used in the managed flow only.
    // managed: {
   	//	 token: 'XXXX-XXXX-XXXX-XXXX'
    // }
  
  	// This parameter is OPTIONAL. This is used to load the Checkout UI directly to a specific lender
    // lenderId : XXXXXXXXX,
});
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
    channel: "E_COMMERCE",
  
    // This object is OPTIONAL
    preferences: { 
      language: 'En' 
    },
  
    // 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 object is OPTIONAL. This is used in the managed flow only.
    // managed: {
   	//	 token: 'XXXX-XXXX-XXXX-XXXX'
    // }
  
  	// This parameter is OPTIONAL. This is used to load the Checkout UI directly to a specific lender
    // lenderId : XXXXXXXXX,
});


🚧

In order to avoid any impact to the performance of your website, the script is loaded asynchronously. This means that the ChargeAfter.checkout.present() function might not be available immediately after document load.

The ConsumerDetails Object (1)

It is recommended to provide all the available customer information when launching the 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 (see below).

The following details can and should be provided:

NameTypeDescription
firstNamestringConsumer first name. For example: "John"
lastNamestringConsumer last name. For example: "Doe"
emailstringConsumer email. Should be a valid email format. For example: "[email protected]"
mobilePhoneNumberstringConsumer phone number. For example: "2124454545"
merchantConsumerIdstringThe merchant identifier for the consumer
shippingAddressobjectThe shipping address object. See more info in Address object.
billingAddressobjectThe billing address object. See more info in Address object.

Address object:

NameTypeDescription
line1stringAddress line 1
line2stringAddress line 2
citystringCity name. For example: "New York" (US) or “Edmonton” (CA)
zipCodestringZipCode / Postal Code. For example: "10019"/ “A1A 1A1”
statestringState/Province. The value to be set is either 2 character state code or State/Province name. For example: "New York"/“Alberta”

🚧

Billing and Shipping address

As an anti-fraud measure, billingAddress and shippingAddress (if provided) must be the same, otherwise the checkout will not work. If the order is an in-store pickup, please provide only the billing address.

The cartDetails Object (2)

Cart Details is an array that contains various elements of the cart:

NameTypeRequired/Optional, Format
itemsarrayRequired
discountsarrayOptional
merchantOrderIdstringOptional
taxAmountnumberRequired
shippingAmountnumberRequired
totalAmountnumberRequired

Items is an array that contains the details of every item in the cart:

NameTypeRequired/Optional, Format
namestringRequired
pricenumberRequired
skustringRequired
quantitynumberRequired, integer
leasablebooleanTrue if the specific item is leasable.
False or undefined if not.
If an item is not leasable, some leasing options will not be available to pay for the order
productCategorystringProduct category or full taxonomy path
warrantyobjectOptional (see Warranty section below)

Discounts

The discounts field is an optional array that consists of one or more of applied discounts:

NameTypeRequired/Optional
namestringRequired
amountnumberRequired

Warranty

Optionally nested within each item object, is the warranty object. If added, then all fields below are required as shown:

NameTypeRequired/Optional
namestringRequired
pricenumberRequired
skustringRequired

Additional Information

The following fields provide additional checkout information:

NameTypeRequired/Optional
merchantOrderIdstringOptional
totalAmountnumberRequired
taxAmountnumberRequired
shippingAmountnumberRequired

All items from your website's cart must be included in the cartDetails portion of the code and must be equal to the total amount of the cart. This may include warranty, discounts, fees (recycling, installation, delivery, etc.)

🚧

Amount/price fields are restricted to present up to 2 decimal places. In cases where a number has more than 2 decimal places, ChargeAfter will automatically round it up to the nearest whole cent.

Currency for these fields is determined by merchant country.

🚧

The totalAmount field represents the bottom line for this checkout, after adding tax and shipping cost, and subtracting any discounts.

The OnDataUpdate Callback (3)

  • In the onDataUpdate field you are asked to provide a function that will be called whenever any consumer information is updated during the checkout flow.

The process works as follows:
Consumer makes changes to their personal information such as their shipping address state in the ChargeAfter modal, ChargeAfter sends the merchant the updated consumer information in the updatedData object, the merchant then sends ChargeAfter a callback with the updated shippingAmount (optional), taxAmount (optional), and totalAmount (optional)

The callback function will send the following arguments:

updatedData

An object that is very similar to the options object that is provided initially in the ChargeAfter.checkout.present(opt) call. It contains the updated checkout details, and it is composed of the following fields (see the full object above for further details):

NameRequirement
totalAmountRequired
taxAmountRequired
shippingAmountRequired
itemsRequired
consumerDetailsRequired
discountsRequired

callback

Once the data passed back to the merchant using this callback has been processed, the merchant should return the refreshed information including any changes back to ChargeAfter.

The "onDataUpdate" function can return a value. However, if you choose not to return a value, you would need to call the provided "callback" function later on to pass the updated information back to ChargeAfter.

The data update should have the following structure:

NameRequirement
shippingAmountOptional
taxAmountOptional
totalAmountOptional

Examples
If you want to update the shipping and tax amount depending on the entered ZIP code, the function can be implemented like this:

function(updatedData, callback) {
      var zipCode = updatedData.consumerDetails.billingAddress.zipCode;
      if (zipCode) {

          // ... call backend to calculate updated shipping and tax amount,
          // and invoke callback with result

          callback({
              taxAmount: CALCULATED_TAX_AMOUNT,
              shippingAmount: CALCULATED_SHIPPING_AMOUNT,
              totalAmount: UPDATED_TOTAL_AMOUNT
          });
      } else {
          // nothing to update, so just invoke callback with no parameters
          callback();

          // alternatively (see next paragraph), just return an empty object
          // return {};
      }

      // no need to return, as we're invoking the callback above
  }
  • Alternatively, this function may return a value immediately. In this case, there’s no need to call the callback function. If no value is returned (like in the example above), then the callback function is expected to be invoked.
    For example, if the updated checkout details are available on the spot, 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 {};
      }
  }

🚧

Do not forget to either immediately return an object from the onDataUpdate function, or invoke the callback function. The merchant’s website response is a condition for moving forward with the checkout flow.

📘

Remember to pass the correct types in the callback. For example, amount fields (like totalAmount) are typically numbers, and not strings (i.e. 45.9 rather than “45.9”).

The Completion Callback (4)

  • The callback will be invoked upon checkout flow completion. The callback should accept 3 arguments function callback(token, data, error)
    • token - a confirmation token that can be used to commit a charge. This parameter will be null if the user was not able to checkout successfully (in case of a decline or error)
    • data - information that was collected before and during the checkout flow. This object contains the following fields:
NameTypeDescription
consumerDetailsobjectNon-sensitive consumer details that were entered during the checkout flow - use this information to process the order in the merchant’s systems.
lenderobjectThe lender that is behind the selected financing option, as detailed below
totalAmountnumber
taxAmountnumber
shippingAmountnumber

The Lender Object

NameTypeDescription
idstringThe lender’s unique identifier in the ChargeAfter system
namestringThe lender’s name
  • error - an error object containing details about the failure. This parameter will be 'undefined' in case of a successful checkout flow. The object type will be:
{
    "code": "Error code",
    "message": "Human readable description of the error"
}

Error codes:

CodeDescription
BACK_TO_STOREConsumer clicked the “Back to Store” button
CONSUMER_CANCELLEDConsumer intentionally closed the Checkout UI
CREATE_CHECKOUT_FAILEDCheckout creation or merchant settings fetch failed
BILLING_SHIPPING_MISMATCHBilling and shipping address must be the same
GENERALSome general error occurred (message should provide more information)

Channel(5)

The channelobject is an optional parameter that indicates where the merchant initiated the flow (E_COMMERCE / IN_STORE / CALL_CENTER)

Preferences (6)

The preferences object is optional, and has the following fields:

  1. Language - to specify the language in which the Checkout UI will be launched. The is an optional filed of String type. The expected value should consist of two letters representing the language. The default value is En and other languages currently supported are:
  • English - En
  • French - Fr
  1. Currency - to specify currencies in fields and variables. The is an optional filed of String type, followed by the ISO 4217 code. ChargeAfter provides the multi-currency functionality, which allows merchants to accept payments in a variety of currencies for the buyer's and merchant's convenience. The default value is USD.
  2. Country - to specify countries and regions supported by ChargeAfter in fields and variables. The is an optional filed of String type, followed by the ISO-3166 country codes. The default value is US.

What’s Next