Versione 2.0

Aggiornamenti principali rispetto alla versione 1.0

NOTA 1: per gli sviluppatori python è stata definita una libreria a cui fare riferimento per la validazione del nuovo evento, è consultabile qui.

NOTA 2: per gli sviluppatori python, il repository da cui prendere spunto per applicare le modifiche riportate in questa sezione e in quelle successive è consultabile qui.

Arricchimento della descrizione del pagamento

Con la versione 2.0 aggiornata del pagamento sono stati aggiunti nuovi campi che arricchiscono la descrizione del pagamento, in particolare i campi sono:

  • type: serve a distinguere tra un pagamento ordinario e una marca da bollo digitale, può avere PAGOPA o STAMP come valori

  • receiver: definisce il beneficiario del pagamento, non è un campo obbligatorio ma può essere utilizzato nel caso di pagamenti con beneficiario differente dall'ente su cui viene creato il pagamento. Se viene valorizzato è obbligatorio valorizzare i campi receiver.tax_identification_number e receiver.name

  • due_type: indica la categorizzazione del dovuto sull'intermediario di pagamento, e viene valorizzato dalla configurazione del pagamento

  • pagopa_category: indica la categorizzazione del dovuto su pagoPA, e viene valorizzato dalla configurazione del pagamento

  • document: è un campo che serve a descrivere il documento su cui viene apposta la marca da bollo digitale, se viene valorizzato è obbligatorio valorizzare il campo document.hash .

  • split: con la versione 2.0 dell'evento, questo campo, che viene alimentato dal bilancio contenuto nella configurazione del pagamento, avrà un tipo ben definito, composto da

    • split.code: indica l'identificativo della voce di bilancio

    • split.amount: indica l'importo della voce di bilancio

    • split.meta: oggetto contenente il resto dei campi presenti nella voce di bilancio

  • links.confirm: è un campo che serve a contenere l'API per forzare il completamento di un pagamento, per il momento tutti i proxy mancano di questa API, ma il campo è stato aggiunto per utilizzi futuri.

  • links.cancel: è un campo che serve a contenere l'API per forzare l'annullamento di un pagamento.

  • debtor: in aggiunta al payer è stato aggiunto un campo equivalente debtor, e serve a distinguere tra il debitore e il pagatore di un pagamento, ad esempio è possibile che un cittadino paghi per conto di terzi e in questo caso e debitore e pagatore sono distinti. Per ora non viene valorizzato né utilizzato.

JSON Evento Pagamento

