> ## 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.

# eKYC with Fraud Check

> A guide on creating a customized electronic Know Your Customer (eKYC) flow with form handling, validation, and fraud detection capabilities.

<Callout icon="star" color="#3DD892" iconType="regular">
  Instead of building your own flow, it's *highly recommended* to fork an existing flow from the public sample codes [found here <Icon icon="arrow-up-right-from-square" size={12} />](https://github.com/FrankieOne/frontend-onesdk-public-sample-codes/)
</Callout>

<Panel>
  <CardGroup cols={2}>
    <Card title="Features" icon="list-check">
      * OneSDK eKYC-only flow
      * Multi-step verification process
      * Retry handling mechanism
      * Using Sardine to help checking device verification
    </Card>
  </CardGroup>
</Panel>

<Steps>
  <Step title="Initialize OneSDK">
    ```javascript theme={null}
    const oneSDKInstance = await OneSdk({
      session: sessionObjectFromBackend,
      mode: "production",
      recipe: {
        form: {
          provider: {
            name: "react",
            googleApiKey: '<YOUR GOOGLE MAPS API KEY>'
          },
        },
      },
    });
    ```

    <Callout icon="star" color="#3DD892" iconType="regular">
      Replace `<YOUR GOOGLE MAPS API KEY>` with your actual Google Maps API key for the address feature.
    </Callout>
  </Step>

  <Step title="Set Up Individual Profile">
    ```javascript theme={null}
    const oneSdkIndividual = oneSDKInstance.individual();
    oneSdkIndividual.setProfileType("auto");
    ```
  </Step>

  <Step title="Configure Form Components">
    <AccordionGroup>
      <Accordion title="Basic Forms">
        ```javascript theme={null}
          // Initialize device tracking
          const device = oneSDKInstance.component("device", {
            activityType: "REGISTRATION",
          });
          device.start();

        // Welcome Screen
        const welcome = oneSDKInstance.component("form", {
          name: "WELCOME",
          mode: "individual",
          type: "manual",
        });

        // Consent Form
        const consent = oneSDKInstance.component("form", {
          name: "CONSENT",
          mode: "individual",
          type: "manual",
        });
        ```
      </Accordion>

      <Accordion title="Personal Details Form">
        ```javascript theme={null}
        const personal = oneSDKInstance.component("form", {
          name: "PERSONAL",
          mode: "individual",
          type: "manual",
          title: {
            label: "Personal Details",
          },
          descriptions: [
            {
              label: "In this section, we need your personal information",
            },
            {
              label: "Please enter your information accordingly",
            },
          ],
        });
        ```
      </Accordion>

      <Accordion title="Result Handling Forms">
        ```javascript theme={null}
        const result_success = oneSDKInstance.component("form", {
          name: "RESULT",
          type: "manual",
          state: "SUCCESS",
          title: { label: "Complete" },
          descriptions: [
            { label: "Process is now complete. You can close the page" },
          ],
          cta: { label: "Done" },
        });

        const result_fail = oneSDKInstance.component("form", {
          name: "RESULT",
          type: "manual",
          state: "FAIL",
        });
        ```
      </Accordion>
    </AccordionGroup>
  </Step>
</Steps>

## Event Handling

<CodeGroup>
  ```javascript title="Form Navigation Events" theme={null}
  welcome.on("form:welcome:ready", () => {
    consent.mount(appContainer);
  });

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

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

  ```

  ```javascript title="Review and Result Events" theme={null}
  review.on("form:review:success", async () => {
    result_success.mount(appContainer);
  });

  review.on("form:review:failed", async () => {
    result_fail.mount(appContainer);
  });
  ```
</CodeGroup>

## Retry Logic Implementation

<Info>
  The implementation includes a retry mechanism that allows users up to 2
  attempts before showing the failure screen.
</Info>

```javascript theme={null}
let retryCount = 0;
review.on("form:review:partial", async () => {
  if (retryCount < 2) {
    partial.mount(appContainer);
  } else {
    result_fail.mount(appContainer);
  }
});

partial.on("form:result:partial", async () => {
  retryCount += 1;
  retry.mount(appContainer);
});
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Error Handling" icon="shield-check">
    Always implement proper error handling and validation for each form step to
    ensure data quality.
  </Card>

  <Card title="User Experience" icon="user">
    Provide clear feedback and instructions in the user's preferred language,
    especially for country-specific forms.
  </Card>
</CardGroup>
