KEY CONCEPTS
Admin Users are the operational team that you give access to manage your platform, who have access to the Difitek Back Office.
In the database model, Admin Users are Users whose is_admin
flag is set to true.
Admin Users are able to act as normal Users on your front-end, so they can use their same profile to create Offerings or Investments as if they were a non-Admin User.
Admin Users also have certain additional privileges to access data through the Difitek API. For instance, the GET /offerings
function only returns Offerings that are Published, Closing or Settled when logged in as a normal, non-Admin User. When logged in as an Admin User, the same function will return all Offerings, including those that have Draft lifecycle status.
Similarly calling GET /offerings/{offering_id}
for an Offering whose life_cycle_stage
is Draft will return 'Not Found' for non-Admin Users but it will return the Offering's data for Admin Users.
This allows Admin Users to see how an Offering will appear to your Users on your front-end when screening the Offering before it is published and visible to non-Admin Users.
When you create your Network by signing up for developer access, the email address and password that you provide are used to register a new Admin User for your Network. Get in touch with Difitek to add more Admin Users to your account or to enable or disable the is_admin
flag for any User in your Network.
A common approach to building up a fintech application's User base is to work with 'affiliates', which are individuals or organizations that recommend new Users to your platform. The affiliates system in the Difitek back-end allows you to keep track of which new Users were recommended by a given affiliate source.
Each User has an affiliate_code
attribute and a referral_code
attribute, which are both optional. Use affiliate_code
to store the code that should be given out by the affiliate User and used by new Users when they join your platform. Use referral_code
to save an affiliate code given to a User as they sign up. Therefore a new User A will be considered to have been referred to your platform by User B if User A's referral_code
is equal to User B's affiliate_code
.
A User's affiliate activity can then be tracked through the Difitek Back Office by clicking on the 'User Affiliate Activity' option from the Users page, which will show a list of all Users who were recommended and a list of their Investments, in case you wish to set up any kind of commission arrangement with your affiliate Users.
One common use case of the affiliates system is to allow Brokers to onboard their existing investor bases to allow them to invest through your platform, whilst keeping track of their investment activities using the Users' referral_code
attributes.
The Difitek API makes extensive use of HTTP Status Codes and exceptions in order to help you handle various types of User error on your front-end. In general the API will always return one of the following HTTP Status Codes:
API responses showing an HTTP Status Code of 200 indicate that the API request has been processed successfully. Responses in the 4xx range indicate that the API is operating successfully but for some reason the server has not processed the request. A 5xx response means that the API is not responding correctly, and if you see such a response please get in touch with the Difitek support team to let us know.
The most common 4xx responses used by the Difitek API are:
id
when no such object exists in the databaseIn addition to the HTTP Status Codes shown in the status
field and 'success' or 'failure' strings provided in the outcome
field, every API Exception also returns:
code
- a unique exception reference number for this exceptionuser_message
- a user-friendly message that you may display to Users on your front-end by default (although of course you are free to display your own custom error message to Users if you would prefer)developer_message
- a longer-form message that should not be shown to Users but may help your development team to debug the front-end applicationWhen implementing your front-end, you should take into account as many exceptions as you expect your Users to encounter, especially when they concern critical processes such as making an Investment or adding funds to a Wallet.
Blocking a User means that the User will no longer be able to log in to your platform. If the User tries to authenticate with the API then it will return an exception indicating that the User does not currently have access to the platform.
Users can be blocked from using your platform in two ways: automatically through the API by implementing POST /self/blockUser
based on some activities on your front-end or through the Difitek Back Office.
An example of a scenario in which you may wish to call the 'block user' function automatically from the front-end is if your User has failed part of your registration process, such as getting a 'FAIL' response from a third-party KYC/AML service or perhaps failing an investor appropriateness quiz.
Users can be blocked indefinitely or for a set time-period such as 30 days. If they are blocked for a set time-period then they will automatically be unblocked after that expiry date, and they will then be able to log in and interact normally with your platform.
Please see http://contego.com for more information about Contego services.
A Content Delivery Network (CDN) is an online storage facility for your documents.
When using Difitek's CDN through the Back Office, set the Document's source_type
attribute to 0 so that when you retrieve the Document later its url
will be automatically signed with Difitek's CDN credentials, which will allow you to access the Document for a short period of time.
When using your own CDN through the API then set the Document's source_type
to 1 so that you retrieve the plain url
from the Difitek database and then add your own access credentials if required.
All Documents that are uploaded through the Difitek Back Office application are held in Difitek's CDN, and accessible from the Back Office or through the API. No additional agreement is required to use the Difitek CDN through the Back Office application.
Custom Fields can be used to extend the native Difitek database model with your own attributes that are required for your preferred object models.
Objects such as Users, Organizations, Offerings and Investments can use any number of custom fields in addition to the native fields that are provided by the Difitek database.
To create a new custom field through the API you can use the relevant PATCH
function to set a value for a new field by providing the field name and its value in a JSON array. For instance, to create a new custom field for the logged-in User called investor_type
with a value of High Net Worth Individual you would implement PATCH /self
with request body:
{ "custom" : { "investor_type" : "High Net Worth Individual" } }
Then when you call GET /self
the data response will include your new investor_type
attribute in the User's custom
data array.
By default there is a limit of the number of custom fields available per object in the sandbox environment. If you come across an API exception that indicates that you have reached your limit of custom fields then get in touch with the Difitek support team in order to raise your limit.
Data Models
Through the Back Office or the Admin API it is possible to create and store a structure for your platform's custom fields for Users, Organizations, Offerings and Investments.
Note that the creation of Data Model objects is not required in order to use the custom
attribute of any object: Data Models are designed to be no more than helpers for non-technical users of the Back Office, so that they can be guided when entering data that are not part of the Difitek native object data model.
A Deal Room is a collection of functionality that can be added to an Offering in order to support a variety of investor due diligence, discussion, communications and task management functions.
An Offering can have any number of Deal Rooms. Typically an Offering would just have one Deal Room if it is used for a due diligence process that is the same for all relevant Users. However, there is no reason why you cannot have several Deal Rooms for a single Offering if you want to have multiple discussion forums or multiple different task lists, with different groups of Users given access to each one.
Deal Rooms can only be accessed by Users who apply to access them and are subsequently granted permission by the manager of the Deal Room. By default the creator of the Deal Room is its only manager. Once other Users have been granted access to the Deal Room, the manager can grant manager access to those Users as well, so that they have management privileges such as approving or rejecting requests to join the Deal Room.
Once a User has been granted access to the Deal Room, they will be able to access a discussion Forum (if you have implemented it on your front-end), create Topics, add a Post to a Topic, and add a Comment to a Post. A User approved to a Deal Room will also be able to respond to due diligence Tasks by marking them as Started or Completed. Such Users can also be granted access to Document Groups in order to view private Documents that are restricted only to Users who are granted access on an individual basis.
The email verification feature allows you to ensure that your Users have a valid email address before allowing them to continue interacting with your platform.
It is an optional feature but it is recommended to prevent your platform from accepting Investments from Users whom you later cannot reach because the email address that they used to register is not correct.
By turning on the 'New User Created' mail trigger in the Difitek Back Office, and creating a mail template that uses the #EMAIL_VERIFY_STRING# keyword, the Difitek Back Office will send an email containing a validation link to all Users at the point that they register on your platform.
By clicking this link, the new User can be taken to a page on your front-end which implements POST /public/verifyEmail
, which will set the User's email_verified
flag to true.
If the User has email_verified
empty or set to false then they have not yet verified their email address, and you can use this flag to redirect them to an email verification page on your front-end as soon as they log in to your platform if you want to force all Users to verify their email address before continuing with your full registration process.
If your User for some reason does not receive the verification email, or it is accidentally sent to their spam folder, you can allow them to re-send the verification email by implementing POST /self/resendVerificationEmail
.
If the User has accidentally entered the wrong email when first registering, you can allow them to change their email address by implementing POST /self/changeEmail
.
Implementing the Change Email function at any time will reset the User's email_verified
flag to false, and it will re-send the verification email to the new email address, so if the User had previously verified an old email address then they will need to verify the new one in order to restore email_verified
to true.
Offerings can be marked as 'featured' through the Difitek Back Office, meaning that their is_featured
flag is set to true.
Featured Offerings are accessible to unauthenticated Users, i.e., Users who have not yet logged in, through the GET /public/featuredOfferings
route. They are also accessible through the logged-in equivalent GET /offerings
. In both cases, only Offerings that are Published, Closing or Settled will be returned.
Use featured Offerings to display Offerings on pages that are accessible to users before they have logged in, for instance on your homepage.
Note that in some circumstances and in certain regulatory environments, Offerings should not be displayed publicly due to securities promotions restrictions. In those cases, you should require all Users to log in, and perhaps pass an accreditation or KYC/AML process, before allowing them to view the details of any Offerings. In that scenario the Featured Offerings feature would not be used.
A common requirement when returning lists of data is to return the list in a filtered or sorted format. For instance, on your front-end's Offerings page you may wish to display a list of Offerings by date order or by increasing or decreasing number of investors who have invested in the Offering so far.
Similarly, you may wish to filter the Offerings by their additional_type
in order to show your Users the Offerings in their preferred sector or category.
In both of these cases, you should use this format to add filtering or sorting options to the GET
request:
Filtering
GET /.../{endpoint}?orderby={attribute}&sort={asc|desc}
Sorting
GET /.../{endpoint}?filter[{attribute}][operator]={op}&filter[{attribute}][value]={value}
where {op} can be: = (EQUALS), in (IN ARRAY), > (GREATER THAN) or < (LESS THAN)
or
GET /.../{endpoint}?filter[{attribute}][operator]={op}&filter[{attribute}][lower_value]={value}&filter[{attribute}][upper_value]={value}
where {op} is: between (BETWEEN)
For example, to return all Offerings sorted by descending created_at
date (i.e., newest first) you would implement:
GET /offerings?orderby=created_at&sort=desc
To return all of the User's Offerings that have greater than 50,000 shares you would implement:
GET /self/offerings?filter[num_of_shares][operator]=>&filter[num_of_shares][value]=50000
To return all of the User's Payouts with a due_date
between 1 April 2015 and 31 March 2016 you would implement:
GET /self/payouts?filter[due_date][operator]=between&filter[due_date][lower_value]=2015-04-01&filter[due_date][upper_value]=2016-03-31
To filter using a custom field, prepend custom__
in front of your attribute name. Therefore, to return all Offerings which have
{
...,
"custom" : {
"regulation" : "506c"
},
...
}
you would implement:
GET /offerings?filter[custom__regulation][operator]==&filter[custom__regulation][value]=506c
Please see https://www.gbgplc.com for more information about GBGroup services.
Please see http://www.globalcustodian.co.uk for more information about GCEN services.
Please see https://www.gojip2p.com for more information about Goji P2P services.
Difitek has produced a whitepaper entitled: "Three Approaches to KYC/AML as part of an online Investor Onboarding Process". Please get in touch to request a copy.
Investor Onboarding is the process by which your platform’s Users become acceptable investors or lenders for your operations. Acceptability will depend on your regulatory environment, compliance considerations and your own business requirements and focus.
Running this process efficiently is a critical success factor for any online finance platform, because it takes new Users of your platform from the point at which they are willing to register fully to your service to the point at which they can actively engage with the financing opportunities that you provide.
It is the first significant gate through which your Users must pass in order to start using your full service, and therefore it will have some drop-off rate. This drop-off rate can be measured over time. It will be influenced by many factors, such as your platform’s messaging and positioning, the overall user experience, the segmentation of visitors to the platform, and the amount of information each User is asked to provide.
A high drop-off rate is not necessarily worse than a low one: allowing many Users into your platform might reduce the overall success rate of your other key processes such as matchmaking or closing & settlement; or, more importantly, your platform might not be upholding its compliance and regulatory requirements if it simply approves all Users.
The compliance and regulatory requirements are often grouped together under the general category of Anti-Money Laundering and Know Your Customer (‘AML/KYC’), which typically requires your platform to ensure that none of its Users appear on any Politically Exposed Persons (PEPs) or Sanctions lists.
The Difitek framework facilitates various standard approaches and workflows to KYC/AML as well as providing the flexibility for developers to create their own proprietary process, either by building on top of dozens of integrated third-party services that can support online KYC/AML checks or by integrating new such services by using Difitek’s integration kit.
In this section we illustrate three approaches to KYC/AML as part of your online investor onboarding process, showing in general how each one is implemented using the Difitek framework:
We will not cover topics here relating to ‘enhanced KYC/AML and due diligence’, the management of ongoing compliance, or the maintenance of KYC/AML records. Moreover, this whitepaper does not contain any advice - legal or otherwise - for your compliance requirements, and it should not be read as such. It contains solely guidance on technical process design and implementation.
We start by explaining the typical data that are required for an online data collection process and by sharing some sample screenshots from online finance platforms showing the User’s point of view.
The Loanbook object allows for a slightly different investment process, which is common in P2P lending implementations, when compared to the typical structure of creating Investments for an Offering.
When creating an Investment for an Offering, the investor User typically sees a particular Offering that is currently open for investment, and decides to make an Investment into that specific Offering.
Loanbooks, on the other hand, are categories of Offerings that do not represent specific investment opportunities but a set of criteria in which an investor User is interested.
For instance, a Loanbook might be defined as having a term
of 3 years and an interest_rate
of 6%.
Users can make Investments into a Loanbook to indicate that they would like to invest into anything that falls into that category. Once an Investment is made for a Loanbook, the platform admin team can use the Back Office to make investments from a Loanbook into specific Offerings as and when required by the business. This can also be done automatically as part of an 'automatch' process through the Difitek API.
For example, your platform might run two ongoing Loanbooks: one at an interest rate of 8.5% for up to 24 months with LTV of 85%; and another at an interest rate of 6.5% for up to 24 months with LTV of 65%.
Investors will make investments into one of the Loanbooks and the admin team will track how much funding each Loanbook has received through the Back Office. At the same time, the admin team will be identifying and preparing specific investment opportunities which will be the ultimate target of the Users' funds, and which match the criteria of one of the Loanbooks.
On a regular basis, the admin team might decide to invest from the Loanbook into such an investment opportunity, and at that point the investor User's funds are put to work.
Please get in touch with Difitek to enable Loanbook features for your platform.
Please see https://www.mangopay.com for more information about Mangopay services.
Multi-Factor Authentication (MFA) is a method of access control whereby your platform's Users are only able to access your platform after presenting at least two independent pieces of evidence for their identity, typically from the following categories: knowledge (something they know); possession (something they have), and inherence (something they are).
The Difitek back-end supports multi-factor authentication in various ways. All Users are required to provide either an email address and password or social sign-on credentials using a service such as LinkedIn in order to create their account and log in. Either of these counts as single factor authentication, because the User has presented the password (something they know).
You can also request that Users successfully provide a code that is sent to their phone (something they have) via SMS using an integrated service such as Veridu. Such services will update the User's phone_verified
attribute to true, which you can then use on your front-end to grant or deny access to the User.
You can require mult-factor authentication as part of the registration process as a one-off or you can request it at any point in your platform's processes, for instance at the point when a User is trying to make an Investment or download a Deal Room Document.
The Offering object has various attributes that allow you to set hard conditions that will prevent certain Investments from being accepted automatically without needing any kind of manual review or approval process.
If a User tries to make an investment that contravenes any of these rules, the Difitek API will automatically return an Exception, which can then be used to show a message to the User on your front-end.
All of these rules are optional and they are not set by default. If the relevant attribute is set - i.e., contains data - then the rule is considered to be enabled. The data can be set for the Offering through the API or in the Back Office.
open_date
is a date before which it is not possible to create an Investmentclose_date
is a date after which it is not possible to create an Investmentmin_commitment
is a minimum amount for the Investment's investment_amount
. Set this to 1000 to ensure, for example, that all investments are above 1,000 in your currency.max_commitment
is a maximum amount for the Investment's investment_amount
. Set this to 100000 to ensure, for example, that all investments are below 100,000 in your currency.max_overfunding_amount
is the total sum of Investments that will be accepted for an Offering. Set this to the same value as the Offering's funding_goal
to prevent any overfunding. Set it to a higher amount to allow overfunding up to that amount. Set it to a lower amount to create several phases of the Investment such that, for example, 50% should be filled first before the remaining 50% can be opened.The Organization's contact_point
attribute holds the id
of the User who should be considered the main contact for the Organization. The user_id
of an Organization can never be changed: it always holds the id
of the User who created the Organization. However, since Users may leave Organizations at any time, the contact_point
of an Organization can be updated to a different User.
At the point at which the Organization is created, the User who was logged-in when calling the POST /organizations
function is assigned by default as the Organization's contact_point
. This User is also the 'author' of the Organization so the User's id
will also be saved into the Organization's user_id
field.
To update the Organization's contact_point
to a different User, you must first add this User to the Organization's team by calling the POST /organizations/{organization_id}/members/{user_id}
function. After the User is a member of the Organization, i.e., the User is listed in the Organization's members
list, then you can update the Organization's contact_point
by using PATCH /organizations/{organization_id}
to set the new contact User's id
in this field.
If at a later date the contact User leaves the Organization, i.e. you implemented DELETE /organizations/{organization_id}/members/{user_id}
to remove that User from the Organization's members
list, then the Organization's contact_point
will automatically revert to the 'author' of the Organization, i.e. the User whose id
is saved in the Organization's user_id
field.
When an Organization is first created, it automatically has one member - the User who was logged in when creating the Organization. The Organization's members
attribute will contain a list containing just this User. This User is considered to be the 'author' and contact_point
of the Organization.
The User can then add other Users to their Organization by implementing POST /organizations/{organization_id}/members/{user_id}
.
Any User who is a member of an Organization is considered to have equal privileges its the original author, so Organization members can edit the Organization, view the Organization's Draft Offerings, edit Draft Offerings, create a Deal Room for the Offering, and view any Documents that are attached to the Organization, its Offerings or its Offerings' Deal Rooms.
An Organization member can also remove other Users from the Organization (assuming that this function is available and implemented on your front-end), including the Organization's original author, although if all Users are removed from the Organization then the Organization's contact_point
will always revert back to the original author.
The Organization members feature is used in various ways, for instance to show an Organization's fundraising team or to collect various Users together as part of an institutional investment firm. You may also wish to make membership of an Organization a pre-requisite of completing your platform's registration process, by ensuring that the contact_point
of some Organization approves a User by accepting their request to join that User's Organization.
When using the Difitek framework for the first time, one of the most important considerations will be how to represent your platform's particular type of investment activities.
Difitek customers manage investments in many different asset classes: business loans, private securities, real estate investments, P2P lending, equity funding, public/private placements, and many more. In each case the asset needs to be represented in the Difitek data model.
To represent real-life processes as closely as possible, whilst also allowing for the greatest flexibility across different asset classes, Difitek's data model is split into Organizations and Offerings.
An Organization represents the capital raising entity, whether it be a company, a property, a fund, or a project. The Offering represents the activity of raising capital. An Offering must have one and only one Organization. An Organization can have many Offerings, in the case that a company undertakes several capital raises, for example.
When designing your data model, it is recommended to keep this distinction in mind so that the data are held in the most logical place within this structure.
For example, if your Organization will represent a company, then there are certain fields that are independent of the company's current fundraising activities, such as its founding date, its location, or a description of its business practises. By saving these data in the Organization, you can access them once via each of the Organization's Offerings (by looking up the Offering's organization_id
) instead of having to copy the same data into each new Offering every time it is created.
Similarly, if you have information that are only relevant to the Organization's current fundraise, such as a current credit score, valuation, or fundraising open date, then store those data in the Offering.
In real estate implementations, it is most common to use the Organization to represent a property fund or an Special Purpose Vehicle (SPV), i.e., the asset in which investor Users will obtain shares (represented by Capitalizations) once the Offering is closed.
In secondary market implementations, it becomes more important to have a single Organization that owns all the secondary Offerings instead of one Organization per Offering, to ensure that the share registry is maintained correctly through the distribution and management of the Organization's Capitalization records.
The Difitek API is designed to support front-end financial services applications that will typically not show more than a number of items that can be displayed on a single page. For example, the usability of a site or application is affected by trying to display too many Offerings, Investments or Payouts on one page without using a user interface element such as a table.
By default, API requests that return lists of items such as GET /offerings
or GET self/organizations
will return only 12 items.
By specifying a limit parameter you can request more or less than the default number based on the front-end application's design requirements:
GET /offerings?limit=15
This will retrieve the first 15 items from the database. Then to retrieve the second 'batch' of data, specify a page parameter as the offset number of the item from the list:
GET /offerings?limit=15&page=15
This will return the second batch of 15 items from the database (specifying &page=0
would retrieve the page starting with the first item).
These parameters can be used in addition to filtering and sorting parameters, for example, to retrieve the third 10-item page of Organizations sorted by ascending display_name
you would request:
GET /organizations?limit=10&page=20&orderby=display_name&sort=asc
Since the API response time will accordingly be slower as the limit parameter is made larger in the request, it is recommended to use pagination wherever possible and to limit the number of items for any single request to a maximum of 20.
Restricted Offerings are Offerings that are only visible to VIP Users, in other words Users who have the is_vip
flag set to true. Offerings can be set to the Restricted lifecycle stage through the Back Office application or using PATCH /offerings/{offering_id}
.
The purpose of a Restricted Offering is to allow a limited group of your Users to get early access to certain Offerings before they are made generally available to all Users by making them Published.
For instance, you might have a group of power users whom you want to reward by giving them a first chance to see certain Offerings before anyone else. VIP Users can also make Investments for Restricted Offerings before any other non-VIP User gets the chance to see them.
This is not the same as a feature to show Offerings that have not yet opened on an Offering preview page. Under some countries' regulations, it is required to show the details of forthcoming Offerings for a certain time period before the Offering becomes 'Live' such that Users can make Investments for the Offering. To implement this feature, make the Offering Published but use the Offering's open_date
attribute to prevent any Investments until the relevant date.
Note that under some financial promotions regulations it is important to give all potential investors equal access to information about an Offering, so get legal advice before using the Restricted Offerings feature if it means that some Users will have preferential access to certain Offering materials.
Please see https://www.reyker.com for more information about Reyker services.
Introduction
Secondary Markets are common to peer-to-peer lending applications and increasingly to equity-based investment platforms, especially in real estate. A platform that operates a Secondary Market gives its Users the opportunity to re-sell their shares, represented by Capitalizations, to other Users on your platform.
Data Model
Organization
The ’Organization’ object represents the legal entity or asset in which Users own Capitalizations that can be be split and traded between users.
Capitalization
The Capitalization represents a bucket or batch of shares that are owned by a User. Capitalizations have a life_cycle_stage
attribute which is used to track whether the shares are Authorized, Issued or Offered. If a Capitalization is in 'Offered' stage then it can be attached to an Offering in order to be offered on the secondary market.
The Capitalization object ensures that shares cannot be created ex nihilo by creating new secondary Offerings that include a higher number of shares than the User originally acquired through previous Offerings.
Whilst it is in theory possible to operate a simple secondary market without using the Capitalization object, by tracking a chain of primary_offering_id
values of each secondary Offering, this leaves open the possibility that mistakes could be made in calculating how many shares are currently held by each User; and it makes it far more difficult to see at a glance the list of shareholders of an Organization.
Furthermore, your platform's admin team can benefit significantly from the Back Office functionality that enables distributing shares from the Offering to the investor Users in a way that ensures that shares are not accidentally lost or counted twice.
Offering
The ‘Offering(s)’ are comparable to ‘asks’ in a traditional secondary market, which will consist of a set of Offerings created by users who have a share ownership in the given Organization. Once a platform User decides to sell their shares they will create an Offering which inherits the attributes of the Organization, i.e., the asset, and the Capitalization, i.e., the current value of the shareholding.
The share price or value of the offering can either be set by the seller of shares or the platform operator. It is important that the following attributes are saved for secondary market Offerings:
number_of_shares
price_per_share
When attaching a Capitalization to an Offering, Users are not be able to input a figure larger than the number_of_shares
of the new Offering.
If the User wishes to sell only part of their shares, they should first 'split' their Capitalization into multiple parts and then attach one of the child Capitalizations in whole to the new secondary Offering.
Investments
The Investments are comparable to ‘bids’ in a traditional secondary market. The size of the Investment - based on its number_of_shares
value not its investment_amount
- dictates how much Capitalization will be allocated to the User when the Offering is closed. The creator of the Investment therefore represents the buyer.
An important consideration is to save the number_of_shares
into the Investment as well as the investment_amount
so that the Back Office Capitalization distribution features can be used.
Using the Secondary Market Statuses
It is important to use the different statuses of objects correctly. The single most important part in this structure is the Investment's Settled / Withdrawn life_cycle_stage
, to avoid double ownership in the same asset.
Organization:
Capitalization:
Offering:
Investment:
Why this feature is important
A share registry in our system is a list of Users who own shares, represented by the 'Capitalization' object, in an Organization. Many of Difitek's customers, especially those offering their own Organizations or SPVs through their platforms, need to report on this regularly to regulators or auditors.
Our system also provides a complete share valuation history for Users, so that all changes to share prices now feed through to each User’s portfolio, and can be retrieved using GET /self/capitalizations
.
Overall, this feature is a way to manage asset value on an Organization (entity / SPV) level rather than Offering by Offering, or Investment by Investment. Using Capitalizations is a much more logical place to keep this data, especially for platforms that manage secondary markets, which would otherwise need to follow multiple chains of Offerings and Investments in order to ascertain the current, final owner of a share.
How do Share Registries interact with Offerings and Investments?
For platforms that use this share registry feature, the Offerings and Investments are a mechanism to move shares from one User to another. They are no longer the ultimate record of a User’s portfolio: they are simply a record of how a transition of shares happened.
The share registry in Difitek's database is managed by an entity called a Capitalization. Capitalizations are ‘owned’ by an Organization, and an Organization can have multiple Capitalizations. A Capitalization is essentially a record of a User holding a certain number of shares of an Organization at a given price.
Each Capitalization has:
It can also be linked to an Offering, if the shares are currently being offered to Users.
The Back Office application enables a process where a Capitalization can be first attached to an Offering and then distributed automatically to all of the Investors of that Offering based on the number of shares they requested, as part of the Closing & Settlement process.
How does it work (non-technical)?
An Organization can issue shares (i.e. create a Capitalization) at any time. Issuing shares does not automatically adjust or dilute existing Capitalizations in the Organization, although those calculations can be made manually and then used to update the Capitalizations individually through the Back Office.
The Lifecycle Stages for a Capitalization are: Authorized -> Issued -> Offered -> Treasury -> Distributed:
As part of the Closing & Settlement process, there is a Back Office function called Distribute Capitalizations.
This process will take the original set of shares that were offered and then distribute them to the Offering’s investors, according to the number of shares that each investor requested when they created an Investment in the Offering.
In this way, at the end of the Offering->Investment process, an Organization will have an up-to-date list of all its shareholders.
Then if any shareholder wishes to put an offering onto the secondary market, they can follow the same process, to distribute some or all of their shares to new investors.
How does it work (technical)?
number_of_shares
for each Investment, since this will be used when distributing the Capitalization later.life_cycle_stage
= 4).life_cycle_stage
= Distributed and its child Capitalizations will have life_cycle_stage
= Issued. You will be redirected to the Organization's Capitalizations page to see the updated share registry.GET /self/capitalizations
to show a User their current share portfolio.P2P lending applications
Although the description has focused on equity share registries, the same process works just the same for loans.
An Organization offering a loan on a P2P marketplace can also create a Capitalization with Type = Debt instead of Equity, and use it to track and distribute loan parts, especially through a secondary market.
The only difference would be that the Number of Shares in a Capitalization would not necessarily be an integer, because a loan can within reason be split into any number of smaller pieces.
Is it necessary to set up Share Registries?
The methodology of simply setting up Offerings and tracking a User’s portfolio through their Investments works perfectly well without ever needing to create a set of Capitalizations to represent an Organization's share registry and then allocate them to investors.
However, we would recommend that platforms managing secondary markets consider implementing the few extra steps in the Back Office to recording share registries as well as Offerings and Investments, in order to ensure that secondary Offerings never get out of sync with the Organization's original share capital, and to improve the performance of your front-end platform, which might otherwise need to cycle iteratively down several chains of Offerings and Investments to find the current owner of any particular share or loan part.
The Difitek API allows Users to authenticate using an email address and password or through a Single Sign On service such as Facebook, LinkedIn or Twitter.
When authenticating as a User that is not using their email address and password, the cv-auth
header must still be generated in the normal way using one of Difitek's SDKs (see https://www.github.com/crowdvalley) except, instead of providing the User's email address and password, set email
= social and password
= social.
In addition, you must provide an additional header in the API request with:
key
= jwt-authvalue
= 'Bearer code
'As an example, your request might have the following headers:
cv-auth
: AuthToken ApiKey="demo-001", TokenDigest="JgNDOp5I/iU4xsl9P9mRTDE/zTQ=", Nonce="a978bbca17cad3ae915d7c70dac3e406", Created="2016-07-01T18:52:56+00:00", Username="social", Password="FwoOBgAc"jwt-auth
: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJleHAiOjE0Njc0ODM5ODYsInVzZXJuYW1lIjoicGF1bGhpZ2dpbnNAY2FudGFiLm5ldCIsImlhdCI6IjE0NjczOTc1ODYifQ.ihFvMob8OG7CKCMV7m-gTvx0M14ZIcCTDpN2VBX4ZuOw43tdEXul0DjZ6u4Uxh6UVXZsEHBtQIRvuMwlDW-ZZ6Y3n8xUvMR5h2tN520gEXAcc3RefVNbQEOrCPX5IHG_Ki02FIQJ0dOJs-OTZs8UZVAo0P9Tqx-W9AgJAZmUGAIIn order to generate the unique code
for creating the jwt-auth
token, please see the API Documentation for the Social endpoint.
The 'starter functions' are a collection of 15 of the most common back-ed functions in the Difitek API, which are requied by the majority of different fintech applications.
They include basic functions for registering new Users, logging in, showing a User's account information, showing published Offerings and making an Investment.
As a developer building a platform on top of the Difitek API for the first time, we would suggest reviewing and implementing the starter functions as a first step so that you can cover the basics before moving on to other features that may require slightly more complex user workflows, such as Deal Rooms, Payment Schedules or third party integrated services.
The Investment Lifecycle describes the process which Investments follow on the Difitek API.
The processes and rules can be restrictive, especially on the front-end, and they are designed to be so following discussions with financial regulators around the world. For example, it is not possible - even for admin users - to reject an Investment that has previously been Settled, because this would be equivalent to taking an investor's money and accepting a trade of securities, only to decide later that the trade should not be honored.
Similarly, if an Investment has been withdrawn by a User, it cannot be accepted by the admin team.
There are two ways that the lifecycle of Investments can be adjusted: through the API or through the Back Office application. The update rules for each case are as follows.
In the table below, use POST /offerings/{offering_id}/investments
where POST is written to create a new Investment in a starting lifecycle stage.
Use DELETE /investments/{investment_id}
to move an Investment into a different lifecycle stage where DELETE is written.
Use GET /investments/{investment_id}
to retrieve an Investment without updating its lifecycle stage where GET is written.
End Stage-> | Open | Rejected | Approved | Withdrawn | Settled |
---|---|---|---|---|---|
Start Stage | POST | POST | |||
Open | GET | DELETE | |||
Rejected | GET | ||||
Approved | GET | DELETE | |||
Withdrawn | GET | ||||
Settled | GET |
In the table below, use the Back Office features when logged in as an admin user to update the lifecycle stage of another User's Investment.
End Stage-> | Open | Rejected | Approved | Withdrawn | Settled |
---|---|---|---|---|---|
Start Stage | Create | ||||
Open | View | Reject | Approve | Settle | |
Rejected | View | Approve | |||
Approved | Reject | View | Settle | ||
Withdrawn | View | ||||
Settled | View |
The Offering Lifecycle describes the process which Offerings follow on the Difitek API.
The processes and rules can be restrictive, especially on the front-end, and they are designed to be so following discussions with financial regulators around the world. For example, it is not possible - even for admin users - to publish an Offering from the front-end, because this might allow your end Users to start promoting securities before the admin team has had chance to verify the offering materials.
Similarly, if an Offering has been Published, it cannot be reset to Draft status by the admin team, to ensure that the information given to potential investor Users on the front-end is consistent for all Users.
There are two ways that the lifecycle of Offerings can be adjusted: through the API or through the Back Office application. The update rules for each case are as follows.
In the table below, use POST /organizations/{organization_id}/offerings
where POST is written to create a new Offering in a starting lifecycle stage.
Use PATCH /offerings/{offering_id}
to move an Offering into a different lifecycle stage where PATCH is written.
Use DELETE /offerings/{offering_id}
to move an Offering into a different lifecycle stage where DELETE is written.
Use GET /offerings/{offering_id}
to retrieve an Investment without updating its lifecycle stage where GET is written, for the User's own Offerings. The User is not able to see all Offerings of other Users through this GET
function.
End Stage-> | Draft | Submitted | Rejected | Approved | Restricted | Published | Closing | Settled | Canceled |
---|---|---|---|---|---|---|---|---|---|
Start Stage | POST | ||||||||
Draft | GET | PATCH | DELETE | ||||||
Submitted | GET | DELETE | |||||||
Rejected | GET | DELETE | |||||||
Approved | GET | DELETE | |||||||
Restricted | GET | ||||||||
Published | GET | ||||||||
Closing | GET | ||||||||
Settled | GET | ||||||||
Canceled | GET |
In the table below, use the Back Office features when logged in as an admin user to update the lifecycle stage of an Offering.
End Stage-> | Draft | Submitted | Rejected | Approved | Restricted | Published | Closing | Settled | Canceled |
---|---|---|---|---|---|---|---|---|---|
Start Stage | Create | ||||||||
Draft | View | Update | Update | Update | |||||
Submitted | Update | View | Update | Update | Update | ||||
Rejected | Update | View | Update | Update | |||||
Approved | Update | Update | View | Update | Update | Update | |||
Restricted | View | Update | Update | Update | |||||
Published | View | Update | Update | ||||||
Closing | View | Update | Update | ||||||
Settled | View | ||||||||
Canceled | View |
Users of your front-end platform will most likely interact with it once they have logged in so that they can make Investments or submit an Offering for screening. However, you may wish to show some information to website visitors before they log in to your platform. In that case you can work with the API functionality under the /public
endpoint, which is designed for unauthenticated Users, i.e., website visitors who have not yet logged in.
Unauthenticated Users will not have a username or password with which to create a cv-auth token, so when implementing any of the /public
endpoints you must use username
= new and password
= new to create an unauthenticated User token with a Difitek SDK. Unauthenticated Users must still use a valid Network Name, API Key and API Secret in order to create a valid unauthenticated User token.
Once you have created such a token, you can implement any of the the /public
endpoint features, as well as the POST /users
feature, which also requires an unauthenticated User token.
By authenticating with the Difitek API using an unauthenticated User token you can implement Offerings, Organizations and User listings pages on your front-end that are accessible to Users before they log in. However, the majority of the functionality available through Difitek's back-end are restricted to logged-in Users.
Difitek does not provide any preset User onboarding workflows because every platform is unique and yours will inevitably have its own requirements. Instead, you have various ways to build your own User onboarding process.
Each User has several boolean attributes that are commonly used to represent gates in an onboarding process:
email_verified
phone_verified
term_service_accepted
registration_complete
has_been_approved
has_been_blocked
The email_verified
and phone_verified
fields can be viewed for a User but cannot be set directly. They are set to false by default and can only be set to true by the User completing a process.
If the User successfully verifies their email address (by clicking a private link in the verification email, taking them to a page on your front-end which correctly implements the POST /public/verifyEmail
function) then that User's email_verified
attribute will be set to true. This is commonly the very first step in any User onboarding process after the User registers with their email address and password, so a typical implementation of any page on your platform might include a check for email_verified
== true just after the User logs in, and if it is false then the User can for instance be redirected to a holding page explaining that the User must verify their email address in order to continue. It is also common to implement POST /self/resendVerificationEmail
on this holding page, in case the User cannot find the verification email and wishes it to be resent.
We would recommend enforcing email validation for all of your Users so that in the event that they make investments you have a way of reaching them, which under many regulatory environments is obligatory, for instance to send shareholder certificates or tax statements.
The remaining statuses can be used according to your own platform's business process requirements. Each such status is also visible in the Back Office.
Users can register to your platform using an email address and password or with a third-party authentication account such as LinkedIn.
If your User provides an email address and password then you should simply use that data to create a cv-auth token in order to authenticate using the GET /authenticate
API endpoint. You should never store a User's password as plain text in local browser storage, cookies or the User's custom
fields.
The Difitek API will never return the User's plain text password and Difitek staff do not have access to your Users' passwords. All passwords are stored encrypted.
You can allow Users to change their password by implementing the POST /self/changePassword
function.
VIP Users are Users on your platform whose is_vip
flag is set to true. You can grant or revoke VIP status to any User through the Difitek Back Office.
The VIP User feature is typically used to give certain Users early access to Offerings on your platform in conjunction with the Restricted Offerings feature. Offerings whose life_cycle_stage
is Restricted can be seen by VIP Users but not by non-VIP Users, making it possible for you either to create a dedicated page on your front-end for VIP Users to view Restricted Offerings or to show additional Offerings to VIP Users on a standard Offerings page, which implements GET /offerings
.
Equally, you may use the VIP User feature to create a separate class of User that may have additional privileges unrelated to Offerings, for example you may allow VIP Users to access additional content areas of your front-end platform that are not accessible to non-VIP Users.