# API v1

## 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`

<figure><img src="https://2402436129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNwAiDeLoMPCkkp1BdSbI%2Fuploads%2F70c3o2v0w6oBj2Di06j1%2FScreenshot%202024-01-08%20alle%2014.42.26.png?alt=media&#x26;token=b6d534f0-59a0-4b74-b912-7aea32bf5d63" alt=""><figcaption></figcaption></figure>

Lo schema della form sopra riportata è il seguente

```json
{
    "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": "Password",
            "placeholder": "************",
            "description": "Password assegnata da MyPay all’Ente",
            "spellcheck": false,
            "tableView": false,
            "validate": {
                "required": true
            },
            "key": "password",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Password carrello dovuti",
            "placeholder": "************",
            "description": "Password assegnata all’ente creditore. Tale password va richiesta all’amministratore dell’ente creditore.<br>ATTENZIONE: questo dato NON coincide con la password (principale) dell’ente.",
            "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&#x20;

```json
{
  "name": "Comune di Bugliano",
  "IPA_code": "P_TN",
  "password": "4CKSILO7FQPZ",
  "cart_password": "",
  "submit": true,
  "id": "60e35f02-1509-408c-b101-3b1a28109329",
  "application_code": "",
  "active": true
}
```

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 servizio

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

<figure><img src="https://2402436129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNwAiDeLoMPCkkp1BdSbI%2Fuploads%2Fwg3agSfNIaf1Hfj4HKfl%2FScreenshot%202024-01-08%20alle%2014.55.46.png?alt=media&#x26;token=19d51310-079b-436d-92ea-451ebeda9272" alt=""><figcaption></figcaption></figure>

Lo schema della form soprariportata è il seguente

```json
{
    "display": "form",
    "components": [
        {
            "label": "UUID del Servizio",
            "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": "UUID del Tenant",
            "placeholder": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
            "spellcheck": false,
            "attributes": {
                "readonly": "readonly"
            },
            "hidden": true,
            "tableView": false,
            "validate": {
                "required": true
            },
            "key": "tenant_id",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Scegli il tipo di pagamento",
            "widget": "choicesjs",
            "tableView": true,
            "data": {
                "values": [
                    {
                        "label": "PagoPA",
                        "value": "pagopa"
                    },
                    {
                        "label": "Marca da Bollo Digitale",
                        "value": "stamp"
                    },
                    {
                        "label": "PagoPA + Marca da Bollo Digitale",
                        "value": "pagopa_and_stamp"
                    }
                ]
            },
            "validate": {
                "required": true
            },
            "key": "payment_type",
            "type": "select",
            "input": true,
            "defaultValue": "pagopa"
        },
        {
            "label": "Tipo dovuto",
            "placeholder": "TD_CIE",
            "description": "Riferimento alla tipologia del dovuto secondo la classificazione data dal beneficiario.",
            "applyMaskOn": "change",
            "spellcheck": false,
            "tableView": true,
            "validate": {
                "required": true,
                "maxLength": 64
            },
            "key": "management_id",
            "customConditional": "show = data.payment_type == 'pagopa' || data.payment_type == 'pagopa_and_stamp'",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Dati specifici riscossione",
            "placeholder": "9/3300.1",
            "description": "Rappresenta l’indicazione dell’imputazione della specifica entrata ed è così articolato:<br><b>TIPO_CONTABILITA / CODICE_CONTABILITA</b>, dove TIPO_CONTABILITA ha il seguente significato:<ul><li>0 (Capitolo e articolo di Entrata del Bilancio dello Stato)</li><li>1 (Numero della contabilità speciale)</li><li>2 (Codice SIOPE)</li><li>9 (Altro codice ad uso dell’amministrazione)</li></ul>",
            "applyMaskOn": "change",
            "spellcheck": false,
            "tableView": false,
            "defaultValue": "9/3300.1",
            "validate": {
                "required": true,
                "maxLength": 140
            },
            "key": "collection_data",
            "customConditional": "show = data.payment_type == 'pagopa' || data.payment_type == 'pagopa_and_stamp'",
            "type": "textfield",
            "input": true
        },
        {
            "label": "Abilitato",
            "key": "active",
            "type": "checkbox",
            "input": true,
            "hidden": true,
            "defaultValue": true,
            "tableView": false
        },
        {
            "label": "Bilancio",
            "tableView": false,
            "defaultValue": true,
            "key": "split_enable",
            "customConditional": "show = data.payment_type == 'pagopa' || data.payment_type == 'pagopa_and_stamp'",
            "type": "checkbox",
            "input": true
        },
        {
            "label": "Bilancio",
            "reorder": false,
            "addAnotherPosition": "bottom",
            "layoutFixed": false,
            "enableRowGroups": false,
            "initEmpty": true,
            "tableView": false,
            "defaultValue": [
                {
                    "split_id": "",
                    "split_budget_chapter": "",
                    "split_office_code": "",
                    "split_assessment": "",
                    "split_amount": ""
                }
            ],
            "key": "split",
            "conditional": {
                "show": true,
                "when": "split_enable",
                "eq": "true"
            },
            "customConditional": "show = (data.payment_type == 'pagopa' || data.payment_type == 'pagopa_and_stamp') && data.split_enable",
            "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": "Capitolo",
                    "placeholder": "Capitolo di bilancio c1",
                    "validate": {
                        "required": true
                    },
                    "tableView": true,
                    "key": "split_budget_chapter",
                    "type": "textfield",
                    "input": true
                },
                {
                    "label": "Ufficio",
                    "placeholder": "Codice ufficio bilancio c1",
                    "tableView": true,
                    "key": "split_office_code",
                    "type": "textfield",
                    "input": true
                },
                {
                    "label": "Accertamento",
                    "placeholder": "Accertamento c1",
                    "tableView": true,
                    "key": "split_assessment",
                    "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": "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\nif (!data.stamps || data.stamps == 'undefined') {\n  data.stamps = []\n} else if (typeof data.stamps==='object' && Object.keys(data.stamps).length === 0) {\n  data.stamps = [];\n}\n\nfor (i = 0; i < data.stamps.length; i++) {\n  if (data.stamps[i].id) {\n    data.stamps[i].amount = submission.metadata.selectData.stamps[i].id.label\n  } else {\n    data.stamps[i].amount = \"\"\n  }\n} ",
            "key": "hidden",
            "type": "hidden",
            "input": true,
            "tableView": false
        },
        {
            "label": "Informazioni Pagamento MBD",
            "attrs": [
                {
                    "attr": "",
                    "value": ""
                }
            ],
            "content": "<b>NOTA BENE:</b> Nel caso in cui si venga configurato <b>solamente</b> il pagamento la marca da bollo digitale, il valore dell'importo e/o del campo payment_amount nel modulo saranno ignorati",
            "refreshOnChange": false,
            "key": "stamp_info",
            "conditional": {
                "show": true,
                "when": "payment_type",
                "eq": "stamp"
            },
            "type": "htmlelement",
            "input": false,
            "tableView": false
        },
        {
            "label": "Marca da Bollo Digitale",
            "reorder": false,
            "addAnotherPosition": "bottom",
            "layoutFixed": false,
            "enableRowGroups": false,
            "initEmpty": true,
            "tableView": false,
            "defaultValue": [
                {
                    "id": "01",
                    "amount": "16.00",
                    "collection_data": "9/3300.1"
                }
            ],
            "validate": {
                "maxLength": "5",
                "custom": "valid = !(data.stamps.length > 4 && data.payment_type == 'pagopa_and_stamp') ? true : 'Puoi inserire un massimo di 4 marche da bollo'"
            },
            "key": "stamps",
            "customConditional": "show = data.payment_type == 'stamp' || data.payment_type == 'pagopa_and_stamp'",
            "type": "datagrid",
            "input": true,
            "components": [
                {
                    "label": "Taglio",
                    "widget": "choicesjs",
                    "tableView": true,
                    "data": {
                        "values": [
                            {
                                "label": "16.00",
                                "value": "01"
                            }
                        ]
                    },
                    "template": "<span>{{ item.label }}</span> €",
                    "validate": {
                        "required": true
                    },
                    "key": "id",
                    "type": "select",
                    "input": true
                },
                {
                    "label": "Dati specifici riscossione",
                    "placeholder": "9/3300.1",
                    "description": "Rappresenta l’indicazione dell’imputazione della specifica entrata ed è così articolato:<br><b>TIPO_CONTABILITA / CODICE_CONTABILITA</b>, dove TIPO_CONTABILITA ha il seguente significato:<ul><li>0 (Capitolo e articolo di Entrata del Bilancio dello Stato)</li><li>1 (Numero della contabilità speciale)</li><li>2 (Codice SIOPE)</li><li>9 (Altro codice ad uso dell’amministrazione)</li></ul>",
                    "applyMaskOn": "change",
                    "spellcheck": false,
                    "tableView": false,
                    "defaultValue": "9/3300.1",
                    "validate": {
                        "required": true,
                        "maxLength": 140
                    },
                    "key": "collection_data",
                    "type": "textfield",
                    "input": true
                }
            ]
        },
        {
            "label": "Salva",
            "showValidations": false,
            "tableView": false,
            "key": "submit",
            "type": "button",
            "input": true
        }
    ]
}
```

Premendo poi il bottone Salva, viene eseguita una `POST /services` servita dal proxy, con payload&#x20;

```json
{
  "payment_type": "pagopa_and_stamp",
  "management_id": "COSAP_TOSAP",
  "collection_data": "9/0301109AP/",
  "split_enable": true,
  "split": [
    {
      "split_id": "c_1",
      "split_budget_chapter": "Cap1",
      "split_office_code": "Uff1",
      "split_assessment": "Acc1",
      "split_amount": 1
    }
  ],
  "hidden": "",
  "submit": true,
  "id": "e64a3bd1-0096-4b8e-8676-e53f7d6b4b9a",
  "tenant_id": "60e35f02-1509-408c-b101-3b1a28109329",
  "active": true,
  "stamps": [
    {
      "id": "01",
      "amount": "16.00",
      "collection_data": "9/3300.1"
    }
  ]
}
```

Per modificare una configurazione esistente, il proxy serve l'API `PUT /services/{service_id}` e `PATCH /services/{service_id}`

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

## Alberatura configurazioni sullo storage

Le configurazioni di tenant e servizi vengono salvate con la seguente alberatura

`root`\
`|____tenant_id_1`\
`|    |____tenant.json`\
`|    |____service_id_1.json`\
`|    |____service_id_2.json`\
`|    |____.....`\
`|    |____service_id_n.json`\
`|____tenant_id_2`\
`|    |____tenant.json`\
`|    |____service_id_1.json`\
`|    |____service_id_2.json`\
`|    |____.....`\
`|    |____service_id_n.json`\
`|____tenant_id_n`\
&#x20;    `|____tenant.json`\
&#x20;    `|____service_id_1.json`\
&#x20;    `|____service_id_2.json`\
&#x20;    `|____.....`\
&#x20;    `|____service_id_n.json`