{
  "id": "68dada78-2398-4a11-b80a-98aaede3371c",
  "user_id": "5b00796e-ef10-4c98-b9f5-b0f7ffd7a17d",
  "type": "PAGOPA",
  "tenant_id": "60e35f02-1509-408c-b101-3b1a28109329",
  "service_id": "b21c4429-95e4-45d5-930f-44eb74136625",
  "created_at": "2023-06-06T11:59:11+02:00",
  "updated_at": "2023-06-12T00:10:16+02:00",
  "status": "PAYMENT_STARTED",
  "reason": "79501b2a-c9ad-41f8-a9e7-a885f2d570a2 - BNRMHL75C06G702B",
  "remote_id": "79501b2a-c9ad-41f8-a9e7-a885f2d570a2",
  "payment": {
    "type": "PAGOPA",
    "transaction_id": null,
    "paid_at": null,
    "expire_at": "2023-09-04T11:59:05+02:00",
    "amount": 1.34,
    "currency": "EUR",
    "notice_code": "001550000000024427",
    "iud": "68dada7823984a11b80a98aaede3371c",
    "iuv": "550000000024427",
    "receiver": {
      "tax_identification_number": "777777777",
      "name": "Comune di BlaBla",
      "iban": "IT60X0542811101000000123456",
      "address": "Via Del Campo",
      "building_number": "12",
      "postal_code": "38022",
      "town_name": "Roma",
      "country_subdivision": "RM",
      "country": "IT",
    },
    "due_type": "TARI",
    "pagopa_category": "9/12129/TS",
    "document": null,
    "split": [
      {
        "code": "c_1",
        "amount": 1.00,
        "meta": {}
      },
      {
        "code": "c_2",
        "amount": 0.34,
        "meta": {}
      }
    ]
  },
  "links": {
    "online_payment_begin": {
      "url": "https://iris-proxy-qa.boat.opencontent.io/online-payment/68dada78-2398-4a11-b80a-98aaede3371c?gw=https://iristest.rete.toscana.it/gateway/PaymentAuthentication?token=1686045553436001U132&expire_at=2023-06-06T12:13:13",
      "last_opened_at": "2023-06-06T11:59:26+02:00",
      "method": "GET"
    },
    "online_payment_landing": {
      "url": "https://servizi.comune-qa.bugliano.pi.it/lang/it/pratiche/79501b2a-c9ad-41f8-a9e7-a885f2d570a2/detail",
      "last_opened_at": "2023-06-06T11:59:57+02:00",
      "method": "GET"
    },
    "offline_payment": {
      "url": "https://iris-proxy-qa.boat.opencontent.io/notice/68dada78-2398-4a11-b80a-98aaede3371c",
      "last_opened_at": "2023-06-06T11:59:20+02:00",
      "method": "GET"
    },
    "receipt": {
      "url": null,
      "last_opened_at": null,
      "method": "GET"
    },
    "notify": [
      {
        "url": "https://servizi.comune-qa.bugliano.pi.it/lang/api/applications/79501b2a-c9ad-41f8-a9e7-a885f2d570a2/payment",
        "method": "POST",
        "sent_at": null
      }
    ],
    "update": {
      "url": "http://iris-proxy-qa.boat-backplane.opencontent.io/update/68dada78-2398-4a11-b80a-98aaede3371c",
      "last_check_at": "2023-06-12T00:10:16+02:00",
      "next_check_at": "2023-06-12T01:10:16+02:00",
      "method": "GET"
    },
    "confirm": {
      "url": null,
      "last_opened_at": null,
      "method": "PATCH"
    },
    "cancel": {
      "url": "https://api.qa.stanzadelcittadino.it/payment-proxy/mypay-trentino/payments/5f2c4be0-effb-47a9-a6dc-a972043580f3",
      "last_opened_at": null,
      "method": "PATCH"
    }
  },
  "payer": {
    "type": "human",
    "tax_identification_number": "BNRMHL75C06G702B",
    "name": "Michelangelo",
    "family_name": "Buonarroti",
    "street_name": "Cesare Battisti",
    "building_number": "",
    "postal_code": "38010",
    "town_name": "Bugliano",
    "country_subdivision": "PI",
    "country": "IT",
    "email": "lorenzo.bertoli@opencitylabs.it"
  },
  "debtor": {
    "type": "human",
    "tax_identification_number": "BNRMHL75C06G702B",
    "name": "Michelangelo",
    "family_name": "Buonarroti",
    "street_name": "Cesare Battisti",
    "building_number": "",
    "postal_code": "38010",
    "town_name": "Bugliano",
    "country_subdivision": "PI",
    "country": "IT",
    "email": "lorenzo.bertoli@opencitylabs.it"
  },
  "event_id": "e0b25e33-9d38-4781-823a-ed04753aea01",
  "event_version": "2.0",
  "event_created_at": "2023-06-12T00:10:16+02:00",
  "app_id": "iris-payment-proxy-qa:1.2.8"
}

Validazione campi

Payment

CampoTipoObbligatorioValidazione

id

UUID

user_id

UUID

type

string(50)

Ogni proxy deve implementare un tipo di pagamento. Se per esempio, il proxy in questione gestisce pagamenti pagopa allora il campo va validato verificando che esso sia valorizzato a PAGOPA. In caso contrario si scarta l'evento e si emette un log di errore.

tenant_id

UUID

service_id

UUID

created_at

Datetime

ISO8601

updated_at

Datetime

ISO8601

status

Enum

Valori permessi: CREATION_PENDING CREATION_FAILED PAYMENT_PENDING PAYMENT_STARTED PAYMENT_CONFIRMED PAYMENT_FAILED NOTIFICATION_PENDING

COMPLETE EXPIRED

reason

string(140)

Causale del pagamento. Non può eccedere i 140 caratteri.

remote_id

UUID

payment

PaymentData

links

Links

payer

Payer

Soggetto Versante

debtor

Debtor

Soggetto Pagatore

event_id

UUID

event_version

string(10)

L'attuale versione dell'evento deve essere "1.0". Ogni proxy deve validare la versione dell'evento in modo da sapere se processarlo o meno.

event_created_at

Datetime

ISO8601

app_id

string(100)

Valorizzarlo nel formato <nome-proxy>:<versione-proxy> Es. iris-payment-proxy:1.3.0

PaymentData

CampoTipoObbligatorioValidazione

type

Enum

Valori permessi: PAGOPA nel caso in cui si tratto di un dovuto standard STAMP nel caso in cui si tratta di un dovuto di tipo marca da bollo digitale

transaction_id

string(255)

Fornito dall'intermediario di pagamento. La lunghezza dunque può essere variabile

