Introduction à l'API Stripe pour Java

1. Vue d'ensemble

Stripe est un service basé sur le cloud qui permet aux entreprises et aux particuliers de recevoir des paiements sur Internet et propose à la fois des bibliothèques côté client (JavaScript et mobile natif) et des bibliothèques côté serveur (Java, Ruby, Node.js, etc.).

Stripe fournit une couche d'abstraction qui réduit la complexité de la réception des paiements. Par conséquent, nous n'avons pas besoin de traiter directement les détails de la carte de crédit - à la place, nous traitons un jeton symbolisant une autorisation de facturer .

Dans ce didacticiel, nous allons créer un exemple de projet Spring Boot qui permet aux utilisateurs de saisir une carte de crédit et, plus tard, débitera la carte d'un certain montant à l'aide de l'API Stripe pour Java.

2. Dépendances

Pour utiliser l'API Stripe pour Java dans le projet, nous ajoutons la dépendance correspondante à notre pom.xml :

 com.stripe stripe-java 4.2.0  

Nous pouvons trouver sa dernière version dans le référentiel Maven Central.

Pour notre exemple de projet, nous utiliserons le parent spring-boot-starter :

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

Nous utiliserons également Lombok pour réduire le code standard, et Thymeleaf sera le moteur de modèle pour fournir des pages Web dynamiques.

Puisque nous utilisons le spring-boot-starter-parent pour gérer les versions de ces bibliothèques, nous n'avons pas besoin d'inclure leurs versions dans pom.xml :

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

Notez que si vous utilisez NetBeans, vous voudrez peut-être utiliser Lombok explicitement avec la version 1.16.16 , car un bogue dans la version de Lombok fournie avec Spring Boot 1.5.2 entraîne NetBeans à générer de nombreuses erreurs.

3. Clés API

Avant de pouvoir communiquer avec Stripe et exécuter les frais de carte de crédit, nous devons enregistrer un compte Stripe et obtenir des clés API Stripe secrètes / publiques .

Après avoir confirmé le compte, nous nous connecterons pour accéder au tableau de bord Stripe. Nous choisissons ensuite «Clés API» dans le menu de gauche:

Il y aura deux paires de clés secrètes / publiques - une pour le test et une pour le live. Laissons cet onglet ouvert afin que nous puissions utiliser ces clés plus tard.

4. Flux général

Le débit de la carte de crédit se fera en cinq étapes simples, impliquant le front-end (exécuté dans un navigateur), le back-end (notre application Spring Boot) et Stripe:

  1. Un utilisateur accède à la page de paiement et clique sur «Payer par carte».
  2. Un utilisateur est présenté avec la boîte de dialogue de superposition Stripe Checkout, où remplit les détails de la carte de crédit.
  3. Un utilisateur confirme avec «Payer» ce qui:
    • Envoyez la carte de crédit à Stripe
    • Obtenez un jeton dans la réponse qui sera ajouté au formulaire existant
    • Envoyez ce formulaire avec le montant, la clé API publique, l'e-mail et le jeton à notre back-end
  4. Notre back-end contacte Stripe avec le jeton, le montant et la clé API secrète.
  5. Le back-end vérifie la réponse de Stripe et fournit à l'utilisateur un retour d'information sur l'opération.

Nous couvrirons chaque étape plus en détail dans les sections suivantes.

5. Formulaire de paiement

Stripe Checkout est un widget personnalisable, prêt pour les appareils mobiles et localisable qui rend un formulaire pour introduire les détails de la carte de crédit. Grâce à l'inclusion et à la configuration de « checkout.js », il est responsable de:

  • Rendu du bouton "Payer avec la carte"

  • Rendu de la boîte de dialogue de superposition de paiement (déclenché après avoir cliqué sur "Payer par carte")

  • Validation de la carte de crédit
  • Fonction "Se souvenir de moi" (associe la carte à un numéro de mobile)
  • Envoi de la carte de crédit à Stripe et remplacement de celle-ci par un jeton dans le formulaire ci-joint (déclenché après avoir cliqué sur «Payer»)

Si nous devons exercer plus de contrôle sur le formulaire de paiement que celui fourni par Stripe Checkout, nous pouvons utiliser Stripe Elements.

Ensuite, nous analyserons le contrôleur qui prépare le formulaire, puis le formulaire lui-même.

5.1. Manette

Commençons par créer un contrôleur pour préparer le modèle avec les informations nécessaires dont le formulaire de commande a besoin .

Tout d'abord, nous devons copier la version de test de notre clé publique à partir du tableau de bord Stripe et l'utiliser pour définir STRIPE_PUBLIC_KEY en tant que variable d'environnement. Nous utilisons ensuite cette valeur dans le champ stripePublicKey .

Nous définissons également la devise et le montant (exprimés en cents) manuellement ici uniquement à des fins de démonstration, mais dans une application réelle, nous pourrions définir un identifiant de produit / vente qui pourrait être utilisé pour récupérer les valeurs réelles.

Ensuite, nous expédierons à la vue de paiement qui contient le formulaire de paiement:

@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

En cas de succès, l'utilisateur verra quelques détails de l'opération de charge:

En cas d'erreur, l'utilisateur recevra le message d'erreur renvoyé par Stripe:

8. Conclusion

Dans ce didacticiel, nous avons montré comment utiliser l'API Stripe Java pour débiter une carte de crédit. À l'avenir, nous pourrions réutiliser notre code côté serveur pour servir une application mobile native.

Pour tester l'ensemble du flux de charge, nous n'avons pas besoin d'utiliser une vraie carte de crédit (même en mode test). Nous pouvons plutôt nous fier aux cartes de test Stripe.

L'opération de charge est l'une des nombreuses possibilités offertes par l'API Stripe Java. La référence officielle de l'API nous guidera à travers l'ensemble des opérations.

L'exemple de code utilisé dans ce didacticiel se trouve dans le projet GitHub.