Applies to API Package: Equity Crowdfunding Portals (v4.0) by Banca Sella
This article provides a quick reference on how to integrate your backend with Fabrick Platform Equity Crowdfunding Portals solution provided by Banca Sella.
The intended reader for the following contents is a CTO or a developer working to integrate the Equity Crowdfunding Portal backend.
The following sections assume that you have successfully onboarded on Fabrick Platform and have subscribed at least the following API packages:
- Equity Crowdfunding Portals (v4.0)
You will also need the following data in order to successfully integrate the Equity Crowdfunding Portals solution:
- Your
portalId
: the identification code of your portal that must be used to interact with the Equity Crowdfunding Portals solution. This has been released by Fabrick after the activation of the Equity Crowdfunding Portals solution, and looks like the following:PRTWNP603529756
.
Introduction
The Equity Crowdfunding Portals solution is a powerful toolkit ideal to provide operational support to the online activity of equity crowdfunding portals.
Please note that the activation of the Equity Crowdfunding Portals Toolkit is reserved to Italian Equity Crowdfunding Portals operating under the guidelines of the Italian Regulation for Equity Crowdfunding ("Regolamento CONSOB in materia di raccolta di capitali di rischio tramite portali on-line"), and in particular compliant to the OPT-IN option.
Actors
This section provides a quick description of the actors involved in the system and their roles.
The Equity Crowdfunding Portal
The Equity Crowdfunding Portal is the actor that has in charge the overall orchestration of the system usage and workflow of operations. Every event is originated from an action that any actor performs on the Equity Crowdfunding Portal online website. The Equity Crowdfunding Portal is also the subject that interacts with the API endpoints that enable the integration of the Equity Crowdfunding Portal solution into its website.
Investors
An Investor is anyone who agrees to invest in one or more campaigns on the Equity Crowdfunding Portal website. As a consequence, investors are the subjects who originate the orders towards one or more campaigns emitted by a company.
Investors are registered users of the Equity Crowdfunding Portal according to the CONSOB requirements. Ensuring that investors are appropriately registered and guided through the investing process is a duty of the Equity Crowdfunding Portal.
Companies
A company is any registered partner of the Equity Crowdfunding Portal who is entitled of collecting funds in one or more campaigns. As a result, a company is the subject that receives the collected funds related to the orders subscribed by investors.
Any company is a registered partner of the Equity Crowdfunding Portal; its engagement is required by the CONSOB regulation.
Managing Campaigns
Once a company has been registered in the system, a campaign is the first logical object that you should create.
Please note that you cannot create a company, since they are created by Banca Sella after the onboarding process.
Creating a campaign
You can create a campaign by calling the POST Create Campaign endpoint.
The input body sould look like the following:
{
"companyId": "USR03VRXZ1726000668",
"name": "Name of the new campaign",
"description": "Description of the new campaign",
"targetAmountMin": 100000,
"targetAmountMax": 120000,
"currency": "EUR",
"expectedClosingDate": "2019-12-31",
"portalSuccessFee": {
"fixedAmount": 1200,
"variableAmountPercentage": 0.15
}
}
Every campaign is related to a company, and has a specific name
and description
.
The targetAmountMin
is the minumum amount of funds that need to be collected from investors to state that the campaign is successful. Please note that this limit may be modified, and that it constrains the possibility of closing the campaign once the campaign reaches its end.
The targetAmountMax
is the maximum amount of funds that may be collected; this limit does not imply any operational limitation on the subsequent operations on the campaign.
The expectedClosingDate
is the date after which the campaign will be considered closed; on that date, the Equity Crowdfunding Portal should invoke PUT Campaign Closed to avoid the creation of new order subscriptions.
[NEW v4.0] The portalSuccessFee
object contains the optional fields that let the portal to specify if a success fee should be applied to the total amount of funds transferred to the company while cashing out a successful campaign.
Updating a campaign
Once a campaign has been created, it may be updated by invoking PUT Update Campaign.
Opening a campaign
Once a campaign has been created, it should be opened by invoking PUT Campaign Opened in order to allow the creation of new order subscriptions.
Managing an opened campaign
While a campaign is open, you can create orders for your investors. There are a few functions that help you managing an open campaign.
You can retrieve the amount of funds collected on a specific campaign by calling GET Campaign Amount.
You can retrieve the full list of orders of a specific campaign by calling GET Campaign Orders.
You can retrieve the full list of investors that have placed an order on a specific campaign by calling GET Campaign Investors.
Closing a campaign
At the end the collection period, a campaign should be closed by invoking PUT Campaign Closed to avoid the creation of new orders. Orders waiting for payment will still be able to correctly receive the subscription funds.
Please note that closing a campaign does not imply any action on collected funds, neither on pending orders.
Finalizing a successful campaign
Once a campaign has been closed, it must be finalized. The finalization of a campaign is the last action that has to be performed, and depends on the result of the campaign itself.
If the campaign was successful (i.e., at least the targetAmountMin
amount of funds has been collected), the campaign should be put in FINALIZED_SUCCESS
status by invoking PUT Campaign Finalized - Success and providing the following data:
{
"ordersToExecute": [
"TRX4387623841827947",
"TRX4387623841827124",
"TRX4387623841809974"
],
"ordersToUndo": [
"TRX2309823841827364"
],
"orderToSplit": {
"orderId": "TRX2309823842182736",
"companyAmountToExecute": 600,
"companyAmountToUndo": 400,
"feeAmountToExecute": 60,
"feeAmountToUndo": 40
}
}
The ordersToExecute
array contains the full list of IDs of all the orders that must be aggregated to cashout the collected funds. This array must contain at least one order ID. The cashout operation is performed by bulking all the collected funds and executing a unique money transfer towrds the company bank account. Please note that if a portal success fee was specified, it will be subtracted by the total amount of funds collected before executing the cashout money transfer.
The ordersToUndo
array contains the full list of IDs of all the orders that must be refunded to the investors. This array may be empty. The refund operation is perfomed by refunding each investor by providing a money back of the submitted funds on the original submission channel (i.e., if the order was payed through a credit card, a money back on the same credit card will be executed).
The orderToSplit
object contains the information of the unique order that may be split across the targetAmountMin
amount, if required.
Once the campaign has been finalized, a campaign cashout is created to provide details about the actual execution of the money transfer to the company. You can retrieve such details by calling GET Campaign Cashout using the cashoutId
returned by the PUT Campaign Finalized - Success call.
Finalizing an unsuccessful campaign
If the campaign was unsuccessful (i.e., the amount of funds collected was not at least equal to targetAmountMin
), the campaign should be put in FINALIXED_FAIL
status by invoking PUT Campaign Finalize - Failure. Please note that this endpoint does not require any additional parameter other than the ID of the campaign; the effect of finalizing a campaign with failure is that the entire amount of collected funds is refunded to the investors that had subscribed any order on that campaign. All refund operations are perfomed by refunding each investor by providing a money back of the submitted funds on the original submission channel (i.e., if the order was payed through a credit card, a money back on the same credit card will be executed).
Cancelling a campaign
If you have created a campaign but you need to discard it, you can cancel a campaign by invoking PUT Campaign Cancelled. Please note that the campaign must be either in CREATED
, OPEN
or CLOSED
status. If the campaign is in OPEN
or CLOSED
status, there must be no orders created on the campaign itself.
Managing Investors
Once you have created a campaign, the next step towards the creation of an order is the creation of an investor.
Creating an investor
You can create an investor by calling POST Create Investor and providing the following data:
{
"name": "Mario",
"surname": "Rossi",
"businessName": null,
"fiscalCode": "RSSMRA81L04A859O",
"type": "NATURAL_PERSON",
"address": "via dei Fori Imperiali, 34",
"postalCode": "00100",
"city": "Roma",
"country": "Italia",
"email": "mario.rossi@email.it",
"phone": "+393471234567"
}
Every investor is an independent object with its own data fields. A fundamental distinction is that between physical investors (i.e., those with type NATURAL_PERSON
) and company investors (i.e., those with type LEGAL_PERSON
).
Updating an investor
Once an investor has been created, it may be updated by invoking PUT Update Investor. All the data fields of an investor may be updated, including its type.
Please be careful while updating an investor since once updated, also all the previous registered orders of that investor will be related to the updated object; this may cause inconsistencies or even data loss.
Managing Orders
An order is the pivotal concept of the whole Equity Crowdfunding Portals solution. An order is by all means the representation of an actual subscription order placed by an investor in a specific campaign on the website of the equity crowdfunding portal. Please note that the information related to an order must be compliant to the data declared by the investor while stepping through the investment-awareness process on the equity crowdfunding portal website, as required by the CONSOB regulation.
Creating an order
You can create an order by calling POST Create Order and providing the following data:
{
"investorId": "INV4387623841827364",
"companyId": "USR035DXCJF1708000011",
"campaignId": "COL17031405X2DY182241000067",
"investorAccount": {
"iban": "IT08I0129518672180944821099",
"holderName": "Mario",
"holderSurname": "Rossi",
"holderBusinessName": null
},
"totalAmount": 1100,
"orderAmount": 1000,
"feeAmount": 100,
"currency": "EUR",
"channel": "MONEY_TRANSFER",
"description": "Order KZ78/23/2017-CAMP56/2017",
"portalOrderCode": "KZ78/23/2017",
"portalOrderDatetime": "2019-06-12T12:45:12.234Z",
"portalInvestorCode": "RSSMRA81L04A859O",
"portalCompanyCode": "KZ78",
"portalCampaignCode": "CAMP56/2017"
}
As you can see from the above example, an order ties together the other three main objects described above in this tutorial: an investor, a company and a campaign.
While creating an order, you are asked to provide data to recognize the source of the money-in flow that the investor will use to submit the order payment (see paragraph below for more details on order payments). Typically, if the investor is going to pay by means of a money transfer, you will need to specify the investor's bank account details in the investorAccount
object. These data is useful to perform checks of consistency against the payer name and account after having received the order payment. You can find more details in the money in section below.
The orderAmount
is the exact amount of money that the investor will be payed back in company shares if the campaign is going to be successful. You can specify additional fees to be debited to the investor in the feeAmount
field. The field totalAmount
must be equal to the sum of orderAmount
and feeAmount
.
The portal*Code
fields are provided for easyness of reconciliation with the equity crowdfunding portal information system, and allow the specification of custom identification codes to be related to the newly created order.
Please note that these data cannot be modified once submitted to the system.
Once you have created a new order, you will be returned an orderId
that uniquely identifies the newly created order. Please remember to store the ID in your database since it is required to correctly manage the order lifecycle.
Once created, an order may be managed with the following operations:
PUT Order Waiting. If the investor agrees to submit the money, then you need to declare to be waiting the order payment by calling PUT Order Waiting. Declaring an order waiting sets up the system to be prepared to receive the incoming money-in flow. This is the typical step that you may want to follow whenever your investor requires to pay by means of a money transfer, or if the credit card transaction has been successfully authorized.
PUT Order Failed. If the investor requires to pay by means of a credit card, but the transaction authorization is refused, then you need to declare the order as failed by calling PUT Order Failed. This call sets up the system to automatically discard any money-in flow related to that order.
PUT Order Cancelled. If the investor requires the cancellation of the order, you can set the order as cancelled by calling PUT Order Cancelled. Please be aware that:
- if the order was in
WAITING
status, then any related payment will be rejected. - if the order was in
ACCEPTED
status, then the money is automatically refunded to the investor.
Managing Payments
Every order has an associated payment. This ojbect contains all the references to the different steps each payment follows from the investor towards the company collecting funds.
MoneyIn
A moneyin is the reception of a money flow from the investor through a specific channel, as specified in the order creation call. Currently, we support the following channels through which you can handle moneyins from your investors.
Money transfers. You can accept payments by means of direct money transfers. In order to integrate money transfers, you should use the MONEYTRANSFER
identifier for the channel while creating an order. You should also provide your users the complete instructions on how to correctly perform the money transfer to the collection account of your portal, by providing the following information:
- IBAN: the IBAN associated to your portal account
- Debtor: name and surname of the investor
- Creditor: BANCA SELLA S.p.A.
- Description: the
orderId
you got after calling POST Create Order (e.g.,TRX4387623841809974
) - Amount: the
totalAmount
declared while calling POST Create Order - Currency: EUR
Once you have provided the operational instructions to your investor, you should set the order as WAITING
, by calling PUT Order Waiting.
MoneyOut
A moneyout is the internal financial flow associated with an order. The creation of moneyouts happens automatically when the system receives a moneyin matching with a waiting order and performs the routing instructions provided by the order creation instruction.
Once a moneyout has been created, it means that:
- The related orderAmount has been transferred to the company account dedicated to the campaign;
- The related feeAmount has been transferred to your fee collection account (this cash component is optional)
You can retrieve the full list of moneyouts by calling GET Order Payment Moneyouts. For each element of the list, you have access to some basic descriptive properties as shown in the example below.
{
"moneyoutId": "MO181951400555230W9V5001485",
"companyId": "USR02KZLN1827000201",
"status": "AVAILABLE",
"amount": 810.68,
"cashoutAvailableAmount": 810.68,
"currency": "EUR",
"createdDatetime": "2019-05-30T18:51:40.000Z",
"executedDatetime": null
}
Refund
A refund is automatically created whenever an order is returned to its investor. You cannot explicitly create a refund since the system automatically manages a refund creation in the following cases:
- When you require the cancellation of an already accounted order;
- When you finalize an unsuccessful campaign, a new refund will be created for each one of its orders.
Each refund is executed accordingly to the channel of the related moneyin; i.e., if the moneyin happened through a credit card transaction, then the refund is performed by requiring a write off of the corresponding transaction; if the moneyin happened through a money transfer, then the refund is performed through a money transfer as well.
You can retrieve a refund by calling GET Order Payment Refund; the call will return some basic descriptive properties as shown in the example below.
{
"refundId": "MB0287617555553OEKR12000041",
"status": "EXECUTED",
"createdDatetime": "2018-06-28T02:26:28.000Z",
"executedDatetime": "2018-06-28T06:00:25.000Z",
"amount": 40,
"currency": "EUR"
}
Unidentified Transfers
A unidentified transfer is a money flow that is received by the equity crowdfunding portal that cannot be matched with any order in either CREATED
or WAITING
status.
More specifically, a unidentified transfer can be originated in these occasions:
- A money transfer without a
orderId
. If noorderId
is provided in the description of an incoming money transfer, then the system cannot recognize it as a potential moneyin for anyWAITING
order. As a consequence, the incoming transfer is marked as unidentified transfer. - A money transfer with an invalid
orderId
. If anorderId
is provided in the description of an incoming money transfer, but it cannot be matched with theorderId
of any order in eitherCREATED
orWAITING
status, then the incoming transfer is marked as unidentified transfer. - A money transfer with a valid
orderId
, but with an incorrecttotalAmount
. A money transfer with an incorrecttotalAmount
is marked as unidentified transfer since it cannot be correctly matched with any order in eitherCREATED
orWAITING
status. Please note that the investor should be notified to execute again the money transfer with the correctorderId
andtotalAmount
, since it is not allowed to aggregate moneyins (i.e., for each order one and only one moneyin is expected).
Whenever an unidentified transfer is detected, the system automatically reacts by rejecting the money transfer and sending back to the investor exactly the same amount of money received.
You cannot interact, configure or modify this mechanism, since it is put in place in order to preserve the correct alignment of the money flows of the system itself.
If an unidentified transfer is detected, you may have evidence of such event by requesting the list of unidentified transfers with GET Unidentified Transfers. For each element of the list, you have access to some basic descriptive properties as shown in the example below.
{
"unidentifiedTransferId": "UTR170309AHMC07172815000001",
"amount": 120,
"currency": "EUR",
"description": "TRXWRONGID",
"payerName": "John Doe",
"status": "RECEIVED",
"type": "UNIDENTIFIED",
"receivedDatetime": "2019-06-24T09:39:19Z",
"refundedDatetime": null
}