🛠️
Opencity Italia
Sviluppatori e partner tecnologici
Sviluppatori e partner tecnologici
  • Introduzione
  • Architettura
    • Pattern: microservizi
    • Pattern: event sourcing
    • Vista generale
  • Standard e convenzioni
    • Standard della piattaforma
    • Microservizi
  • Roadmap
  • Integrazioni
    • Integrazione Widget servizio (FormIO)
    • Integrazioni con il flusso delle pratiche
      • API ReST
      • Webhooks
    • Modello di integrazione con l'area personale
    • Integrazione con Intermediari di pagamento PagoPA
      • Requisiti per l'integrazione
      • Il Pagamento
        • Versione 1.0
        • Versione 2.0
      • Schema di Funzionamento
      • Configurazione dei pagamenti
        • API v1
        • API v2
      • Un pagamento in dettaglio
      • Gli stati di un pagamento
      • Processo di sviluppo
      • Implementazione di un proxy
    • Integrazione con Protocollo Informatico
      • Requisiti per l'integrazione
      • Documento digitale
        • Esempio documento con allegati non protocollato
        • Esempio documento con allegati protocollato
        • Esempio documento con campo retry_meta prodotto dal protocol proxy
        • Esempio documento con campo retry_meta modificato dal sistema di retry
        • Usecase: Il Documento originato dalle pratiche dai servizi digitali
        • Stati del documento
      • Architettura del sistema di protocollazione
      • WorkFlow sistema di protocollazione
        • Configurazione tenant e servizi
      • Protocol Proxy: Specifiche Implementative
      • Processo di sviluppo
    • Integrazioni con il Sito Istituzionale
    • Single Sign-On
      • SSO mediante oAuth2
      • SSO mediante JWT
    • Processi asincroni (job)
      • Importazione dovuti
    • Integrazione di un servizio di terze parti protetto da autenticazione
      • Esempio con GovWay
  • 👩‍💻Sviluppo
    • Multilingua
    • Temi grafici
Powered by GitBook
LogoLogo

Opencity Labs

  • Sito web
  • Product page

Developers Italia

  • Sito web
  • Area personale e Servizi Digitali

Documentazione Opencity Italia

On this page

Was this helpful?

Export as PDF
  1. Integrazioni
  2. Integrazione con Intermediari di pagamento PagoPA
  3. Configurazione dei pagamenti

API v2

Aggiornamenti principali rispetto all'API v1

Introduzione di campi "standard"

Con la versione 2 delle API di configurazione sono stati introdotti dei campi da introdurre obbligatoriamente in ogni integrazione.

Tenant

I campi da introdurre obbligatoriamente a livello di configurazione del tenant sono:

  • id: identificativo univoco del tenant

  • name: nome del tenant

  • tax_identification_number: codice fiscale dell'ente

Campo
Tipo
Obbligatorio
Validazione

id

UUID

Identificativo univoco

name

String

Non vuoto, massimo 255 caratteri

tax_identification_number

String

Codice fiscale valido

Configurazione pagamento

I campi da introdurre obbligatoriamente a livello di configurazione del pagamento sono:

  • payment_type: tipo di pagamento, può assumere i valori pagopa o stamp, serve a distinguere tra un pagamento ordinario (es. TARI) e una marca da bollo digitale. Questa distinzione è necessaria in quanto in alcuni intermediare i metodi di creazione di un pagamento di una marca da bollo digitale differiscono da quelli di creazione di un pagamento ordinario.

  • remote_collection.id: identificativo della collezione di provenienza della configurazione di pagamento.

  • remote_collection.type: tipo di collezione di provenienza della configurazione di pagamento, può assumere valori quali application, service o altro.

  • amount: importo del pagamento configurato.

  • reason: causale del pagamento configurato

  • expire_at: numero di giorni di validità del pagamento

  • receiver.tax_identification_number: codice fiscale del beneficiario del pagamento, da usare in caso di pagamenti multibeneficiario

  • receiver.name: nome del beneficiario del pagamento, da usare in caso di pagamenti multibeneficiario

  • collection_data: tassonomia di pagoPA dei pagamenti

