---
title: "Pagamenti ricorrenti con carta e wallet"
description: "I pagamenti ricorrenti permettono di addebitare il metodo di pagamento del cliente in momenti successivi all'acquisto. In questa guida scoprirai come inizializzare la serie con una transazione First autenticata e come eseguire le transazioni Next con carta, Apple Pay, Google Pay e Click to Pay."
url: "https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/recurring-payments/"
language: "it"
---

# Pagamenti ricorrenti con carta e wallet

Le transazioni inizializzate dall'esercente (*Merchant Initiated Transactions – MIT*) sono tipiche dei modelli di business in cui i pagamenti vengono effettuati in momenti successivi rispetto all'acquisto.

In questi scenari l'acquirente autorizza l'esercente a eseguire addebiti futuri, accettando i **termini e le condizioni** definiti nell'accordo contrattuale tra le parti.

> **Esempi di utilizzo**
>
> - **Importo e periodicità fissi**: abbonamenti, servizi digitali.
> - **Importo o periodicità variabili**: bollette, servizi a consumo.

Un flusso di pagamenti ricorrenti si compone di due tipologie di transazione:

| Transazione                                      | Chi la avvia | Cliente presente | Autenticazione                                               |
| ------------------------------------------------ | ------------ | ---------------- | ------------------------------------------------------------ |
| **First – Customer Initiated Transaction (CIT)** | Il cliente   | Sì               | **Strong Customer Authentication (SCA)** sempre obbligatoria |
| **Next – Merchant Initiated Transaction (MIT)**  | L'esercente  | No               | Non richiesta                                                |

La transazione **First** verifica l'identità del pagatore e genera l'identificativo di riferimento necessario per processare le **Next**. Il token del metodo di pagamento può essere richiesto contestualmente alla First, oppure può essere utilizzato un token generato in precedenza. Le Next vengono processate dall'esercente in assenza del cliente.

> **Richiesta del token**
>
> Il token può essere generato anche in un momento diverso dalla transazione ricorrente, e utilizzato successivamente per la First. Per le modalità di richiesta consulta la sezione [Tokenizzazione](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/token/).

> **Ambito normativo**
>
> Le transazioni MIT sono considerate **out of scope rispetto alla PSD2** e, pertanto, **non richiedono l'autenticazione a due fattori**.

---

## Tipologie di ricorrenza

Fabrick Payment Orchestra supporta due tipologie di pagamento ricorrente. La scelta determina il valore del campo `transDetails.type` di tutte le transazioni della serie.

|                      | Ricorrenti                     | Non programmate                                                              |
| -------------------- | ------------------------------ | ---------------------------------------------------------------------------- |
| **Importo**          | Fisso                          | Variabile                                                                    |
| **Periodicità**      | Costante e definita            | Variabile, senza pianificazione                                              |
| **Casi d'uso**       | Abbonamenti e servizi digitali | Bollette, servizi a consumo, no-show fee, penali per danni a beni noleggiati |
| **Type della First** | `01F`                          | `03F`                                                                        |
| **Type delle Next**  | `01N`                          | `03N`                                                                        |

---

## Metodi di pagamento supportati

| Metodo       | First (CIT)                                                                          | Next (MIT)                              |
| ------------ | ------------------------------------------------------------------------------------ | --------------------------------------- |
| Carta        | Integrazioni hosted oppure API Only, con dati carta o token già esistente            | Token generato o utilizzato nella First |
| Apple Pay    | Integrazioni hosted oppure API Only, con il payload Apple Pay o token già esistente  | Token generato o utilizzato nella First |
| Google Pay   | Integrazioni hosted oppure API Only, con il payload Google Pay o token già esistente | Token generato o utilizzato nella First |
| Click to Pay | Solo integrazioni hosted                                                             | Token generato o utilizzato nella First |

Per le transazioni **Next** il flusso è comune a tutti i metodi. I wallet sono gestiti come carte, il token generato o utilizzato durante la First va sempre inviato nel campo `paymentTypeDetails.creditcard.token`.

---

## Requisiti comuni

Le transazioni **Next** sono valide solo se sono soddisfatte tutte queste condizioni:

- esiste un **accordo tra esercente e acquirente** che autorizza gli addebiti
- ogni Next **include il riferimento alla transazione First** (`paymentID`)
- ogni Next è presentata con lo **stesso shopLogin** della First
- la First **non è stata cancellata**: la catena ricorrente non sarebbe più valida
- la First è stata **autenticata tramite SCA**