paid_at

Datetime

ISO8601

expire_at

Datetime

ISO8601 E' già valorizzato a priori, quindi non viene gestito dal proxy

amount

float

E' già valorizzato a priori, quindi non viene gestito dal proxy

reason

string(140)

Causale del pagamento. Non può eccedere i 140 caratteri.

currency

string(3)

ISO4217

notice_code

string(50)

iud

string(50)

iuv

string(50)

receiver

Receiver

Destinatario o beneficiario del versamento/dovuto

due_type

string(256)

Tipo di dovuto secondo la classificazione dell'intermediario di riferiemento

pagopa_category

string(12)

Tipo di dovuto secondo la tassonomia ufficiale di pagoPA

document

Document

Contiene le informazioni riguardanti il documento informatico o la segnatura di protocollo cui è associata la marca da bollo digitale

split

List[PaymentDataSplit]

Receiver

CampoTipoObbligatorioValidazione

tax_identification_number

string(255)

name

string(255)

iban

string(34)

ISO 13616 (obbligatorio solo dal secondo beneficiario in poi)

street_name

string(255)

building_number

string(255)

postal_code

string(255)

town_name

string(255)

country_subdivision

string(2)

ISO 3166-2

country

string(2)

ISO 3166-1 alpha-2

Document

CampoTipoObbligatorioValidazione

id

UUID

Identificativo del documento

ref

string

Url per scaricare il documento

hash

string

Hash digest del documento informatico

PaymentDataSplit

CampoTipoObbligatorioValidazione

code

string(50)

amount

float

meta

json

CampoTipoObbligatorioValidazione

online_payment_begin

UrlData

online_payment_landing

UrlData

offline_payment

UrlData

receipt

UrlData

notify

List[Notify]

update

Update

confirm

UrlData

cancel

UrlData

UrlData

CampoTipoObbligatorioValidazione

url

string

last_opened_at

Datetime

ISO8601

method

Enum

Valori permessi: GET POST PUT PATCH DELETE

Notify

CampoTipoObbligatorioValidazione

url

string

method

Enum

Valori permessi: GET POST

sent_at

Datetime

ISO8601

Update

CampoTipoObbligatorioValidazione

url

string

last_check_at

Datetime

ISO8601

next_check_at

Datetime

ISO8601

method

Enum

Valori permessi: GET POST

Payer

CampoTipoObbligatorioValidazione

type

Enum

Valori permessi: human legal

tax_identification_number

string(255)

name

string(255)

family_name

string(255)

street_name

string(255)

building_number

string(255)

postal_code

string(255)

town_name

string(255)

country_subdivision

string(2)

ISO 3166-2

country

string(2)

ISO 3166-1 alpha-2

email

string(255)

Debtor

CampoTipoObbligatorioValidazione

type

Enum

Valori permessi: human legal

tax_identification_number

string(255)

name

string(255)

family_name

string(255)

street_name

string(255)

building_number

string(255)

postal_code

string(255)

town_name

string(255)

country_subdivision

string(2)

ISO 3166-2

country

string(2)

ISO 3166-1 alpha-2

email

string(255)

Flussi

Punti aperti

  1. Determinazione delle URL di ritorno: Come si gestiscono le URL di ritorno? È possibile utilizzare l'indirizzo del proxy per gestire i redirect?

  2. Gestione dell'happy path del pagamento: Come gestire il percorso ideale del pagamento e cosa accade se l'utente chiude la pagina di pagamento e poi ritorna?

Configurazione Pagamento

Happy Path

Error Path

Compilazione Pratica

  1. Compilazione e invio pratica: L'utente compila la pratica per il servizio e invia la richiesta al Core.

  2. Verifica pagamenti: Il Core verifica se, nella fase attuale della pratica, è necessario effettuare dei pagamenti (es. pagamento anticipato o posticipato).

  3. Creazione pagamenti: Il Core invia i dettagli al servizio di pagamento, che restituisce gli identificativi dei pagamenti creati. Questo passaggio è fondamentale, poiché il Core deve salvare i dettagli dei pagamenti all'interno della pratica, assicurandosi che siano coerenti con il flusso (anticipato o posticipato).

  4. Restituzione della pratica: Una volta ottenuti gli ID dei pagamenti, il Core restituisce all'utente l'intera pratica aggiornata con gli identificativi.

Punti aperti:

