openapi: 3.0.3 info: termsOfService: https://notifichedigitali.pagopa.it/pubbliche-amministrazioni/index.html x-api-id: api-external-b2b-pa title: 'Piattaforma Notifiche: API B2B per le Pubbliche Amministrazioni' x-summary: 'Piattaforma Notifiche: API B2B per le Pubbliche Amministrazioni' version: 1.0.0 description: >- ## Abstract API utilizzate dalle pubbliche amministrazioni per __inviare richieste di notifiche__ e __ottenere informazioni in modalità pull__ sullo stato della _"richiesta di notifica"_ (accettata o rifiutata) e, in caso di richiesta accettata, sulle comunicazioni effettuate, o solo tentate, nei confronti dei destinatari della notifica. ## Operazioni utilizzate, in sequenza temporale
![]() |
### Ciclo di vita della notifica lato mittente
#### 1. Caricamento dei documenti della notifica
Prima di invocare la richiesta di notifica è necessario caricare i documenti della notifica (documenti e bollettini di pagamento).
#### 1.a. Richiesta presigned Url
Invocare l'operazione [presignedUploadRequest](#/NewNotification/presignedUploadRequest)
con cui prenotare il caricamento. Possono essere effettuate un massimo di 15 prenotazioni di caricamento
per ogni richiesta.
In risposta si ottengono le seguenti informazioni: \- httpMethod \- secret \- url L'url restituito ha una validità di 1h. #### 1.b Upload documenti della notifica Per ogni documento utilizzare un richiesta HTTP con metodo _httpMethod_ (POST o PUT) all'url indicato dal campo _url_. In tale richiesta vanno aggiunti i seguenti header: \- _content-type_: valorizzato come il campo "contentType" della richiesta di cui al punto (1.a) \- _x-amz-meta-secret_: valorizzato con il valore del campo "secret" della risposta di cui al punto (1.a) \- _trailer_: valorizzato con ```x-amz-checksum-sha256``` \- _x-amz-checksum-sha256_: valorizzato con il checksum sha256, codificato in base 64, del contenuto binario del file che verrà caricato. (__N.B.__ questo è un trailer HTTP non un header). Vedi [HTTP Trailer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer) __NOTA:__ se l'operazione di upload è stata eseguita con successo, si otterrà come risposta _status 200 OK_. Nell'header di questa risposta, si otterrà il campo __x-amz-version-id__ che dovrà essere utilizzato durante l'inserimento della notifica, nel campo ref.__versionToken__ in corrispondenza del documento ad esso associato. #### 2. Richiesta di invio della notifica Per effettuare una richiesta di invio notifica, invocare l'operazione [sendNewNotification](#/NewNotification/sendNewNotification) utilizzando i riferimenti dei file caricati ottenuti al punto (1.b). ![]() |
{Iun}
della notifica di interesse: all'interno del campo timeline della response è possibile trovare l'elenco degli eventi di quella notifica ed i legalFactType e legalFactId in corrispondenza degli eventi che generano documenti.
### 1) Creazione dello stream ed inserimento notifica
In questo esempio creo 2 stream con il servizio di [creazione stream](#/Streams/createEventStream): uno per gli status e l'altro per gli eventi di timeline. Vedesi le request a) di esempio con le relative response b), Da notare che sono presenti dei filtri per ottenere solo specifici status o eventi; se si vogliono ottenere tutte le variazioni limitatamente agli eventi della v1, non bisogna inserire alcun filtro:
"filterValues": []
Una volta creati gli stream, bisogna utilizzare il servizio di [inserimento nuova notifica](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/pagopa/pn-delivery/develop/docs/openapi/api-external-b2b-pa-v1.yaml#/NewNotification/sendNewNotification) sulla Piattaforma. A questo punto bisognerà attendere che vengano completati i controlli di validazione e se questi avranno esito positivo e la notifica verrà accettata, comincerà il workflow di consegna della stessa. Con l'avanzare del tempo verranno generati degli eventi e dei cambiamenti di stato che verranno puntualmente registrati negli stream configurati precedentemente a partire già dal primo evento che certifica l'accettazione o il rifiuto della notifica appena inserita con il relativo passaggio allo stato ACCEPTED.
### 2) Prima interrogazione degli stream appena creati
Col passare del tempo, potremo interrogare gli stream appena creati per leggere gli eventi registrati, a partire già dall'evento di accettazione della notifica. Si possono interrogare gli eventi registrati all'interno di uno stream con il servizio di [lettura degli eventi](#/Events/consumeEventStream) passando il valore desiderato nello {streamId} ed otterremo la response c) che contiene un array con un numero massimo di 50 eventi corrispondenti a quelli che impattano tutte le notifiche inserite dalla creazione dello stream in poi e che potranno essere salvati sul database del client chiamante. Da notare che ogni evento contiene l'eventId ad esso associato.
A questo punto bisogna controllare il parametro retry-after contenuto nell'header della response per capire quanto tempo attendere prima di richiamare lo stream ed ottenere nuovi risultati:
retry-after ≠ 0 ; infatti tale parametro regola la cadenza di chiamata al servizio, mentre il consumo degli eventi deve avvenire in ogni chiamata nella quale si ottengono eventi in risposta.
### 3) Successive interrogazioni degli stream appena creati
Se la response della prima interrogazione degli stream restituisce nell'header: retry-after = 0 significa che lo stream contiene altri eventi che possono essere consumati subito con un'ulteriore chiamata al servizio di [lettura degli eventi](#/Events/consumeEventStream), ma questa volta per consumare gli eventi successivi, bisogna valorizzare nei query params della request il parametro lastEventId con l'eventId ottenuto nella precedente chiamata. Così facendo il servizio eliminerà dallo stream tutti gli eventi precedenti a quello inserito nel lastEventId e restituirà nella response d) solamente quelli successivi.
A questo punto si potrà capire, sempre dal valore del retry-after contenuto nell'header se chiamare subito il servizio ed inserire il lastEventId di questa ulteriore chiamata o attendere il tempo indicato nell'header
NOTA: gli eventi eliminati dallo stream in seguito alla chiamata del servizio di [lettura degli eventi](#/Events/consumeEventStream) con il query param lastEventId valorizzato, non potranno più essere recuperati dallo stream in nessun modo. E' quindi fondamentale salvare di volta in volta gli eventi che si ottengono all'interno database del chiamante, rispettando la logica del producer/consumer di eventi proposta dagli stream. In caso di eliminazione degli eventi avvenuta per errore, sarà possibile come ultima istanza chiamare il servizio di [lettura dettaglio notifica](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/pagopa/pn-delivery/develop/docs/openapi/api-external-b2b-pa-v1.yaml#/SenderReadB2B/retrieveSentNotification) che però esporrà tutti gli eventi di timeline e lo stato attuale della singola notifica ed è quindi meno performante delle stream.
|
#### a) Request di POST /delivery-progresses/streams
{ {
"title": "stream-status-prova", "title": "stream-timeline-prova",
"eventType": "STATUS", "eventType": "TIMELINE",
"filterValues": [ "filterValues": [
"ACCEPTED" "REQUEST_ACCEPTED"
] ]
} }
#### b) Response di POST /delivery-progresses/streams
{ {
"title": "stream-status-prova", "title": "stream-timeline-prova",
"eventType": "STATUS", "eventType": "TIMELINE",
"filterValues": [ "filterValues": [
"ACCEPTED" "REQUEST_ACCEPTED"
], ],
"streamId": "streamId":
"4e6d5e59-85fc-4ef7-bad8", "6d87ree59-31ff-2rr7-lok1",
"activationDate": "activationDate":
"2022-12-12T14:52:23.362454Z" "2022-12-12T14:53:23.362454Z"
} }
#### c) Response di GET /delivery-progresses/streams/{streamId} /events
Headers: { "retry-after": "60000" }
[
{
"eventId": "0000000000000000000001",
"timestamp": "2022-12-06T08:14:26.140041Z",
"notificationRequestId": "QUJDRC1BQkNELUFCQ0QtMjAyMjEyLVYtMQ==",
"iun": "ABCD-ABCD-ABCD-202212-V-1",
"newStatus": "ACCEPTED",
"timelineEventCategory": "REQUEST_ACCEPTED",
"recipientIndex": "0",
"analogCost": "0",
"channel": "PEC",
"legalfactIds": [
"PN_LEGAL_FACTS-0002-9G2S-RK3M-JI62-JK9Q",
"PN_LEGAL_FACTS-0002-9G2S-RK3M-JI62-JK9E"
]
},
... // altri eventi nell'array
]
#### d) Response di GET /delivery-progresses/streams/{streamId} /events chiamato valorizzando nei query params il parametro lastEventId con l'eventId dell'ultimo evento nella precedente chiamata.
Headers: { "retry-after": "60000" }
[
{
"eventId": "0000000000000000000011",
"timestamp": "2022-12-07T10:13:22.158041Z",
"notificationRequestId": "QUJDRC1BQkNELUFCQ0QtMjAyMjEyLVYtMQ==",
"iun": "ABCD-ABCD-ABCD-202212-V-1",
"newStatus": "DELIVERED",
"timelineEventCategory": "DIGITAL_SUCCESS_WORKFLOW",
"recipientIndex": "0",
"analogCost": "0",
"channel": "PEC",
"legalfactIds": [
"PN_LEGAL_FACTS-0002-9G2S-RK3M-JI62-JK9Q",
"PN_LEGAL_FACTS-0002-9G2S-RK3M-JI62-JK9E"
]
},
... // altri eventi nell'array
]
|