Loan Approval & Checkout (Ecomm)

At this point in the Application Process a customer has been approved for a loan. This page walks through the remaining steps to finish out a loan application. To use complete the steps on this page, you should still have the Koalafi orderId for the app in progress as well as the loan applicationId and loan options returned from the apply mutation.

1. Update Order Items

If a customer has had the chance to update their cart since their initial loan approval you need to call updateOrderItems before checkout to sync the Koalafi cart with the customer’s. Please note it is not necessary to call updateOrderItems after every cart change as we only need the final cart they have at checkout. For example, our e-commerce plugins call updateOrderItems before they open our modal on the checkout page. This ensures that the customer's cart and the Koalafi cart are always in sync.

An example of mutation for updateOrderItems looks something like:

mutation updateOrderItems($input: UpdateOrderItemsInput! ) {
  updateOrderItems(input: $input) {
    order {
      id
      details{
        items{
          price
        }
      }
    }
    orderErrors{
      __typename
      ... on CartValidation {
        message
        extensions {
          validationErrType
          approvalType
          approvedAmount
        }
      }
      ... on BadRequest{
        message
      }
      ... on CartMinNotMet{
        message
      }
    }  
  } 
}

For this response, the most important thing to check is orderErrors as any error needs to be addressed before the customer can continue with their application. We have broken down the different possible errors for this mutation and recommended resolution in our Handling Common Errors page.

Discount Codes / Coupons

Some retailers will offer discount codes or coupons at checkout. In order to make sure the Koalafi contract amount matches the discounted price from the merchant, you will need to apply the coupon/discount to the items' prices before calling updateOrderItems. Before calling this mutation, you need to make sure that the cart total you are sending matches the discounted cart total on the site and that each item's price is formatted to have 2 decimal places and is greater than $0.00. If their cart contains multiple items, the price you send for each item should match what's shown on the e-comm site.

2. Select Loan Option Type

Customers can be approved for multiple loan products. The different loan products are returned from apply as objects in the list of options. You will need to use selectLoanOptionType to designate which loan product the customer will be using. Depending on the merchant configuration, one or many loan products can be returned.

If only one loan product option is returned, then you can pass the productId for that option into selectLoanOptionType. However, if more than one option is returned then you should present the options to the customer and let them choose which loan option they would like.

Presenting Loan Options

At present, most of our merchants only offer one loan product but as they continue to grow, it's possible they will start to offer multiple loan products. As a reminder, the option information returned from apply looks like

{ "options": [
    {
        "productID": 7,
        "deferredInterestPeriod": 3,
        "lineAmount": 10000,
        "minimumSpend": 300,
        "rate": "32.99",
        "termLength": 24
    }
  ]
}

If multiple options are returned, we want to display the different loan products to the customer in a way that makes it easy for them to understand and choose their best option. The fields that are most helpful to present to the customer are as follows:

  • deferredInterestPeriod which is the number of months in which the customer has to repay the loan interest free. If that number is greater than 0 we recommend spotlighting this when showing the repayment options
  • lineAmount represents the total amount the customer was approved for
  • rate represents the APR the customer was approved for
  • termLength which represents the length of the loan in months

Please reach out to us if you would like guidance on how to display the different loan options to the customer.

Selecting the Loan Option

Once you know the loan product, you can use the selectLoanOptionType mutation to select the loan product within the Koalafi system. The input for this mutation looks like the following, where orderId is the same orderId you've been using for the application and productId is the productId of the option selected.

{"input":{
    "orderId": "<your order ID> ",
    "productId": 3
  }
}

An example mutation for selectLoanOptionType looks something like the following:

mutation selectLoanOptionType($input: SelectLoanOptionInput!) {
  selectLoanOptionType(input: $input) {
    loanSummary {
        id
        finalPaymentAmount
        paymentAmount
        firstPaymentDue
        annualPercentageRate
        financeCharge
        termLength
        amountFinanced
        loanAmount
        deferredInterestPeriod
      }
    loanOptionErrors {
      __typename
      ... on SoftDecline {
        extensions {
          appId
          declineField
        }
      }
    }
  }
}


More loan information can be returned in the response of this mutation, but all the information will be presented in the loan documents the customer signs so you do not need to worry about presenting the information returned from this mutation.

Success

An example condensed success response will look like:

{
    "data": {
        "selectLoanOptionType": {
            "loanSummary": {
                "id": 26211
            },
            "loanOptionErrors": []
        }
    }
}

You'll be able to identify it as a successful response because loanSummary is not null and returns data while loanOptionErrors is an empty list.

Errors

An example error response will look like the following:

{
    "data": {
        "selectLoanOptionType": {
            "loanSummary": null,
            "loanOptionErrors": [
                {
                    "__typename": "NotFound"
                }
            ]
        }
    }
}

You can identify it as an error response because loanSummary is null and loanOptionErrors contains an error. For more details on troubleshooting the errors returned, see Handling Common Errors. Errors returned from this mutation must be resolved before continuing on.

3. Generate Loan Contract

After completing Steps 1 and 2 you can use the generateLoanContract mutation to generate and retrieve the loan documents.

  mutation generateLoanContract($orderId: String!) {
    generateLoanContract(orderId: $orderId) {
      loanDocuments {
        loanAgreement
        tila
      }
      loanDocumentsErrors {
        __typename
        ... on FatalError {
          message
        }
        ... on BadRequest {
          message
        }
      }
    }
  }

If you encounter errors on this mutation, they will need to be resolved before moving forward. This mutation only works for loans so if you get a BadRequest error returned, double check that the orderId you have passed is for a loan, not a lease. If you get a FatalError back, then you should retry the mutation as this is caused by an internal or downstream error while trying to complete the mutation.

Once generateLoanContract has successfully completed, you will need to display these returned documents for customers to review and sign to complete their financing with Koalafi.

4. Sign Loan Agreement

Once the customer reviews the loan agreement, you will need to capture their consent with signLoanAgreement mutation.

Compared to our other mutations, signLoanAgreement is fairly simple with both a small input and small response as shown in the examples below.

Example input:

 {"input": { 
        "orderId": "<your orderId> ",
        "marketingConsent": true
    }
 }

orderId is the same orderId you've been using throughout the application process and marketingConsent in a boolean indicating whether or not a customer has agreed to marketing notifications from Koalafi. It is required, so unless you explicitly ask the customer about marketing, you should pass false.

The signLoanAgreementResponse object only contains errors so your mutation only needs to check for the errors like in this example:

 mutation signLoanAgreement($input: SignLoanAgreementInput!) {
    signLoanAgreement(input: $input) {
      signingErrors {
        __typename
        ... on FatalError {
          message
        }
        ... on BadRequest {
          message
        }
        ... on NotSigned {
          message
        }
         ... on OrderNotFound {
          message
        }
      }
    }
  }

Any errors returned from this mutation need to be resolved before proceeding. FatalError and NotSigned are caused by errors within our API. If you encounter one of these you should call the mutation again. If the error persists after a retry please reach out to our support team so we can help with resolution. You can reach us at [email protected]

If you get a BadRequest or OrderNotFound error you should check your input and make sure the values passed in meet the validation requirements.

Once the customer has signed the agreement, merchants should submit the purchase in their system for processing. You also need to save the orderID you used throughout this application as you will need to have it to submit your loan for funding. Continue on to our Completing an Order page to learn about submitting a loan for funding.

❗️

Cart Changes

If the customer changes their cart at all prior to submitting the purchase in your system, then you’ll need to start this section again at Step 2 and repeat all the subsequent steps. This is important because it ensures that loan agreement the customer signs matches the price of the purchases they’re making on your site.


What’s Next