Migrating to OneSDK

❗️

Smart UI will soon be retired

We are officially discontinuing Smart UI support and updates effective December 31, 2024. It will be replaced by our new OneSDK Onboarding Forms.

What This Means for Current Smart UI Users:

Until December 31, 2024:

  • No new feature requests will be accepted.
  • Smart UI will remain functional, and support requests will be addressed.

After December 31, 2024:

  • All support requests and updates will cease.
  • Smart UI will still function, but no support will be provided.
    Information on how to migrate to OneSDK is found at Migrating to OneSDK.

Contact your Customer Success manager for further details about the Smart UI integration to OneSDK.


OneSDK offers enhanced flexibility regarding IDV vendors, and introduces new modular components such as OCR capabilities and advanced analytics functionalities.

If you're currently using Smart UI with your FrankieOne integration, use the following information to migrate to OneSDK.

Migration Paths

There are two main migration paths expected, based on your current integration with Smart UI:

SmartUI implementationMigration path
SmartUI + OnfidoBiometrics-first for a faster and better UX
SmartUI OnlyLeverage the new eKYC forms (manual capture)

To get a quick start on how the onboarding flow looks like for these migration paths, please visit OneSDK Quick Start.
For further details, please go through the following sections.

Migration Path 1: OneSDK Biometrics-first

If you have been using Smart UI with Onfido, we recommend Biometrics-first approach in OneSDK to have a faster and better onboarding experience. In OneSDK, you can switch to either Onfido Motion or Incode to run OCR and Biometrics.
Please go through the following steps to learn more about OneSDK:

Step 1: OneSDK initialisation

Please visit OneSDK Getting Started to learn more about OneSDK and how to initialise it.

📘

Session token

Generating a session token is similar as before but you need to change the preset to one-sdk

Step 2: Integrating with an IDV vendor

Once you get started, to integrate with different IDV vendors, navigate to the following pages:

To have a full E2E experience and optimise your UX, OneSDK modular forms will also provide out-of-the-box screens which you can embed at any point of your onboarding. The most commonly used screens are loading and review screens.
Please visit Modular Forms - Biometrics/OCR flow to learn more about OCR/Biometrics onboarding forms. You can find a couple of sample codes here: E2E sample code.

Step 3: E2E Sample code - Smart UI vs OneSDK

Here's an example of the current Smart UI + Onfido integration vs OneSDK Biometrics-first with Onfido. In this sample, we configure Australian DL and Passport in both Smart UI and OneSDK:

<html>

