---
title: "White Label: AIS"
description: "Questa sezione descrive il flusso completo per ottenere le informazioni di conto, saldi e movimenti, di utente tramite l'aggregazione PSD2."
url: "https://docs.fabrick.com/payment-institution/open-banking-and-psd2/active-engine/dev/white-label-ais/"
language: "it"
---

# White Label: AIS

Questa sezione descrive il flusso completo per ottenere le informazioni di conto, saldi e movimenti, di utente tramite l'aggregazione PSD2.

## Flusso alto livello

In questa sezione viene mostrato il flusso ad alto livello per

### Flusso API

Per ottenere un flusso minimo funzionale è sufficiente invocare nell'ordine le seguenti API:

- POST CreateUser
- POST CreateConsent
- GET GetConsentDetails
- GET GetBalances (refresh = true)
- POST RefreshTransactions + GET GetPfmTransactions

Di seguito il diagramma che mostra l'intero flusso con i parametri essenziali:

![WlAisFlowDiagram](https://docs.fabrick.com/img/payment-institution/open-banking-and-psd2/active-engine/wl-ais-flow-diagram.png)

### Dashboard di gestione conti aggregati

Oltre alle API descritte nella sezione precedente, si consiglia di esporre ai clienti finali una dashboard web che ne semplifichi la gestione, senza richiedere integrazioni custom per le operazioni più comuni.

#### Concetto chiave: aggregazione vs. IBAN

Un consenso PSD2 è legato a un set di credenziali bancarie, non a un singolo conto. Con le stesse credenziali un utente può avere più IBAN e può avere più consensi distinti sulla stessa banca usando credenziali diverse (es. conto personale e conto business su Intesa Sanpaolo).

E' consigliabile quindi organizzare la dashboard per **aggregazione** (consenso), non per singolo IBAN:

- la lista principale mostra le aggregazioni attive, in scadenza o revocate, ciascuna identificata da banca + alias scelto dall'utente (es. "Intesa Sanpaolo — conto personale");
- selezionando un'aggregazione, il dettaglio mostra uno o più IBAN, risultato della stessa chiamata `GetBalances` / `GetPfmTransactions`.

**Esempio UI in base al numero di IBAN:**

| Caso    | Comportamento                                                                                   |
| ------- | ----------------------------------------------------------------------------------------------- |
| 1 IBAN  | Si passa direttamente al dettaglio saldo/movimenti, senza viste intermedie                      |
| 2+ IBAN | Sopra al dettaglio compaiono dei tab per passare da un IBAN all'altro, senza cambiare schermata |

Questo evita un click aggiuntivo nel caso più comune (un solo IBAN per aggregazione) e tiene comunque tutto sotto controllo quando il consenso comprende più conti.

#### Struttura della pagina

- **Lista aggregazioni** (colonna sinistra) — elenco di tutti i consensi attivi dell'utente, con banca, alias, numero di IBAN compresi e stato del consenso (attivo / in scadenza / revocato). In cima alla lista, il tasto **Aggiungi aggregazione** avvia l'onboarding di un nuovo consenso, dato che l'azione produce una nuova riga nella lista stessa.
- **Dettaglio aggregazione** (colonna destra) — saldo e movimenti dell'IBAN selezionato (o del primo se ce n'è uno solo), con i tab per passare tra IBAN se l'aggregazione ne comprende più di uno.
- **Azioni rapide** — nella parte superiore del dettaglio, tre funzioni legate al ciclo di vita del consenso selezionato:

| Azione                   | Effetto                                                 | API sottostante                          |
| ------------------------ | ------------------------------------------------------- | ---------------------------------------- |
| **Rinnova consenso**     | Estende la validità di un consenso in scadenza/scaduto  | *CreateConsent* (Param per RenewConsent) |
| **Revoca consenso**      | Interrompe l'aggregazione lasciando lo storico visibile | *DeleteConsent*                          |
| **Rimuovi aggregazione** | Elimina conto e dati associati dalla piattaforma        | *DeleteConsent* + *DeleteBankProfile*    |

Le tre azioni operano sempre a livello di **aggregazione** (consenso), non di singolo IBAN: revoca e rinnovo riguardano l'intero set di credenziali, non un conto specifico.

#### Mockup di riferimento