> **Tokenizzazione obbligatoria**
>
> Ogni serie ricorrente è associata a un **token** del metodo di pagamento, da utilizzare per le Next. Il token può essere richiesto contestualmente alla First, oppure può essere utilizzato un token generato in precedenza per una carta o un wallet già tokenizzati: in questo caso la First non richiede una nuova tokenizzazione (vedi [Integrazione API Only](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/recurring-payments/#integrazione-api-only)). Per le modalità di richiesta consulta la sezione [Tokenizzazione](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/token/).

---

## Flusso First (CIT)

### Campi della richiesta

Per indicare al sistema che la transazione è la prima di una serie ricorrente, aggiungi l'oggetto `transDetails` alla chiamata `payment/create`, oltre ai campi obbligatori previsti:

| Campo                                         | Ricorrenti `01F` | Non programmate `03F` | Descrizione                                                                                           |
| --------------------------------------------- | ---------------- | --------------------- | ----------------------------------------------------------------------------------------------------- |
| `transDetails.type`                           | `01F`            | `03F`                 | Tipologia della ricorrenza                                                                            |
| `transDetails.authenticationAmount`           | ✅                | ✅                     | Importo massimo atteso secondo l'accordo tra le parti                                                 |
| `transDetails.recurringTransaction.expiry`    | ✅                | ❌                     | Data di scadenza dell'accordo, formato `YYYYMMDD`. Oltre questa data non possono essere eseguite Next |
| `transDetails.recurringTransaction.frequency` | ✅                | ❌                     | Numero minimo di giorni tra due addebiti della stessa serie                                           |

> **Importo massimo autorizzato**
>
> Se `authenticationAmount` non è valorizzato, oppure se `amount` è superiore ad `authenticationAmount`, il sistema utilizza `amount` come **importo massimo autorizzato** per le Next e, contestualmente, esegue l'addebito iniziale per quell'importo.

### Importo iniziale a zero (ASI)

Se il servizio prevede un **periodo di prova gratuito** o un **addebito posticipato**, puoi valorizzare `amount` con **zero**. In questo caso la richiesta è definita **ASI** (*Account Status Inquiry*) ed è necessario valorizzare `authenticationAmount` con l'importo massimo previsto dall'accordo per le Next.

L'importo indicato in `authenticationAmount` **potrebbe essere visualizzato dal compratore** durante l'autenticazione, in base alle configurazioni della sua banca, in alternativa può essere mostrato l'importo del campo `amount`.

> **ASI**
>
> L'ASI è finalizzata alla verifica del metodo di pagamento e l'inizializzazione della ricorrente, la transazione non può essere movimentata né cancellata.

### Scelta della modalità di integrazione

La First può essere gestita con due modalità, che differiscono per chi raccoglie i dati di pagamento e per il numero di chiamate necessarie:

| Scenario                                                                                                                   | Integrazione                                                                                                                                                                  | Chiamate                                                              |
| -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| Il cliente inserisce la carta o sceglie un wallet (Apple Pay, Google Pay, Click to Pay) tramite le **integrazioni hosted** | [Hosted](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/recurring-payments/#integrazione-hosted) (Checkout Page, Pay By Link, Lightbox, Web Component) | `payment/create`                                                      |
| La carta o il wallet sono **già stati tokenizzati** in precedenza                                                          | [API Only](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/recurring-payments/#integrazione-api-only)                                                   | `payment/create` senza `requestToken` + `payment/submit` con il token |
| Il cliente inserisce i dati della carta in un **form di pagamento** sul sito dell'esercente                                | [API Only](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/recurring-payments/#integrazione-api-only)                                                   | `payment/create` + `payment/submit` con i dati carta                  |
| Il cliente paga con **Apple Pay o Google Pay** direttamente dal **checkout** del sito dell'esercente                       | [API Only](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/recurring-payments/#integrazione-api-only)                                                   | `payment/create` + `payment/submit` con il payload del wallet         |

> **Click to Pay**
>
> Click to Pay è disponibile **solo con le integrazioni hosted**. A differenza di Apple Pay e Google Pay non richiede un payload dedicato e segue lo stesso flusso della carta.

> **Autenticazione sempre obbligatoria**
>
> La First richiede **sempre** l'autenticazione forte del cliente (SCA). Non è possibile richiedere esenzioni, indipendentemente dalla modalità di integrazione e dalla disponibilità del token. Con le integrazioni hosted l'autenticazione è gestita da Fabrick, con API Only il redirect verso la banca del cliente è a carico dell'esercente.

> **Informativa obbligatoria al buyer**
>
> La First comporta la tokenizzazione del metodo di pagamento: il buyer deve esserne informato **prima** dell'invio della transazione.
>
> - Con le **integrazioni hosted** (Checkout Page, Pay By Link, Lightbox, Web Component) l'informativa è **già gestita** da Fabrick, il messaggio viene mostrato automaticamente.
> - Con una **pagina di pagamento personalizzata** (API Only) l'informativa è **a carico dell'esercente**.
>
> I messaggi mostrati dalle integrazioni hosted sono descritti nella sezione [Tokenizzazione](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/token/).

---

### Integrazione hosted

Con le integrazioni hosted al cliente vengono presentati la carta e i wallet abilitati. È sufficiente la chiamata `payment/create`: in base al metodo scelto dal cliente, al termine del pagamento viene restituito il token da utilizzare per le Next.

#### Passo 1 — Creazione della richiesta

Utilizza `payment/create` lato server, includendo:

- `requestToken` valorizzato con `MASKEDPAN`, per richiedere la tokenizzazione
- `paymentType` valorizzato con `CREDITCARD`, per limitare la pagina alla carta e ai wallet

> **Carta e wallet sulla stessa pagina**
>
> Con `paymentType` valorizzato a `CREDITCARD`, la pagina mostra anche **Apple Pay**, **Google Pay** e **Click to Pay**, se abilitati sullo shopLogin. La richiesta non cambia in base al metodo, è il cliente a scegliere in pagina, e il token restituito corrisponde al metodo utilizzato.

> **Oggetto paymentChannel**
>
> Gli esempi utilizzano **Pay By Link**. Con [Lightbox](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/integration-methods/lightbox/) o [Web Component](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/integration-methods/web-component/) rimuovi l'oggetto `paymentChannel` dalla chiamata.

**Ricorrenti (01F)**

**Request**

```http
POST /api/v1/payment/create
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
Authorization: apikey ****************
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "amount": "0",
    "currency": "EUR",
    "shopTransactionID": "FBK-C01F_OrderID",
    "paymentChannel": { "channelType": ["LINK"] }, // Solo per Pay By Link
    "paymentType": ["CREDITCARD"],
    "requestToken": "MASKEDPAN",
    "transDetails": {
        "type": "01F",
        "authenticationAmount": "100",
        "recurringTransaction": {
            "expiry": 20261231,
            "frequency": 15
        }
    }
}
```

**Non programmate (03F)**

**Request**

```http
POST /api/v1/payment/create
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
Authorization: apikey ****************
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "amount": "0",
    "currency": "EUR",
    "shopTransactionID": "FBK-C03F_OrderID",
    "paymentChannel": { "channelType": ["LINK"] }, // Solo per Pay By Link
    "paymentType": ["CREDITCARD"],
    "requestToken": "MASKEDPAN",
    "transDetails": {
        "type": "03F",
        "authenticationAmount": "100"
    }
}
```

#### Passo 2 — Presentazione della pagina di pagamento

La risposta a `payment/create` contiene `paymentToken` e `paymentID`, con Pay By Link viene restituito il link di redirect in `payload.userRedirect.href`.

**Pay By Link**

Reindirizza il cliente al link presente in `payload.userRedirect.href`.

**Response**

```json
{
    "error": {
        "code": "0",
        "description": "request correctly processed"
    },
    "payload": {
        "paymentToken": "8a901523-67a5-4aca-bbd2-c7c412934289",
        "paymentID": "1360119538182",
        "userRedirect": {
            "href": "https://sandbox-web.axerve.com/orchestra/checkout/a/dc1e181fe487435c86a09120550327a9/b/925e8ec8839a1baf2da2d49f5ecf87cf..."
        },
        "qrCode": null
    }
}
```

**Lightbox o Web Component**

Utilizza `paymentToken` e `paymentID` nello script della [Lightbox](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/integration-methods/lightbox/) o nel [Web Component](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/integration-methods/web-component/) per mostrare la pagina di pagamento.

**Response**

```json
{
    "error": {
        "code": "0",
        "description": "request correctly processed"
    },
    "payload": {
        "paymentToken": "8a901523-67a5-4aca-bbd2-c7c412934289",
        "paymentID": "1360119538182",
        "userRedirect": null,
        "qrCode": null
    }
}
```

#### Passo 3 — Esito del pagamento

Al termine del pagamento il comportamento dipende dall'integrazione:

| Integrazione      | Comportamento                                                                                                                                                                                                                                                                                                        |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Pay By Link**   | Il cliente viene reindirizzato alla URL di esito positivo o negativo (vedi [Pay By Link](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/integration-methods/pay-by-link/#dettaglio-transazione-e-notifica-del-pagamento))                                                                              |
| **Web Component** | Il cliente viene reindirizzato alla URL di esito positivo o negativo (vedi [Web Component](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/integration-methods/web-component/#passo-4--recupera-lesito))                                                                                                |
| **Lightbox**      | Redirect automatico alla URL di esito positivo o negativo, oppure, se viene utilizzato l'oggetto di callback, URL disponibile nel campo `responseURL` (vedi [Lightbox](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/integration-methods/lightbox/#conclusione-transazione-e-notifica-del-pagamento)) |

Prosegui con la [verifica dell'esito e il recupero del token](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/recurring-payments/#verifica-dellesito-e-recupero-del-token).

---

### Integrazione API Only

Con l'integrazione API Only l'esercente raccoglie i dati di pagamento sulla propria pagina e li invia a Fabrick con `payment/submit`. La gestione del redirect per l'autenticazione è a carico dell'esercente.

#### Passo 1 — Creazione della richiesta

Utilizza `payment/create` lato server: la richiesta è la stessa per carta, Apple Pay e Google Pay. Click to Pay non è disponibile con questa integrazione.

> **Quando utilizzare requestToken**
>
> Inserisci `requestToken` con valore `MASKEDPAN` solo nella `payment/create`, e solo se al passo 2 invii i dati della carta o il payload di Apple Pay o Google Pay.
>
> Se invece la First utilizza un token già esistente, ometti il campo: il metodo di pagamento è già tokenizzato e lo stesso token servirà per le Next. Con `requestToken` presente, la `payment/submit` con il token restituisce l'errore:
>
> ```text
> 1107 - Unexpected parameter name. Please double check Fields and Parameters configuration in Back Office
> ```

**Ricorrenti (01F)**

**Request**

```http
POST /api/v1/payment/create
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
Authorization: apikey ****************
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "amount": "0",
    "currency": "EUR",
    "shopTransactionID": "FBK-C01F_OrderID",
    "requestToken": "MASKEDPAN", // Non utilizzare se nella submit si utilizza un token
    "transDetails": {
        "type": "01F",
        "authenticationAmount": "100",
        "recurringTransaction": {
            "expiry": 20261231,
            "frequency": 15
        }
    }
}
```

**Non programmate (03F)**

**Request**

```http
POST /api/v1/payment/create
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
Authorization: apikey ****************
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "amount": "0",
    "currency": "EUR",
    "shopTransactionID": "FBK-C03F_OrderID",
    "requestToken": "MASKEDPAN", // Non utilizzare se nella submit si utilizza un token
    "transDetails": {
        "type": "03F",
        "authenticationAmount": "100"
    }
}
```

**Response**

```json
{
    "error": {
        "code": "0",
        "description": "request correctly processed"
    },
    "payload": {
        "paymentToken": "8a901523-67a5-4aca-bbd2-c7c412934289",
        "paymentID": "1360119538182",
        "userRedirect": null,
        "qrCode": null
    }
}
```

La risposta contiene `paymentToken`, da utilizzare nell'header della `payment/submit`, e `paymentID`, da utilizzare per verificare l'esito e come riferimento per le Next.

#### Passo 2 — Invio dei dati di pagamento

Invia i dati di pagamento con `payment/submit`, valorizzando l'header `PaymentToken` con il valore ricevuto al passo precedente. Il body dipende dal metodo di pagamento ed è lo stesso per `01F` e `03F`.

**Carta o wallet tokenizzati**

Se la carta o il wallet sono già stati tokenizzati in precedenza, invia il token nel campo `paymentTypeDetails.creditcard.token`: i wallet sono gestiti come carte. La chiamata può essere effettuata lato server, perché non transitano dati carta.

In questo caso la `payment/create` del passo 1 **non deve contenere** il campo `requestToken`.

**Request**

```http
POST /api/v1/payment/submit
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
PaymentToken: 8a901523-67a5-4aca-bbd2-c7c412934289
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "paymentType": "CREDITCARD",
    "paymentTypeDetails": {
        "creditcard": {
            "token": "40ZUU8NXALR33101"
        }
    }
}
```

**Dati carta**

Invia i dati della carta nell'oggetto `paymentTypeDetails.creditcard`.

> **Sicurezza dei dati carta**
>
> I dati della carta possono transitare sul server dell'esercente **solo se tale server è parte di un ambiente conforme alla PCI DSS**, con conformità validata tramite **AOC** (e, se richiesto dal livello, **ROC**).
>
> In assenza di conformità PCI DSS è obbligatorio raccogliere i dati tramite un **form visualizzato nella sessione del buyer** e inviarli a Fabrick con `payment/submit` **lato client**: in questo modo i dati carta non transitano mai sui sistemi dell'esercente.

**Request**

```http
POST /api/v1/payment/submit
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
PaymentToken: 8a901523-67a5-4aca-bbd2-c7c412934289
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "paymentType": "CREDITCARD",
    "paymentTypeDetails": {
        "creditcard": {
            "number": "4012000000003101",
            "expMonth": "05",
            "expYear": "27",
            "CVV": "123"
        }
    }
}
```

**Apple Pay**

Invia il payload restituito da Apple Pay nell'oggetto `paymentTypeDetails.applePay.PKPaymentToken`.

**Request**

```http
POST /api/v1/payment/submit
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
PaymentToken: 8a901523-67a5-4aca-bbd2-c7c412934289
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "paymentType": "APPLEPAY",
    "paymentTypeDetails": {
        "applePay": {
            "PKPaymentToken": {
                "paymentData": {
                    "data": "***",
                    "signature": "***",
                    "header": {
                        "publicKeyHash": "***",
                        "ephemeralPublicKey": "***",
                        "transactionId": "***"
                    },
                    "version": "EC_v1"
                },
                "paymentMethod": {
                    "displayName": "Visa 2237",
                    "network": "Visa",
                    "type": "debit"
                },
                "transactionIdentifier": "***"
            }
        }
    }
}
```

**Formato alternativo: payload come stringa**

In alternativa all'oggetto, il payload può essere inviato come stringa JSON serializzata nel campo `paymentTypeDetails.applePay.applePayPKPaymentToken`.

```json
{
    "shopLogin": "GESPAY12345",
    "paymentType": "APPLEPAY",
    "paymentTypeDetails": {
        "applePay": {
            "applePayPKPaymentToken": "{\"transactionIdentifier\":\"***\",\"paymentMethod\":{\"displayName\":\"Visa 4915\",\"type\":\"debit\",\"network\":\"visa\"},\"paymentData\":{\"data\":\"***\",\"signature\":\"***\",\"header\":{\"publicKeyHash\":\"***\",\"ephemeralPublicKey\":\"***\",\"transactionId\":\"***\"},\"version\":\"EC_v1\"}}"
        }
    }
}
```

**Google Pay**

Invia il payload restituito da Google Pay nell'oggetto `paymentTypeDetails.googlePay.tokenizationData`.

**Request**

```http
POST /api/v1/payment/submit
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
PaymentToken: 8a901523-67a5-4aca-bbd2-c7c412934289
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "paymentType": "GOOGLEPAY",
    "paymentTypeDetails": {
        "googlePay": {
            "tokenizationData": {
                "token": {
                    "signature": "***",
                    "protocolVersion": "ECv1",
                    "signedMessage": "{\"encryptedMessage\":\"***\",\"ephemeralPublicKey\":\"***\",\"tag\":\"***\"}"
                }
            }
        }
    }
}
```

#### Passo 3 — Gestione della risposta

La risposta a `payment/submit` può presentare tre scenari:

**Autenticazione richiesta**

Il campo `transactionErrorCode` restituisce `8006`: è necessario reindirizzare il cliente alla pagina di autenticazione della sua banca, utilizzando il link presente in `payload.userRedirect.href`.

**Response**

```json
{
    "error": {
        "code": "0",
        "description": "request correctly processed"
    },
    "payload": {
        "transactionErrorCode": "8006",
        "transactionErrorDescription": "Verify By Visa",
        "paymentID": "1360119538182",
        "userRedirect": {
            "href": "https://sandbox.gestpay.net/pagam/pagam3d.aspx?a=GESPAY12345&b=8a901523-67a5-4aca-bbd2-c7c412934289&axerve3D=True&IsLightBox=False"
        }
    }
}
```

**Esito immediato**

Se l'autenticazione non è richiesta, l'esito viene restituito **immediatamente**, insieme al token nel campo `payload.token`. La URL di esito definita dall'esercente è disponibile in `payload.userRedirect.href`.

**Response**

```json
{
    "error": {
        "code": "0",
        "description": "request correctly processed"
    },
    "payload": {
        "transactionType": "submit",
        "transactionResult": "OK",
        "transactionErrorCode": "0",
        "transactionErrorDescription": "Transaction correctly processed",
        "bankTransactionID": "492",
        "shopTransactionID": "FBK-C01F_OrderID",
        "authorizationCode": "188190",
        "paymentID": "1360119538182",
        "currency": "EUR",
        "country": "ITALIA",
        "company": "VISA",
        "productType": "Credit",
        "token": "40ZUU8NXALR33101",
        "tokenExpiryMonth": "05",
        "tokenExpiryYear": "27",
        "userRedirect": {
            "href": "https://sandbox.gestpay.net/pagam/AxerveThankYou.aspx"
        }
    }
}
```

**Errore**

La risposta contiene l'oggetto `error` con il codice `error.code` e la descrizione `error.description`. Consulta la [lista completa degli errori](https://api.paymentorchestra.fabrick.com/#errors).

**Response**

```json
{
    "error": {
        "code": "1165",
        "description": "Token not found"
    },
    "payload": {}
}
```

---

### Verifica dell'esito e recupero del token

Al termine del pagamento il sistema invia una **notifica server-to-server (S2S)** con l'esito e i dati `paymentToken` e `paymentID`, contestualmente all'eventuale redirect del cliente. La notifica permette di aggiornare lo stato del pagamento anche se il cliente non torna sul sito.

```text
https://merchant-url.com?a=GESPAY12345&Status=OK&paymentID=1360119538182&paymentToken=8a901523-67a5-4aca-bbd2-c7c412934289
```

Utilizza `payment/detail` per verificare l'esito e recuperare il token, della carta o del wallet, nel campo **`payload.token`**. Per maggiori informazioni sul token è possibile leggere l'oggetto `payload.tokenDetails`, che riporta lo stesso valore in `TokenValue` insieme a scadenza e ultime cifre della carta (`CardDetails`).

**Dettaglio risposta**

**Request**

```http
GET /api/v1/payment/detail/{paymentID}
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
Authorization: apikey ****************
Content-Type: application/json
```

**Response**

```json
{
    "error": {
        "code": "0",
        "description": "request correctly processed"
    },
    "payload": {
        "transactionType": "detail",
        "transactionResult": "APPROVED",
        "transactionState": "AUT",
        "transactionErrorCode": "0",
        "transactionErrorDescription": "Transaction correctly processed",
        "bankTransactionID": "492",
        "shopTransactionID": "FBK-C01F_OrderID",
        "shopTransactionID_2": "",
        "authorizationCode": "188190",
        "paymentID": "1360119538182",
        "currency": "EUR",
        "country": "ITALIA",
        "company": "VISA",
        "tdLevel": "FULL",
        "threeDS": {
            "authenticationResult": {
                "authenticationLevel": "2C",
                "authenticationStatus": "Y",
                "authStatusReason": "",
                "challengeResultTransStatus": "",
                "XID": "12e6e4ce-8ccc-49f9-b5a4-18b486f1d29d",
                "AV": "MTIzNDU2Nzg5MDA5ODc2NTQzMjE=",
                "ECI": "05",
                "AVAlgorithm": "",
                "threeDsVersion": "2.1.0"
            },
            "transDetails": {
                "authData": "",
                "authMethod": "02",
                "authTimeStamp": "202407111313",
                "acsID": "48a413bf-fe27-4de2-a39e-dc6039e4aef7"
            }
        },
        "events": [
            {
                "event": {
                    "eventtype": "AUT",
                    "eventamount": "0.00",
                    "eventdate": "11/07/24 13:13:56",
                    "eventARN": "",
                    "eventID": "",
                    "eventReferred": ""
                }
            }
        ],
        "buyer": {
            "name": "",
            "email": ""
        },
        "risk": {
            "riskResponseCode": "",
            "riskResponseDescription": ""
        },
        "customInfo": null,
        "alertCode": "",
        "alertDescription": "",
        "cvvPresent": "TRUE",
        "dcc": null,
        "maskedPAN": "",
        "paymentMethod": "VISA",
        "productType": "Credit",
        "token": "40ZUU8NXALR33101",
        "tokenExpiryMonth": "05",
        "tokenExpiryYear": "27",
        "tokenDetails": {
            "TokenValue": "40ZUU8NXALR33101",
            "TokenExpiryMonth": "05",
            "TokenExpiryYear": "27",
            "TokenProvider": "AXERVE",
            "CardDetails": {
                "CardSuffix": "3101",
                "CardExpiryMonth": "05",
                "CardExpiryYear": "27",
                "CardHolderName": null
            },
            "CardAssets": {
                "CardArt": {
                    "Type": null,
                    "MediaContents": null,
                    "Height": null,
                    "Width": null
                },
                "BrandLogo": {
                    "Type": null,
                    "MediaContents": null,
                    "Height": null,
                    "Width": null
                }
            }
        },
        "fraudPrevention": {
            "check": "FALSE",
            "state": "",
            "description": "",
            "order": ""
        },
        "automaticOperation": {
            "type": "CAN",
            "date": "05/08/24 00:00:00",
            "amount": "0"
        }
    }
}
```

#### Dati da salvare per le Next

| Dato                   | Dove si trova                                                                            | Tipologia    | Utilizzo nelle Next                           |
| ---------------------- | ---------------------------------------------------------------------------------------- | ------------ | --------------------------------------------- |
| `paymentID`            | Risposta di `payment/create`                                                             | `01F`, `03F` | `transDetails.previousTransDetails.paymentID` |
| `token`                | `payment/detail` → `payload.token`, oppure il token già esistente utilizzato nella First | `01F`, `03F` | `paymentTypeDetails.creditcard.token`         |
| `authenticationAmount` | Valore inviato nella First                                                               | `01F`, `03F` | Importo massimo addebitabile                  |
| `expiry`               | Valore inviato nella First                                                               | `01F`        | Data oltre la quale non eseguire Next         |
| `frequency`            | Valore inviato nella First                                                               | `01F`        | Giorni minimi tra due Next                    |

> **paymentID**
>
> In risposta alla chiamata `payment/create` Fabrick restituisce il `paymentID`. Se la transazione si conclude con esito positivo, questo valore diventa l'identificativo da utilizzare come riferimento per le transazioni Next. Per addebitare un metodo di pagamento diverso è necessario eseguire una nuova First.

> **Gestione del token**
>
> Per maggiori informazioni sulla gestione del token consulta la sezione [Tokenizzazione](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/token/).

---

### Dopo la First: cattura, storno e cancellazione

Una volta completata la First e salvati i dati necessari, è possibile procedere con la **cattura** o lo **storno** dell'importo autorizzato.

| Caso                                                   | Comportamento                                                                                                                                                                        |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **First con importo 0,00 € (ASI)**                     | Il sistema non consente la cancellazione: interromperebbe la catena e impedirebbe le Next                                                                                            |
| **First con importo maggiore di zero e MOTO separato** | Non cancellare la transazione tramite `payment/cancel` o Dashboard. Per rimborsare il cliente, cattura l'intero importo ed esegui successivamente uno storno: la catena resta attiva |

> **Non cancellare mai la First**
>
> La cancellazione della First, tramite API `payment/cancel` o Dashboard, rende impossibile eseguire le transazioni Next.

---

## Flusso Next (MIT)

Le transazioni Next sono i **pagamenti successivi** alla First e vengono eseguite sulla base dell'autorizzazione rilasciata durante la First. Vengono eseguite in assenza del cliente e non richiedono la presentazione della pagina di pagamento né alcuna interazione da parte sua.

L'esecuzione delle Next non è gestita automaticamente da Fabrick: è l'esercente che deve **programmare, avviare e gestire** ciascun addebito, nel rispetto degli accordi contrattuali.

> **Stesso flusso per carta e wallet**
>
> Il flusso Next è identico per carta, Apple Pay, Google Pay e Click to Pay: i wallet sono gestiti come carte, quindi in tutti i casi si utilizza il token ottenuto durante la First, inviato nel campo `paymentTypeDetails.creditcard.token`.

### Campi della richiesta

| Chiamata         | Campo                                         | Descrizione                                           |
| ---------------- | --------------------------------------------- | ----------------------------------------------------- |
| `payment/create` | `transDetails.type`                           | `01N` per le ricorrenti, `03N` per le non programmate |
| `payment/create` | `transDetails.previousTransDetails.paymentID` | `paymentID` della First                               |
| `payment/submit` | `paymentTypeDetails.creditcard.token`         | Token ottenuto durante la First                       |

> **ShopLogin della First**
>
> Il `paymentID` della First è valido **esclusivamente** sullo shopLogin su cui è stata generata: una Next presentata su un altro shopLogin non può essere processata.
>
> Per incassare la ricorrenza su un altro shopLogin è necessario **generare una nuova First autenticata sul nuovo shopLogin** e utilizzarne il `paymentID` per tutte le Next successive.

### Passo 1 — Creazione della richiesta

Utilizza `payment/create` lato server, indicando il riferimento alla First.

**Ricorrenti (01N)**

**Request**

```http
POST /api/v1/payment/create
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
Authorization: apikey ****************
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "amount": "100",
    "currency": "EUR",
    "shopTransactionID": "FBK-C01N_OrderID",
    "transDetails": {
        "type": "01N",
        "previousTransDetails": {
            "paymentID": "1360119538182"
        }
    }
}
```

**Non programmate (03N)**

**Request**

```http
POST /api/v1/payment/create
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
Authorization: apikey ****************
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "amount": "100",
    "currency": "EUR",
    "shopTransactionID": "FBK-C03N_OrderID",
    "transDetails": {
        "type": "03N",
        "previousTransDetails": {
            "paymentID": "1360119538182"
        }
    }
}
```

**Response**

```json
{
    "error": {
        "code": "0",
        "description": "request correctly processed"
    },
    "payload": {
        "paymentToken": "7ebd948a-c9ad-44c9-ac43-02b0beb55a7a",
        "paymentID": "1541109548247",
        "userRedirect": null,
        "qrCode": null
    }
}
```

### Passo 2 — Invio del token

Utilizza `payment/submit` lato server, inviando il token ottenuto durante la First. La richiesta è la stessa per `01N` e `03N`.

**Request**

```http
POST /api/v1/payment/submit
Host (sandbox): sandbox.gestpay.net
Host (produzione): ecomms2s.sella.it
PaymentToken: 7ebd948a-c9ad-44c9-ac43-02b0beb55a7a
Content-Type: application/json
```

```json
{
    "shopLogin": "GESPAY12345",
    "paymentType": "CREDITCARD",
    "paymentTypeDetails": {
        "creditcard": {
            "token": "40ZUU8NXALR33101"
        }
    }
}
```

### Passo 3 — Gestione della risposta

L'esito della Next viene restituito **immediatamente** in risposta alla `payment/submit` e, contestualmente, tramite notifica S2S. È possibile, opzionalmente, interrogare la transazione con `payment/detail`: la struttura della risposta è la stessa mostrata per la [First](https://docs.fabrick.com/payment-hub-and-orchestra/ecommerce/features/recurring-payments/#verifica-dellesito-e-recupero-del-token).

**Esito positivo**

**Response**

```json
{
    "error": {
        "code": "0",
        "description": "request correctly processed"
    },
    "payload": {
        "transactionType": "submit",
        "transactionResult": "OK",
        "transactionErrorCode": "0",
        "transactionErrorDescription": "Transaction correctly processed",
        "bankTransactionID": "569",
        "shopTransactionID": "FBK-C01N_OrderID",
        "authorizationCode": "188190",
        "paymentID": "1541109548247",
        "currency": "EUR",
        "country": "ITALIA",
        "company": "VISA",
        "productType": "Credit",
        "userRedirect": {
            "href": "https://sandbox.gestpay.net/pagam/AxerveThankYou.aspx"
        }
    }
}
```

**Nuova autenticazione richiesta**

In casi eccezionali la banca del cliente può richiedere una nuova autenticazione: il campo `transactionErrorCode` restituisce `8026` (*Soft Decline*). Lo scenario può verificarsi con **qualsiasi metodo di pagamento**, carta o wallet, e va quindi sempre gestito.

È necessario **contattare il cliente** e inizializzare una **nuova First**, per ottenere un nuovo `paymentID` da utilizzare per le Next successive.

**Response**

```json
{
    "error": {
        "code": "0",
        "description": "request correctly processed"
    },
    "payload": {
        "transactionType": "submit",
        "transactionResult": "KO",
        "transactionErrorCode": "8026",
        "transactionErrorDescription": "Soft decline - Cardholder authentication required",
        "bankTransactionID": "569",
        "shopTransactionID": "FBK-C01N_OrderID",
        "authorizationCode": "",
        "paymentID": "1541109548247",
        "currency": "EUR",
        "country": "ITALIA",
        "company": "VISA",
        "productType": "Credit",
        "userRedirect": {
            "href": "https://sandbox.gestpay.net/pagam/AxerveThankYou.aspx"
        }
    }
}
```

**Errore**

La risposta contiene l'oggetto `error` con il codice `error.code` e la descrizione `error.description`. Consulta la [lista completa degli errori](https://api.paymentorchestra.fabrick.com/#errors).

**Response**

```json
{
    "error": {
        "code": "1165",
        "description": "Token not found"
    },
    "payload": {}
}
```

Confermato l'esito positivo è possibile procedere con la **cattura** o lo **storno** della transazione.
