Upfront Pay redefines affordability for your customers with financing that both incorporates and streamlines incentives.

Overview

Upfront Pay should be rendered on the checkout screen as a payment option. See an example UI on the demo site. On the demo, Upfront Pay is rendered in a radio button list of payment options, but it also would work as an individual button. Before you can use Upfront Pay, follow the Upfront.js init steps outlined in the Upfront.js Docs.

Step 1: Render Upfront Pay(<upfront-pay>)

Insert the Upfront Pay element into your payment options UI. See an example below of adding Upfront Pay into an existing payment radio button form:

...
<div id="upfront-pay-div">
  <input type="radio" id="upfront" name="paymentMethod" value="upfront">
  <label for="upfront">
    <upfront-pay id="upfront-pay-option"></upfront-pay>
  </label>
</div>
...

Step 2: Check if the cart is eligible for UpfrontPay

Upfront.js exposes a helper method isEligibleCart to determine if the products in the cart are eligible for UpfrontPay.

isEligibleCart accepts a list of objects containing item id and quantity.

upfrontjs.init('<merchant public key value>').then((upfrontHandler) => {
  upfrontHandler.isEligibleCart(
    [
      {"id": "PRODUCT_ID_1", "quantity": 1},
      {"id": "PRODUCT_ID_2", "quantity": 5},
    ],
  )
    .then(data => {
    if (!data.is_eligible) {
      // Example logic to hide the upfront pay option.
      document.getElementById('upfront-pay-div').style.display = 'none'
    }
  })
})

You can decide how to use isEligibleCart in your UI. For example, show/hide radio button or display an extra tab.

Step 3: Create checkoutID when a user places an order

When a user confirms their order, make a call to /create_checkout from your backend to generate a temporary checkout_id. Note: you need to complete checkout using this checkout_id within 1 day.

❗️

It's important to only call /create_checkout from your backend, because you need to pass your private api key! Never make that call from the frontend!

...
const cart = {
  products: [
    {"id": "PRODUCT_ID_1", "quantity": 1, "price": 10000},
    {"id": "PRODUCT_ID_2", "quantity": 5, "price": 2000},
  ],
  subtotal: 20000,
  shipping: 1000,
  tax: 2000,
  discount: 0,
  total: 23000,
  zip: 12345, // optional
}

// !!! THIS REQUEST SHOULD BE IN MERCHANT'S BACKEND ONLY !!!
return fetch("https://api.knowupfront.com/create_checkout", {
  method: "POST",
  headers: {
    "Content-Type": "application/json", // Specify content type as JSON
    "public-key": "<merchant public key value>",
    "x-private-key": "merchant private key value",  // NEVER EXPOSE YOUR PRIVATE KEYS IN FRONTEND
  },
  body: JSON.stringify({
    cart: cart,
  })
})
.then((res) => {
  if (res.status === 400) {
    throw new Error(res.error)
  }
  return res.json()
}).then((data) => {
  return data.checkout_id
})
...

Optional: Validate your cart amounts

Upfront.js has a helper method isValidCartAmount to help you validate amounts in your cart before making a backend call. It simply checks subtotal against sum of all product prices * quantities, then it checks that total is equal to sutotal with all fees / discounts.

...
const cart = {
  products: [
    {"id": "PRODUCT_ID_1", "quantity": 1, "price": 10000},
    {"id": "PRODUCT_ID_2", "quantity": 5, "price": 2000},
  ],
  subtotal: 20000,
  shipping: 1000,
  tax: 2000,
  discount: 0,
  total: 23000,
  zip: 12345, // optional
}
const isValid = upfrontHandler.isValidCartAmount(cart)
if (!isValid) {
  return onError({
    'message': 'Cart total does not add up. Please check your product prices and fees',
  })
}
...

Step 4: Open UpfrontPay modal using checkoutID

After making a call to your backend to generate checkoutID use openCheckout to open UpfrontPay modal.

// !!! THIS SHOULD BE A CALL TO MERCHANT'S BACKEND !!!
yourBackend.createCheckoutId(cart)
  .then((checkout_id) => {
  // Open UpfrontPay modal using generated checkoutID
  upfrontHandler.openCheckout(
    checkout_id,
    onCheckoutSuccess,
    onCheckoutError,
    onCheckoutExit,
  )
})

openCheckout accepts four parameters: checkoutId, onSuccess, onError, and onExit.

Parameter nameTypeDescription
checkoutIdstringUnique Id identifying this checkout generated by calling /create_checkout from your backend
onSuccessfunctionOn a successful Upfront checkout, this will be passed the loanId as a parameter.
onErrorfunctionOn a checkout error, this will be passed an error message string.
onExitfunctionOn exit of the checkout, this will be called and passed no parameters.

See examples below of implementing these callback parameters:

function onCheckoutSuccess(loanId) {
  const result = document.getElementById('result')
  result.textContent = loanId
}

function onCheckoutError(error) {
  const result = document.getElementById('result')
  result.textContent = "Error: " + error
}

function onCheckoutExit() {
  const result = document.getElementById('result')
  result.textContent = 'User pressed exit'
}

On most merchant checkout pages, the user selects their payment option and then clicks a button to finalize the payment. If the user has selected Upfront Pay as their payment option, this is where you will be launching the Upfront checkout:

function processCheckout() {
  var paymentMethod = document.querySelector('input[name="paymentMethod"]:checked').value;
  if (!paymentMethod) {
    return
  }
  // the user has selected Upfront Pay, use Upfront.js to launch checkout through Upfront
  if (paymentMethod === 'upfront') {
    // !!! THIS SHOULD BE A CALL TO MERCHANT'S BACKEND !!!
    yourBackend.createCheckoutId(cart)
      .then((checkout_id) => {
      // Open UpfrontPay modal using generated checkoutID
      upfrontHandler.openCheckout(
        checkout_id,
        onCheckoutSuccess,
        onCheckoutError,
        onCheckoutExit,
      )
    })
  }
}

Step 5: Finalize the checkout by calling /confirm_purchase

Once an Upfront checkout has been completed, you need to call our backend API /confirm_purchase using the loanId received in the onCheckoutSuccess callback. You'll also need to include a unique purchase ID from your side. Calling this endpoint marks the purchase as finalized.

function onCheckoutSuccess(loanId) {
  const result = document.getElementById('result')
  result.textContent = loanId
  
  // save the Upfront loanId to your DB
  // and call /confirm_purchase from your backend
  yourBackend.confirmUpfrontPurchase(loanId);
}

After receiving a success response from /confirm_purchase, you can redirect the user to your purchase confirmed screen.