Gestione degli errori nella creazione dei pagamenti:

  • Cosa accade se la creazione di un pagamento fallisce?

    • Il personale dell'ufficio preposto dovrebbe essere notificato in caso di fallimento.

  • Stato "Creation Pending": Quando un pagamento viene creato, si ottiene comunque un ID associato al pagamento, ma questo potrebbe essere in stato di "creation pending".

  • Politiche di retry: Si potrebbe considerare l'implementazione di politiche di retry, ma è necessario consultare il Product Manager (PM) per decidere la miglior esperienza utente (UX).

    Ipotesi: Al secondo o terzo tentativo di retry (o dopo un timeout di 10 secondi), potremmo mostrare un messaggio d'errore all'utente, suggerendo di riprovare o di avvisare l'assistenza (es. con un link "Clicca qui e avvisa"). Questo sarebbe un errore a livello ERROR.

  • Errore di configurazione: Se si verifica un errore di configurazione errata, è possibile fare affidamento sui messaggi restituiti dall'intermediario. In questo caso, si può evitare il retry e notificare direttamente il responsabile (es. Lorello). Questo tipo di errore potrebbe essere classificato come FATAL.

Happy Path

Error Path - Creazione Pagamenti

Il sequence diagram sopra riportato rappresenta il flusso di creazione e gestione dei pagamenti in un'applicazione, con particolare attenzione al retry in caso di fallimento e alla gestione dello stato del pagamento. Il flusso si svolge come segue:

  1. Inizio del processo: L'utente invia la pratica e il Core richiama il Payment Dispatcher API per creare il pagamento. Se la creazione ha successo, si procede, altrimenti si ritenta fino a 3 volte.

  2. Attesa di aggiornamenti dal Read Model: Quando la creazione del pagamento va a buon fine, il Core si mette in attesa di aggiornamenti dal Read Model.

  3. Retry gestito dal Retry Orchestrator: Se il Read Model restituisce lo stato CREATION_FAILED, il Core delega il processo di retry al Retry Orchestrator, che gestisce i retry tramite Kafka. Il Retry Orchestrator tenterà di risolvere il problema creando il pagamento sull'intermediario esterno.

  4. Risultati del Retry Orchestrator:

    • Se il retry riesce, il Retry Orchestrator segnalerà il successo al Core, che mostrerà all'utente lo stato PAYMENT_PENDING per procedere con il pagamento.

    • Se i retry falliscono, l'utente riceverà un alert di errore.

  5. Conclusione: L'utente vedrà le informazioni di pagamento in caso di successo o un messaggio d'errore in caso di fallimento, dopo aver superato il numero massimo di tentativi.

Error Path - Creazione Carrello Pagamenti

  • Gestione di pagamenti parziali: Se due pagamenti vanno a buon fine e uno fallisce, come dovrebbe comportarsi il frontend? Attualmente, il processo di checkout potrebbe risultare incompleto.

  • Invio degli ID di pagamento: Durante il checkout, il sistema riceve tutti gli ID dei pagamenti che devono essere completati in un’unica operazione.

Creazione pagamento posticipato da operatore

Il sequence diagram sopra riportato rappresenta il flusso di creazione e gestione dei pagamenti posticipati in fase approvazione della pratica da parte dell'operatore. Il flusso si svolge come segue:

  1. Creazione delle configurazioni: L'utente modifica e invia le configurazioni, che vengono temporaneamente salvate tramite il Payment Proxy. Se fallisce, l'errore viene mostrato all'utente.

  2. Creazione del pagamento tramite Payment Dispatcher: Il Core invia la richiesta di creazione pagamento al Payment Dispatcher API. Se fallisce, viene avviato un retry per un massimo di 3 tentativi. Se dopo 3 tentativi non riesce, viene mostrato un errore all'utente.

  3. Attesa di aggiornamenti dal Read Model: Quando la creazione del pagamento va a buon fine, il Core si mette in attesa di aggiornamenti dal Read Model, che monitora lo stato del pagamento.

  4. Stato CREATION_FAILED e Retry Orchestrator:

    • Se il Read Model restituisce lo stato CREATION_FAILED, il Core delega il retry al Retry Orchestrator, che gestisce i retry attraverso i topic di Kafka.

    • Se il Retry Orchestrator completa con successo la creazione, il Read Model aggiorna lo stato del pagamento, e l'utente può procedere con il pagamento (PAYMENT_PENDING).

    • Se anche il Retry Orchestrator fallisce dopo vari tentativi, viene restituito un errore al Core e un alert viene mostrato all'utente.

  5. Output finale: Se il pagamento va a buon fine (PAYMENT_PENDING), l'utente riceve le informazioni per procedere con il pagamento. In caso di errore persistente, viene mostrato un alert.

Last updated

Logo

Documentazione Opencity Italia