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 investor
by 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 investors
that 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
investor
agrees to submit the money, then you need to declare to be waiting the order payment by calling PUT Order Waiting. Declaring anorder
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 yourinvestor
requires to pay by means of a money transfer, or if the credit card transaction has been successfully authorized. - Failed. If the
investor
requires to pay by means of a credit card transaction, but the transaction authorization is refused, then you need to declare theorder
as 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
order
needs 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:
CREATED
Theorder
has been created.WAITING
Theorder
has been confirmed, but not yet accounted.ACCOUNTED
Theorder
has been accounted.SPLITTED
Theorder
has been placed in thecompany
account.INCORRECT_AMOUNT
Theorder
has been payed with an incorrect amount.FAILED
Theorder
has been declared as failed.EXPIRED
Theorder
has 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
'scampaign
account. In order to integrate money transfers moneyins, you should use theMONEYTRANSFER
identifier for thechannel
while 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
orderId
you got after calling POST Create Order - Amount: the
totalAmount
declared while calling POST Create Order - Currency: EUR
investor
, you should set theorder
asWAITING
, by calling PUT Order Waiting. - Credit cards. You can enable your
investors
to use any valid credit card of the VISA and MASTERCARD circuits. In order to integrate credit card moneyins, you should use theCARD
identifier for thechannel
while 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
order
asWAITING
, by calling PUT Order Waiting, if the credit card transaction has been authorized; - Set the
order
asFAILED
, 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
orderAmount
has been transferred to thecompany
account dedicated to thecampaign
- 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.
"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 newrefund
will 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
investor
may 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 theinvestor
credit 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
dispute
is 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:
WON
In this case, the dispute will not result in any effect;LOST
In 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 noorderId
is provided in the description of an incoming money transfer, then it cannot be recognized as a potentialmoneyin
for anyorder
. 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 anyorder
in 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 incorrecttotalAmount
is marked as unidentified transfer since it cannot be correctly matched with anyorder
in created/waiting status. Please note that theinvestor
should be notified to repeat the money transfer with the correctorderId
andtotalAmount
, since it is not allowed to aggregatemoneyins
(i.e., for eachorder
one and only onemoneyin
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", "type" : "UNIDENTIFIED", "status" : "SENT_BACK", "amount" : "120.00", "currency" : "EUR", "description" : "An unexpected money transfer", "payerName" : "John Doe" }