<head>
  <!-- UTF-8 encoding you page is important as some text in the smart UI might not come out as you expect -->
  <meta charset="utf-8" />
  <meta name="referrer" content="no-referrer" />
  <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,700;1,300;1,400&display=swap"
    rel="stylesheet" />
  
  <script src="https://assets.frankiefinancial.io/onboarding/v4/ff-onboarding-widget.umd.min.js"></script>

  <script>
    //Here's the environments available to run this. Please don't use this html page for production it's meant as an illustration only
    
    let backend_URL_UAT = "https://backend.kycaml.uat.frankiefinancial.io";
    let backend_URL_PROD = "https://backend.kycaml.frankiefinancial.io";

    // Set your environment
    let selected_ENV = backend_URL_UAT;

    // Set customer ID and API Key
    const CUSTOMER_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxx-xxxx"
    const CUSTOMER_CHILD_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    const API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

    const getToken = async () => {
        const response = await fetch(
          `${selected_ENV}/auth/v2/machine-session`,
          {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              authorization: `machine ${btoa(
                `${CUSTOMER_ID}:${CUSTOMER_CHILD_ID}:${API_KEY}`
              )}`,
            },
            body: JSON.stringify({
              permissions: {
                preset: "smart-ui",
              },
              referrer: "https://*.2.63.80:5500/ || *://*.2.63.80:5500/*"
            }),
          }
        );
        return response.headers.get("token");
      };

    //This is the configuration for the smart UI object. Please see https://apidocs.frankiefinancial.com/docs/smart-ui-configuration for full list available of options
    //HOT TIP: leaving list of accepted countries to null gives you the full list of countries to chose from.
    
    let ff_config_object = {
      "mode": "production",
      frankieBackendUrl: selected_ENV,
      ageRange: [18, 125],
      "checkProfile": "auto",
      "phrases": phrases_v2,
      "welcomeScreen": true,
      "maxAttemptCount": 2,
      "documentTypes": [
        {
          "icon": "driving-licence",
          "type": "DRIVERS_LICENCE",
           "acceptedCountries": [
            "AUS"
          ]
        },
        {
          "idExpiry": true,
          "icon": "passport",
          "type": "PASSPORT",
          "acceptedCountries": [
            "AUS"
          ]
        }
      ],
      "successScreen": {
        "ctaUrl": null,
        "ctaText": "Continue to My Account"
      },
      "failureScreen": true,
      "progressBar": true,
      //"googleAPIKey": "YOUR_GOOGLE_API_KEY",
      "acceptedCountries": [
        "AUS"
      ],

      "organisationName": "Organisation",
      "dateOfBirth": {
        "type": "gregorian"
      },
      "idScanVerification": {
          "releaseVersion": "v1.2",
          "welcomeScreen": {
            "title": 'Verify your identity',
            "content": ["We need to collect some personal information to verify your identity before we can open your account."],
            "ctaText": 'Start Identity Verification',
          },
          "useMobileDevice": true,
          "useLiveness": true,
          //injectedCss: string,
          //language: PhrasesDictionary
      },
      "pendingScreen": {
        "htmlContent": null,
        "ctaActions": []
      },
      //"consentText": "help",
      "requestAddress": {
        "acceptedCountries": [
          "AUS"
        ]
      },
      "documentUploads": false,
      "lazyIDCheck": false,
      "requestID": true,
      "disableThirdPartyAnalytics": false,
      "saveOnly": true
    };


    var phrases_v2 = {
      "failure_screen": {
        "title": "Oh no!",
        "subtitle": "Unfortunately we couldn't verify your identity at this time.",
        "failure_hint": "Please contact our customer support team who will be happy to help you open your account."
      }
    }
    
    // Specify a customer reference
    let applicant_reference = "YOUR_UNIQUE_CUSTOMER_REF";

    function onLoaded() {
        getToken().then((token) => {
          frankieFinancial.initialiseOnboardingWidget({
            ffToken: token, //This is the token to authenticate your Smart UI session
            applicantReference: applicant_reference, //This should be your unique customer reference for the person filling in this form.
            
            config: ff_config_object,
            width: "390px",
            //height: "844px",
          });
        });
      }

    var body = document.getElementsByTagName("body")[0];

    document.addEventListener("DOMContentLoaded", onLoaded);
  </script>
</head>

<body style="background-color: black; position: absolute; top: 0; left: 50%; transform: translateX(-50%)" >
  <ff-onboarding-widget> </ff-onboarding-widget>

  <script>
    //Once you get the FF_CHECK_RESULT event AND you're not going to do the biometrics/idScanVerification process it's a trigger to do something for the customer.
    //if they've gotten to the end of the smart UI move them along to your next part of the process.

    window.addEventListener("FF_CHECK_RESULT", handle_results);
    function handle_results(event) {
      //Console log the event details if you want to see the structure of the event returned. YOU DO NOT WANT TO DO THIS IN PRODUCTION AS IT DOES CONTAIN PII INFORMATION!
      console.log(event);
    }

    window.addEventListener("SCREEN:FAILURE", handle_failure_screen);

    function handle_failure_screen(event) {
      console.log("Emmiting the Screen Failure event");
      console.log(event);
    }

    window.addEventListener("SCREEN:DOCUMENT_TYPE_SELECT", handle_doc_select_screen);

    function handle_doc_select_screen(event) {
      console.log("Emmiting the DOCUMENT_TYPE_SELECT event");
      console.log(event);
    }


    window.addEventListener(
      "FF_EXTERNAL_IDV_CHECK_COMPLETED",
      handle_biometric_results
    );

    function handle_biometric_results(event) {
      console.log(event);
    }
  </script>
</body>

