# Importazione massiva pagamenti

## Scopo e Campo di Applicazione

Questa sezione descriverà nello specifico il flusso di recupero dei dati di pagamento dai provider esterni e della loro elaborazione all’interno del sistema di pagamento locale. Questo flusso viene attivato da eventi di login utente e gestisce la sincronizzazione dei record di pagamento tra i provider esterni e il sistema di archiviazione locale.

## Flusso Completo

{% @mermaid/diagram content="sequenceDiagram
%% Partecipanti
participant U as "Utente"
participant KUsers as "Kafka Topic (users)"
participant H as "HandleUserEventMessage"
participant V as "FlowUserLogged"
participant A as "FlowProviderPaymentAuthenticate"
participant I as "FlowImportPayments"
participant JPPA as "Provider API"
participant IPA as "IPA Registry"
participant PPG as "PagoPA Dataset"
participant ST as "Storage Backend"
participant KPay as "Kafka Topic (payments)"

```
%% Login e consumo evento
U->>KUsers: Login Event
KUsers->>H: Consume User Event
H->>H: Acquire lock (thread-safety)

%% Validazione utente/tenant
H->>V: Exec()
V-->>H: User data + Tenant info (ok)

%% Autenticazione provider
H->>A: send()
A->>JPPA: POST /auth/v1/login
JPPA-->>A: AuthToken
A-->>H: AuthToken

%% Fase 1: prepareRequest
H->>I: prepareRequest()
Note over I: Build ImportPaymentsRequest<br/>Costruisci JSON payload<br/>DebtorTaxCode = EntityCode

%% Fase 2: doRequest
I->>I: doRequest()
I->>JPPA: POST /estrattoConto/v1/ricerca<br/>Headers: Bearer Token, Content-Type
JPPA-->>I: ImportPaymentsResponse (debts[])
I->>I: Monitor Prometheus

%% Fase 3: importPayments (loop su ogni debt)
I->>I: importPayments()

loop For each debt in response
    I->>I: findPayment()
    alt Payment esistente
        I->>I: updateExistingPayment()
    else Nuovo pagamento
        I->>I: buildNewPayment()
    end

    %% Enrichment da fonti esterne
    I->>IPA: Fetch entity data
    IPA-->>I: TaxIdentificationNumber + Name

    I->>PPG: Fetch category data
    PPG-->>I: ToService (categoria)

    I->>I: updatePayment()
    I->>ST: StorePayment()
    I->>KPay: ProducePayment()
end

%% Fine flusso
H-->>KUsers: Pagamenti sincronizzati
H->>H: Release lock
```

" %}

## Attivazione del flusso di importazione

Il flusso di importazione viene attivato nel momento in cui il cittadino fa login sull'area personale. Questa azione scatena la produzione di un evento sul topic kafka users, il quale, nel momento in cui viene recepito dal proxy di pagamento avvia il flusso di importazione dei pagamenti per quel cittadino

{% @mermaid/diagram content="flowchart TB
A\[Kafka users topic]
B\[HandleUserEventMessage]
C\[FlowUserLogged]
D\[FlowProviderPaymentAuthenticate]
E\[FlowImportPayments]
F\[Payment Provider API]

```
A -->|User login event| B
B --> C
C -->|Validation successful| D
D -->|Authentication successful| E
E --> F" %}
```

### Gestione dell'evento di login

Per ogni cittadino che fa login sulla piattaforma viene prodotto sul topic users il seguente evento

```json
{
  "app_id": "symfony-core:3.24.3",
  "app_version": "3.24.3",
  "country_of_birth": null,
  "county_of_birth": "RM",
  "created_at": "2025-08-21T11:10:40+02:00",
  "date_of_birth": "1988-02-29T11:10:40+01:00",
  "domicile": {
    "address": null,
    "country": null,
    "county": null,
    "municipality": null,
    "post_code": null
  },
  "email": "email@gmail.com",
  "event_created_at": "2025-08-21T11:10:40+02:00",
  "event_id": "3d9d356c-a5e4-4495-9845-662064f2f3ea",
  "event_version": 2,
  "family_name": "ROSSI",
  "full_name": "MARIO ROSSI",
  "gender": "M",
  "given_name": "MARIO",
  "id": "26fbf418-97fc-4e45-9fee-619ad2c2ce54",
  "mobile_phone": "+393466163313",
  "path": "/users",
  "place_of_birth": "Roma",
  "residency": {
    "address": null,
    "country": null,
    "county": null,
    "municipality": null,
    "post_code": null
  },
  "role": "user",
  "source_type": "http",
  "spid_code": "QXZRMP7L9K2HTJD",
  "tax_code": "RSSMRA74D22A001Q",
  "telephone": null,
  "tenant_id": "d48b7031-57c1-4105-8979-c9fd6f3cd8ab",
  "timestamp": "2025-08-21T09:10:40.804829317Z",
  "updated_at": "2025-08-21T11:10:40+02:00",
  "x-forwarded-for": "172.31.77.252"
}
```

L'evento viene poi processato dal flusso descritto nel seguente diagramma

{% @mermaid/diagram content="sequenceDiagram
participant KC as Kafka Consumer
participant H as HandleUserEventMessage
participant V as FlowUserLogged
participant A as FlowProviderPaymentAuthenticate
participant I as FlowImportPayments

```
KC->>H: kafka.Message
H->>V: Esecuzione validazione

alt Validazione completata
    V-->>H: User e tenant validati
    H->>A: Autenticazione sul provider

    alt Autenticazione completata
        A-->>H: AuthToken ottenuto
        H->>I: Importazione pagamenti del cittadino
        I-->>H: Pagamenti importati
    else Autenticazione fallita
        A-->>H: Autenticazione fallita
    end

else Validazione fallita
    V-->>H: User/tenant non valido
end" %}
```

### Validazione dell'evento di login

La validazione degli eventi di login in ingresso attraverso un processo di validazione a più stadi.

| **Fase di Validazione** | **Scopo**                                                          |
| ----------------------- | ------------------------------------------------------------------ |
| Estrazione Evento       | Analizzare il JSON e validare la struttura dell’evento             |
| Verifica Feature Flag   | Verificare che il tenant sia abilitato all’importazione massiva    |
| Validazione Tenant      | Assicurarsi che il tenant esista e abbia una configurazione valida |

***

{% @mermaid/diagram content="flowchart TB
A\[Evento di login] --> B\[Estrazione Utente]
B --> C{Validazione JSON / Validazione versione evento / Check esistenza Tenant / Validazione codice fiscale }
C -- Sì --> D\[Check Feature Flag]
C -- No / dati non validi --> VF\[Validazione fallita]

```
D --> E{Tenant abilitato?}

E -- No --> VF

E -- Sì --> G[checkTenant]
G --> H{Tenant esiste nello storage}
H -- Sì --> VC[Validazione completata]
H -- No --> VF
```

" %}

Gli eventi di login devono rispettare una struttura specifica e superare le fasi di validazione prima di poter essere elaborati.

#### Validazione della Versione Evento

Il sistema elabora esclusivamente eventi con **versione pari a 2**, rifiutando versioni obsolete o non supportate.

#### Campi Obbligatori

* `tenant_id`: deve essere valorizzato per identificare correttamente l'ente.
* `tax_code`: deve essere lungo esattamente 16 caratteri (formato del codice fiscale italiano).

#### Integrazione con Feature Flag

Il sistema utilizza un meccanismo di cache per mantenere l’elenco dei tenant abilitati alla funzionalità di importazione dei pagamenti. Solo gli utenti appartenenti a tenant abilitati possono attivare i flussi di importazione.&#x20;

## Flusso di Importazione Pagamenti

Se la validazione del cittadino va a buon fine, il sistema avvia un processo in due fasi:

1. **Autenticazione:** ottenimento di un token di autenticazione sul provider esterno.
2. **Importazione**: recupero ed elaborazione dei pagamenti per l’utente autenticato.

Le informazioni relative al codice fiscale dell’utente e al tenant vengono propagate al flusso di importazione, in modo da circoscrivere correttamente l’operazione al cittadino e al contesto comunale specifico.

{% @mermaid/diagram content="flowchart TB
A\["Esecuzione flusso importazione"]

```
%% Preparazione richiesta
subgraph S1["Preparazione richiesta"]
    RP1["Build Payload ImportRequest"]
    RP2["Set Provider endpoint"]
    RP3["Aggiunta Bearer token"]
    RP1 --> RP2 --> RP3
end
A --> RP1

%% Esecuzione richiesta
RP3 --> E

subgraph S2["Esecuzione Richiesta"]
    E["HTTP POST to Provider with fiscal code"]
    F["Parse JSON response"]
    G["Aggiornamento metriche Prometheus"]
    E --> F --> G
end

H["Importa Pagamenti"] --> L
G --> H


L["Cerca pagamento"] --> M{"Esiste?"}
M -- Sì --> N["Aggiorna Pagamento Esistente"]
M -- No --> O["Crea nuovo pagamento"]
N --> P["Arricchimento dati pagamento"]
O --> P
P --> Q["Salva Pagamento"]
Q --> R["Prossimo Pagamento"]
R --> L
R -- iterazione completata --> S["Return success/failure"]" %}
```

### Flusso arricchimento dati pagamento

Dopo aver ottenuto i dati del pagamento dal provider, il pagamento viene ulteriormente arricchito con dati proveniente da diverse fonti esterne e interne

{% @mermaid/diagram content="sequenceDiagram
participant F as FlowImportPayments
participant JPPA as Provider API
participant IPA as IPA Registry API
participant PPG as PagoPA Dataset API
participant PB as PocketBase API

```
F->>JPPA: POST /estrattoConto/v1/ricerca
JPPA-->>F: ImportPaymentsResponse

loop For each debt
    F->>IPA: GET /api/3/action/datastore_search 
    IPA-->>F: Dettagli dell'ente

    F->>PPG: GET /datasets/pagopa
    PPG-->>F: Categoria pagamento

    F->>PB: Get Tenant URL
    PB-->>F: Landing page URL
end" %}
```

#### Integrazione con l’IPA Registry

Il primo step di arricchimento recupera le informazioni sull'ente dal registro della Pubblica Amministrazione italiana:

* Interroga il registro per codice IPA ente
* Restituisce denominazione dell’organizzazione e codice fiscale
* Utilizzato per popolare i campo `receiver.tax_identification_number` e `receiver.name` relative al destinatario del pagamento

#### Integrazione con il Dataset PagoPA

Il secondo step di arricchimento consiste nella categorizzazione dei pagamenti secondo la tassnomia ufficiale di pagoPA:

* Recuperano i dati di categorizzazione tramite le [API OpenCity](https://api.opencityitalia.it/datasets/pagopa)
* Associano i codici di tassonomia ai tipi di servizio
* Impostano il campo `pagopa_category` per i pagamenti leggendo dal campo `TIPO SERVIZIO`

#### Generazione dei Link di Pagamento

Il terzo step di arricchimento genera gli URL relativi ai pagamenti, ognuno destinato a operazioni differenti:

<table data-header-hidden><thead><tr><th width="242.43359375"></th><th width="413.0078125"></th><th></th></tr></thead><tbody><tr><td><strong>Tipo di Link</strong></td><td><strong>Pattern URL</strong></td><td><strong>Scopo</strong></td></tr><tr><td><code>online_payment_begin</code></td><td><code>/online-payment/{id}</code></td><td>Avvio del pagamento online</td></tr><tr><td><code>online_payment_landing</code></td><td><code>URL tenant PocketBase + /it/user/payments/{id}</code></td><td>Pagina di ritorno  al pagamento sull'area personale</td></tr><tr><td><code>offline_payment</code></td><td><code>/notice/{id}</code></td><td>Generazione dell’avviso di pagamento pdf</td></tr><tr><td><code>receipt</code></td><td><code>/receipt/{id}</code></td><td>Ricevuta di pagamento</td></tr><tr><td><code>update</code></td><td><code>/update/{id}</code> (interno)</td><td>Aggiornamenti dello stato del pagamento</td></tr></tbody></table>

Tutti i link includono i metodi HTTP appropriati (**GET**) e il tracciamento dei timestamp per il monitoraggio degli accessi.

#### Integrazione con la Configurazione del Servizio

L'ultimo step di arricchimento carica e applica la configurazione del servizio ai pagamenti importati.

#### Processo di Applicazione della Configurazione

* Si ottiene l'id del servizio a partire dal campo `codiceTipoDebito` (o equivalente)
* Si carica la configurazione del servizio
* Si applicano tipologia di pagamento, importi e regole di scadenza
* Si validano i campi di configurazione obbligatori

#### Gestione dello stato del pagamento

Infine, il flusso, in base alle informazioni ritornate dal provider, imposta lo stato del pagamento:

{% @mermaid/diagram content="stateDiagram-v2
\[*] --> PAYMENT\_PENDING: Nuovo pagamento pendente
\[*] --> COMPLETE: Nuovo pagamento completato
PAYMENT\_PENDING --> COMPLETE: Pagamento esistente completato

```
note right of COMPLETE
  payment.paid_at = dataPagamento
end note
```

" %}

#### Riepilogo della mappatura dei campi e la relativa fonte di arricchimento

#### Campi Base del Payment

| campo        | tipo fonte   | logica                 |
| ------------ | ------------ | ---------------------- |
| `id`         | Provider API | Solo per nuovi payment |
| `user_id`    | User Event   | Solo per nuovi payment |
| `tenant_id`  | User Event   | Solo per nuovi payment |
| `service_id` | Config       |                        |
| `remote_id`  | Provider API | Se vuoto               |
| `type`       | Hardcoded    | Solo per nuovi payment |
| `status`     | Provider API | Basato su paid         |
| `reason`     | Provider API | Solo per nuovi payment |

#### Campi Payment Detail

| campo         | tipo fonte   | logica                                              |
| ------------- | ------------ | --------------------------------------------------- |
| `amount`      | Provider API | Solo per nuovi payment                              |
| `currency`    | Hardcoded    | Hardcoded per nuovi payment                         |
| `expire_at`   | Provider API | Convertito da stringa a Time                        |
| `paid_at`     | Provider API | Solo se il pagamento è completato                   |
| `notice_code` | Provider API | Solo per nuovi payment                              |
| `iud`         | Provider API | Rimuove trattini se uniquePaymentIdentifier è vuoto |
| `iuv`         | Provider API | Solo per nuovi payment                              |

#### Receiver (da IPA API)

| campo                       | tipo fonte | logica                       |
| --------------------------- | ---------- | ---------------------------- |
| `tax_identification_number` | IPA API    | Da API IPA usando entityCode |
| `name`                      | IPA API    | Da API IPA usando entityCode |

#### Payer (da User Event)

| campo                 | tipo fonte | logica                       |
| --------------------- | ---------- | ---------------------------- |
| `street_name`         | User Event | Se vuoto e User ha indirizzo |
| `postal_code`         | User Event | Se vuoto e User ha CAP       |
| `town_name`           | User Event | Se vuoto e User ha comune    |
| `country_subdivision` | User Event | Se vuoto e User ha provincia |
| `email`               | User Event | Se vuoto e User ha email     |
| `country`             | User Event | Se vuoto e User ha paese     |

#### PagoPA Category

| campo             | tipo fonte  | logica                                                                              |
| ----------------- | ----------- | ----------------------------------------------------------------------------------- |
| `pagopa_category` | Dataset API | <p>Matching con </p><p>DATI SPECIFICI DI INCASSO</p><p> nel campo TIPO SERVIZIO</p> |

#### Links e Configurazione

| campo                      | tipo fonte    | logica                      |
| -------------------------- | ------------- | --------------------------- |
| `online_payment_begin_url` | Server Config | URL per pagamento online    |
| `offline_payment_url`      | Server Config | URL per avviso di pagamento |
| `update_url`               | Server Config | URL per aggiornamenti       |
| `receipt_url`              | Server Config | URL per ricevuta            |

#### Metadati

| campo              | tipo fonte    | logica                      |
| ------------------ | ------------- | --------------------------- |
| `updated_at`       | System        | Timestamp corrente          |
| `event_created_at` | System        | Timestamp corrente          |
| `event_id`         | System        | Nuovo UUID                  |
| `app_id`           | Server Config | Identificativo applicazione |

### Esempio di Importazione

#### Richiesta

```json
{
  "codiceFiscaleDebitore": "BNRMHL75C06G702B",
  "codiceIpa": "c_b240",
  "codiceTipoDebito": "VOTIVE",
  "dataDiPagamento": {
    "beginDate": "2020-07-10T08:41:43.606Z",
    "endDate": "2025-08-21T11:32:44.402Z"
  },
  "dataDiScadenza": {
    "beginDate": "2020-07-10T08:41:43.606Z",
    "endDate": "2026-08-21T11:32:44.402Z"
  },
  "elementiInPagina": 10,
  "inEsecuzione": 0,
  "pagamento": 1,
  "pagina": 1
}
```

#### Risposta

```json
{
  "numeroTotaleDiElementi": 33,
  "debiti": [
    {
      "identificativoUnivocoVersamento": "04240000000019065",
      "pagato": true,
      "modalitaPagamento": "MOD3",
      "importoDebito": 1,
      "iDeb": "fad17259-ae4c-4d97-b55c-2be55dca5bf9",
      "iPosDeb": "fad17259-ae4c-4d97-b55c-2be55dca5bf9",
      "codiceTipoDebito": "VOTIVE",
      "codiceIpaEnte": "c_b240",
      "base64RT": "UEQ5NGJXd2dkbVZ5YzJsdmJqMGlNUzR3SWlCbGJtTnZaR2x1WnowaVZWUkdMVGdpSUhOMFlXNWtZV3h2Ym1VOUlubGxjeUkvUGdvOFVsUWdlRzFzYm5NOUltaDBkSEE2THk5M2QzY3VaR2xuYVhSd1lTNW5iM1l1YVhRdmMyTm9aVzFoY3k4eU1ERXhMMUJoWjJGdFpXNTBhUzhpUGdvZ0lDQWdQSFpsY25OcGIyNWxUMmRuWlhSMGJ6NDJMakl1TUR3dmRtVnljMmx2Ym1WUFoyZGxkSFJ2UGdvZ0lDQWdQR1J2YldsdWFXOCtDaUFnSUNBZ0lDQWdQR2xrWlc1MGFXWnBZMkYwYVhadlJHOXRhVzVwYno0d016UTRNamt5TURFMU9Ed3ZhV1JsYm5ScFptbGpZWFJwZG05RWIyMXBibWx2UGdvZ0lDQWdQQzlrYjIxcGJtbHZQZ29nSUNBZ1BHbGtaVzUwYVdacFkyRjBhWFp2VFdWemMyRm5aMmx2VW1salpYWjFkR0UrTVRkbVlUSTROVEJqWXpobE5HVXdZbUkzTVRRek1HSXlORFE1TlRNeVlXVThMMmxrWlc1MGFXWnBZMkYwYVhadlRXVnpjMkZuWjJsdlVtbGpaWFoxZEdFK0NpQWdJQ0E4WkdGMFlVOXlZVTFsYzNOaFoyZHBiMUpwWTJWMmRYUmhQakl3TWpRdE1URXRNVGxVTVRRNk1qYzZORGc4TDJSaGRHRlBjbUZOWlhOellXZG5hVzlTYVdObGRuVjBZVDRLSUNBZ0lEeHlhV1psY21sdFpXNTBiMDFsYzNOaFoyZHBiMUpwWTJocFpYTjBZVDR4TjJaaE1qZzFNR05qT0dVMFpUQmlZamN4TkRNd1lqSTBORGsxTXpKaFpUd3ZjbWxtWlhKcGJXVnVkRzlOWlhOellXZG5hVzlTYVdOb2FXVnpkR0UrQ2lBZ0lDQThjbWxtWlhKcGJXVnVkRzlFWVhSaFVtbGphR2xsYzNSaFBqSXdNalF0TVRFdE1qQThMM0pwWm1WeWFXMWxiblJ2UkdGMFlWSnBZMmhwWlhOMFlUNEtJQ0FnSUR4cGMzUnBkSFYwYjBGMGRHVnpkR0Z1ZEdVK0NpQWdJQ0FnSUNBZ1BHbGtaVzUwYVdacFkyRjBhWFp2Vlc1cGRtOWpiMEYwZEdWemRHRnVkR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeDBhWEJ2U1dSbGJuUnBabWxqWVhScGRtOVZibWwyYjJOdlBrSThMM1JwY0c5SlpHVnVkR2xtYVdOaGRHbDJiMVZ1YVhadlkyOCtDaUFnSUNBZ0lDQWdJQ0FnSUR4amIyUnBZMlZKWkdWdWRHbG1hV05oZEdsMmIxVnVhWFp2WTI4K01EVTVOak15TXpFd01EVThMMk52WkdsalpVbGtaVzUwYVdacFkyRjBhWFp2Vlc1cGRtOWpiejRLSUNBZ0lDQWdJQ0E4TDJsa1pXNTBhV1pwWTJGMGFYWnZWVzVwZG05amIwRjBkR1Z6ZEdGdWRHVStDaUFnSUNBZ0lDQWdQR1JsYm05dGFXNWhlbWx2Ym1WQmRIUmxjM1JoYm5SbFBsZHZjbXhrYkdsdVpTQk5aWEpqYUdGdWRDQlRaWEoyYVdObGN5QkpkR0ZzYVdFZ1V5NXdMa0V1UEM5a1pXNXZiV2x1WVhwcGIyNWxRWFIwWlhOMFlXNTBaVDRLSUNBZ0lEd3ZhWE4wYVhSMWRHOUJkSFJsYzNSaGJuUmxQZ29nSUNBZ1BHVnVkR1ZDWlc1bFptbGphV0Z5YVc4K0NpQWdJQ0FnSUNBZ1BHbGtaVzUwYVdacFkyRjBhWFp2Vlc1cGRtOWpiMEpsYm1WbWFXTnBZWEpwYno0S0lDQWdJQ0FnSUNBZ0lDQWdQSFJwY0c5SlpHVnVkR2xtYVdOaGRHbDJiMVZ1YVhadlkyOCtSend2ZEdsd2IwbGtaVzUwYVdacFkyRjBhWFp2Vlc1cGRtOWpiejRLSUNBZ0lDQWdJQ0FnSUNBZ1BHTnZaR2xqWlVsa1pXNTBhV1pwWTJGMGFYWnZWVzVwZG05amJ6NHdNelE0TWpreU1ERTFPRHd2WTI5a2FXTmxTV1JsYm5ScFptbGpZWFJwZG05VmJtbDJiMk52UGdvZ0lDQWdJQ0FnSUR3dmFXUmxiblJwWm1sallYUnBkbTlWYm1sMmIyTnZRbVZ1WldacFkybGhjbWx2UGdvZ0lDQWdJQ0FnSUR4a1pXNXZiV2x1WVhwcGIyNWxRbVZ1WldacFkybGhjbWx2UGtOdmJYVnVaU0JrYVNCQ2RXTmphVzVoYzJOdlBDOWtaVzV2YldsdVlYcHBiMjVsUW1WdVpXWnBZMmxoY21sdlBnb2dJQ0FnSUNBZ0lEeHBibVJwY21sNmVtOUNaVzVsWm1samFXRnlhVzgrYmk5aFBDOXBibVJwY21sNmVtOUNaVzVsWm1samFXRnlhVzgrQ2lBZ0lDQWdJQ0FnUEdOaGNFSmxibVZtYVdOcFlYSnBiejV1TDJFOEwyTmhjRUpsYm1WbWFXTnBZWEpwYno0S0lDQWdJRHd2Wlc1MFpVSmxibVZtYVdOcFlYSnBiejRLSUNBZ0lEeHpiMmRuWlhSMGIxWmxjbk5oYm5SbFBnb2dJQ0FnSUNBZ0lEeHBaR1Z1ZEdsbWFXTmhkR2wyYjFWdWFYWnZZMjlXWlhKellXNTBaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BIUnBjRzlKWkdWdWRHbG1hV05oZEdsMmIxVnVhWFp2WTI4K1Jqd3ZkR2x3YjBsa1pXNTBhV1pwWTJGMGFYWnZWVzVwZG05amJ6NEtJQ0FnSUNBZ0lDQWdJQ0FnUEdOdlpHbGpaVWxrWlc1MGFXWnBZMkYwYVhadlZXNXBkbTlqYno1Q1RsSk5TRXczTlVNd05rYzNNREpDUEM5amIyUnBZMlZKWkdWdWRHbG1hV05oZEdsMmIxVnVhWFp2WTI4K0NpQWdJQ0FnSUNBZ1BDOXBaR1Z1ZEdsbWFXTmhkR2wyYjFWdWFYWnZZMjlXWlhKellXNTBaVDRLSUNBZ0lDQWdJQ0E4WVc1aFozSmhabWxqWVZabGNuTmhiblJsUGxKdmMzTnBJRTFoY21sdlBDOWhibUZuY21GbWFXTmhWbVZ5YzJGdWRHVStDaUFnSUNBZ0lDQWdQR2x1WkdseWFYcDZiMVpsY25OaGJuUmxQbFpwWVNCU1pYTnBaR1Z1ZW1FOEwybHVaR2x5YVhwNmIxWmxjbk5oYm5SbFBnb2dJQ0FnSUNBZ0lEeGphWFpwWTI5V1pYSnpZVzUwWlQ0eE1qd3ZZMmwyYVdOdlZtVnljMkZ1ZEdVK0NpQWdJQ0FnSUNBZ1BHTmhjRlpsY25OaGJuUmxQakV5TXpRMVBDOWpZWEJXWlhKellXNTBaVDRLSUNBZ0lDQWdJQ0E4Ykc5allXeHBkR0ZXWlhKellXNTBaVDVCYkdacFlXNXZJRTVoZEhSaFBDOXNiMk5oYkdsMFlWWmxjbk5oYm5SbFBnb2dJQ0FnSUNBZ0lEeHdjbTkyYVc1amFXRldaWEp6WVc1MFpUNUJURHd2Y0hKdmRtbHVZMmxoVm1WeWMyRnVkR1UrQ2lBZ0lDQWdJQ0FnUEc1aGVtbHZibVZXWlhKellXNTBaVDVKVkR3dmJtRjZhVzl1WlZabGNuTmhiblJsUGdvZ0lDQWdJQ0FnSUR4bExXMWhhV3hXWlhKellXNTBaVDV0YVhKcmJ5NWpjbTlpZFVCdmNHVnVZMjl1ZEdWdWRDNXBkRHd2WlMxdFlXbHNWbVZ5YzJGdWRHVStDaUFnSUNBOEwzTnZaMmRsZEhSdlZtVnljMkZ1ZEdVK0NpQWdJQ0E4YzI5bloyVjBkRzlRWVdkaGRHOXlaVDRLSUNBZ0lDQWdJQ0E4YVdSbGJuUnBabWxqWVhScGRtOVZibWwyYjJOdlVHRm5ZWFJ2Y21VK0NpQWdJQ0FnSUNBZ0lDQWdJRHgwYVhCdlNXUmxiblJwWm1sallYUnBkbTlWYm1sMmIyTnZQa1k4TDNScGNHOUpaR1Z1ZEdsbWFXTmhkR2wyYjFWdWFYWnZZMjgrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeGpiMlJwWTJWSlpHVnVkR2xtYVdOaGRHbDJiMVZ1YVhadlkyOCtRazVTVFVoTU56VkRNRFpITnpBeVFqd3ZZMjlrYVdObFNXUmxiblJwWm1sallYUnBkbTlWYm1sMmIyTnZQZ29nSUNBZ0lDQWdJRHd2YVdSbGJuUnBabWxqWVhScGRtOVZibWwyYjJOdlVHRm5ZWFJ2Y21VK0NpQWdJQ0FnSUNBZ1BHRnVZV2R5WVdacFkyRlFZV2RoZEc5eVpUNVNiM056YVNCTllYSnBiend2WVc1aFozSmhabWxqWVZCaFoyRjBiM0psUGdvZ0lDQWdJQ0FnSUR4cGJtUnBjbWw2ZW05UVlXZGhkRzl5WlQ1V2FXRWdVbVZ6YVdSbGJucGhQQzlwYm1ScGNtbDZlbTlRWVdkaGRHOXlaVDRLSUNBZ0lDQWdJQ0E4WTJsMmFXTnZVR0ZuWVhSdmNtVStNVEk4TDJOcGRtbGpiMUJoWjJGMGIzSmxQZ29nSUNBZ0lDQWdJRHhqWVhCUVlXZGhkRzl5WlQ0eE1qTTBOVHd2WTJGd1VHRm5ZWFJ2Y21VK0NpQWdJQ0FnSUNBZ1BHeHZZMkZzYVhSaFVHRm5ZWFJ2Y21VK1FXeG1hV0Z1YnlCT1lYUjBZVHd2Ykc5allXeHBkR0ZRWVdkaGRHOXlaVDRLSUNBZ0lDQWdJQ0E4Y0hKdmRtbHVZMmxoVUdGbllYUnZjbVUrUVV3OEwzQnliM1pwYm1OcFlWQmhaMkYwYjNKbFBnb2dJQ0FnSUNBZ0lEeHVZWHBwYjI1bFVHRm5ZWFJ2Y21VK1NWUThMMjVoZW1sdmJtVlFZV2RoZEc5eVpUNEtJQ0FnSUNBZ0lDQThaUzF0WVdsc1VHRm5ZWFJ2Y21VK2JXbHlhMjh1WTNKdlluVkFiM0JsYm1OdmJuUmxiblF1YVhROEwyVXRiV0ZwYkZCaFoyRjBiM0psUGdvZ0lDQWdQQzl6YjJkblpYUjBiMUJoWjJGMGIzSmxQZ29nSUNBZ1BHUmhkR2xRWVdkaGJXVnVkRzgrQ2lBZ0lDQWdJQ0FnUEdOdlpHbGpaVVZ6YVhSdlVHRm5ZVzFsYm5SdlBqQThMMk52WkdsalpVVnphWFJ2VUdGbllXMWxiblJ2UGdvZ0lDQWdJQ0FnSUR4cGJYQnZjblJ2Vkc5MFlXeGxVR0ZuWVhSdlBqRXVNREE4TDJsdGNHOXlkRzlVYjNSaGJHVlFZV2RoZEc4K0NpQWdJQ0FnSUNBZ1BHbGtaVzUwYVdacFkyRjBhWFp2Vlc1cGRtOWpiMVpsY25OaGJXVnVkRzgrTURReU5EQXdNREF3TURBd01Ua3dOalU4TDJsa1pXNTBhV1pwWTJGMGFYWnZWVzVwZG05amIxWmxjbk5oYldWdWRHOCtDaUFnSUNBZ0lDQWdQRU52WkdsalpVTnZiblJsYzNSdlVHRm5ZVzFsYm5SdlBqRTNabUV5T0RVd1kyTTRaVFJsTUdKaU56RTBNekJpTWpRME9UVXpNbUZsUEM5RGIyUnBZMlZEYjI1MFpYTjBiMUJoWjJGdFpXNTBiejRLSUNBZ0lDQWdJQ0E4WkdGMGFWTnBibWR2Ykc5UVlXZGhiV1Z1ZEc4K0NpQWdJQ0FnSUNBZ0lDQWdJRHh6YVc1bmIyeHZTVzF3YjNKMGIxQmhaMkYwYno0eExqQXdQQzl6YVc1bmIyeHZTVzF3YjNKMGIxQmhaMkYwYno0S0lDQWdJQ0FnSUNBZ0lDQWdQR1Z6YVhSdlUybHVaMjlzYjFCaFoyRnRaVzUwYno0d1BDOWxjMmwwYjFOcGJtZHZiRzlRWVdkaGJXVnVkRzgrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeGtZWFJoUlhOcGRHOVRhVzVuYjJ4dlVHRm5ZVzFsYm5SdlBqSXdNalF0TVRFdE1UazhMMlJoZEdGRmMybDBiMU5wYm1kdmJHOVFZV2RoYldWdWRHOCtDaUFnSUNBZ0lDQWdJQ0FnSUR4cFpHVnVkR2xtYVdOaGRHbDJiMVZ1YVhadlkyOVNhWE5qYjNOemFXOXVaVDR4TjJaaE1qZzFNR05qT0dVMFpUQmlZamN4TkRNd1lqSTBORGsxTXpKaFpUd3ZhV1JsYm5ScFptbGpZWFJwZG05VmJtbDJiMk52VW1selkyOXpjMmx2Ym1VK0NpQWdJQ0FnSUNBZ0lDQWdJRHhqWVhWellXeGxWbVZ5YzJGdFpXNTBiejR5TlRFNU9UQXRkR1Z6ZERBeE1TQnBiWEJ2Y25RZ2JXRnpjMmwyYnlCa2IzWjFkR2tnYlc5MWMyeHBiVHd2WTJGMWMyRnNaVlpsY25OaGJXVnVkRzgrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeGtZWFJwVTNCbFkybG1hV05wVW1selkyOXpjMmx2Ym1VK09TOHdNVEUwTVRBd1ZGTXZQQzlrWVhScFUzQmxZMmxtYVdOcFVtbHpZMjl6YzJsdmJtVStDaUFnSUNBZ0lDQWdQQzlrWVhScFUybHVaMjlzYjFCaFoyRnRaVzUwYno0S0lDQWdJRHd2WkdGMGFWQmhaMkZ0Wlc1MGJ6NEtQQzlTVkQ0Sw==",
      "statoPagamento": "CONTABILIZZATO",
      "dataPagamento": "2024-11-19T13:27:48Z",
      "dataScadenzaPagamento": "2025-01-22T23:00:00Z",
      "codiceDiTassonomia": "0114100TS/",
      "descrizioneTassonomia": "0114100TS/ VOTIVE",
      "causalePagamento": "251990-test011 import massivo dovuti mouslim",
      "numeroAvviso": "304240000000019065",
      "codiceServizio": "OPENCITY",
      "gruppo": "1",
      "inEsecuzione": false
    },
    ...
  ]
}
```

#### Evento di pagamento arricchito

```json
{
  "id": "fad17259-ae4c-4d97-b55c-2be55dca5bf9",
  "user_id": "5b00796e-ef10-4c98-b9f5-b0f7ffd7a17d",
  "type": "PAGOPA",
  "tenant_id": "60e35f02-1509-408c-b101-3b1a28109329",
  "service_id": "c2732467-8611-4000-9741-dc05dd040494",
  "created_at": "2024-11-19T14:24:42+01:00",
  "updated_at": "2025-02-10T15:56:53+01:00",
  "status": "COMPLETE",
  "reason": "251990-test011 import massivo dovuti mouslim",
  "remote_id": "c2732467-8611-4000-9741-dc05dd040494",
  "payment": {
    "type": "PAGOPA",
    "transaction_id": "e95ec86b-57c4-4c77-bb24-87790d4fb62c",
    "paid_at": "2024-11-19T13:27:48Z",
    "expire_at": "2025-01-22T23:00:00Z",
    "amount": 1,
    "currency": "EUR",
    "notice_code": "304240000000019065",
    "iud": "04240000000019065",
    "iuv": "04240000000019065",
    "receiver": {
      "tax_identification_number": "03482920158",
      "name": "Comune di Buccinasco",
      "iban": "IT60X0542811101000000123456",
      "address": "Via Del Campo",
      "building_number": "12",
      "postal_code": "38022",
      "town_name": "Roma",
      "country_subdivision": "RM",
      "country": "IT",
    },
    "due_type": "VOTIVE",
    "pagopa_category": "Oneri cimiteriali & Lampade Votive",
    "document": null,
    "split": null
  },
  "links": {
    "online_payment_begin": {
      "url": "https://api.qa.stanzadelcittadino.it/payment-proxy/jppa/online-payment/fad17259-ae4c-4d97-b55c-2be55dca5bf9",
      "last_opened_at": null,
      "method": "GET"
    },
    "online_payment_landing": {
      "url": "https://servizi.comune-qa.bugliano.pi.it/lang/it/user/payments",
      "last_opened_at": "2024-11-19T14:28:25+01:00",
      "method": "GET"
    },
    "offline_payment": {
      "url": "https://api.qa.stanzadelcittadino.it/payment-proxy/jppa/notice/fad17259-ae4c-4d97-b55c-2be55dca5bf9",
      "last_opened_at": null,
      "method": "GET"
    },
    "receipt": {
      "url": "https://api.qa.stanzadelcittadino.it/payment-proxy/jppa/receipt/fad17259-ae4c-4d97-b55c-2be55dca5bf9",
      "last_opened_at": null,
      "method": "GET"
    },
    "notify": [
      {
        "url": "#",
        "method": "",
        "sent_at": null
      }
    ],
    "update": {
      "url": "http://jppa-proxy-qa.boat-backplane.opencontent.io/payment-proxy/jppa/update/fad17259-ae4c-4d97-b55c-2be55dca5bf9",
      "last_check_at": "2025-02-10T15:56:53+01:00",
      "next_check_at": "2025-02-15T15:56:53+01:00",
      "method": "GET"
    }
  },
  "payer": {
    "type": "human",
    "tax_identification_number": "BNRMHL75C06G702B",
    "name": "Michelangelo",
    "family_name": "",
    "street_name": "test",
    "building_number": "",
    "postal_code": "",
    "town_name": "",
    "country_subdivision": "EE",
    "email": "valentina.russo@opencontent.it"
  },
  "debtor": {
    "type": "human",
    "tax_identification_number": "BNRMHL75C06G702B",
    "name": "Michelangelo",
    "family_name": "",
    "street_name": "test",
    "building_number": "",
    "postal_code": "",
    "town_name": "",
    "country_subdivision": "EE",
    "email": "valentina.russo@opencontent.it"
  },
  "event_id": "a1a92abb-6bfd-49ff-bd43-6c7d359ddd7b",
  "event_version": "2.0",
  "event_created_at": "2025-02-10T15:56:53+01:00",
  "app_id": "jppa-payment-proxy:1.0.37"
}
```
