> For the complete documentation index, see [llms.txt](https://docs.app.grut-tech.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.app.grut-tech.com/project-examples/b2b-kyc-process-automation.md).

# B2B KYC - Process Automation

Create your own B2B KYC using Grut's Actions

Now that you know how to create your custom atomic blocks and workflows, you can create complex projects with our powerfull tool.

## Content

1. Integrate with B2B data provider
2. Parse response
3. Build your rules with workflow
4. Putting all together
5. Save to your database
6. Deploy to production

### 1. Integrate with B2B data provider

For our example, we will use [Consulta dados de CNPJ](https://developers.receitaws.com.br/#/operations/queryCNPJFree), a produt from [ReceitaWS](https://www.receitaws.com.br/), a free data provider for Business from Brazil.

For that you will need to get to the API's [documentation](https://developers.receitaws.com.br/#/operations/queryCNPJFree) and get the code snippet from the right side.

<figure><img src="https://3076900743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzrrXYXUZDKOwwzos9oK6%2Fuploads%2FCFsxkZ7h0E3dzzmLiFhk%2Fimage.png?alt=media&amp;token=f0afe5b4-72c6-4ab6-a34a-8f4cbe3d4b3f" alt=""><figcaption><p>ReceitaWS API Documentation</p></figcaption></figure>

Go to Grut's Studio and go to create workflow. Start your workflow with built-in action [requests-get](https://app.grut-tech.com/studio/actions?id_action=requests-get). Set the parameters inpt\_headers and inpt\_params with *None.* Leaver the *inpt\_url* as we will use it later. Mark the checkbox beside the output variables to make them available for other blocks to consume.&#x20;

Now give name your new block as "consulta-receitaws-free" and save it.&#x20;

Test your block by running and passing the url for the endpoint.

<figure><img src="https://3076900743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzrrXYXUZDKOwwzos9oK6%2Fuploads%2FY97H8ipskMjfbso1uHlR%2Fimage.png?alt=media&amp;token=bbbae3ed-06be-4fdb-ba47-378bdfed7236" alt=""><figcaption><p>Running receita ws free API</p></figcaption></figure>

### 2. Parse API's response

From Receita WS documentation page, we can check the API's response example.

```json
{
  "status": "OK",
  "ultima_atualizacao": "2019-08-24T14:15:22Z",
  "cnpj": "string",
  "tipo": "MATRIZ",
  "porte": "string",
  "nome": "string",
  "fantasia": "string",
  "abertura": "string",
  "atividade_principal": [
    {
      "code": "string",
      "text": "string"
    }
  ],
  "atividades_secundarias": [
    {
      "code": "string",
      "text": "string"
    }
  ],
  "natureza_juridica": "string",
  "logradouro": "string",
  "numero": "string",
  "complemento": "string",
  "cep": "string",
  "bairro": "string",
  "municipio": "string",
  "uf": "string",
  "email": "string",
  "telefone": "string",
  "efr": "string",
  "situacao": "string",
  "data_situacao": "string",
  "motivo_situacao": "string",
  "situacao_especial": "string",
  "data_situacao_especial": "string",
  "capital_social": "string",
  "qsa": [
    {
      "nome": "string",
      "qual": "string",
      "pais_origem": "string",
      "nome_rep_legal": "string",
      "qual_rep_legal": "string"
    }
  ],
  "billing": {
    "free": true,
    "database": true
  }
}

```

We can [autogenerate variables based on the example dict](#user-content-fn-1)[^1] above to get all values from response as variables or parse only what we really need.

For the purpose of this project we will use Grut's automation to generate the parser. To do so, go to [create-dict-to-outputs-workflow](https://app.grut-tech.com/studio/actions?id_workflow=create-dict-to-outputs-workflow) built-in Grut's workflow and run it with the following parameters:

1. **inpt\_dict\_var:** our example of response displayed above
2. **inpt\_name\_process:** *parse-receitaws*
3. **inpt\_email:** your email/username registred in Grut's Studio
4. **inpt\_pwd:** your pwssword for Grut's Studio

After your run it, you can [check your parser and test](https://app.grut-tech.com/studio/actions?id_workflow=outputs-dict-parse-receitaws) it with a valid re Wesponse.

### 3. Build your rules with workflow

This is the most critical part, where you build the core of our KYC. We recommend you to first draw a flowchart using [MIRO](https://miro.com/app/dashboard/) or similar tool to save time and get organized before coding it with Grut.

In our example we want to validate some conditions to either approve or denied a company during our KYC process. We will run a basic KYC checking ***status*** of the response from receita WS, the ***company's situation*** with brazilian IRS and the ***province of company***, where we only want to approve those registered in São Paulo.&#x20;

We've drawn the following flowchart to represent our KYC process.

<figure><img src="https://3076900743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzrrXYXUZDKOwwzos9oK6%2Fuploads%2FN89ljSgZkEdJXUKhuZYs%2Fimage.png?alt=media&amp;token=88196505-c239-4349-974d-0474d5911ccf" alt="" width="375"><figcaption><p>KYC Decision Process - Example</p></figcaption></figure>

Now that we have organized our decision process, we will create a new workflow. Our first block will be our new autogenerated workflow [we've created here](https://docs.app.grut-tech.com/project-examples/pages/iTUEfmjhKsMju7LxNzfG#2.-parse-apis-response). We will check the outputs *status, situacao and UF* as final outputs so we can track the workflow complete response.&#x20;

Add a second block, select the *Gateway* option and fill up the fields corresponding with the first Rule (status == 'OK').&#x20;

Create the blocks for when the above condition is either True or False and you will have something like the image below.&#x20;

<figure><img src="https://3076900743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzrrXYXUZDKOwwzos9oK6%2Fuploads%2FTG0pyj17dOsr2SaLD7OL%2Fimage.png?alt=media&amp;token=a9d308b2-c370-4bd1-b966-f8d15758c7d0" alt="" width="401"><figcaption><p>Rule 1: Status consulta</p></figcaption></figure>

Note that if *status == 'OK'* we will pass (meaning not doing anithing). If it's false, meaning status != 'OK', we will set the denied reason as "status\_consulta|" and continue to check other variables. We will use it later.

<figure><img src="https://3076900743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzrrXYXUZDKOwwzos9oK6%2Fuploads%2FpTABO6RrjB7rhBhoivWJ%2Fimage.png?alt=media&amp;token=f5149157-7701-4289-b4a2-b76059a0e35b" alt=""><figcaption><p>Rule 1: set deny reason</p></figcaption></figure>

Add another gateway for second rule (situacao != 'ATIVA') and fill the blocks corresponding with True and False. Do the same for the third condition (UF != 'SP').&#x20;

<figure><img src="https://3076900743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzrrXYXUZDKOwwzos9oK6%2Fuploads%2FaDOMqWyjWy1W56TKkp3B%2Fimage.png?alt=media&amp;token=386c6cd6-5f07-48b4-8d5b-8c5368bebce5" alt=""><figcaption><p>Rule 2: Company IRS situation </p></figcaption></figure>

<figure><img src="https://3076900743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzrrXYXUZDKOwwzos9oK6%2Fuploads%2FFZEc29BQT6xIGddDKuxl%2Fimage.png?alt=media&amp;token=c3a4431f-f172-4449-a078-e3b65e96530a" alt="" width="338"><figcaption><p>Rule 3: Company brazilian district </p></figcaption></figure>

<figure><img src="https://3076900743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzrrXYXUZDKOwwzos9oK6%2Fuploads%2F34T0ZrMZ1GsP4OCgslSg%2Fimage.png?alt=media&amp;token=134ae56c-6c71-4373-a046-f9d2c09dc389" alt="" width="277"><figcaption><p>Concatenate rules decisions</p></figcaption></figure>

<figure><img src="https://3076900743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzrrXYXUZDKOwwzos9oK6%2Fuploads%2FeuMkjmRYo5j3v6kQ4Pyh%2Fimage.png?alt=media&amp;token=7212084f-677b-4cc3-8b0a-f99c99339587" alt="" width="281"><figcaption><p>Workflow Settings</p></figcaption></figure>

Now that we have all possible flows for our KYC process, we concatenate possible deny reasons using [generic-concatenate built-in action](https://app.grut-tech.com/studio/actions?id_action=generic-concatenate) and check if it's empty, which means we should deny the KYC process if there are at least one reason for denial. If there are none, we should approve our KYC.

We then save our KYC workflow and test it with a valid example such as the below dict.

`{"status": "OK", "situacao": "ATIVA", "uf": "SP"}`

We should see a response as follows:

```json
{
   "Block 1 - aprovado": True,
   "Block 2 - motivo_reprova_situacao": None,
   "Block 3 - motivo_reprova_status": None,
   "Block 4 - motivo_reprova_uf": None,
   "Block 5 - motivos_reprova":"",
   "Block 6 - reprovado": None,
   "Block 7 - situacao_21":"ATIVA",
   "Block 8 - status_23":"OK",
   "Block 9 - uf_26":"SP"
}

```

You should also check if the intire workflow is working properly, validating all situations.

### 4. Putting all together

[^1]: To autogenerate variables based on example dict you need to use Grut's API
