# Usa Stripe per accettare pagamenti con SCA

> Formspree Docs · Plugin · 28 febbraio 2026

#### Disponibile sui piani: Free (Test mode), Professional, Business

Stripe è una piattaforma di elaborazione dei pagamenti che consente ai commercianti di accettare pagamenti con carta di credito sulle loro app e siti web. Quando colleghi il tuo modulo a un account Stripe, puoi effettuare addebiti e ricevere pagamenti dal tuo sito web.  
  
**Cosa c'è di nuovo?**  
Il plugin di Stripe (V2) ora supporta la validazione lato backend dei pagamenti, addebiti variabili per le donazioni e la [Strong Customer Authentication](https://stripe.com/docs/strong-customer-authentication) facoltativa.  
  
La Strong Customer Authentication (SCA) è una normativa entrata in vigore il 14 settembre 2019. Richiede modifiche al modo in cui i clienti europei autenticano i pagamenti online. Questa normativa si [applica](https://stripe.com/docs/strong-customer-authentication#impact) solo ai pagamenti online in cui la banca del cliente e l'azienda si trovano entrambe nello [Spazio economico europeo](https://en.wikipedia.org/wiki/European_Economic_Area) (SEE).  
  
Puoi capire se stai usando il nuovo plugin Stripe V2 se le impostazioni del tuo plugin mostrano una Stripe Publishable Key. Se non vedi la Publishable Key, puoi aggiornare il tuo plugin all'ultima versione eliminando e ricollegando il plugin. Nessun dato verrà perso.

## Passaggio 1: Collegamento a Stripe

### Test Mode vs Live Mode

 Le modalità test e live funzionano in modo quasi identico, con alcune differenze necessarie:

-   In modalità test, i pagamenti non vengono elaborati dai circuiti delle carte o dai fornitori di pagamento e possono essere usate solo le nostre [informazioni di pagamento di test](https://stripe.com/docs/testing).
-   Alcuni metodi di pagamento che usano [Sources](https://stripe.com/docs/sources) hanno un flusso più articolato in modalità live, con più passaggi richiesti rispetto a quelli in modalità test.
-   Anche le contestazioni hanno un flusso più articolato in modalità live e un [processo di test](https://stripe.com/docs/testing#disputes) più semplice.
-   In modalità test, i [webhook](https://stripe.com/docs/webhooks) che non sono stati confermati con successo vengono ritentati tre volte nell'arco di poche ore (rispetto alle 72 ore della modalità live).

Per vedere gli addebiti di test, vai alla tua Stripe Dashboard e fai clic su View Test Data

  
![mceclip0.png](/images/zendesk/9479210aa8c1e005.png)

_**Tieni presente che se vuoi passare dalla Test Mode alla Live Mode dovrai eliminare e creare di nuovo il plugin per ottenere nuove credenziali valide tramite Stripe OAuth.**_

_Ti consigliamo di avere un modulo dell'ambiente di sviluppo/staging collegato alla modalità test e un modulo di produzione collegato alla modalità live._

### Configurazione del plugin di Stripe

Una volta che hai aggiunto un modulo in Formspree, puoi collegarti a Stripe usando il plugin di Stripe. Per farlo, prima vai alla scheda Plugins del tuo modulo. Poi fai clic sul pulsante del plugin di Stripe.

![mceclip0.png](/images/zendesk/e61d8f0b2e0b9e6c.png)

Dopo aver fatto clic sul pulsante del plugin di Stripe potrai collegarti in modalità Test o Live.  
La **Test mode** è disponibile per tutti i piani. La **Live mode** è disponibile solo per i piani aggiornati.

![mceclip4.png](/images/zendesk/ac89283388ab406b.png)

Seleziona la modalità che vuoi e fai clic su connect. Una volta effettuato l'accesso usando il tuo nome utente e password di Stripe, ti verrà chiesto di impostare le informazioni di addebito di Stripe per questo modulo. Imposta la valuta e il prezzo che verrà addebitato ogni volta che il modulo viene inviato.  
  
Facendo clic su **allow variable price** consentirai allo sviluppatore o al visitatore del sito di impostare il prezzo lato client. Questo consente a un modulo di addebitare un importo variabile, ad esempio per una donazione. Può anche essere usato per consentire a un modulo di addebitare prezzi diversi a seconda di altri fattori, come un prodotto selezionato. Una volta fatto clic su **allow variable price**, il prezzo verrà letto dal campo del modulo **price**.   
  
_**Attenzione: se il prezzo variabile è abilitato, qualsiasi cliente può modificare questo valore direttamente, o tramite il reverse-engineering del tuo codice, e creare addebiti per qualsiasi importo. Assicurati di verificare gli addebiti inviati al tuo account Stripe. Non validiamo questo valore.**_

![mceclip0.png](/images/zendesk/f97e2f49dac06df8.png)

Una volta completata la configurazione, fai clic su **Connect** per abilitare il plugin.

In futuro, se vuoi cambiare la descrizione e il prezzo o disabilitare completamente il plugin, puoi farlo facendo di nuovo clic sul pulsante Stripe per regolarne le impostazioni.

Una volta completata la configurazione e il collegamento del tuo plugin di Stripe, vedrai questo messaggio:

![mceclip1.png](/images/zendesk/e07fed14e1716088.png)

Copia la **Publishable Key**. La useremo per costruire il nostro workflow di checkout.

## Passaggio 2: Costruisci il tuo flusso di checkout con Stripe Elements (nessuna SCA richiesta)

**NOTA**: se stai usando React, dai un'occhiata al nostro tutorial su [Come costruire un modulo di pagamento React personalizzato con Stripe](https://formspree.io/blog/custom-payment-stripe/). 

Ora che hai configurato il tuo modulo Formspree con il plugin di Stripe, è il momento di costruire il tuo flusso di checkout. Per addebitare i pagamenti, devi tokenizzare una carta di credito per inviarla in modo sicuro a Formspree.

Un modo semplice per farlo è usare [Stripe Elements](https://stripe.com/payments/elements). È un insieme di componenti UI predefiniti, come input e pulsanti, per costruire il tuo flusso di checkout. È disponibile come funzionalità di Stripe.js. Stripe.js _tokenizza_ le informazioni sensibili all'interno di un Element senza mai farle toccare ai tuoi o ai nostri server.  
  
Poi devi solo inviare il metodo di pagamento tokenizzato a Formspree che creerà e addebiterà il pagamento.

Ecco un esempio ispirato alla [documentazione di Stripe](https://stripe.com/docs/payments/accept-a-payment-synchronously):

**File HTML**

```html
<head>
  <title>Checkout</title>
  <script src="https://js.stripe.com/v3/"></script>
  <script src="https://code.jquery.com/jquery-latest.min.js"></script>
 </head>

 <body>
   <form id="payment-form" action="">
     <div id="card-element">
       <!-- Elements will create input elements here -->
     </div>

     <!-- We'll put the error messages in this element -->
     <div id="card-errors" role="alert"></div>

     <button id="submit">Pay</button>
   </form>
 </body>
```

**File JS**

```javascript
$(document).ready(function () {
  // Stripe settings
  var stripe = Stripe("YOUR_PUBLISHABLE_KEY_COPIED_FROM_DASHBOARD");
  var elements = stripe.elements();
  var style = {
    base: {
      color: "#32325d",
    },
  };
  var card = elements.create("card", {
    style: style,
  });

  card.mount("#card-element");
  card.on("change", ({ error }) => {
    const displayError = document.getElementById("card-errors");
    if (error) {
      displayError.textContent = error.message;
    } else {
      displayError.textContent = "";
    }
  });
  // end stripe

  var form = document.getElementById("payment-form");
  form.addEventListener("submit", function (event) {
    event.preventDefault();
    // Tokenize card info
    stripe
      .createPaymentMethod({
        type: "card",
        card: card,
        billing_details: {
          // Include any additional collected billing details.
          name: "Jenny Rosen",
          email: "jenny@rosen.com",
        },
      })
      .then(stripePaymentMethodHandler);
  });

  function stripePaymentMethodHandler(result) {
    if (result.error) {
      // Show error to user
      console.log(result.error);
    } else {
      // Otherwise send payment method to your server
      fetch("https://formspree.io/f/FORM_ID", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          // Send the tokenized card
          paymentMethod: result.paymentMethod.id,
          email: "jenny@rosen.com",
          // add here any data that you want to send to Formspree
        }),
      }).then(function (result) {
        // Handle server response
        result.json().then(function (json) {
          handleServerResponse(json);
        });
      });
    }
  }

  function handleServerResponse(response) {
    if (response.error) {
      // Display errors on the payment form
      console.log(response.error);
    } else {
      // Display a success message
      console.log("Payment finished successfully");
    }
  }
});
```

Per applicare uno stile ai tuoi elementi Stripe, dai un'occhiata a [questo esempio](https://gist.github.com/colevscode/9cf19623e157cbe6822ffb8bd6e707fb), oppure ai nostri stili di reset del modulo di esempio [qui](https://gist.github.com/colevscode/ce67075b62f843b7e95b1d5a1370035b).

A questo punto, hai un modulo funzionante che può effettuare addebiti ai titolari di carte non UE.

## Passaggio 3: (Facoltativo) Supportare i pagamenti SCA

Dopo aver completato il passaggio 2, il tuo modulo dovrebbe inviare correttamente e creare addebiti in Stripe. Tuttavia, se la SCA è richiesta dalla banca del mittente, il modulo genererà un errore. Per supportare la SCA dobbiamo aggiungere un altro passaggio al flusso precedente.

Nella prima richiesta, il server Formspree proverà a creare un [Payment Intent](https://stripe.com/docs/payments/payment-intents) e ad addebitarlo. Se la carta richiede un'azione aggiuntiva come la SCA, l'addebito fallirà e il payment intent restituirà uno stato `requires_action`.

Il server Formspree restituirà un HTTP Status 402 con le seguenti informazioni:

-   L'ID del payment intent creato
-   Un client secret del payment intent che verrà usato per effettuare una richiesta a Stripe per validare il pagamento
-   Una `resubmit_key` che verrà usata per reinviare la richiesta a Formspree una volta che il pagamento è stato validato

#### **Esempio del corpo della risposta**

```javascript
{
  "message": "requires_action",
  "resubmitKey": <key_generated_by_formspree>,
  "stripe": {
    "paymentIntentId": <id_from_the_payment_intent>,
    "paymentIntentClientSecret": <secret_generated_by_stripe>,
    "requiresAction": true
  }
}
```

Ora possiamo validare il pagamento chiamando la funzione [handleCardAction](https://stripe.com/docs/js/payment_intents/handle_card_action) di Stripe, inviando il `payment_intent_client_secret`. Questo eseguirà qualsiasi validazione front-end richiesta, come l'apertura del [3DS Modal](https://stripe.com/docs/payments/3d-secure) per completare la SCA.

Il seguente esempio dimostra come aggiornare la funzione `handleServerResponse()` che abbiamo creato nell'ultimo passaggio per intercettare eventuali azioni richieste. Poi reinvia il modulo con il payment intent e la nuova `resubmit_key`.  
  
**Esempio JS**

```javascript
function handleServerResponse(response) {
  if (response.error) {
    // Show error from server on payment form
    console.log(response.error);
  } else if (response && response.stripe.requiresAction) {
    // Stripe require additional actions to charge this card
    // Use Stripe.js to handle required card action and open 3DS
    stripe
      .handleCardAction(response.stripe.paymentIntentClientSecret)
      .then(function (stripeResult) {
        // TODO: implement this function to resubmit the form
        resubmitForm(stripeResult, response.resubmitKey);
      });
  } else {
    console.log("Payment finished successfully");
  }
}
```

#### **Stripe 3DS Modal**

![mceclip2.png](/images/zendesk/dcb1c309939d07c1.png)

Se la funzione [handleCardAction](https://stripe.com/docs/js/payment_intents/handle_card_action) ha successo, ora puoi reinviare il modulo a Formspree inviando la `resubmit_key` e il `paymentIntent` che hai ricevuto in precedenza dopo il primo tentativo fallito.

**Esempio di reinvio del modulo:**

```javascript
function resubmitForm(result, resubmitKey) {
  console.log("handle Stripe SCA result");
  if (result.error) {
    // Show error in payment form
    console.log("Stripe SCA error");
  } else {
    // The card action has been handled
    // The PaymentIntent can be confirmed again on the server
    fetch('https://formspree.io/f/', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ 
        paymentIntent: result.paymentIntent.id ,
        resubmitKey: resubmitKey,
        email: 'jenny@rosen.com',
      })
    }).then(function(result) {
      return result.json();
    }).then(handleServerResponse);
  }
}
```

Quando Formspree riceve il secondo invio, tenterà di nuovo di addebitare il payment intent con le informazioni della carta che dovrebbero essere state validate lato client tramite il flusso SCA di Stripe. Puoi reinviare gli stessi campi dell'invio originale. Qualsiasi modifica a questi campi aggiornerà i dati del modulo.

Tieni presente che la `resubmit_key` scadrà se non viene usata in tempo utile. In questo scenario, Formspree restituirà un codice di stato HTTP 404.

## Riepilogo

In sintesi, i passaggi sono:

1.  Prova ad addebitare la carta. Se richiede la SCA verrà restituita una risposta 402 con i dati del payment intent e la resubmit key.
2.  Chiama handleCardAction di Stripe con il client secret del payment intent restituito dal primo tentativo ed esegui la [3DS](https://stripe.com/docs/payments/3d-secure).
3.  Reinvia il modulo inviando la resubmit key, l'id del payment intent e l'email. Formspree riproverà ad addebitare per completare l'invio.

Dai un'occhiata al flusso di checkout completo con SCA  
  
**File JS (SCA)**

```javascript
$(document).ready(function () {
  // Stripe settings
  var stripe = Stripe("YOUR_PUBLISHABLE_KEY_COPIED_FROM_DASHBOARD");
  var elements = stripe.elements();
  var style = {
    base: {
      color: "#32325d",
    },
  };
  var card = elements.create("card", {
    style: style,
  });

  card.mount("#card-element");
  card.on("change", ({ error }) => {
    const displayError = document.getElementById("card-errors");
    if (error) {
      displayError.textContent = error.message;
    } else {
      displayError.textContent = "";
    }
  });
  // end stripe

  var form = document.getElementById("payment-form");
  form.addEventListener("submit", function (ev) {
    event.preventDefault();

    stripe
      .createPaymentMethod({
        type: "card",
        card: card,
        billing_details: {
          // Include any additional collected billing details.
          name: "Jenny Rosen",
          email: "jenny@rosen.com",
        },
      })
      .then(stripePaymentMethodHandler);
  });

  function stripePaymentMethodHandler(result) {
    if (result.error) {
      console.log("Error creating payment method");
    } else {
      // First submission attempt
      fetch("https://formspree.io/f/FORM_ID", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          paymentMethod: result.paymentMethod.id,
          email: "jenny@rosen.com",
        }),
      }).then(function (response) {
        // Handle server response (see Step 4)
        response.json().then(function (json) {
          handleServerResponse(json);
        });
      });
    }
  }

  function handleServerResponse(response) {
    if (response.stripe && response.stripe.requiresAction) {
      // Stripe require additional actions to charge this card
      // Use Stripe.js to handle required card action and open 3DS
      stripe
        .handleCardAction(response.stripe.paymentIntentClientSecret)
        .then(function (stripeResult) {
          // Get handleCardAction response and resubmit
          resubmitForm(stripeResult, response.resubmitKey);
        });
    } else if (response.error) {
      // Show error from server on payment form
      console.log(response.error);
    } else {
      console.log("Payment finished successfully");
    }
  }

  function resubmitForm(result, resubmitKey) {
    console.log("handle Stripe SCA result");
    if (result.error) {
      // Display error in the payment form
      console.log("Stripe SCA error");
    } else {
      // The card action has been handled
      // The PaymentIntent can be confirmed again on the server
      fetch("https://formspree.io/f/FORM_ID", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          paymentIntent: result.paymentIntent.id,
          resubmitKey: resubmitKey,
          email: "jenny@rosen.com",
        }),
      })
        .then(function (confirmResult) {
          return confirmResult.json();
        })
        .then(handleServerResponse);
    }
  }
});
```

Per saperne di più sui test con Stripe e Stripe SCA visita [https://stripe.com/docs/testing](https://stripe.com/docs/testing) e il nostro [articolo del blog](https://formspree.io/blog/custom-payment-stripe/).