Campo
Tipo
Obbligatorio
Validazione

payment_type

Enum

Valori: PAGOPA, STAMP

remote_collection.id

UUID

Identificativo univoco

remote_collection.type

String

Valori: application, service, altro

amount

float

Maggiore di 0

reason

String

Non vuoto, massimo 255 caratteri

expire_at

int

Maggiore di 0

receiver.tax_identification_number

String

Codice fiscale valido

receiver.name

String

Non vuoto, massimo 255 caratteri

collection_data

String

Tassonomia pagoPA valida

Configurazione tenant

L'admin, dall'interfaccia di configurazione dei pagamenti della Stanza del Cittadino compila la configurazione mediante una form, il cui json schema è servito dall'API /tenants/schema

Lo schema della form sopra riportata è il seguente

{
    "display": "form",
    "components": [
        {
            "label": "UUID del Tenant",
            "placeholder": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
            "spellcheck": false,
            "attributes": {
                "readonly": "readonly"
            },
            "hidden": true,
            "tableView": false,
            "validate": {
                "required": true
            },
            "key": "id",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Nome dell'ente",
            "placeholder": "Comune di Bugliano",
            "tableView": true,
            "validate": {
                "required": true
            },
            "key": "name",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Codice IPA dell'ente",
            "placeholder": "A000",
            "description": "Codice (tutto maiuscolo) assegnato all'Ente nel registro <a href='http://www.indicepa.gov.it' target='__blank'>indice PA</a>",
            "spellcheck": false,
            "tableView": true,
            "validate": {
                "required": true
            },
            "key": "IPA_code",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Codice fiscale dell'ente",
            "placeholder": "123456789",
            "spellcheck": false,
            "key": "tax_identification_number",
            "type": "textfield",
            "validate": {
                "required": true
            },
            "input": true,
            "tableView": true
        },
        {
            "label": "Password",
            "placeholder": "************",
            "description": "Password assegnata da MyPay all\u2019Ente",
            "spellcheck": false,
            "tableView": false,
            "validate": {
                "required": true
            },
            "key": "password",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Password carrello dovuti",
            "placeholder": "************",
            "description": "Password assegnata all\u2019ente creditore. Tale password va richiesta all\u2019amministratore dell\u2019ente creditore.<br>ATTENZIONE: questo dato NON coincide con la password (principale) dell\u2019ente.",
            "spellcheck": false,
            "tableView": true,
            "key": "cart_password",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Codice applicazione",
            "spellcheck": false,
            "tableView": true,
            "key": "application_code",
            "type": "textfield",
            "input": true,
            "hidden": true,
            "defaultValue": "SDC"
        },
        {
            "label": "Abilitato",
            "key": "active",
            "type": "checkbox",
            "input": true,
            "hidden": true,
            "defaultValue": true
        },
        {
            "label": "Salva",
            "showValidations": false,
            "tableView": false,
            "key": "submit",
            "type": "button",
            "input": true
        }
    ]
}

Premendo poi il bottone Salva, viene eseguita una POST /tenants servita dal proxy, con payload

{
    "name": "Comune di Bugliano",
    "IPA_code": "p_tn",
    "tax_identification_number": "00337460224",
    "password": "4CKSILO7FQPZ",
    "cart_password": "",
    "application_code": "",
    "active": true,
    "enable_checkout": false,
    "id": "60e35f02-1509-408c-b101-3b1a28109329"
}

Per modificare una configurazione esistente, il proxy serve l'API PUT /tenants/{tenant_id} e PATCH /tenants/{tenant_id}

Per eliminare una configurazione esistente, il proxy serve l'API DELETE /tenants/{tenant_id} . In questo caso l'eliminazione è una soft-delete, ovvero la configurazione viene semplicemente disattivata settando il parametro active a false ed eliminando la configurazione dalla memoria ma non dallo storage.

Configurazione pagamento

