Disbursement blocks

Enable beneficiary compensation to be initiated from the claims workflow

Overview

If a claim is approved, this typically results in some form of compensation in favour of the beneficiary. Such benefit transfers are implemented on Root by means of payout requests (for monetary compensation) and fulfillment requests (for non-monetary compensation).

You can include disbursement blocks, which are a special flavour of block, in the claims blocks schema for your product module to enable the creation of disbursement requests as part of the claims workflow. Root currently supports three types of blocks for initiating benefit transfers to beneficiaries:

These blocks render as a card with a summary and an action button, and positionally renders on the same form as the other claims blocks. Unlike other blocks, disbursement blocks do not accept direct user input, and rely on either other blocks or existing policy data to complete their fields (e.g. payout amount, bank details).

Creating payment and fulfillment requests

Disbursement blocks serve a single function - to create payout or fulfillment requests. These requests are objects saved to the platform and displayed in the payout workflow tooling on the Root management dashboard. Creating a request does not result in an immediate transfer to the beneficiary. The transfer only occurs once the request has been processed in the payout tooling.

Payout requests contain information on the recipient (including their bank account details) and the amount to be paid out. Fulfillment requests contain additional customised information on the nature and quantity of the compensation.

By default, disbursement blocks can be viewed and actioned at any step, from when the claim is opened to when it's finalised. You can hide or disable individual disbursement blocks during specific stages of the claim process using display conditions. For example, you may want to disable a payout request block until the claim has an approval status of "approved". While a disbursement block is disabled or hidden, it cannot be used to create a payout or fulfillment request.

Currently, disbursement requests cannot be created via the API. They can only be created via the Root dashboard user interface, by clicking the "Create..." action button rendered by the corresponding disbursement block.

On a given claim, each disbursement block can be used to create only a single request. Once the "Create..." action button has been clicked the button will change to display a link to the created request. This means that you cannot overwrite the request you created. To enable the creation of multiple requests on a single claim, you can add multiple disbursement blocks to the claims blocks schema.

Setting the request object parameters

Disbursement blocks are not form inputs and do not accept direct user input. The request parameters can be populated in one of the following ways.

1. Hardcode the values

You can hardcode the parameters values in the block definition in the claims blocks schema. Such hardcoded values cannot be changed by the dashboard user working on the claim, and will therefore be the same for every claim on the product. In the example below, the payout amount is hard coded as 100000 (cents), which is equivalent to R1000.00.

[
  {
    "type": "payout_request",
    "key": "claim_payout_request",
    "title": "Payout request",
    "description": "Claim payout",
    "amount": "100000",
    "payee": {
      ...
    }
  }
]

2. Reference policy parameters

You can use handlebars to reference benefit information saved on the policy. For example, you could configure the product module to save the benefit amount on the policy's module object.

Policy object:

{
  "claim": {
    "policy": {
      "module": {
        "benefit_amount": 100000
       },
      ...
    },
    ...
  }
}

Claim payout request block:

[
  {
    "type": "payout_request",
    "key": "claim_payout_request",
    "title": "Payout request",
    "description": "Claim payout",
    "amount": "{{claim.policy.module.benefit_amount}}",
    "payee": {
      ...
    }
  }
]

πŸ“˜

Beneficiaries and existing bank details

This method is also most often used to reference the bank details of the relevant beneficiaries automatically, not relying on the dashboard user to manually enter bank details.

3. Reference another block's state

You can use handlebars to reference another block state, which can in turn allow for user input. For example, you can reference a block of type "input.currency" to allow the user to change the payout amount.

[
  {
    "type": "input.currency",
    "key": "payout_amount",
    "title": "Enter the amount to pay out"
  },
  {
    "type": "payout_request",
    "key": "claim_payout_request",
    "title": "Payout request",
    "description": "Claim payout",
    "amount": "{{claim.block_states.payout_amount.value}}",
    "payee": {
      ...
    }
  }
]

Disbursement block states

Like other blocks, each disbursement block has a corresponding block state object saved to the claim. However, unlike other blocks, disbursement blocks do not store any input parameters in state.

If no disbursement request has been created using a specific block, that block's state will be empty. Once a request has been created, the UUID of the corresponding request object will be saved to the block state, together with its type and status. This UUID can be used to retrieve the request together with all the parameters stored on the request object.

Payout request block

Payout requests are created from blocks of type "payout_request". These blocks create requests for monetary payouts like electronic funds transfers (EFTs) into the beneficiary's bank account. Settlements to other credit or ledger systems (e.g. store card account) are implemented using fulfillment requests.

Block definition

Properties

PropertyDefinition
"key"String. The unique identifier for this block.
"type"String. The block type. In this case, "payout_request".
"title"String. The text heading that will be rendered for this block.
"description"String. The description of the payout request.
"amount"String. The payout amount in cents. Note: This should be the final payout amount that the recipient will receive.
"payee"Object. See the payee table.

