rehive / service-onfido

Rehive Onfido KYC extension
MIT License
0 stars 0 forks source link

Create (and Document) Onfido KYC Extension. #1

Closed OdinsPlasmaRifle closed 1 year ago

OdinsPlasmaRifle commented 1 year ago

It seems like implementing a KYC extension in Onfido should be viable. Initially it could be implemented to only do documents and addresses but it could be extended to support other features.

An initial design plan would be:

This may not be perfect but seems to match the resources in the Onfido API reference. There will probably be edge cases i am not seeing now that would come up during development.

Additionally, there are some situations we would need to consider:

API Reference: https://documentation.onfido.com Supported documents: https://onfido.com/supported-documents/

OdinsPlasmaRifle commented 1 year ago

Crate documentation for this extension so it can be shared with interested clients.

OdinsPlasmaRifle commented 1 year ago

Overview

The Onfido extension uses the Onfido services to perform document verification in Rehive. The current implementation only support document verification.

NOTE: This extension is using the new document-type resources instead of the static document types. This means it will only function in a company that has enabled this feature on the Platform.

The database models:

The extension has the following base endpoints:

The extension's primary functionality is handled via the following endpoints:

Document-types endpoints

These endpoints are used to map Rehive document-types to Onfido document types. Clients may choose to name their documents anything and therefore manual mapping of types is required.

Each document type in the Onfido extensions consists of the following data:

{
    "id": "string",
    "platform_type": "string",
    "onfido_type": "string",
    "side": "string",
    "created": 0,
    "updated": 0
}

The platform_type is the ID of the document-type in the Rehive Platform.

The onfido_type currently supports the following values:

The side must either be a null value or front/back value.

Platform webhook endpoint

This endpoint is used to receive events from Rehive. The extension needs to know when certain Platform activity occurs in order to trigger Onfido logic.

Only the following webhook events need to be sent to this endpoint:

This documentation contain info on handling Rehive webhook events.

When a relevant event is received, it is saved to the database where an unique id field on the table ensures that each webhook event is only saved once. Then, the specific event is added to a task queue.

The task queue processes events asynchronously. If the event is document.created the following steps are taken:

  1. Create a user in the extension database based on the Platform document's owner:
    • This only happens if the user has not been created yet. Otherwise get the existing user.
  2. Create a new Document database entry in the extension for the Platform document.
    • This only happens if a valid document-type mapping can be found for the Platform document-type. If no mapping is found skip the rest of the steps.
    • The Platform document ID is saved along with the document type mapping (so we know which Onfido document this should create).
  3. Create a new Document entry in Onfido using the above Document data.
    • Fetch the file URL from the Platform's document.
    • Convert the file into an in-memory-uppload.
    • Upload the file to Onfido along with the applicant ID and appropriate Onfido document type.
    • Save the returned Onfido ID onto the database entry in the extension.
  4. Finally, attach the document to a check in the database.
    • If it is a single-sided document then create a new check.
    • If this is a double-sided document, try and find an existing check for the opposite side. If none exists, create one. If the check already exists simply add this document to it as well.
    • The new check does not create its corresponding Onfido check immediately.

After adding the check, some special logic needs to be performed in order to decide "when" to create the check in Onfido. The logic used for processing the addition of Onfido checks is as follows:

  1. Post check creation/save (in PENDING) hook:
    • If no checks are currently processing for the applicant
    • Submit the next ready check (if one exists) in FIFO order to Onfido.
  2. Post check completion (in FAILED or COMPLET) hook:
    • If no checks are currently processing for the applicant
    • Submit the next ready check (if one exists) in FIFO order to Onfido.

A ready check is any check that satisfies the multi-side document requirements of the documents in the check. This extension marks these shecks with the status PENDING.

Onfido webhook endpoint

This endpoint is used to receive events from Onfido. The extension needs to know when certain Onfido activity occurs in order to trigger extension logic.

Only the following webhook events need to be sent to this endpoint:

This documentation contain info on handling Onfido webhook events.

When a relevant event is received, it is saved to the database where an unique id field on the table ensures that each webhook event is only saved once. Then, the specific event is added to a task queue.

The task queue processes events asynchronously. If the event is check.completed the following steps are taken:

  1. Try and find a check related to the event object.
    • If no check exists, discontinue processing.
  2. If a check is found evaluate the check to see whether the extension data need to be updated according to Onfido.
    • Ensure the extension check has not already been completed
    • Ensure the Onfido check has a "complete" status (complete or withdrawn).
    • For each document in the check, update the corresponding document in the Platform with the status (result) provided by Onfido.
    • Save the check's status in the extension.

NOTE: The current implementation only marks documents as "verified" in the Platform if Onfido marked them as "clear". The following Onfido statuses will be set to "declined" in the Platform: "rejected", "suspected", "caution".

Notes:

There are some issues with using Onfido:

  1. Onfido has very restrictive sandbox throttling rules.
    • 1 request per second with a burst of 2 requests. 30 requests per minute total.
    • As such we have had to take into account the possibility that an Onfido request could fail at any arbitrary point. This is probably good practice generally, but it does make prorotypes or phase 1 implementations significantly harder.
  2. The full list of Onfido document types are not clearly documented.
  3. You cannot create a check if there is a currently ongoing check on an applicant already.
    • This means we have to manage the check processing queue ourselves.
    • Similar to point 1, this is good practice but makes prorotyping harder.
OdinsPlasmaRifle commented 1 year ago

going forward this will be documented here:

https://github.com/rehive/service-onfido/wiki/Overview