L'admin, dall'interfaccia di configurazione dei pagamenti per un servizio compila la configurazione mediante una form, il cui json schema è servito dall'API /configs/schema

Lo schema della form soprariportata è il seguente

{
    "display": "form",
    "components": [
        {
            "label": "UUID del Tenant",
            "hidden": true,
            "placeholder": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
            "spellcheck": false,
            "attributes": {
                "readonly": "readonly"
            },
            "validate": {
                "required": true
            },
            "key": "tenant_id",
            "type": "textfield",
            "input": true,
            "tableView": true
        },
        {
            "label": "Container",
            "tableView": false,
            "validateWhenHidden": false,
            "key": "remote_collection",
            "type": "container",
            "input": true,
            "components": [
                {
                    "label": "UUID del Servizio",
                    "placeholder": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
                    "applyMaskOn": "change",
                    "hidden": true,
                    "spellcheck": false,
                    "tableView": true,
                    "validate": {
                        "required": true
                    },
                    "validateWhenHidden": false,
                    "key": "id",
                    "attributes": {
                        "readonly": "readonly"
                    },
                    "type": "textfield",
                    "input": true
                }
            ]
        },
        {
            "label": "Tipo di pagamento",
            "widget": "choicesjs",
            "tableView": true,
            "defaultValue": "pagopa",
            "data": {
                "values": [
                    {
                        "label": "PagoPA",
                        "value": "pagopa"
                    },
                    {
                        "label": "Marca da Bollo Digitale",
                        "value": "stamp"
                    }
                ]
            },
            "validate": {
                "required": true
            },
            "key": "payment_type",
            "type": "select",
            "input": true
        },
        {
            "label": "Codice Tributo",
            "placeholder": "AAAAA_AAAAA_AAAAA",
            "description": "Questo codice è fornito dall'ente e comunicato a IRIS (inserire in maiuscolo)",
            "applyMaskOn": "change",
            "tableView": true,
            "validate": {
                "required": true
            },
            "key": "code",
            "conditional": {
                "show": true,
                "when": "payment_type",
                "eq": "pagopa"
            },
            "type": "textfield",
            "input": true
        },
        {
            "label": "Descrizione del servizio",
            "placeholder": "Contributo Pratiche Polizia Municipale",
            "applyMaskOn": "change",
            "tableView": true,
            "validate": {
                "required": true
            },
            "key": "description",
            "conditional": {
                "show": true,
                "when": "payment_type",
                "eq": "pagopa"
            },
            "type": "textfield",
            "input": true
        },
        {
            "label": "Importo",
            "applyMaskOn": "change",
            "mask": false,
            "tableView": false,
            "delimiter": false,
            "requireDecimal": false,
            "inputFormat": "plain",
            "truncateMultipleSpaces": false,
            "validate": {
                "required": true,
                "custom": "valid = (data.payment_type == 'stamp' && data.amount == 16) || (data.payment_type == 'pagopa') ? true : 'In caso di marca da bollo digitale l\\'unico importo permesso è di 16 euro'"
            },
            "validateWhenHidden": false,
            "key": "amount",
            "type": "number",
            "input": true
        },
        {
            "label": "Causale",
            "applyMaskOn": "change",
            "tableView": true,
            "validate": {
                "required": true,
                "maxLength": 60
            },
            "key": "reason",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Scadenza",
            "inputMask": "99/99/9999",
            "applyMaskOn": "change",
            "tableView": true,
            "validate": {
                "required": true
            },
            "key": "expire_at_label",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Scadenza",
            "applyMaskOn": "change",
            "hidden": true,
            "tableView": true,
            "validate": {
                "required": true
            },
            "key": "expire_at",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Categoria",
            "widget": "choicesjs",
            "description": "Selezione dalla Tassonomia di PagoPA dei pagamenti.",
            "tableView": true,
            "dataSrc": "url",
            "data": {
                "url": "https://api.opencityitalia.it/datasets/pagopa",
                "headers": [
                    {
                        "key": "",
                        "value": ""
                    }
                ]
            },
            "dataType": "object",
            "idPath": "",
            "valueProperty": "DATI SPECIFICI DI INCASSO",
            "template": "<span>{{ item[\"NOME MACRO AREA\"] }}: {{ item[\"TIPO SERVIZIO\"] }}</span>",
            "customDefaultValue": "await new Promise(r => setTimeout(r, 1000));",
            "validate": {
                "required": true
            },
            "key": "collection_data",
            "type": "select",
            "disableLimit": false,
            "noRefreshOnScroll": false,
            "input": true
        },
        {
            "label": "Abilitato",
            "hidden": true,
            "defaultValue": true,
            "key": "active",
            "type": "checkbox",
            "input": true,
            "tableView": false
        },
        {
            "label": "Bilancio",
            "tableView": false,
            "defaultValue": true,
            "key": "split_enable",
            "conditional": {
                "show": true,
                "when": "payment_type",
                "eq": "pagopa"
            },
            "type": "checkbox",
            "input": true
        },
        {
            "label": "Bilancio",
            "reorder": false,
            "addAnotherPosition": "bottom",
            "layoutFixed": false,
            "enableRowGroups": false,
            "initEmpty": true,
            "tableView": false,
            "defaultValue": [
                {
                    "split_id": "",
                    "split_type": "",
                    "split_code": "",
                    "split_description": "",
                    "split_budget_chapter": "",
                    "split_assessment": ""
                }
            ],
            "key": "split",
            "customConditional": "show = data.split_enable && data.payment_type == 'pagopa'",
            "type": "datagrid",
            "input": true,
            "components": [
                {
                    "label": "ID",
                    "description": "Identificativo univoco della voce di bilancio. Testo libero",
                    "placeholder": "c_1",
                    "tableView": true,
                    "validate": {
                        "required": true
                    },
                    "key": "split_id",
                    "type": "textfield",
                    "input": true
                },
                {
                    "label": "Tipo",
                    "placeholder": "Tipo c1",
                    "tableView": true,
                    "key": "split_type",
                    "type": "textfield",
                    "input": true
                },
                {
                    "label": "Codice",
                    "placeholder": "Codice c1",
                    "tableView": true,
                    "key": "split_code",
                    "type": "textfield",
                    "input": true
                },
                {
                    "label": "Descrizione",
                    "placeholder": "Descrizione c1",
                    "tableView": true,
                    "key": "split_description",
                    "type": "textfield",
                    "input": true
                },
                {
                    "label": "Importo",
                    "description": "Importo della voce di bilancio. NB: La somma degli importi delle voci DEVE equivalere all'importo totale",
                    "placeholder": "16.00",
                    "validate": {
                        "required": true
                    },
                    "mask": false,
                    "tableView": false,
                    "delimiter": false,
                    "requireDecimal": false,
                    "inputFormat": "plain",
                    "truncateMultipleSpaces": false,
                    "key": "split_amount",
                    "type": "number",
                    "input": true
                },
                {
                    "label": "Capitolo",
                    "placeholder": "Capitolo di bilancio c1",
                    "tableView": true,
                    "key": "split_budget_chapter",
                    "type": "textfield",
                    "input": true
                },
                {
                    "label": "Accertamento",
                    "placeholder": "Accertamento c1",
                    "tableView": true,
                    "key": "split_assessment",
                    "type": "textfield",
                    "input": true
                }
            ]
        },
        {
            "label": "hidden",
            "calculateValue": "if (!data.split || data.split == 'undefined') {\n  data.split = []\n} else if (typeof data.split==='object' && Object.keys(data.split).length === 0) {\n  data.split = [];\n}\n\nlet passedDate = moment(data.expire_at_label, 'DD/MM/YYYY');\nif (!passedDate.isValid()){\n  valid = \"La data inserita non è valida\";\n}\nif (passedDate.isAfter(moment())){\n  valid = \"La data inserita non può essere successiva alla data odierna\";\n}\n\nif (passedDate.isValid()){\n  data.expire_at = new Date(data.expire_at_label).toISOString();\n}",
            "key": "hidden",
            "type": "hidden",
            "input": true,
            "tableView": false
        },
        {
            "label": "Codice ufficio",
            "placeholder": "FSE",
            "description": "Il “codice ufficio” permette di distinguere l’ufficio di regione Toscana competente.",
            "applyMaskOn": "change",
            "tableView": true,
            "validate": {
                "required": true
            },
            "key": "office_code",
            "conditional": {
                "show": true,
                "when": "payment_type",
                "eq": "stamp"
            },
            "type": "textfield",
            "input": true
        },
        {
            "label": "Descrizione ufficio",
            "placeholder": "Fondo Sociale Europeo",
            "description": "Valorizzare con il nome dell’ufficio competente",
            "applyMaskOn": "change",
            "tableView": true,
            "validate": {
                "required": true
            },
            "key": "office_description",
            "conditional": {
                "show": true,
                "when": "payment_type",
                "eq": "stamp"
            },
            "type": "textfield",
            "input": true
        },
        {
            "label": "Codice Riferimento Bollo",
            "placeholder": "TIROCINI",
            "description": "Il “codice riferimento bollo” permette di distinguere il bollo per lo specifico ufficio.",
            "prefix": "BOLLO_",
            "applyMaskOn": "change",
            "tableView": true,
            "validate": {
                "required": true
            },
            "key": "reference_code",
            "conditional": {
                "show": true,
                "when": "payment_type",
                "eq": "stamp"
            },
            "type": "textfield",
            "input": true
        },
        {
            "label": "Note",
            "placeholder": "Pagamento Bollo Tirocinio Avviso: Avviso contributo tirocini non curriculari on line Giovanisì - FSE dal 1 Settembre 2017 per Soggetto Ospitante: CTP SYSTEM SRL",
            "description": "Necessaria per la corretta visualizzazione di ulteriori dettagli sulla ricevuta di pagamento",
            "applyMaskOn": "change",
            "tableView": true,
            "key": "notes",
            "conditional": {
                "show": true,
                "when": "payment_type",
                "eq": "stamp"
            },
            "type": "textfield",
            "input": true
        },
        {
            "label": "Salva",
            "showValidations": false,
            "key": "submit",
            "type": "button",
            "input": true,
            "tableView": false
        }
    ]
}

