Payment workflow
All the non-inquiry operations require a Strong Customer Authentication. This means that these operations must be split in more than one API; there should be:
- one or more steps to insert the required operation data
- a process, composed of a certain number of steps, to implement the 2-factor authentication. In this process, the exact operation inserted will be authorized
-
one final steps which will actually execute the operation inserted (if and only if it's authorized) We adopted a standard naming for the types of the API involved in this process:
- GET .../< OPERATION_NAME >/prepare → (optional) this API returns generic information/suggestions about the operation to execute (e.g. the allowed dates, allowed recipient nations...), which will be useful to compose the request to the subsequent APIs. You can avoid to call it, since all the subsequent APIs integrate the input validation
- POST .../< OPERATION_NAME >/verify → the first API in which the user passes the operation data. This API creates a transaction resource, and it returns the resourceId field in response
- PUT .../< OPERATION_NAME >/{resourceId}/verify< NUMBER > → potential other APIs that insert additional operation data (the majority of operations do not have this type of API in the flow). The resourceId is the one created by the API above, the NUMBER is an incremental number, to distinguish the position in the flow
- GET /private/auth/security/sca/{resourceId}/approach → the call to this API starts the authorization flow (which is managed by Mediobanca Premier website)
- GET /private/operations/{resourceId}/status → this API returns the current operation state (if it's been authorized and/or executed). It must be called until the authenticationState is no more PENDING
- PUT .../< OPERATION_NAME >/{resourceId}/execute → the final API, which actually executes the operation; this API generally does not have parameters (the ones saved by the first API in the flow will be used)
The /private/operations/{resourceId}/status and .../< OPERATION_NAME >/{resourceId}/execute should be called after the callback to the TPP application has been executed.
Payment authorization
The /verify API is required to insert the payment data, while the /execute API is the one that actually executes the payment.
In the middle of these APIs, the user needs to authorize the payment. The payment authorization is completely managed by Mediobanca Premier systems, and it's an OAuth-like flow.
In summary, the steps to perform a payment are the following:
- you, as a third party provider, can call an API to insert the payment data
- once the API has correctly finished, you have to call the
/private/auth/security/sca/{resourceId}/approach
API, specifying your preferred SCA approach. This API will return the allowed approach for the payment operation executing (the possible values are REDIRECT or DECOUPLED).- in case of REDIRECT approach, the API will return also the redirect URL to which the user must be redirected (browser-side). The user will then log-in to a Mediobanca Premier application and perform the payment authorization
- in case of DECOUPLED approach, the API will only tell the user to perform the authorization on another channel
- in both cases, you have to call the
/private/operations/{resourceId}/status
API (in polling mode) to retrieve the authorization status. When the API returns the authorizationStatus =AUTHORIZED
, you finally can proceed with the payment execution. If the authorizationStatus returned isNOT_AUTHORIZED
orEXPIRED
you should stop polling and should not execute the payment. - you can call the payment execution API, which will check the authorization status and will execute the payment
- (optional) if you want, you can call the
/private/operations/{resourceId}/status
API to get the transaction outcome
At the moment, only the REDIRECT flow is supported
Payment flow diagram
Here's a complete schema of a login+payment flow:
API flow
The operation flow is guided by the HAL structure in the API responses. So what you will see is (bank transfer example, but you can apply to every operation):
Prepare data
GET .../< OPERATION_NAME >/prepare - response
{
"data":{
...specific API data...
},
"_links": {
"next": {
"href": "verify",
"method": "POST"
},
"self": {
"href": "prepare",
"method": "GET"
},
"curies": [{
"href": "https://external-api.mediobancapremier.io/private/customers/<CUSTOMER_ID>/products/<PRODUCT_ID>/moneyTransfer/{rel}",
"name": "moneyTransfer"
}]
},
"_embedded": {
}
...
}
Insert and validate data
POST .../< OPERATION_NAME >/verify - response
{
"data":{
...specific API data...
},
"resources": {
"resourceId": "5e8134cc-401d-48a6-9f6c-26d0711c7c36"
},
"_links": {
"next": {
"href": "5e8134cc-401d-48a6-9f6c-26d0711c7c36/execute",
"method": "PUT"
},
"self": {
"href": "verify",
"method": "POST"
},
"curies": [{
"href": "https://external-api.mediobancapremier.io/private/customers/<CUSTOMER_ID>/products/<PRODUCT_ID>/moneyTransfer/{rel}",
"name": "moneyTransfer"
}]
},
"_embedded": {}
...
}
Start authorization flow
GET /private/auth/security/sca/{resourceId}/approach - response
{
"resources": {
"resourceId": "5e8134cc-401d-48a6-9f6c-26d0711c7c36"
},
"result": {
"result": {
"requestId": "<REQUEST_UNIQUE_ID>",
"outcome": "SUCCESS",
"flushMessages": true,
"messages": []
},
"_links": {},
"_embedded": {},
"data": {
"scaRedirectURL": "https://clienti.mediobancapremier.com/sca-authorize/?resourceId=<RESOURCE_ID>",
"chosenScaApproach": "REDIRECT"
}
}
Check authorization status
If the authorizationStatus is AUTHORIZED, you can proceed with the execution.
GET /private/operations/{resourceId}/status - response
{
"data": {
"creationTimestamp": "2019-09-03T18:14:25",
"authorizationStatus": "AUTHORIZED",
"executionStatus": "PENDING"
},
"result": {
"requestId": "XW6RYgra5AsAAO6Nv94AAABY",
"outcome": "SUCCESS",
"flushMessages": true,
"messages": []
},
"_embedded": {
},
"resources": {
"resourceId": "5e8134cc-401d-48a6-9f6c-26d0711c7c36"
}
}
Execute operation
PUT .../< OPERATION_NAME >/{resourceId}/execute - response
{
"data":{
...specific API data...
},
"resources": {
"resourceId": "5e8134cc-401d-48a6-9f6c-26d0711c7c36"
},
"_links": {
"self": {
"href": "5e8134cc-401d-48a6-9f6c-26d0711c7c36/execute",
"method": "PUT"
},
"curies": [{
"href": "https://external-api.mediobancapremier.io/private/customers/<CUSTOMER_ID>/products/<PRODUCT_ID>/moneyTransfer/{rel}",
"name": "moneyTransfer"
}]
},
"_embedded": {
"printer": {
"href": "https://external-api.mediobancapremier.io/private/customers/<CUSTOMER_ID>/products/<PRODUCT_ID>/common/printer/5e8134cc-401d-48a6-9f6c-26d0711c7c36/retrieve",
"method": "GET"
}
}
...
}
Notes
You can find the specific documentation of all the APIs you have to call here
Complete example
Here you will find a complete workflow for the bank transfer operation, with all the requests and responses that a TPP should manage. The authorization phase (what happens between the /private/auth/security/sca/{resourceId}/approach and the TPP_CALLBACK_AFTER_SCA) is a blackbox for the TPP, since it's managed completely by Mediobanca Premier systems.
Prepare data (optional)
Response:
{
"data": {
"abi": "03058",
"sepa": true,
"swift": true,
"swiftcontractSigned": true,
"initialData": {
},
"executionDateMinimumWireTransferAtBank": "03/09/2019",
"executionDateMinimumWireTransferInternal": "03/09/2019",
"flagUrgency": false,
"ABI": "03058",
"addBeneficiary": true,
"editBeneficiary": true,
"today": "03/09/2019",
"executionDateLimit": "03/09/2020",
"holidays": ["01/01/2020",
"25/12/2019",
"01/05/2020",
"13/04/2020",
"26/12/2019"],
"currency": {
"currencyList": [{
"label": "Euro - EUR",
"value": "EUR",
"rate": ""
},
{
"label": "Dollaro americano - USD",
"value": "USD",
"rate": ""
},
...
{
"label": "Zloty polacco - PLN",
"value": "PLN",
"rate": ""
}],
"updated": {
"date": "03/09/2019",
"hour": "17:56"
},
"selected": "EUR"
},
"SEPA": true,
"SWIFT": true,
"SWIFTContractSigned": true,
"countries": [{
"label": "ABU DHABI",
"value": "0238"
},
{
"label": "AFGHANISTAN",
"value": "0002"
}
...
]
},
"result": {
"requestId": "XW6NIgrZ5gsAAG@Cr04AAABV",
"outcome": "SUCCESS",
"flushMessages": false,
"messages": []
},
"_links": {
"next": {
"href": "verify",
"method": "POST"
},
"self": {
"href": "prepare",
"method": "GET"
},
"curies": [{
"href": "https://external-api.mediobancapremier.io/private/customers/1134596/products/0001486570/moneyTransfer/{rel}",
"name": "moneyTransfer"
}]
},
"_embedded": {
}
}
Insert and validate data
Request:
{
"data": {
"moneyTransferAmount": {
"currency": "EUR",
"amount": "1.00"
},
"flagUrgency": false,
"type": "SEPA",
"moneyTransferExecutionDate": "03/09/2019",
"ibanBeneficiary": "IT78Q0347551609CC0099237243",
"beneficiaryName": "Mario Rossi",
"description": "payment to Mario Rossi"
}
}
Response:
{
"data": {
"totalAmount": {
"amount": "1.00",
"currency": "EUR"
},
"commissions": {
"commissions": "0.00",
"currency": "EUR"
},
"equivalentAmount": {
"amount": "",
"currency": ""
},
"bankName": "UNICREDIT BANCA DI ROMA SPA",
"branchName": "ROMA 80 - PIAZZA MONTE",
"address": "PIAZZA MONTE DI PIETA, 3 - 00186 ROMA (RM)",
"moneyTransferOffline": false,
"holdersEnabled": false
},
"result": {
"requestId": "XW6O4grZ5gsAAG@Css4AAABd",
"outcome": "SUCCESS",
"flushMessages": true,
"messages": []
},
"_links": {
"next": {
"href": "5c99d862-6917-4006-b9a6-e5677e8a867b/execute",
"method": "PUT"
},
"self": {
"href": "verify",
"method": "POST"
},
"curies": [{
"href": "https://external-api.mediobancapremier.io/private/customers/1134596/products/0001486570/moneyTransfer/{rel}",
"name": "moneyTransfer"
}]
},
"_embedded": {},
"resources": {
"resourceId": "5c99d862-6917-4006-b9a6-e5677e8a867b"
}
}
Start authorization flow
Response
{
"resources": {
"resourceId": "5c99d862-6917-4006-b9a6-e5677e8a867b"
},
"result": {
"result": {
"requestId": "XW6O4grZ5gqXAG@Css4AAACZ",
"outcome": "SUCCESS",
"flushMessages": true,
"messages": []
},
"_links": {},
"_embedded": {},
"data": {
"scaRedirectURL": "https://clienti.mediobancapremier.com/sca-authorize/?resourceId=5c99d862-6917-4006-b9a6-e5677e8a867b",
"chosenScaApproach": "REDIRECT"
}
}
Check authorization status
Response
{
"data": {
"creationTimestamp": "2019-09-03T18:14:25",
"authorizationStatus": "AUTHORIZED",
"executionStatus": "PENDING"
},
"result": {
"requestId": "XW6RYgra5AsAAO6Nv94AAABY",
"outcome": "SUCCESS",
"flushMessages": true,
"messages": []
},
"_embedded": {
},
"resources": {
"resourceId": "5c99d862-6917-4006-b9a6-e5677e8a867b"
}
}
Execute operation
Request:
{}
Response:
{
"data": {
"cro": "1909031807313004480160433140IT12470",
"moneyTransferOffline": false,
"sendEmailEnabled": true
},
"result": {
"requestId": "XW6PwgrZ5gsAAG@CtFYAAABY",
"outcome": "SUCCESS",
"flushMessages": true,
"messages": [{
"code": "BONIFICO24",
"message": "Hai effettuato un bonifico a Mario Rossi!",
"type": "SUCCESS"
},
{
"code": "BONIFICO23",
"message": "Una volta prodotta, troverai la contabile delle tue operazioni nell'Archivio presente nel menù di destra. Seleziona il conto e le date di riferimento. La troverai in un click!",
"type": "INFO"
}]
},
"_links": {
"self": {
"href": "5c99d862-6917-4006-b9a6-e5677e8a867b/execute",
"method": "PUT"
},
"curies": [{
"href": "https://external-api.mediobancapremier.io/private/customers/1134596/products/0001486570/moneyTransfer/{rel}",
"name": "moneyTransfer"
}]
},
"_embedded": {},
"resources": {
"resourceId": "5c99d862-6917-4006-b9a6-e5677e8a867b"
}
}