> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frankieone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Web App Step-by-step Guide

> Learn how to setup and verify an individual using the OneSDK.

### How it works

The user onboarding flow works as follows:

1. User navigates to your registration page.
2. Before serving the front-end, your server communicates with Frankie's server to create a temporary session.
3. Your server passes the session object to your front-end for it to initialize OneSDK using the session object.
4. OneSDK modules are activated to handle the collection and processing of identity verification data.
5. You verify the individual using OneSDK's `submit()` method.

<Steps>
  <Step title="Create a session and forward it to your front-end">
    #### Construct the API credentials

    1. Serialize your FrankieOne API credentials to a string using the ':' separator.
    2. Encode the resulting string using Base64 encoding.

    Run the following command:

    ```shell Shell theme={null}
    echo -n 'CUSTOMER_ID:API_KEY' | openssl base64
    ```

    ```javascript JavaScript theme={null}
    const base64EncodedCredentials = Buffer.from(
      `${CUSTOMER_ID}:${API_KEY}`,
    ).toString("base64");
    ```

    If you have a child account with FrankieOne, modify the above command to the following:

    ```sh theme={null}
    echo -n 'CUSTOMER_ID:CUSTOMER_CHILD_ID:API_KEY' | openssl base64
    ```

    #### Obtain a temporary session token

    Send a `POST` request to the `/machine-session` endpoint of our Backend for Frontend server (BFF). The appropriate URL for BFF depends on the environment you're integrating with:

    | Environment | URL                                                                        |
    | :---------- | :------------------------------------------------------------------------- |
    | Demo        | `<https://backend.demo.frankiefinancial.io/auth/v1/machine-session>`       |
    | UAT         | `<https://backend.kycaml.uat.frankiefinancial.io/auth/v1/machine-session>` |
    | Production  | `<https://backend.kycaml.frankiefinancial.io/auth/v1/machine-session>`     |

    <Callout icon="thumbtack" color="#1A6CFF" iconType="regular">
      ###### Different Base URL">

      The base URL for the `/machine-session` endpoint is different to the server
      API.
    </Callout>

    Pass the encoded credential in the `Authorization` request header using `machine` as the scheme:

    `Authorization: machine YOUR_ENCODED_CREDENTIAL`

    Include the following parameters in the body of the request:

    \| Parameter name          | Required                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                         |

    | Parameter               | Required   | Description                                                                                                                                                                                                                                                                                                                                                                                          |
    | :---------------------- | :--------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `permissions`           | Required   | A hash containing `preset` and either `entityId` or `reference`.                                                                                                                                                                                                                                                                                                                                     |
    | `permissions.preset`    | Required   | The string `'one-sdk'`.                                                                                                                                                                                                                                                                                                                                                                              |
    | `permissions.reference` | Required\* | A string containing a unique customer reference for the individual being verified. <br />If a new reference is used, once the individual completes verification this value can be used to retrieve the details via the API or the Portal. <br />If an existing reference is used, the existing data will be retrieved and the new information captured by users will be attached to the same entity. |
    | `permissions.entityId`  | Required\* | A string containing the entity ID for the individual being verified.                                                                                                                                                                                                                                                                                                                                 |

    \* Either `entityId` or `reference` is required, but not both.

    The following example creates a session object for a user using a unique customer reference:

    ```shell Shell theme={null}
    ENCODED_CREDENTIAL=$(echo -ne "$YOUR_CUSTOMER_ID:$API_KEY" | base64);

    curl https://backend.demo.frankiefinancial.io/auth/v1/machine-session \
      -X POST \
      -H "Authorization: machine $ENCODED_CREDENTIAL"
      -H 'Content-Type: application/json' \
      -d '{
        "permissions": {
          "preset": "one-sdk",
          "reference": "YOUR_UNIQUE_CUSTOMER_REF",
        }
      }';
    ```

    ```javascript JavaScript theme={null}
    const sessionObject = fetch(`${FRANKIE_BFF_URL}/auth/v2/machine-session`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        authorization:
          "machine " +
          Buffer.from(`${CUSTOMER_ID}:${CUSTOMER_CHILD_ID}:${API_KEY}`).toString(
            "base64",
          ),
      },
      body: JSON.stringify({
        permissions: {
          preset: "one-sdk",
          reference: "YOUR_UNIQUE_CUSTOMER_REF",
        },
      }),
    }).then((response) => response.json());
    ```

    <Info title="Keep your credentials confidential">
      Don't publish your credentials to your front-end. They should remain accessible only from your server.
    </Info>

    Sample response:

    ```json JSON theme={null}
    {
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
    }
    ```

    #### Pre-fill applicant data

    If you use an existing reference or `entityId `when creating a session object, OneSDK will retrieve the existing data and pre-fill the applicant, and new information captured by the user will be updated to the same entity:

    ```javascript JavaScript theme={null}
    //using existing entityId
    permissions: {
      preset: "one-sdk",
      entityId: "YOUR_ENTITY_ID"
    }

    //using existing reference
    permissions: {
      preset: "one-sdk",
      reference: "YOUR_EXISTING_REF"
    }
    ```
  </Step>

  <Step title="Set up OneSDK">
    Use OneSDK to onboard an individual into your application.

    #### Install the SDK

    We recommend installing OneSDK via a `<script>` tag so that your webpage always receives the latest, most up-to-date version.

    ##### Embed script

    The URL below will point to the latest stable v1 version. Alternatively, you can point to a specific version by swapping out the `v1` URL parameter with a specific major and minor version (i.e. `v1.6.1-beta`).

    ```javascript JavaScript theme={null}
    <script src="https://assets.frankiefinancial.io/one-sdk/v1/oneSdk.umd.js"></script>
    ```

    ##### NPM Module

    <Info title="NPM only works with React + Vite or React + Rollup">
      We're working on enabling other frameworks such as Next.js, Vue, and React + Webpack.
    </Info>

    ```shell Shell theme={null}
    npm install @frankieone/one-sdk
    ```

    Import the SDK into your application:

    ```
    import OneSdk from '@frankieone/one-sdk'
    ```

    If you install OneSDK as an npm package, you are responsible for updating the version in your `package.json` file to ensure you always have the most up-to-date version.

    #### Create a configuration object

    Create an object for the global configuration of your SDK integration. This section shows the required and recommended parameters.

    | Parameter name |                      Required                      | Description                                                                                                                                        |
    | :------------: | :------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------- |
    |    `session`   | Required, unless `mode` is specified as `"dummy"`. | The session object from your call to `/machine-session`.                                                                                           |
    |     `mode`     |                      Optional                      | One of `"production"` or `"dummy"`. If this is set as `"dummy"`, then `session` doesn't need to be specified. The default value is `"production"`. |

    Sample configuration:

    ```js theme={null}
    const configuration = {
      session: sessionObject,
    };
    ```

    Pass the entire object returned from the response of the `/machine-session` endpoint as the value for the `session` parameter. Don't extract the token or any other field from the response.

    For example, your code may look like this:

    ```javascript JavaScript theme={null}
    <?php $sessionResponse = createFrankieSession(); ?>
    <script>
      const session = JSON.parse('<?php echo json_encode($sessionResponse) ?>'); // session is the object { token: "...." }
      const oneSdk = await OneSdk({ session });
    </script>
    ```

    ```javascript JavaScript theme={null}
    <script>
      {% set sessionObject = await createFrankieSession(); %}

      const sessionObject = JSON.parse("{{ sessionObject | json_encode | raw }}"); // session is the object { token: "...." }
      const oneSdk = await OneSdk({ session: sessionObject });
    </script>
    ```

    #### Initialize the OneSDK object

    Create an instance of OneSDK using the configuration object you created.

    The `OneSDK` function returns a promise, which can be `await`-ed in JavaScript ES2017's `await`.

    ```js theme={null}
    const oneSdk = await OneSdk(configuration);
    ```

    Otherwise, you can use Javascript's Promise API.

    ```js theme={null}
    OneSdk(configuration).then((oneSdk) => {
      // The oneSDK instance is ready to use...
    });
    ```
  </Step>

  <Step title="Verify document details via OCR">
    Use the OCR Component provided by OneSDK to verify document details.

    #### Create the OCR Component

    Create an instance of the OCR Component by passing `'ocr'` in `component(type)`.

    ```javascript JavaScript theme={null}
    const ocr = oneSdk.component("ocr");
    ```

    #### Obtain results

    Listen to the `results` event to get notified when the OCR extracted results are available.

    ```js theme={null}
    ocr.on("results", ({ document }) => {
      // Present the details of the document that were detected from the uploaded image or images.
      // Decide whether to proceed to the next stage of the onboarding process
      // depending on whether document verification was successful.
      if (document) {
      } else {
      }
    });
    ```

    #### Handle errors

    Listen to the `error` event to handle any errors from the OCR component. For example, the supplied image may not be processable.

    ```js theme={null}
    ocr.on("error", (error) => {
      console.error(error.message);
    });
    ```

    #### Start the document capture flow

    Finally, start the document capture flow by mounting the OCR component.

    ```js theme={null}
    ocr.mount("#<container>");
    ```
  </Step>

  <Step title="Verify biometrics">
    Use the Biometrics Component provided by OneSDK to verify the user's facial image/video.

    You may skip this step if biometrics isn't required in your onboarding flow.

    #### Create the container element for the Biometrics component

    Create a DOM container element on your onboarding web page where you want the component to be rendered. Make sure to give the container element a descriptive ID. The container element for Biometrics and OCR components can be the same.

    For example:

    ```html theme={null}
    <div id="biometrics-container"></div>
    ```

    If you are using JavaScript frameworks such as Vue or React, make sure that you use references instead of selectors and that you don't re-render the DOM element.

    #### Create the Biometrics component

    Create an instance of the Biometrics component by passing `'biometrics'` in `component(type, options?)`.

    ```javascript JavaScript theme={null}
    const biometrics = oneSdk.component("biometrics");
    ```

    #### Obtain results

    Listen to the `results` event to get notified when biometrics results are available.

    ```javascript JavaScript theme={null}
    biometrics.on("results", ({ checkStatus, processing }) => {
      // Decide whether to proceed to the next stage of the onboarding process
      // depending on whether biometrics verification was successful.
      if (processing) {
      } else {
      }
    });
    ```

    #### Handle errors

    ##### Handle detection failed events

    When the biometrics component fails to detect the user, it will emit a `detection_failed` event.

    You can re-attempt another capture by mounting the component again upon receiving the `detection_failed` event.

    ```js theme={null}
    biometrics.on("detection_failed", (error) => {
      console.error(error);

      if (retriesAttempted <Steps 3) {
        biometrics.mount("#biometrics-container");
      }
    });
    ```

    Listen to the `error` event to handle any other errors.

    ```js theme={null}
    biometrics.on("error", ({ message, payload }) => {
      console.error(message);
    });
    ```

    #### Start the biometrics flow

    ##### Mount the component

    Finally, start the facial capture flow by mounting the component in your container element.

    ```js theme={null}
    biometrics.mount("#biometrics-container");
    ```

    #### Get notified when the capture feed is ready

    The component may take a moment to initialize and display the image/video capture feed. During this time you can optionally display your own loading state. Listen to the `ready` event to know when the biometrics capture feed is ready to use.

    ```js theme={null}
    biometrics.on("ready", () => {
      // If you provided your own loading state it can now be hidden.
      loadingElement.remove();
    });
    ```
  </Step>

  <Step title="Submit information">
    Access the Individual object to represent the person being onboarded.

    ```js theme={null}
    const individual = oneSdk.individual();
    ```

    Make sure that the user consent has been added and then submit the information to verify the individual according to your recipe.

    ```js theme={null}
    individual.addConsent();
    individual.submit({
      verify: true,
    });
    ```
  </Step>
</Steps>