Payee

Which properties are required on the payee object depends on whether the payee is the policyholder.

PropertyDefinition
"type"String. The payee type. One of ["beneficiary", "policyholder"].
"amount"String. The final amount to be paid out to the payee. Note: This should be the same as block.amount.
"percentage"String. The percentage of the total disbursement represented by this payout. Note This percentage is only for information purposes and is not automatically applied to the payout amount. If you want to apply a percentage to the payout amount you can achieve this using handlebars helpers (see example below).
"payment_details"Object. See the payment details table.
"last_name"String. Required if payee type is "beneficiary". Forbidden otherwise.
The last name of the payee.
"first_name"String. Required if payee type is "beneficiary". Forbidden otherwise.
The first name of the payee.
"policyholder_id"String. Required if payee type is "policyholder". Forbidden otherwise.
The UUID of the policyholder.

Payment details

PropertyDefinition
"type"String. The type of payment. Only "eft" is allowed.
"details"Object. The banking details for the Electronic Funds Transfer. See the details table.

Details

PropertyDefinition
"bank_name"String. The name of the bank. Must be one of ["absa", "african_bank", "bidvest", "capitec", "discovery_bank", "fnb", "investec", "ithala", "nedbank", "old_mutual", "postbank", "standard_bank", "tyme_bank"].
"branch_code"String. The branch code.
"account_type"String. The account type. Must be one of ["savings_account", "cheque_account"].
"account_number"String. The bank account number.

Example

{
  "block": {
    "type": "payout_request",
    "key": "payout_request",
    "title": "Claim payout",
    "amount": "{{ divide (multiply claim.block_states.total_payout_amount.value claim.policy.beneficiaries.[0].percentage) 100}}",
    "description": "Monetary payout to be actioned on approval of claim {{ claim.claim_number }} ",
    "payee": {
      "type": "beneficiary",
      "first_name": "{{ claim.policy.beneficiaries.0.first_name }}",
      "last_name": "{{ claim.policy.beneficiaries.0.last_name }}",
      "amount": "{{ divide (multiply claim.block_states.total_payout_amount.value claim.policy.beneficiaries.[0].percentage) 100}}",
      "percentage": "{{ claim.policy.beneficiaries.0.percentage }}",
      "payment_details": {
        "type": "eft",
        "details": {
          "bank_name": "{{ claim.policy.beneficiaries.0.payment_details.details.bank_name }}",
          "branch_code": "{{ claim.policy.beneficiaries.0.payment_details.details.branch_code }}",
          "account_type": "{{ claim.policy.beneficiaries.0.payment_details.details.account_type }}",
          "account_number": "{{ claim.policy.beneficiaries.0.payment_details.details.account_number }}"
        }
      }
    }
  }
}
12801280

State

PropertyDefinition
"type"String. The block type. In this case, "payout_request".
"payout_request_id"String. The UUID of the payout request created using this block.
"status"String. The current status of the payout request created using this block One of ["pending", "completed", "rejected" or "pending_claim_approval"].
{
  "claim": {
    "block_states": {
      "claim_payout_request": {
        "type": "payout_request",
        "payout_request_id": "f6ee39a8-109a-4541-bb8c-2eb4d1b48530",
        "status": "pending"
      }
    },
   ...
  }
}

Fulfillment request block

Fulfillment requests are created from blocks of type "fulfillment_request". These blocks facilitate benefit transfers that do not involve a direct funds transfer to the beneficiary. Examples include airtime, vouchers, and settlements on client-side credit or ledger systems.

Fulfillment request blocks must reference a fulfillment type, which you need to define separately.

Type definition

The fulfillment type serves as a template for fulfillment request objects generated from a fulfillment request block. This allows you to specify the data that will be included on the fulfillment request.

Fulfillment types are defined for each product module as an array of objects in a JSON schema. This array is configured using the Workbench CLI tool in the root-config.json file.

Properties

PropertyDefinition
"key"String. The unique identifier of the fulfillment type. Referenced in the block definition.
"label"String. The description of the fulfillment type.
"fulfillmentData"Object. See the fulfillment data section.

Fulfillment data

The fulfillmentData object allows you to specify the custom parameters that will be included on each fulfillment request of this fulfillment type.

Within the fulfillmentData object, each parameter is defined as a key-value pair. In each case, the key is the name of the parameter, which you need to define. The keys will be referenced in the block definition.

The "value" is an object that constrains the nature of the data that can be stored under that parameter.

{
  "<key>": <value>,  
  "<key>": <value>
}

The value corresponding to each key is its own object with the following properties.

PropertyDefinition
"label"String. The description of the parameter.
"valueType"String. The data type for the parameter. One of ["string", "currency", "enum"].
"valueOptions"String. Required if the valueType is "enum". Forbidden otherwise.
The list of possible values that can be stored under this parameter. Each option is defined as a key-value pair. The value must be referenced in the block definition.

