Quick Start

In this quick start guide, you can quickly run two sample onboarding flows with OneSDK and see it in action.

1. Obtain your API credentials

📘

API Access

Contact FrankieOne support to request new credentials if you don’t have an account yet.

To be able to run OneSDK, you need to have the API URL and credentials ready:

2. Copy the following code snippet

❗️

API Credentials

Never expose your credentials in the front-end. The sample HTML code below is for demonstration purposes. Generate a session token server-side and only send the token to the front-end.

Sample 1: eKYC only

The following code sample will give you an onboarding flow with eKYC only (manual capture).

<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() {
    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("https://backend.kycaml.uat.frankiefinancial.io/auth/v1/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": "random"//"<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"
          },
        }
      }
    });
    oneSdk.on('*', console.log);

    const oneSdkIndividual = oneSdk.individual();
    oneSdkIndividual.setProfileType('auto');

    const welcome = oneSdk.component("form", {
      name: "WELCOME",
      type: "manual",
      /*descriptions: [
              { label: 'This is a sample dynamic page.', style: {} },
              { label: 'It can contain multiple paragraphs.', style: {} },
            ], */
      //cta: {style: {'ff-button':{backgroundColor: "red"}}}
    });
    const consent = oneSdk.component("form", {name: "CONSENT"});

    const personal = oneSdk.component("form", {
      name: "PERSONAL",
      type: "manual",
    });

    const document = oneSdk.component("form", {
      name: "DOCUMENT",
      type: "manual",
      numberOfIDs: 1,
    });

    const review = oneSdk.component("form", {
      name: "REVIEW",
      type: "manual",
      verify: true
    });

    const retry = oneSdk.component("form", {
      name: "RETRY",
      type: "manual",
    });

    const result_fail = oneSdk.component("form", {
      name: "RESULT",
      type: "manual",
      state: 'FAIL',
      title: {label:'Max attempt reached'},
      descriptions: [{label:'You have reached all the attempts. Our officer will review your details and get in touch.'}, {label:'Please close the browser'}],
      cta:{label: 'Close'}
    });

    welcome.mount("#form-container");
    welcome.on("form:welcome:ready", () => {
      consent.mount("#form-container");
    });

    consent.on("form:consent:ready", async () => {
      personal.mount("#form-container");
    });

    welcome.on("form:welcome:failed", () => {
      // display error message
    });

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

    personal.on("form:personal:ready", async () => {
      document.mount("#form-container");
    });

    document.on("form:document:back", async ({inputInfo}) => {
      personal.mount("#form-container");
    });


    document.on("form:document:ready", async ({inputInfo}) => {
      review.mount("#form-container");
    });

    let count = 0;
    review.on("form:result:partial", async () => {
      if (count < 2)
      {
        retry.mount("#form-container");
        count+=1;
      }
      else
      {
        result_fail.mount("#form-container");
      }

    });

  }

</script>

<style>
  
</style>

</head>
<body style="background-color: white" onload="startOneSdk()">
  <div id="form-container" style="position:fixed;top: 0;left: 0; width: 100%; height: 100%;"></div>
</body>

Sample 2: IDV flow

The following code sample gives you an onboarding flow with OCR and Biometrics.

<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() {
    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("https://backend.kycaml.uat.frankiefinancial.io/auth/v1/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": "random"//"<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"
          },
        }
      }
    });
    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>
</html>

3. Replace your credentials

In the code snippet, replace the following items with your credentials

  • CUSTOMER_ID
  • CUSTOMER_CHILD_ID: If you don't have a child ID, please remove CUSTOMER_CHILD_ID from the code line below:
"authorization": "machine " + btoa(`${CUSTOMER_ID}:${CUSTOMER_CHILD_ID}:${API_KEY}`)
  • API_KEY
  • reference: Use a unique customer reference
  • Google Map API key (Optional): If you do have a Google Map API key, you can provide it in the following format, so that you can auto search addresses in the OneSDK forms:
const oneSdk = await OneSdk({
  session: sessionObjectFromBackend,
  mode: "development",
  recipe: {
    form: {
      provider: {
        name: 'react',
        googleApiKey: "YOUR_API_KEY"
      },
    }
  }
});

4. Run the sample

Save the final code into an HTML file, and simply open it on your desktop or mobile browser.