User Onboarding

Web application

Example with React:

import React from 'react';
import ZeroHashSDK, { AppIdentifier } from 'zh-web-sdk';

const App = () => {
  const sdk = new ZeroHashSDK({
    zeroHashAppsURL: "https://web-sdk.cert.zerohash.com",
    userOnboardingJWT: "<JWT_TOKEN_HERE>"
  });

  sdk.openModal({appIdentifier: AppIdentifier.ONBOARDING})
  return <></>;
}

export default App;
📘

You can also get a token for the onboarding module another way. See Acquire an onboarding access token.

Choose an onboarding flow

openModal accepts an optional onboardingFlow parameter for AppIdentifier.ONBOARDING. It selects the onboarding experience that the SDK shows. Other app identifiers ignore it.

ValueEnumExperience
'full_with_tax'OnboardingFlow.FULL_WITH_TAXFull onboarding, with the tax certification. This is the default.
'full_without_tax'OnboardingFlow.FULL_WITHOUT_TAXFull onboarding, without the tax certification.
'tax_only'OnboardingFlow.TAX_ONLYTax certification only, for participants who are already onboarded.
import { AppIdentifier, OnboardingFlow } from 'zh-web-sdk';

sdk.openModal({
  appIdentifier: AppIdentifier.ONBOARDING,
  jwt: "<JWT_TOKEN_HERE>",
  onboardingFlow: OnboardingFlow.FULL_WITHOUT_TAX, // Optional: defaults to OnboardingFlow.FULL_WITH_TAX
});

Before you use onboardingFlow:

  • Ask your account team to turn on the new onboarding flows for your platform. Until they do, the SDK ignores onboardingFlow and shows the current flow.
  • On the web, use zh-web-sdk 3.12.0 or later to send a value. Older versions cannot send the parameter, so they get full_with_tax. In a mobile WebView, send onboardingFlow in the OPEN_MODAL payload. See Open Modal.
  • For tax_only, use a client access token. See Tax certification for existing participants.

Each time you call openModal, send the flow that you want. If you omit it, the SDK uses full_with_tax. It does not reuse the value from an earlier call. If you send a value that the SDK does not recognize, it also uses full_with_tax.

For what the customer sees in each flow, see Tax Data Collection - KYCaaS.

Tax certification for existing participants

Use OnboardingFlow.TAX_ONLY to collect a tax certification from a participant who is already onboarded. This works for participants onboarded through the SDK and for participants created through the API.

  1. On your server, request a client access token for the participant. Send their participant_code and the update-participant permission:
{
  "permissions": ["update-participant"],
  "participant_code": "CUST01",
  "reference_id": "a81bc81b-dead-4e5d-abff-90865d1e13b1"
}
  1. Open the Onboarding SDK with that token and onboardingFlow: OnboardingFlow.TAX_ONLY:
import { AppIdentifier, OnboardingFlow } from 'zh-web-sdk';

sdk.openModal({
  appIdentifier: AppIdentifier.ONBOARDING,
  jwt: '<CLIENT_ACCESS_TOKEN>',
  onboardingFlow: OnboardingFlow.TAX_ONLY,
});
🚧

Use a client access token

The onboarding access token from POST /participants/onboarding_token identifies the user by email and is for new users only. tax_only needs a token issued for an existing participant_code.

In tax_only:

  • The customer sees the information that zerohash has on file, read-only, and the tax certification. If zerohash has no tax ID on file, the customer enters one.
  • The SDK does not show the terms again if the customer already accepted them.
  • The SDK does not run identity verification again. ONBOARDING_COMPLETED reports the participant's existing KYC status, or UNKNOWN. Do not wait for a new KYC result webhook.

Mobile application (WebView)

You do not need to install or include zh-web-sdk in a mobile app. A zerohash proxy server calls the SDK for you.

Events

The SDK sends events from the UI to the native app with the postMessage API. Handle these events in your WebView component. The SDK sends these events:

MessageMeaning
SDK_MOBILE_READYThe SDK can receive postMessage events, for example OPEN_MODAL.
ONBOARDING_APP_LOADEDThe SDK is loaded and visible to the customer.
ONBOARDING_CLOSE_BUTTON_CLICKEDThe customer clicked the close (X) button in the top-right corner. The modal hides and keeps its state. If you reopen it in the same instance, the UI shows the state it had when it closed.
ONBOARDING_PENDING_APPROVALThe KYC submission needs a manual review by the zerohash compliance team. A participant status webhook matches this message.
ONBOARDING_COMPLETEDThe customer completed the flow and the internal calls succeeded. "Completed" does not mean "approved". The participant status can still be "rejected". In tax_only, the SDK does not run KYC again, and the event reports the participant's existing KYC status.
ONBOARDING_FAILEDThe customer got an error that they cannot fix in the current session.
CAMERA_PERMISSIONS_REQUIREDThe customer is about to start a step that needs the camera. Use this event to ask for camera permission just in time. The SDK sends it on the processing page when the customer must capture a document. It always sends it on the document capture page.
TOKEN_EXPIREDThe token expired. Get a new one. See Acquire an onboarding access token.

Messages

After you receive SDK_MOBILE_READY, you can control the WebView with postMessage. The WebView accepts these messages.

Open Modal

Opens the modal for the app identifier, with the JWT that you provide.

{type: "OPEN_MODAL", payload: {jwt: "<JWT_HERE>", appIdentifier: "onboarding"}}
Payload attributeDescription
appIdentifier (required)The flow to open. Use appIdentifier: "onboarding".
jwt (optional)The JWT for the onboarding flow. It is optional if you gave a JWT when you created the SDK instance.
navigate (optional)Opens a specific page. The only accepted value is {to: "edit-address"}.
onboardingFlow (optional)Selects the onboarding flow: "full_with_tax" (default), "full_without_tax" or "tax_only". If you omit it or send an unknown value, the modal opens the default flow. See Choose an onboarding flow.

Open the modal with the tax certification only, for a participant who is already onboarded. Use a client access token. See Tax certification for existing participants.

{type: "OPEN_MODAL",
  payload: {
    jwt: "<CLIENT_ACCESS_TOKEN>",
    appIdentifier: "onboarding",
    onboardingFlow: "tax_only"
  }
}

Open the modal on the edit-address page:

{type: "OPEN_MODAL",
  payload: {
    jwt: "<JWT_HERE>",
    appIdentifier: "onboarding",
    navigate: {to: "edit-address"}
  }
}

Close Modal

Hides the modal and keeps its current state. If you reopen the modal in the same instance, the state stays the same.

{type: "CLOSE_MODAL", payload:{appIdentifier: "onboarding"}}
📘

Closing and opening the modal works as pause and resume, because the UI keeps its state. To restart the flow, create a new modal instance.

For more about the SDK in WebViews, see Integration with Mobile Apps.