Example

{
  "configVersion": "2021-05-09",
  "productModuleName": "Dinosure",
  "productModuleKey": "dinosure",
  ...
  "settings": {
    ...
    "claims": {
      ...
      "fulfillmentTypes": [  
        {
          "key": "airtime",
          "label": "Airtime",
          "fulfillmentData": {
            "airtime_amount": {
              "label": "Airtime amount",
              "valueType": "enum",
              "valueOptions": {
                "10000": "R100",
                "20000": "R100"
              }
            },
            "cellphone_number": {
              "label": "Cellphone number",
              "valueType": "string"
            }
          }
        }
      ]
    }
  }
}

Block definition

Properties

PropertyDefinition
"key"String. The unique identifier for this block.
"type"String. The block type. Must be "fulfillment_request".
"title"String. The text heading that will be rendered for this block
"description"String. The description of the request.
"fulfillment_type_key"String. The key of the fulfillment type referenced by this block.
"fulfillment_data"Object. The fulfillment data that will be included on the request object. Must correspond to the fulfillmentData object defined on the fulfillment type.

Example

{
    "block": {
        "type": "fulfillment_request",
        "key": "claim_fulfillment_request",
        "title": "Fulfillment request",
        "description": "Airtime benefit",
        "fulfillment_type_key": "airtime",
        "fulfillment_data": {
          "airtime_amount": "R100",
          "cellphone_number": "0663633538"
        }
    }
}
811811

State

PropertyDefinition
"type"String. The block type. In this case, "fulfillment_request".
"fulfillment_request_id"String. The UUID of the fulfillment request created using this block.
"status"String. The status of the fulfillment request created using this block. One of ["pending", "successful" or "rejected"].
{
  "claim": {
    "block_states": {
      "claim_fulfillment_request": {
        "type": "fulfillment_request",
        "fulfillment_request_id": "c51d67d4-fbcb-4ebc-8a73-628c866b7912",
        "status": "pending"
      }
    },
   ...
}

Annuity request block

Annuity requests are configurable schedules that automatically generate payout requests at a specified interval and for a specified duration. Annuity requests are useful for income protection or similar products where regular payouts need to be made to the policyholder over a specified period in the event of a valid claim.

Once the annuity request is successfully created, platform will automatically create payout requests at the specified interval, for the specified duration. These payout requests can then be processed by the insurer's finance team in the payout tooling on the Root management dashboard.

πŸ“˜

Annuity request limitations

Annuity requests have the following limitations:

  • They can only be created for payout requests, not fulfillment requests
  • The payouts must be in favour of the policyholder

Block definition

Top-level properties

PropertyDefinition
"type"String. The block type. In this case, "annuity_request".
"key"String. The unique identifier for this block.
"description"String. This description will appear on the claim view on the Root management dashboard. It can be used to inform the user processing or handling the claim about the nature of the annuity request.
"frequency"Object. The frequency at which payouts will be created. See the frequency table.
"duration"Object. The period of time over which payout or fulfillment requests will be created. See the duration table.
"amount"Integer.
The amount, in cents, of each payout request that will be generated.

Frequency

PropertyDefinition
"type"String. One of ["monthly", "yearly"].
"time_of_day"String. The time of day that the payout or fulfillment requests should be created, in HH:MM 24-hour format.
"day_of_month"Integer. The day of the month that payout fulfillment requests should be created.
"month_of_year"Integer. Required if type equals "yearly". Forbidden otherwise. The month of the year when payout or fulfillment requests will be created.

Duration

PropertyDefinition
"count"Integer. Required if end_date is omitted. Forbidden otherwise. The total number of payout or fulfillment requests that will be created.
"end_date"String. Required*if count is omitted. Forbidden otherwise. The date, in format "YYYY-MM-DD", after which payout or fulfillment requests will no longer be created.

Example

{
    "block": {
      "key": "retrenchment_annuity_request",
      "type": "annuity_request",
      "amount": 500000,
      "duration": {
        "count": 12
      },
      "frequency": {
        "type": "monthly",
        "time_of_day": "00:30",
        "day_of_month": 1
      },
      "description": "Payout schedule for the retrenchment benefit"
    },
    "disabled_if": "{{#ifEquals 'approved' claim.approval_status}}false{{else}}true{{/ifEquals}}"
  }
12841284

An annuity request block on the claims workflow

State

PropertyDefinition
"type"String. The block type. In this case, "annuity_request".
"annuity_request_id"String. The UUID of the annuity request object created from this block.
"status"String. The status of the annuity request created using this block. One of ["active", "completed"].
{
  "claim": {
    "block_states": {
      "retrenchment_annuity_request": {
        "type": "annuity_request",
        "annuity_request_id": "765edf67-3c32-4210-b604-ba9e08fd582f",
        "status": "active"
      }
    },
   ...
  }
}

What’s Next