Introduzione all'API Stripe per Java

1. Panoramica

Stripe è un servizio basato su cloud che consente ad aziende e privati ​​di ricevere pagamenti su Internet e offre sia librerie lato client (JavaScript e mobile nativo) sia librerie lato server (Java, Ruby, Node.js, ecc.).

Stripe fornisce un livello di astrazione che riduce la complessità della ricezione dei pagamenti. Di conseguenza, non abbiamo bisogno di trattare direttamente i dettagli della carta di credito, ma ci occupiamo invece di un token che simboleggia un'autorizzazione ad addebitare .

In questo tutorial, creeremo un progetto Spring Boot di esempio che consente agli utenti di inserire una carta di credito e successivamente addebiterà sulla carta un determinato importo utilizzando l'API Stripe per Java.

2. Dipendenze

Per utilizzare l'API Stripe per Java nel progetto, aggiungiamo la dipendenza corrispondente al nostro pom.xml :

 com.stripe stripe-java 4.2.0  

Possiamo trovare la sua ultima versione nel repository Maven Central.

Per il nostro progetto di esempio, faremo leva su spring-boot-starter-parent :

 org.springframework.boot spring-boot-starter-parent 2.2.6.RELEASE 

Useremo anche Lombok per ridurre il codice boilerplate e Thymeleaf sarà il motore dei modelli per la distribuzione di pagine web dinamiche.

Dato che stiamo usando lo spring-boot-starter-parent per gestire le versioni di queste librerie, non dobbiamo includere le loro versioni in pom.xml :

 org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-thymeleaf   org.projectlombok lombok 

Nota che se stai usando NetBeans, potresti voler usare Lombok esplicitamente con la versione 1.16.16 , poiché un bug nella versione di Lombok fornita con Spring Boot 1.5.2 fa sì che NetBeans generi molti errori.

3. Chiavi API

Prima di poter comunicare con Stripe ed eseguire addebiti con carta di credito, dobbiamo registrare un account Stripe e ottenere chiavi API Stripe segrete / pubbliche .

Dopo aver confermato l'account, effettueremo il login per accedere alla dashboard di Stripe. Quindi scegliamo "chiavi API" nel menu a sinistra:

Ci saranno due coppie di chiavi segrete / pubbliche: una per il test e una per il live. Lasciamo aperta questa scheda in modo da poter utilizzare questi tasti in seguito.

4. Flusso generale

L'addebito sulla carta di credito avverrà in cinque semplici passaggi, coinvolgendo il front-end (eseguito in un browser), il back-end (la nostra applicazione Spring Boot) e Stripe:

  1. Un utente va alla pagina di pagamento e fa clic su "Paga con carta".
  2. A un utente viene presentata la finestra di dialogo in sovrimpressione Stripe Checkout, dove vengono inseriti i dettagli della carta di credito.
  3. Un utente conferma con "Paga" che:
    • Invia la carta di credito a Stripe
    • Ottieni un token nella risposta che verrà aggiunto al modulo esistente
    • Invia il modulo con l'importo, la chiave API pubblica, l'email e il token al nostro back-end
  4. Il nostro back-end contatta Stripe con il token, l'importo e la chiave API segreta.
  5. Il back-end controlla la risposta di Stripe e fornisce all'utente un feedback sull'operazione.

Tratteremo ogni passaggio in maggiore dettaglio nelle sezioni seguenti.

5. Modulo di pagamento

Stripe Checkout è un widget personalizzabile, mobile ready e localizzabile che rende un modulo per introdurre i dettagli della carta di credito. Attraverso l'inclusione e la configurazione di " checkout.js ", è responsabile di:

  • Rendering del pulsante "Paga con carta"

  • Rendering della finestra di dialogo di pagamento in sovrapposizione (attivato dopo aver fatto clic su "Paga con carta")

  • Convalida della carta di credito
  • Funzione "Ricordami" (associa la carta a un numero di cellulare)
  • Invio della carta di credito a Stripe e sostituzione con un gettone nel modulo allegato (attivato dopo aver fatto clic su "Paga")

Se abbiamo bisogno di esercitare un controllo maggiore sul modulo di pagamento rispetto a quello fornito da Stripe Checkout, allora possiamo utilizzare Stripe Elements.

Successivamente, analizzeremo il controller che prepara il modulo e quindi il modulo stesso.

5.1. Controller

Iniziamo creando un controller per preparare il modello con le informazioni necessarie di cui ha bisogno il modulo di checkout .

Innanzitutto, dovremo copiare la versione di prova della nostra chiave pubblica dalla dashboard di Stripe e utilizzarla per definire STRIPE_PUBLIC_KEY come variabile di ambiente. Quindi utilizziamo questo valore nel campo stripePublicKey .

Stiamo anche impostando manualmente valuta e importo (espresso in centesimi) qui solo a scopo dimostrativo, ma in un'applicazione reale, potremmo impostare un ID prodotto / vendita che potrebbe essere utilizzato per recuperare i valori effettivi.

Quindi, invieremo alla visualizzazione di checkout che contiene il modulo di checkout:

@Controller public class CheckoutController { @Value("${STRIPE_PUBLIC_KEY}") private String stripePublicKey; @RequestMapping("/checkout") public String checkout(Model model) { model.addAttribute("amount", 50 * 100); // in cents model.addAttribute("stripePublicKey", stripePublicKey); model.addAttribute("currency", ChargeRequest.Currency.EUR); return "checkout"; } }

Regarding the Stripe API keys, you can define them as environment variables per application (test vs. live).

As is the case with any password or sensitive information, it is best to keep the secret key out of your version control system.

5.2. Form

The “Pay with Card” button and the checkout dialog are included by adding a form with a script inside, correctly configured with data attributes:

  Price:    

The “checkout.js” script automatically triggers a request to Stripe right before the submit, which then appends the Stripe token and the Stripe user email as the hidden fields “stripeToken” and “stripeEmail“.

These will be submitted to our back-end along with the other form fields. The script data attributes are not submitted.

We use Thymeleaf to render the attributes “data-key“, “data-amount“, and “data-currency“.

The amount (“data-amount“) is used only for display purposes (along with “data-currency“). Its unit is cents of the used currency, so we divide it by 100 to display it.

The Stripe public key is passed to Stripe after the user asks to pay. Do not use the secret key here, as this is sent to the browser.

6. Charge Operation

For server-side processing, we need to define the POST request handler used by the checkout form. Let's take a look at the classes we will need for the charge operation.

6.1. ChargeRequest Entity

Let's define the ChargeRequest POJO that we will use as a business entity during the charge operation:

@Data public class ChargeRequest { public enum Currency { EUR, USD; } private String description; private int amount; private Currency currency; private String stripeEmail; private String stripeToken; }

6.2. Service

Let's write a StripeService class to communicate the actual charge operation to Stripe:

@Service public class StripeService { @Value("${STRIPE_SECRET_KEY}") private String secretKey; @PostConstruct public void init() { Stripe.apiKey = secretKey; } public Charge charge(ChargeRequest chargeRequest) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { Map chargeParams = new HashMap(); chargeParams.put("amount", chargeRequest.getAmount()); chargeParams.put("currency", chargeRequest.getCurrency()); chargeParams.put("description", chargeRequest.getDescription()); chargeParams.put("source", chargeRequest.getStripeToken()); return Charge.create(chargeParams); } }

As was shown in the CheckoutController, the secretKey field is populated from the STRIPE_SECRET_KEY environment variable that we copied from the Stripe dashboard.

Once the service has been initialized, this key is used in all subsequent Stripe operations.

The object returned by the Stripe library represents the charge operation and contains useful data like the operation id.

6.3. Controller

Finally, let's write the controller that will receive the POST request made by the checkout form and submit the charge to Stripe via our StripeService.

Note that the “ChargeRequest” parameter is automatically initialized with the request parameters “amount“, “stripeEmail“, and “stripeToken” included in the form:

@Controller public class ChargeController { @Autowired private StripeService paymentsService; @PostMapping("/charge") public String charge(ChargeRequest chargeRequest, Model model) throws StripeException { chargeRequest.setDescription("Example charge"); chargeRequest.setCurrency(Currency.EUR); Charge charge = paymentsService.charge(chargeRequest); model.addAttribute("id", charge.getId()); model.addAttribute("status", charge.getStatus()); model.addAttribute("chargeId", charge.getId()); model.addAttribute("balance_transaction", charge.getBalanceTransaction()); return "result"; } @ExceptionHandler(StripeException.class) public String handleError(Model model, StripeException ex) { model.addAttribute("error", ex.getMessage()); return "result"; } }

On success, we add the status, the operation id, the charge id, and the balance transaction id to the model so that we can show them later to the user (Section 7). This is done to illustrate some of the contents of the charge object.

Our ExceptionHandler will deal with exceptions of type StripeException that are thrown during the charge operation.

If we need more fine-grained error handling, we can add separate handlers for the subclasses of StripeException, such as CardException, RateLimitException, or AuthenticationException.

The “result” view renders the result of the charge operation.

7. Showing the Result

The HTML used to display the result is a basic Thymeleaf template that displays the outcome of a charge operation. The user is sent here by the ChargeController whether the charge operation was successful or not:

   Result   

Success!

Id.: Status: Charge id.: Balance transaction id.: Checkout again

In caso di successo, l'utente vedrà alcuni dettagli dell'operazione di addebito:

In caso di errore, all'utente verrà presentato il messaggio di errore restituito da Stripe:

8. Conclusione

In questo tutorial, abbiamo mostrato come utilizzare l'API Java Stripe per addebitare una carta di credito. In futuro, potremmo riutilizzare il nostro codice lato server per fornire un'app mobile nativa.

Per testare l'intero flusso di carica, non è necessario utilizzare una vera carta di credito (anche in modalità test). Possiamo invece fare affidamento sulle carte di prova Stripe.

L'operazione di addebito è una delle tante possibilità offerte dall'API Java Stripe. Il riferimento API ufficiale ci guiderà attraverso l'intera serie di operazioni.

Il codice di esempio utilizzato in questo tutorial può essere trovato nel progetto GitHub.