Applies to API Package: Equity Crowdfunding Portals (v3.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:
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 workflow.
The Equity Crowdfunding Portal
The Equity Crowdfunding Portal is the actor that has in charge the overall orchestration of the workflow. 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 Toolkit into a website. To subscribe as an Equity Crowdfunding Portal, you must:
Be an Italian company, or a foreign company with a permanent operational branch in Italy;
Be entitled of an Italian Fiscal Code;
Review and prepare all the documents and informations required in the Engagement and KYC section below;
Submit a subscription request.
Please note that your subscription request may not be accepted in accordance to the terms and conditions of Banca Sella S.p.A.
Investors
An Investor is anyone who agrees to invest in one or more campaigns through the Equity Crowdfunding Portal website. As a consequence, Investors are those who originate Orders towards one or more Campaigns emitted by Companies. 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, Companies are those who receive the collected funds related to the Orders subscribes online by Investors. Any Company is a registered partner of the Equity Crowdfunding Portal; its engagement is required by the CONSOB regulation. To subscribe as a Company, you must:
- Be an Italian company, or a foreign company with a permanent operational branch in Italy;
- Be entitled of an Italian Fiscal Code;
- Have subscribed and agreed with the terms and conditions of an Equity Crowdfunding Portal that has previously subscribed and activated the Equity Crowdfunding Portals Toolkit.
- Review and prepare all the documents and informations required in the Engagement and KYC section below;
- Submit a subscription request.
- Be compliant to the CONSOB regulation for being registered as an "Offerente".
Please note that your subscription request may not be accepted in accordance to the terms and conditions of Banca Sella S.p.A.
System setup and service activation
The system setup and service activation requires some steps that you need to perform before it is possible to operate online.
In order to fight fraud, money laundering and financing of terrorism, you will be required to answer to a set of legal obligations related to the banking license known as KYC (Know Your Customer).
In order to fulfill to these legal obligations, you will be required to provide a set of documents and informations in addition to the contracts for the service subscription. In the following you can find the list of all the documents and informations that will be required.
| Legal entities |
|---|
| Company name Full company profile Articles of incorporation Corporate budget of last fiscal year A complete extraction from the company register All the natural person documents and informations related to the company legal responsible |
The engagement and KYC process is structured as follows:
- Provide the data required to fill the subscription contracts online through our web forms
- Print and sign the pre-compiled subscription contracts
- Send via mail the signed subscription contracts
- We will receive and review the subscription contracts, and perform the evaluation process; at the end of the evaluation process we will provide a feedback by contacting you directly
Operational Workflow
This section provides a detailed description of the workflow that involves Investors and Companies while interacting in the Equity Crowdfunding Portal website.
Campaigns
A campaign is the first logical object that has to be created, once a company has been registered in the system.
Creating a campaign
You can create a campaign by calling POST Create Campaign and providing the following data:
{
"companyId": "USR03VRXZ1726000668",
"name": "Name of the new campaign",
"description": "Description of the new campaign",
"targetAmountMin": "100000.00",
"targetAmountMax": "120000.00",
"currency": "EUR",
"closeDate": "30/12/2017"
}
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 closeDate is the date after which the campaign will be considered closed; on that date, the Equity Crowdfunding Portal should invoke PUT Campaign Closed and avoid the creation of new order subscriptions.
Updating a campaign
Once a campaign has been created, it may be updated by invoking PUT Update Campaign. Please note that only name, description, targetAmountMin and targetAmountMax fields may be updated.
Opening a campaign
Once a campaign has been created, it should be opened by invoking PUT Campaign Open in order to allow the creation of new order subscriptions.
Managing an open campaign
While a campaign is open, you can create order subscriptions from 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 places an order on a specific campaign by calling GET Campaign Investors.
Closing a campaign
At the end of its duration, a campaign should be closed by invoking PUT Campaign Closed and avoid the creation of new order subscriptions.
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 Success and providing the following data:
{
"ordersToExecute": [
"ORD4387623841827947",
"ORD4387623841827124",
"ORD4387623841809974"
],
"ordersToUndo": [
"ORD2309823841827364"
],
"orderToSplit": {
"orderId": "ORD2309823842182736",
"companyAmountToExecute": "600.00",
"companyAmountToUndo": "400.00",
"feeAmountToExecute": "60.00",
"feeAmountToUndo": "40.00"
}
}
The ordersToExecute array contains the full list of IDs of all the order objects 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 directed to the company bank account.
The ordersToUndo array contains the full list of IDs of all the order objects that must be refunded to the respective investor. This array may be empty. The refund operation is perfomed by refunding each investorby providing a money back of the originally 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 splitted across the targetAmountMax amount, if required.
Once the campaign has been finalized, a campaignCashout 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 Cashoutusing the cashoutId returned by the PUT Campaign 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 FINALIZED_FAIL status by invoking PUT Campaign Failure. Please note that this endpoint does not require any additional parameted other than the ID of the campaign; the effect of finalizing a campaign with unsuccess is that the entire amount of collected funds is refunded to the investorsthat have subscribed an order for that campaign. The refund operation is performed as described above.
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 for the campaign itself.
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": "",
"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.
investor object 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.Orders
An order is the pivotal concept of the whole Equity Crowdfunding Portals Toolkit. 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",
"orderTimestamp": "2018-02-14 14:34:17,785",
"orderThreshold": "OVER_THRESHOLD",
"investorAccount": {
"iban": "IT08I0129518672180944821099",
"holderName": "Mario",
"holderSurname": "Rossi",
"holderBusinessName": ""
},
"totalAmount": "1100.00",
"orderAmount": "1000.00",
"feeAmount": "100.00",
"currency": "EUR",
"channel": "MONEYTRANSFER",
"description": "Order KZ78/23/2017-CAMP56/2017",
"item": "1000 company shares",
"itemUnitPrice": "",
"itemQuantity": "",
"portalOrderCode": "KZ78/23/2017",
"portalInvestorCode": "RSSMRA81L04A859O",
"portalCompanyCode": "KZ78",
"portalCampaignCode": "CAMP56/2017"
}
An order ties together the other three main object described above in this tutorial: an investor, a company and a campaign.
Mandatory fields that identify an order are orderTimestamp (which represents the timestamp of the event of order subscription confirmed by the investor, as tracked by the Portal website) and orderThreshold(which provides info about the fact that the order is under or over the investment thresholds as specified by the CONSOB Regulation). 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 orderPayment (see paragraph below for more details on orderPayment object). 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 field.
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 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 paymentId in your database since it is required to correctly manage the order lifecycle.
Managing an order
Once created, an order may be managed through the following steps:
- Waiting. If the
investoragrees to submit the money, then you need to declare to be waiting the order payment by calling PUT Order Waiting. Declaring anorderwaiting 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 yourinvestorrequires to pay by means of a money transfer, or if the credit card transaction has been successfully authorized. - Failed. If the
investorrequires to pay by means of a credit card transaction, but the transaction authorization is refused, then you need to declare theorderas failed by calling PUT Order Failed. This call sets up the system to automatically discard any money-in flow related to thatorder. - Cancelled. If the
orderneeds to be declared as null, then you should call PUT Order Cancelled. Please note that this operation should be intended as "unusual practice" and avoided whenever possible.
You can retrieve the details of an order by calling GET Order. The status of an order may be one of the following:
CREATEDTheorderhas been created.WAITINGTheorderhas been confirmed, but not yet accounted.ACCOUNTEDTheorderhas been accounted.SPLITTEDTheorderhas been placed in thecompanyaccount.INCORRECT_AMOUNTTheorderhas been payed with an incorrect amount.FAILEDTheorderhas been declared as failed.EXPIREDTheorderhas expired.
Cancelling an order
order has regulatory side-effects, and should be an operation performed only in the cases set out in the CONSOB regulation.An order can be excluded from the order list of a campaign in the following cases:
- after having been created, but not yet accounted, or
- after having been accounted.
You can cancel an order by calling PUT Order Cancelled. Once an order has been cancelled, it cannot be cashed out to the company owning the campaign.
order, then it will be automatically refunded to its investor by the system. This operation is instantaneous and cannot be undone.Order Payments
An orderPayment is the actual payment associted to an order object. It is automatically created whenever you create a new order.
You can retrieve an orderPayment by calling GET Order Payment. All the sub-components of a orderPayment are described in the following paragraphs.
Moneyins
A moneyin is the reception of a money flow from the investor of an order through a specific channel, as specified in the order creation call.
Before the creation of an order, typically you should have asked the investor which is the payment method he/she is going to use in order to actually perform the orderPayment for the order he/she is submitting on the equity crowdfunding platform website. Currently, we support the following channels through which you can handle moneyins from your investors:
- Money transfers. You can accept order payments by means of direct money transfers to the
company'scampaignaccount. In order to integrate money transfers moneyins, you should use theMONEYTRANSFERidentifier for thechannelwhile creating anorder. You should also provide your users the complete instructions on how to correctly perform the money transfer to your collection account, by providing the following information:- IBAN: the IBAN associated to your portal account
- Payer: name and surname of the
investor - Receiver: BANCA SELLA S.p.A.
- Description: the
orderIdyou got after calling POST Create Order - Amount: the
totalAmountdeclared while calling POST Create Order - Currency: EUR
investor, you should set theorderasWAITING, by calling PUT Order Waiting. - Credit cards. You can enable your
investorsto use any valid credit card of the VISA and MASTERCARD circuits. In order to integrate credit card moneyins, you should use theCARDidentifier for thechannelwhile creating anorder. After having created theorder, you should interact with the GestPay APIs in order to correctly manage the process of actually performing the credit card transaction. Once the credit card transaction has been managed, you should either:- Set the
orderasWAITING, by calling PUT Order Waiting, if the credit card transaction has been authorized; - Set the
orderasFAILED, by calling PUT Order Failed, in the credit card transaction has been rejected.
- Set the
After having declared the order as WAITING, a moneyin will be created whenever the matching money flow will be detected by the system, either by receiving the amount of the credit card transaction or by receiving the expected money transfer in the collection account.
You can retrieve the moneyin of each order by calling GET Order Payment Moneyin; the call will return some basic descriptive properties as shown in the example below.
"moneyin" : {
"moneyinId": "MI1718015031960314A4ODNM",
"channel": "CARD",
"date": "14/03/2017 18:01:50",
"status": "ACCEPTED",
"totalAmount": "105.00"
}
Moneyouts
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
orderAmounthas been transferred to thecompanyaccount dedicated to thecampaign - The related
feeAmounthas 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.
"moneyout" : {
"moneyoutId": "MO171743030374714XDN8M544",
"orderId": "TRX201703141743034503BTAO",
"companyId": "USR03OGDXBF1709000024",
"requestedDate": "14/03/2017 17:43:03",
"status": "REQUESTED",
"totalAmount": "105.00",
"feeAmount ": "5.00",
"companyAmount": "100.00",
"cashoutAvailableAmount": "100.00",
"currency": "EUR"
}
Refunds
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 newrefundwill be created for each one of itsorders.
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 transactions; if the moneyin happened through a money transfer, then the refund is performed by 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.
"refund" : {
"refundId": "MB0536717121200E7YV8K13121",
"orderId": "TRX20170308174401625CTVMSP",
"companyId": "USR036K3SKK1708000013",
"description": "Refunding payment TRX20170308174401625CTVMSP",
"requestedDate": "13/03/2017 05:12:01",
"executedDate": "13/03/2017 07:11:38",
"status": "EXECUTED",
"failDescription": "",
"companyAmount": "100.00",
"currency": "EUR"
}
Disputes
A dispute happens whenever an investor requires a refund of a specific credit card transaction directly to his/her bank, without contacting the equity crowdfunding portal.
The typical process that leads to the creation of a dispute is as follows:
- An
investormay ask to be refunded for the total (or partial) amount of a transaction that has been processed on his/her credit card. This process may be initiated directly by the issuer bank of theinvestorcredit card, with no interaction with the equity crowdfunding portal that handled the transaction. The reason that motivate such request may be related to fraud suspects (e.g., the credit card has been stolen) or because of commercial reasons (e.g., the payer has not received the items - this case should not happen in equity crowdfunding). - As a consequence, the issuer bank requires the cerdit card circuits to open a dispute, in order to get a refund for the
investor. - Whenever such event happens, then a
disputeis created and the equity crowdfunding portal is notified via email. - In order to properly handle each
dispute, you will be requested to provide all the documentation that may help to contest the dispute and submit evidence to try to reverse the payer repudiation and reclaim the funds.
As a consequence of this process, a dispute may be closed as either:
WONIn this case, the dispute will not result in any effect;LOSTIn this case, the equity crowdfunding portal is asked to provide the funds to fully refund theinvestor. These funds are automatically debited to the equity crowdfunding portal cash account.
If a dispute is created, you may have evidence of such event by requesting the list of disputes with GET Disputes. For each element of the list, you have access to some basic descriptive properties as shown in the example below.
"dispute" : {
"disputeId": "DSP170309HS5D6V101",
"orderId": "TRX20170308155833621AYEY2A",
"orderAmount": "30.0",
"status": "OPEN",
"openDate": "25/02/2017",
"closeDate": ""
}
Exceptions
An exception is an unattended event that prevents the system from its expected behavior. Usually, an exception is a signal of something that went wrong while performing some action.
Three levels of severity of exceptions may be expected:
WARNING: typically, is raised whenever the system required your attention on some specific event that requires your intervention to be addressed, but that is not blocking the correct execution of the expected workflow.ERROR: is raised whenever something wrong happened in the internal subsystem. Your intervention is not explicitly required, but be prepared to be contacted by our service assistance in order to help solve the problem.CRITICAL: is raised whenever something wrong happened while moving funds in the internal subsystem. Your intervention is not explicitly required, but be prepared to be contacted by our service assistance in order to help solve the problem.
If an exception is raised, you may have evidence of such event by requesting the list of exceptions with GET Exceptions. For each element of the list, you have access to some basic descriptive properties as shown in the example below.
"exception": {
"exceptionId": "EXSPLT1222917030219IVZYRX14241",
"description": "Cash out error",
"objectId": "COU17131212834031008VHWWDI",
"objectType": "CASH_OUT",
"priority": "CRITICAL",
"status": "OPEN"
}
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 created or waiting status.
More specifically, a unidentified transfer can be originated in these occasions:
- A money transfer without a
orderId. If noorderIdis provided in the description of an incoming money transfer, then it cannot be recognized as a potentialmoneyinfor anyorder. As a consequence, the incoming transfer is marked as unidentified transfer. - A money transfer with an invalid
orderId. If anorderIdis provided in the description of an incoming money transfer, but it cannot be matched with theorderIdof anyorderin created/waiting 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 incorrecttotalAmountis marked as unidentified transfer since it cannot be correctly matched with anyorderin created/waiting status. Please note that theinvestorshould be notified to repeat the money transfer with the correctorderIdandtotalAmount, since it is not allowed to aggregatemoneyins(i.e., for eachorderone and only onemoneyinis 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",
"type" : "UNIDENTIFIED",
"status" : "SENT_BACK",
"amount" : "120.00",
"currency" : "EUR",
"description" : "An unexpected money transfer",
"payerName" : "John Doe"
}