</html>
<html lang="en">
  <head> 
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>oneSdk onboarding</title>
   <script src="https://assets.frankiefinancial.io/one-sdk/v1/oneSdk.umd.js"></script>

  <script>
  async function startOneSdk() {
     //Here's the environments available to run this. Please don't use this html page for production it's meant as an illustration only
    
    let backend_URL_UAT = "https://backend.kycaml.uat.frankiefinancial.io";
    let backend_URL_PROD = "https://backend.kycaml.frankiefinancial.io";

    // Set your environment
    let selected_ENV = backend_URL_UAT;

    // Set customer ID and API Key
    const CUSTOMER_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxx-xxxx"
    const CUSTOMER_CHILD_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    const API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

    const tokenResultRaw = await fetch(`${selected_ENV}/auth/v2/machine-session`, {
            method: "POST",
            headers: {
                "authorization": "machine " + btoa(`${CUSTOMER_ID}:${CUSTOMER_CHILD_ID}:${API_KEY}`),
                "Content-Type": "application/json"
            },
            body: JSON.stringify({
                permissions: {
                    "preset": "one-sdk",
                    "reference": "YOUR_UNIQUE_CUSTOMER_REF"
                }
            })
        });

    const tokenResult = await tokenResultRaw.json();

    const sessionObjectFromBackend = tokenResult;

    const oneSdk = await OneSdk({
      session: sessionObjectFromBackend,
      mode: "development",
      recipe: {
        form: {
          provider: {
            name: 'react'
            //googleApiKey: "YOUR_API_KEY"
          },
        },
        ocr: {
          provider: {
            name: 'onfido',
            /*customUI: {
              borderRadiusButton: "10px";
            }*/// UI Customisation
          },
          documents: [
            {
              type: "DRIVERS_LICENCE",
              countries: ["AUS"]
            },
            {
              type: "PASSPORT",
              countries: ["AUS"]
            },
          ],
        },
        biometrics: {
          provider: {
            name: 'onfido',
            /*customUI: {
              borderRadiusButton: "10px";
            }*/// UI Customisation
          }
        }
      }
    });
    oneSdk.on('*', console.log);
    
    const oneSdkIndividual = oneSdk.individual();
    oneSdkIndividual.addConsent("general");
    oneSdkIndividual.addConsent("docs");
    oneSdkIndividual.addConsent("creditheader");
    await oneSdkIndividual.submit();

    const idv = oneSdk.flow("idv");
    const loading1 = oneSdk.component("form", {name: "LOADING", title: {label: "Loading..."}, descriptions: [{label: ""}]});
    const loading2 = oneSdk.component("form", {name: "LOADING", title: {label: "Processing results..."}, descriptions: [{label: "Hold tight, this can take up to 30 seconds. Please do not refresh this page or click the 'back' button on your browser."}]});
    const review = oneSdk.component("form", {
        name: "REVIEW",
        type: "ocr",
      });

    let before = true;
    idv.on("loading", (display)=>{
      if(display){
        if (before)
        {
          loading1.mount("#loading1");
        }
      }else{
        if (before)
        {
          loading1.unmount();
        }
        before = false;
      }
    })

    idv.on("results", async ({checkStatus, document, entityId}) => {
        if (checkStatus) {
          console.log("results succesfful");
          loading2.unmount();
          review.mount("#idv-el");
        } else {
          console.log("no data returned");
        }
    });

    idv.on("error", ({ message, payload }) => {
      console.log("received error");
      console.log(message, payload);
    });


    idv.on("detection_complete", (message) => {
      console.log("capture finished");
      console.log(message);
      loading2.mount("#loading2");
    });

    idv.on("*", (message) => {
        console.log(message);
      });

    review.on("form:review:ready", async (message) => {
      console.log(message);
    });

    idv.mount("#idv-el");

  }

</script>

<style>
  
</style>

</head>
<body style="background-color: white" onload="startOneSdk()">
  <div id="idv-el" style="top: 0;left: 0; width: 100%; height: 100%; display: block"></div>
  <div id="loading1"></div>
  <div id="loading2"></div>
</body>

Migration Path 2: OneSDK eKYC forms (Manual capture)

If you have been using Smart UI only, without IDV, we recommend using the new Manual Forms in OneSDK. Please go through the following steps one by one for the migration:

Step 1: OneSDK initialisation

Please visit OneSDK Getting Started to learn more about OneSDK and how to initialise it.

📘

Session token

Generating a session token is similar as before but you need to change the preset to one-sdk

Step 2: Render Manual forms

OneSDK modular forms will provide manual forms as well. Please visit Modular Forms - Manual flow to learn more about manual onboarding forms.
You can find a couple of sample E2E scenarios here: E2E sample code