![sampleDashboard](https://docs.fabrick.com/img/payment-institution/open-banking-and-psd2/active-engine/sample-dashboard.png)

Questa struttura mappa 1:1 il flusso ad alto livello della sezione 1: la lista aggregazioni rappresenta l'insieme dei `CreateConsent` attivi, il dettaglio mostra l'output di `GetBalances` / `GetPfmTransactions` per ciascun IBAN, e le azioni coprono l'intero ciclo di vita del consenso PSD2 (creazione, rinnovo, revoca, cancellazione).

## Dettagli API

### Gestione utente

Ogni PSU corrisponde ad uno user lato Fabrick. In particolare ad una coppia univoca *userCode* - *userId*, il primo è una stringa scelta dalla TPP, memtre il secondo è l'id univoco che rappresenta

#### Creazione utente

Per la creazione di un nuovo utente useremo l'API **POST CreateUser**. Questo endpoint prende in input lo *userCode* (chiave surrogata) e restituisce lo *userId*, utilit per tutti i prossimi steps. Ecco un esempio di request

```text
POST {{domain}}/active-engine/v4.0/conf/users

{
  "userCode": "NewFabrickUser"
}
```

in risposta otteniamo

```json
{
  "status": "OK",
  "payload": {
    "userId": "900223467",
    "tppUid": "123456",
    "userCode": "NewFabrickUser",
    "createdDatetime": "2026-06-24T09:01:44.971+0000",
    "lastUpdatedDatetime": "2026-06-24T09:01:44.971+0000",
    "userCustomCodes": [
      "NewFabrickUser"
    ],
    "isDeleted": false
  }
}
```

dove:

- *userId*: indica appunto l'identificativo univoco dell'utente lato Fabrick
- *tppUid*: indica l'id univoco della TPP, si può ignorare ai fini dell'integrazione
- *createdDatetime*: indica la data di creazione in formato ISO 8601
- *lastUpdatedDatetime*: indica la data dell'eventuale ultimo aggiornamento, dell'oggetto ed è in formato in formato ISO 8601. Può essere ignorato
- *userCustomCodes*: da ignorare
- *isDeleted*: da ignorare

#### Ottenere i dettagli di un utente

Dato uno *userId* è possibile recuperare i dettagli dell'utente, utilizzando l'endpoint **GET GetUserDetails**:

```text
GET {{domain}}/active-engine/v4.0/conf/users
```

ottenendo:

```json
{
  "status": "OK",
  "payload": {
    "userId": "900223467",
    "tppUid": "123456",
    "userCode": "NewFabrickUser",
    "createdDatetime": "2026-06-24T09:01:44.971+0000",
    "lastUpdatedDatetime": "2026-06-24T09:01:44.971+0000",
    "userCustomCodes": [
      "NewFabrickUser"
    ],
    "isDeleted": false
  }
}
```

#### Ricerca utenti

Per ottenere la lista completa di tutti gli utenti oppure ricercarne uno specifico tramite lo *userCode* si sfrutterà invece l'API **POST SearchUsers**:

```text
POST {{domain}}/active-engine/v4.0/conf/users/search

{
   "userCode": "NewFabrickUser"
}
```

in questo caso si otterrà in risposta l'utente avente come userCode il valore "NewFabrickUser":

```json
{
  "status": "OK",
  "payload": {
    "list": [
      {
        "userId": "900223467",
        "tppUid": "123456",
        "userCode": "NewFabrickUser",
        "createdDatetime": "2026-06-24T09:01:44.971+0000",
        "lastUpdatedDatetime": "2026-06-24T09:01:44.971+0000",
        "userCustomCodes": [
          "NewFabrickUser"
        ],
        "isDeleted": false
      }
    ]
  }
}
```

si otterrà una lista vuota in caso di mancata corrispondenza.

Lascinado invece il body senza filtri nella request verrà restituità l'intera lista di tutti gli utenti attivi in quel momento.

#### Cancellazione utente

In qualsiasi momento è sempre possibile eliminare uno user presente tramite la **DEL DeleteUser**:

```text
{{domain}}/active-engine/v4.0/conf/users/{{userId}}
```

ottenendo in risposta solamente l'esito dell'operazione come mostra l'esempio di seguito:

```json
{
  "status": "OK"
}
```

È possibile creare un nuovo utente con lo stesso *userCode* in un secondo momento, lo \_*userId* restituito sarà invece diverso da quello precedente.

### Gestione bankProfiles

L'oggetto *bankProfile* è un oggetto Fabrick per semplificare la gestione del flusso di aggregazione. Molto semplicemente è l'associazione tra l'utente (*userId*) e la banca selezionata per l'aggregazione (*bankId*). Ogni banca esposta da Fabrick infatti è identificata in maniera univoca da un intero, chiamato appunto *bankId*. E' possibile consultare la lista completa delle banche esposte, con tutti i dettagli, tramite l'endpoint **POST SearchBanks**.

Andando più nel dettaglio l'oggetto *bankProfile* raggruppa le seguenti caratteristiche di ogni aggregazione:

- *userId*
- *bankId*: l'identificativo della banca aggregata o che si sta per aggregare
- *serviceCode*: se presente, il particolare service della banca sopra indicata. Infatti alcune banche richiedono la selezione di un particolare servizio prima di proecedere con la creazione del consenso, ad esenmpio RETAIL o BUSINESS.
- *environment*: l'ambiente nel quale risiede il conto che si vuole aggregare, infatti in ambiente di pre-produzione Fabrick permette di poter testare sia su conti mock (SANDBOX) che su conti reali (LIVE)
- *alias*: un eventuale alias che la TPP potrebbe decidere di includere al *bankProfile*.

Tutta questa parte, assieme alla più complessa creazione del consenso, viene gestita intramente sulla UI di Fabrick, per questo motivo non ci dilugheremo oltre sui dettagli.

#### Ricerca bankProfiles

Seppur il *bankProfile* risulti trasparente alla TPP al momento della creazione è importante comprenderne il significato perchè fondamentale per la gestione successiva delle aggregazioni.

Per uno specifico utente (*userId*) è possibile recuperare tutti i suoi *bankProfiles* che quindi corrispondono alle aggregazioni attive del cliente:

```text
POST {{domain}}/active-engine/v4.0/conf/users/{{userId}}/bank-profiles/search
```

ottenendo in risposta la lista di tutti i *bankProfiles attivi*:

```json
{
  "status": "OK",
  "payload": {
    "list": [
      {
        "userId": "900223192",
        "bankId": "8",
        "tppUid": "123456",
        "createdDatetime": "2026-06-22T08:42:29.859+0000",
        "lastUpdatedDatetime": "2026-06-22T08:44:47.210+0000",
        "environment": "SANDBOX",
        "consentStatus": "VALID",
        "consentDetails": {
          "consentId": "9afaec5a-7ee0-4f7f-a42b-ccaacb9729ef",
          "userId": "900223192",
          "tppUid": "150116",
          "status": "VALID",
          "frequencyPerDay": "4",
          "recurring": true,
          "createdDatetime": "2026-06-22T08:42:34.540+0000",
          "lastUpdatedDatetime": "2026-06-22T08:44:51.752+0000",
          "access": {
            "allPsd2": "allAccounts"
          },
          "bankConsentId": "194980",
          "aggregationStatus": "READY",
          "authorizationType": "EMBEDDED",
          "bankProfileId": "369313",
          "startDatetime": "2026-06-22T08:42:34.540+0000",
          "endDatetime": "2026-12-18T23:00:00.000+0000"
        },
        "bankProfileId": "369313",
        "activeConsentId": "9afaec5a-7ee0-4f7f-a42b-ccaacb9729ef",
        "isDeleted": false
      }
    ]
  }
}
```

Ogni *bankProfile* è identificato in maniera univoca da un *bankProfileId*.

In caso di consensi già associati e/o attivi è importante notare i parametri:

- *consentStatus*: indica lo stato del consenso (vedere i dettagli nella sezione apposita)
- *consentDetails*: tutti i dettagli del consenso associato
- *activeConsentId*: l'id dell'ultimo consenso attivo

Per tutti i dettagli sul consenso si rimanda alla sezione dedicata.

#### Ottenere i dettagli di un bankProfile

Anche in questo caso è possibile ottenere lo specifico elemento attraverso il proprio *bankProfileId*:

```text
GET {{domain}}/active-engine/v4.0/conf/users/{{userId}}/bank-profiles/{{bankProfileId}}
```

di seguito un esempio di risposta:

```text
{
  "status": "OK",
  "payload": {
    "userId": "900223192",
    "bankId": "8",
    "tppUid": "123456",
    "createdDatetime": "2026-06-22T08:42:29.859+0000",
    "lastUpdatedDatetime": "2026-06-22T15:30:26.303+0000",
    "environment": "SANDBOX",
    "consentStatus": "EXPIRED",
    "consentDetails": {
      "consentId": "9afaec5a-7ee0-4f7f-a42b-ccaacb9729ef",
      "userId": "900223192",
      "tppUid": "150116",
      "status": "EXPIRED",
      "frequencyPerDay": "4",
      "recurring": true,
      "createdDatetime": "2026-06-22T08:42:34.540+0000",
      "lastUpdatedDatetime": "2026-06-22T15:30:26.276+0000",
      "access": {
        "allPsd2": "allAccounts"
      },
      "bankConsentId": "194980",
      "aggregationStatus": "READY",
      "authorizationType": "EMBEDDED",
      "bankProfileId": "369313",
      "startDatetime": "2026-06-22T08:42:34.540+0000",
      "endDatetime": "2026-12-18T23:00:00.000+0000"
    },
    "bankProfileId": "369313",
    "activeConsentId": "9afaec5a-7ee0-4f7f-a42b-ccaacb9729ef",
    "isDeleted": false
  }
}
```

#### Cancellazione di un bankProfile

E' sempre possibile in qualsiasi momento eliminare un bankProfile:

```text
DEL {{domain}}/active-engine/v4.0/conf/users/{{userId}}/bank-profiles/{{bankProfileId}}
```

sarà sempre possibile crearne di nuovi, ovviamente avranno un differente *bankProfileId* È importante notare che il *bankProfile* è l’oggetto che conserva la cronologia / lo storico tra l’utente e la banca in questione; mantenendo lo stesso *bankProfile* sarà sempre possibile recuperare tutte le informazioni relative, ad esempio, l'intero storico delle transazioni salvate nel database Fabrick per quella specifica aggregazione (*bankProfile*). Al contrario, cancellarlo e crearne uno nuovo equivale ad aggregare quella banca per la prima volta.

> La cancellazione non è un'operazione reversibile.

È quindi fondamentale comprendere appieno la differenza tra l’eliminazione di un *bankProfile* e la revoca di un consenso per creare un’interfaccia utente il più chiara possibile per l’utente finale.

### Gestione consensi

La fase di creazione consensi viene gestita completamente sulla pagina di Fabrick, questo permette di rendere traspatente tutta la complessità che si cela dovuta alle differenti varietà di flussi che dipendono dalle scelte dei vari gateway.

La TPP dovrà semplcimeneta avviare un workflow di aggrgeazione senza preoccuparsi quindi della tipologia di consenso, della modalità di interazione con la banca o del metodo di SCA adottato. Tutte scelte che dipendono dalla singola banca seguendo gli standard PSD2.

#### Creazione e rinnovo di un consenso

Come anticipato la TPP invocherà l'API **POST CreateConsent**, per avviare il workflow di aggrgeazione, di seguito un esempio:

```text
POST {{domain}}/win/v4.0/wl-aisp/access/consent-request

{
  "userId": 1234,
  "completionRedirectUrls": {
    "onSuccess": "https://example.com/success",
    "onFailure": "https://example.com/failure"
  }
}
```

Questa richiesta include i campi minimi ed obbligatori, in risposta si otterrà:

```json
{
  "status": "OK",
  "payload": {
    "consentRequestId": "e8a9f044-21fe-42ed-843e-eda83f287d24",
    "status": "CREATED_LINK",
    "createdDatetime": "2026-06-24T11:48:49.621+0000",
    "initiationRedirectUrl": "https://fabrick.com/.../.../e8...d24?jwtToken=..."
  }
}
```

dove:

- *consentRequestId*: indica l'id univoco del workflow di aggregazione
- *payload.status*: indica lo stato del workflow
- *createdDatetime*: indica il timestamp di creazione del workflow
- *initiationRedirectUrl*: contiene il valore della URL sulla quale il PSU (l'utente) dovrà essere reindirizzato per procedere con l'aggregazione dei conti correnti desiderati.

Come si può notare la URL indicata da *initiationRedirectUrl* punta ad una pagina Fabrick, in particolare alla UX di Fabrick che permettere al PSU di procedere con il processo di aggregazione. La pagina è personalizzabile dalla TPP, per i dettagli si rimanda alla sezione apposita.

Nell'esempio precedente è stata mostrata la richiesta più semplice possibile, è possibile comunque aggingere alcuni parametri opzionali per variare leggermente alcuni comportamenti o far fronte a diverse esigenze da parte della TPP.

Di seguito mostriamo un esempio completo:

```text
POST {{domain}}/win/v4.0/wl-aisp/access/consent-request

{
  "completionRedirectUrls": {
    "onSuccess": "https://www.fabrick.com",
    "onFailure": "https://www.google.it"
  },
  "bankCountryCodes": [
    "IT"
  ],
  "consentOneDay": false,
  "historical": {
    "isEnabled": true,
    "numOFMonths": 24,
    "oneShot": true
  },
  "liteAggregation": false,
  "iban": "IT18L0200811770000019486580",
  "userId": 123456
}
```

dove:

- *userId*: indica lo *userId* descritto nelle sezioni precedenti

- *bankProfileId*: identificativo univoco del bankProfile in Fabrick.

- *iban*: IBAN del conto da aggregare.

- *consentOneDay*: se `true` il consenso scade subito dopo l’aggregazione, se `false` è valido 180 giorni.

- *historical*: oggetto relativo allo storico movimenti.

  - *isEnabled*: abilita la richiesta dello storico.
  - *numOfMonths*: numero di mesi per cui recuperare i movimenti.
  - *oneShot*: abilita comportamento one-shot per autorizzazione unica.

- *bankCountryCodes*: filtro per nazionalità banca (ISO 3166-1 alpha-2).

- *completionRedirectUrls*: URLs di redirect a fine flusso sia in caso positivo che in caso di abbandono o di errore da parte del PSU.

- *liteAggregation*: se *true* non verranno eseguite le richieste di recupero di saldi e movimenti in maniera automatica alla fine del workflow, sarà quindi poi la TPP a richiedere l'aggiornamento per ottenere i dati.

> In riferimento a *liteAggregation* è bene ricordare che per aver un aggiornamento di saldi e/o movimenti è obbligatorio che il PSU sia presente, in caso contrario i dati verranno aggiornati automaicamente da Fabrick 4 volte al giorno (v. orari nella sezione Account Details).

##### Dettagli sullo storico

Secondo lo standad PSD2 ogni ASPSP (banca) deve sempre restituire la lista delle transazioni di un lasso temporale pari a 90 giorni. Opzionalmente possono restituire, con una richiesta specifica, un lasso temporale maggiore. Il lasso temporale è quindi variabile per ogni banca e anche il tipo di richiesta può essere differente. Impostando nella richiesta ad esempio 24 mesi verranno richieste alla banca finale tutte le transazioni degli utlimi 24 mesi, in caso in cui la banca ne esponesse solamente 12 (per scelta propria) allora verrano recuperati solo quelli disponibili, appunto 12 mesi. Ad oggi non viene restituito alcun messaggio di dettaglio via API in riferimeno alla disponibilità massima di ogni banca, purtroppo non sono informazioni esposte via API dalle banche.

##### Dettagli sul consenso ricorrente e non

Un conenso può essere ricorrente e non ricorrente; nel primo caso il consenso sarà valido per più richieste di accesso ai dati (saldi e movimenti) e la sua durata potrà essere impostata sino ad un massimo di 180 giorni. Nel caso di Fabrick viene impostato automaticamente a 180 giorni, il massimo disponibile quindi. Nel caso di consenso non ricorrente sarà possibile un solo accesso ai dati e poi non sarà più valido. Alcune banche richiedono questa seconda tipologia di consenso per richiedere lo storico. Per questo motivo, per le suddette banche, se si volesse reucperare lo storico e allo stesso tempo mantenere un consenso ricorrente sarà necessario fare due consensi differenti. Ovviamente il tutto è gestito sempre su UX Fabrick, ma è impotante che la TPP ne sia a conoscenza per supporto al proprio PSU.

Chiariti i due aspetti, vediamo alcuni esempi di richiesta di consenso. Nel seguente esempio verrà richiesto un consenso ricorrente e verrà recuperato uno storico di 12 mesi se la banca selezionata lo permette. Il PSU sarà quindi guidato nel fare uno o due consensi a seconda della banca selezionata e alle specifiche accennare sopra.

```text
POST {{domain}}/win/v4.0/wl-aisp/access/consent-request


{
  "userId": "900206427",
  "historical": {
    "isEnabled": true,
    "numOFMonths": 12
  },
  "bankCountryCodes": [
    "IT"
  ],
  "completionRedirectUrls": {
    "onSuccess": "https://example.com/success",
    "onFailure": "https://example.com/failure"
  }
}
```

Un altro esempio potrebbe essere la richiesta di solo storico, in questo caso il PSU farà sempre e solo un solo consenso.

```text
POST {{domain}}/win/v4.0/wl-aisp/access/consent-request


{
  "userId": "900206427",
  "consentOneDay": true,
  "historical": {
    "isEnabled": true,
    "numOFMonths": 12,
    "oneShot": true
  },
  "bankCountryCodes": [
    "IT"
  ],
  "completionRedirectUrls": {
    "onSuccess": "https://example.com/success",
    "onFailure": "https://example.com/failure"
  }
}
```

#### Ottenere i dettagli a fine aggregazione

Una volta conclusa l'aggregazione il PSU verrà reindirizzato sulle pagine indicate nell'oggetto *completionRedirectUrls*. A questo punto la TPP dovrà invocare l'API **GET getConsentDetails** per reucperare tutti i dettagli necessari per richiedere successivamente le informazioni su saldi e movimenti:

```text
GET {{domain}}/win/v4.0/wl-aisp/access/consent-request/{{consentRequestId}}
```

ottenendo in risposta la lista delle aggregazioni effettuate:

```json
{
  "status": "OK",
  "payload": {
    "status": "VALID",
    "createdDatetime": "2026-06-24T10:18:46.228+0000",
    "consentId": "5697f27d-bef2-4c2a-90a4-137028522a3c",
    "accounts": [
      {
        "accountId": "412377",
        "userId": "900223192",
        "bankProfileId": "369551",
        "bankId": "8",
        "tppUid": "123456",
        "reference": "147629",
        "synchronizationStatus": {
          "transactions": {
            "lastSynchronizedDatetime": "2026-06-24T10:19:53.722+0000",
            "isSynchronized": true,
            "hasActiveConsent": true,
            "wasInLastConsent": true
          },
          "balances": {
            "lastSynchronizedDatetime": "2026-06-24T10:19:55.706+0000",
            "isSynchronized": true,
            "hasActiveConsent": true,
            "wasInLastConsent": true
          },
          "wasAvailable": true
        },
        "name": "Mauro Rossi",
        "valueType": "IBAN",
        "value": "IT35V3615900000000000000011",
        "currency": "USD",
        "retrievedDatetime": "2026-06-24T10:19:44.714+0000",
        "lastUpdatedDatetime": "2026-06-24T10:19:50.179+0000",
        "subsidiaryValues": [],
        "ownerType": "OWNER",
        "consentStatus": "VALID",
        "consentEndDatetime": "2026-12-20T23:00:00.000+0000",
        "isDeleted": false,
        "isMassiveSync": false
      },
      {
        "accountId": "412378",
        "userId": "900223192",
        "bankProfileId": "369551",
        "bankId": "8",
        "tppUid": "123456",
        "reference": "147630",
        "synchronizationStatus": {
          "transactions": {
            "lastSynchronizedDatetime": "2026-06-24T10:19:56.531+0000",
            "isSynchronized": true,
            "hasActiveConsent": true,
            "wasInLastConsent": true
          },
          "balances": {
            "lastSynchronizedDatetime": "2026-06-24T10:19:57.278+0000",
            "isSynchronized": true,
            "hasActiveConsent": true,
            "wasInLastConsent": true
          },
          "wasAvailable": true
        },
        "name": "Mauro Rossi",
        "valueType": "IBAN",
        "value": "IT18W3615900000000000000001",
        "currency": "EUR",
        "retrievedDatetime": "2026-06-24T10:19:44.734+0000",
        "lastUpdatedDatetime": "2026-06-24T10:19:50.345+0000",
        "subsidiaryValues": [],
        "ownerType": "OWNER",
        "consentStatus": "VALID",
        "consentEndDatetime": "2026-12-20T23:00:00.000+0000",
        "isDeleted": false,
        "isMassiveSync": false
      }
    ],
    "userId": "900223192",
    "bankProfileId": "369551"
  }
}
```

> *consentId* è l'id univoco del consenso, mentre *consentRequestId* è l'id univoco del workflow Fabrick per gestire il flusso di creazione consenso.

Per i dettagli dei singoli paranetri si rimada alla sezione *Account Details*. E' importante evidenziare la lista di *bankProfileId* e quella di *accountId*, i parametri utili per le API successive come indicato nel flusso ad alto livello della prima sezione.

#### Cancellazione di un consenso

Come indicato nel flusso ad alto livello, il PSU deve avere la possibilità di annullare il proprio consenso nei confronti della TPP. Per questo motivo è esposta l'API **DEL DeleteConsent**:

```text
https://{{domain}}/api/fabrick/active-engine/v4.0/auth/bank-profiles/{{bankProfileId}}/consents/{{consentId}}
```

in risposta si otterranno i dettagli del consenso in questione:

```json
{
  "status": "OK",
  "payload": {
    "list": [
      {
        "consentType": "ALL_PSD2",
        "permissions": [
          "ACCOUNTS"
        ],
        "consentId": "613d509d-13bf-4f1a-9e1d-95c7d805b8a8",
        "aggregationStatus": "READY",
        "createdDateTime": "2026-06-29T15:48:51.443+0000",
        "expirationDateTime": "2026-12-25T23:00:00.000+0000",
        "consentStatus": "VALID",
        "authenticationFlow": "EMBEDDED",
        "bankConsentId": "195206",
        "isRecurring": true
      }
    ]
  }
} 
```

### Ottenere le informazioni di conto

Una volta creato il consenso e verificato lo stato valido si potrà procedere alla lettura delle informazioni dei conti aggregati ed associato al consenso.

#### Lista conti

Per ottenere la lista conti è possibile l'API **GET getAccounts**:

```text
GET {{domain}}/active-engine/v4.0/access/bank-profiles/{{bankProfileId}}/accounts
```

in risposta si otterrà la lista dei conti come mostra l'esempio:

```json
{
  "status": "OK",
  "payload": {
    "list": [
      {
        "accountId": "414235",
        "userId": "900226869",
        "bankProfileId": "373807",
        "bankId": "8",
        "tppUid": "123456",
        "reference": "147769",
        "synchronizationStatus": {
          "transactions": {
            "lastSynchronizedDatetime": "2026-06-29T15:52:05.981+0000",
            "isSynchronized": true,
            "hasActiveConsent": true,
            "wasInLastConsent": true
          },
          "balances": {
            "lastSynchronizedDatetime": "2026-06-29T15:52:08.171+0000",
            "isSynchronized": true,
            "hasActiveConsent": true,
            "wasInLastConsent": true
          },
          "wasAvailable": true
        },
        "name": "Mauro Rossi",
        "valueType": "IBAN",
        "value": "IT35V3615900000000000000011",
        "currency": "USD",
        "retrievedDatetime": "2026-06-29T15:51:53.855+0000",
        "lastUpdatedDatetime": "2026-06-29T15:52:00.108+0000",
        "subsidiaryValues": [],
        "ownerType": "OWNER",
        "consentStatus": "VALID",
        "consentEndDatetime": "2026-12-25T23:00:00.000+0000",
        "isDeleted": false,
        "isMassiveSync": false
      },
      {
        "accountId": "414236",
        "userId": "900226869",
        "bankProfileId": "373807",
        "bankId": "8",
        "tppUid": "150116",
        "reference": "147770",
        "synchronizationStatus": {
          "transactions": {
            "lastSynchronizedDatetime": "2026-06-29T15:52:10.939+0000",
            "isSynchronized": true,
            "hasActiveConsent": true,
            "wasInLastConsent": true
          },
          "balances": {
            "lastSynchronizedDatetime": "2026-06-29T15:52:11.024+0000",
            "isSynchronized": true,
            "hasActiveConsent": true,
            "wasInLastConsent": true
          },
          "wasAvailable": true
        },
        "name": "Mauro Rossi",
        "valueType": "IBAN",
        "value": "IT18W3615900000000000000001",
        "currency": "EUR",
        "retrievedDatetime": "2026-06-29T15:51:53.883+0000",
        "lastUpdatedDatetime": "2026-06-29T15:52:00.102+0000",
        "subsidiaryValues": [],
        "ownerType": "OWNER",
        "consentStatus": "VALID",
        "consentEndDatetime": "2026-12-25T23:00:00.000+0000",
        "isDeleted": false,
        "isMassiveSync": false
      }
    ]
  }
}
```

è inoltre possibile invocare anche l'API **POST SearchAccounts** che permette di filtrare per banca:

```text
POST {{domain}}/active-engine/v4.0/access/users/{{userId}}/accounts/search

{
    "bankIds": [8]
}
```

Eventualmente è sempre possibile recueprare i dettagli di un singolo conto tramite il relativo *accountId* invocando l'API **GET GetAccountDetails**

```text
GET {{domain}}/active-engine/v4.0/access/bank-profiles/{{bankProfileId}}/accounts/{{accountId}}
```

in risposta si avrà un solo elemento:

```json
{
  "status": "OK",
  "payload": {
    "accountId": "414235",
    "userId": "900226869",
    "bankProfileId": "373807",
    "bankId": "8",
    ...
    "name": "Mauro Rossi",
    "valueType": "IBAN",
    "value": "IT35V3615900000000000000011",
    "currency": "USD"
  }
}
```

#### Prefazione aggiornamento in tempo reale

Di seguito saranno descritte le API per recuperare le informazioni di conto relativi ai saldi e alla lista movimenti. E' importante considerare le due modalità di richiesta:

- *attended*
- *unattanded*

Nel contesto della Direttiva sui servizi di pagamento (PSD2) i termini *attended* e *unattanded* indicano se l'utente (PSU) sta interagendo attivamente con un terminale o un’applicazione.

Modalità *unattanded*: quando uno script automatizzato, un’attività in background o un processo di sistema recupera i dati senza che l’utente stia utilizzando attivamente l’app. Le banche in genere limitano il numero di recuperi di dati a 4 volte ogni 24 ore.

Modalità *attended*: quando l’utente interagisce attivamente con l’app sullo schermo (ad esempio, visualizzando l’elenco dei conti) e richiede dati più aggiornati in tempo reale. Ai sensi della PSD2, non vi sono limitazioni al recupero dei dati in modalità con utente, in questo caso è necessario passare nelle richieste l’indirizzo IP attivo dell’utente che sarà condiviso con la banca finale.

Per quanto riguarda gli aggiornamenti *unattanded* sarà Fabrick a gestire le 4 interazioni quoridiane in modo che la TPP abbia sempre i dati aggiornati senza preoccuparsi di sviluppare uno scheudeler. Gli orari sono indicati nella sezione *Account Details*.

Per quanto riguarda l'aggiornamento *attended* invece Fabrick gestisce saldi e movimenti in due modalità differenti:

- saldi: il parametro, di tipo boolean, *refresh* indica il tipo di richiesta

- transazioni: un'API esplicita richiede l'aggiornamento in tempo reale della lista delle transanzioni in modo asincrono.

Nelle sezioni seguenti verranno descritti i dettagli.

#### Dettaglio Saldi

Per recuperare le informazioni relative ai saldi si dovrà invocare l'API **GET GetAccountBalances**:

```text
GET {{domain}}/active-engine/v4.0/access/bank-profiles/{{bankProfileId}}/accounts/{{accountId}}/balances?refresh=true
```

da notare il query param *refresh*:

- se omesso o *false*, la richiesta sarà considerata *unattanded* e le informazioni saranno recuperati dai DB di Fabrick. In caso di prima aggregazione potrebbe quindi restituire una lista vuota in attesa del primo aggiornamento utile con la banca finale

- se \*true \*la chiamata sarà considerata *attended* , le informazioni saranno recuperate direttamente dalla banca in tempo reale. Ricordiamo che è obbligatoria la presenza dell'utente in questo caso, sarà quindi necessario inserire anche l'header specifico valorizzato con l'indirizzo IP del PSU, come mostra l'esempio:

  ```text
  X-PSU-IP-Address: 1.2.3.4
  ```

in qualsiasi modalità, in risposta si otterrà sempre lo stesso modello mostrato di seguito:

```json
{
  "status": "OK",
  "payload": {
    "list": [
      {
        "userId": "900226869",
        "bankId": "8",
        "tppUid": "123456",
        "accountId": "414235",
        "amount": {
          "value": 458.15,
          "currency": "USD"
        },
        "amountInEuro": {
          "value": 393.80,
          "currency": "EUR"
        },
        "exchangeRate": 1.1634,
        "type": "OPENING_BOOKED",
        "referenceDate": "2026-06-29T00:00:00.000+00:00",
        "retrievedDatetime": "2026-06-29T16:20:50.906+0000",
        "balanceType": "BOOKED",
        "balanceTimePeriod": "OPENING",
        "balancePriority": 5,
        "bankProfileId": "373807",
        "isCreditLimitIncluded": false
      },
      {
        "userId": "900226869",
        "bankId": "8",
        "tppUid": "123456",
        "accountId": "414235",
        "amount": {
          "value": 748.15,
          "currency": "USD"
        },
        "amountInEuro": {
          "value": 643.07,
          "currency": "EUR"
        },
        "exchangeRate": 1.1634,
        "type": "INTERIM_AVAILABLE",
        "referenceDate": "2026-06-29T00:00:00.000+00:00",
        "retrievedDatetime": "2026-06-29T16:20:50.906+0000",
        "balanceType": "AVAILABLE",
        "balanceTimePeriod": "INTERIM",
        "balancePriority": 1,
        "bankProfileId": "373807",
        "isCreditLimitIncluded": false,
        "lastChangeDatetime": "2018-10-29T10:22:00.123+0000"
      }
    ]
  }
}
```

E' anche possibile recuperare tutti saldi aggregati per utente piuttosto che per specifico conto. In questa caso non è possibile sfruttare il parametro *refresh* :

```text
GET {{domain}}/active-engine/v4.0/access/users/{{userId}}/balances
```

tutti i dettagli sono descritti nella sezione dedicata *Balances Details*.

#### Lista transazioni

Per recuperare le informazioni relative alla lista delle transazioni si dovrà invocare l'API **GET GetPfmTransactions**:

```text
GET {{domainPfm}}/api/fabrick/pfm/psd2/{{tenant}}/v4.0/movements/transactions?{{bankProfileId}}={{accountId}}
```

Il dominio del PFM è differente come si può notare, di seguito un esempio di dominio in pre-produzione, ipotizzando Fabrick come tenant:

```text
https://pre.fabrick.com/api/fabrick/pfm/psd2/fabrick/v4.0/movements/transactions?{{bankProfileId}}={{accountId}}
```

Il PFM è un prodotto Fabrick che aggiunge ulteriori informazioni e dettagli ad ogni singola transazione recuperata dalla banca. Per tutti i dettagli far riferimento alla sezione *PFM Details*.

Come anticipato, a differenza dei saldi, nel caso di richieste *attended* sarà necessario invocare prima della suddetta API, l'API di richiesta di aggiornamento, **POST RefreshTransactions**:

```text
POST {{domain}}/active-engine/v4.0/access/bank-profiles/{{bankProfileId}}/accounts/{{accountId}}/transactions

{}
```

Per la normativa PSD2 ogni banca è tenuta a restituire la lista delle transazioni degli ultimi 90 giorni. Opzionalmente è possibile richiedere un lasso temporale maggiore. Fabrick recupererà il massimo tra il valore desiderato ed il valore consentito dalla banca. Purtroppo l'informazione non è nota tramite API, quindi non è possibile verificare alcune condizioni, ad esempio:

- TPP richiede 24 mesi

- Banca restituisce 12 mesi

non sarà possibile verificare se 12 mesi è il limite massimo permesso dalla banca oppure se il conto specifico contiene solamente trasanzioni dell'ultimo anno.

Di seguito l'esempio di richiesta di storico:

```text
POST /api/fabrick/active-engine/v4.0/access/bank-profiles/{{bankProfileId}}/transactions

{
  "numberOfMonths": {{numberOfMonths}}
}
```

A breve sarà introdotta la possibilità di ricevere la callback una volta terminata la fase di aggiornamento. Molto utile soprattutto in caso di richiesta di storico, visto che a seconda della quantità di movimenti e lasso temporale richiesto, potrebbero essere necessari anche 2/3/4 minuti. La callback sarà inviata da Fabrick alla TPP sull'endpoint indicato nel body della request come mostrato nell'esempio seguente:

```text
POST {{domain}}/active-engine/v4.0/access/bank-profiles/{{bankProfileId}}/accounts/{{accountId}}/transactions

{
  "callbackUrl": "https://test-fabrick-callback"
}
```

Ad oggi purtroppo sarà necessaria una fase di polling o attendere qualche secondo.

### Lista banche

Tramite l'API POST SearchBanks è possibile recuperare la lista completa delle banche esposte da Fabrick, comprese quelle ancora in lavorazione per i diversi stati europei.

Come anticipato non è necessario implementarla perchè fa parte dell'aggregazione gestita su pagina Fabrick, ma ovviamente è a disposizione per qualsiasi utilità:

```text
POST {{domain}}/active-engine/v4.0/access/banks/search
{}
```