Premendo poi il bottone Salva, viene eseguita una POST /configs servita dal proxy, con payload

{
  "id": "5ec5668d-fed1-42a2-b648-abe1fe19b87a",
  "tenant_id": "8fdf037e-d8c0-4314-8291-b5fecb5f613a",
  "remote_collection": {
    "id": "d058b207-aedf-4683-b961-6ae146f69773",
    "type": "service"
  },
  "payment_type": "pagopa",
  "code": "CONTR_PRTPM",
  "description": "Contributo Pratiche Polizia Municipale",
  "reason": "Richiesta permesso di occupazione suolo pubblico",
  "split": [
    {
      "split_id": "c_1",
      "split_type": "Tipo c1",
      "split_code": "Codice c1",
      "split_description": "Descrizione d1",
      "split_budget_chapter": "Cap1",
      "split_assessment": "Acc1",
      "split_amount": 16
    }
  ],
  "collection_data": "9/0101102TS/",
  "amount": 16,
  "expire_at": "2024-12-11T23:00:00.000Z"
}

Per ottenere una lista di configurazioni di pagamento (fino a un massimo di 5), il proxy serve l'API GET /configs?config_id=config_id1&config_id=config_id2

Per modificare una configurazione esistente, il proxy serve l'API PUT /configs/{config_id} e PATCH /configs/{config_id}

Per eliminare una configurazione esistente, il proxy serve l'API DELETE /configs/{config_id} . In questo caso l'eliminazione è una soft-delete, ovvero la configurazione viene semplicemente disattivata settando il parametro active a false.

Swagger di esempio

PreviousAPI v1NextUn pagamento in dettaglio

Last updated 1 month ago

Was this helpful?