You are currently viewing Integrating Stripe Payment Gateway with Spring Boot

Integrating Stripe Payment Gateway with Spring Boot

Stripe is a popular payment processing platform that allows businesses to securely accept payments online. Integrating Stripe with a Spring Boot application enables you to easily handle payment transactions, manage customers, and more. In this tutorial, we’ll guide you through the process of integrating Stripe with a Spring Boot backend.

Prerequisites

Before we begin, make sure you have the following:

  • Java and Spring Boot installed on your machine.
  • Basic knowledge of Spring Boot and RESTful APIs.
  • A Stripe account (sign up at Stripe).

Table of Contents

  1. Setting Up a Spring Boot Application
  2. Adding Stripe Dependencies
  3. Configuring Stripe
  4. Creating a Payment Controller
  5. Creating a Checkout Form
  6. Handling Webhooks
  7. Testing the Integration
  8. Conclusion

1. Setting Up a Spring Boot Application

If you haven’t already, create a new Spring Boot project. You can do this manually or by using Spring Initializr.

Using Spring Initializr

Go to Spring Initializr and generate a new project with the following:

  • Project: Gradle or Maven
  • Language: Java
  • Spring Boot Version: Select a version
  • Group: com.example
  • Artifact: stripe-demo
  • Dependencies: Web, Thymeleaf (for frontend, optional)

Download the project and open it in your preferred IDE.

2. Adding Stripe Dependencies

Add the Stripe Java library to your build.gradle (for Gradle) or pom.xml (for Maven).

For Gradle

implementation 'com.stripe:stripe-java:20.41.0'

For Maven

<dependency>
    <groupId>com.stripe</groupId>
    <artifactId>stripe-java</artifactId>
    <version>20.41.0</version>
</dependency>

3. Configuring Stripe

In your Spring Boot application, create a configuration class to set up your Stripe API key.

import com.stripe.Stripe;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class StripeConfig {

    @Value("${stripe.secretKey}")
    private String secretKey;

    @Bean
    public void initStripe() {
        Stripe.apiKey = secretKey;
    }
}

Make sure to store your Stripe secret key in the application.properties or application.yml file:

application.properties

stripe.secretKey=your_stripe_secret_key_here

application.yml

stripe:
  secretKey: your_stripe_secret_key_here

4. Creating a Payment Controller

Create a controller to handle payment requests and interact with the Stripe API.

import com.stripe.exception.StripeException;
import com.stripe.model.Charge;
import com.stripe.param.ChargeCreateParams;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentController {

    @Value("${stripe.currency}")
    private String currency;

    @PostMapping("/charge")
    public ResponseEntity<String> chargeCard(@RequestBody ChargeRequest chargeRequest) {
        try {
            ChargeCreateParams createParams = new ChargeCreateParams.Builder()
                    .setAmount(chargeRequest.getAmount())
                    .setCurrency(currency)
                    .setSource(chargeRequest.getToken())
                    .build();

            Charge charge = Charge.create(createParams);
            return ResponseEntity.ok("Payment successful: " + charge.getId());
        } catch (StripeException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Payment failed: " + e.getMessage());
        }
    }
}

Define the ChargeRequest class:

public class ChargeRequest {
    private String token;
    private Integer amount;

    // getters and setters
}

5. Creating a Checkout Form

Now, create a simple HTML form for testing the payment.

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Stripe Payment</title>
    <script src="https://js.stripe.com/v3/"></script>
</head>
<body>
    <form action="/charge" method="post" id="payment-form">
        <div>
            <label for="amount">Amount (in cents):</label>
            <input type="number" id="amount" name="amount" value="1000">
        </div>
        <div>
            <label for="card-element">
                Credit or debit card
            </label>
            <div id="card-element">
                <!-- A Stripe Element will be inserted here. -->
            </div>

            <!-- Used to display form errors. -->
            <div id="card-errors" role="alert"></div>
        </div>
        <button type="submit">Submit Payment</button>
    </form>

    <script>
        // Set your publishable key
        var stripe = Stripe('your_publishable_key_here');

        // Create an instance of Elements
        var elements = stripe.elements();

        // Create an instance of the card Element
        var card = elements.create('card');

        // Add an instance of the card Element into the `card-element` div
        card.mount('#card-element');

        // Handle real-time validation errors from the card Element
        card.addEventListener('change', function (event) {
            var displayError = document.getElementById('card-errors');
            if (event.error) {
                displayError.textContent = event.error.message;
            } else {
                displayError.textContent = '';
            }
        });

        // Handle form submission
        var form = document.getElementById('payment-form');
        form.addEventListener('submit', function (event) {
            event.preventDefault();

            stripe.createToken(card).then(function (result) {
                if (result.error) {
                    // Inform the user if there was an error
                    var errorElement = document.getElementById('card-errors');
                    errorElement.textContent = result.error.message;
                } else {
                    // Send the token to your server
                    stripeTokenHandler(result.token);
                }
            });
        });

        // Submit the token to your server
        function stripeTokenHandler(token) {
            var form = document.getElementById('payment-form');
            var hiddenInput = document.createElement('input');
            hiddenInput.setAttribute('type', 'hidden');
            hiddenInput.setAttribute('name', 'token');
            hiddenInput.setAttribute('value', token.id);
            form.appendChild(hiddenInput);

            // Submit the form
            form.submit();
        }
    </script>
</body>


</html>

Replace 'your_publishable_key_here' with your Stripe publishable key.

6. Handling Webhooks

Stripe uses webhooks to notify your application of events, such as successful payments or failed charges. You can handle these events in your Spring Boot application.

import com.stripe.model.Event;
import com.stripe.model.EventDataObjectDeserializer;
import com.stripe.net.Webhook;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
public class WebhookController {

    @PostMapping("/webhook")
    public ResponseEntity<String> handleWebhook(@RequestBody String payload, HttpServletRequest request) {
        String secret = "your_webhook_secret_here";

        try {
            Event event = Webhook.constructEvent(payload, request.getHeader("Stripe-Signature"), secret);

            // Handle the event
            switch (event.getType()) {
                case "payment_intent.succeeded":
                    // Handle successful payment
                    break;
                case "payment_intent.payment_failed":
                    // Handle failed payment
                    break;
                // Add more cases for other event types as needed
                default:
                    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Unhandled event type: " + event.getType());
            }

            return ResponseEntity.ok("Webhook handled: " + event.getType());
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Webhook error: " + e.getMessage());
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Webhook error: " + e.getMessage());
        }
    }
}

Make sure to replace 'your_webhook_secret_here' with your actual webhook secret.

7. Testing the Integration

  • Run your Spring Boot application.
  • Access the checkout form (localhost:8080/checkout) in your browser.
  • Enter an amount and use a test credit card number (e.g., 4242 4242 4242 4242).
  • Complete the form and submit the payment.
  • Check the console logs of your Spring Boot application to see the payment details and webhook events.

8. Conclusion

Congratulations! You’ve successfully integrated Stripe with your Spring Boot application. You can now securely process payments and handle webhook events for various payment-related actions. This tutorial covered setting up Stripe dependencies, configuring Stripe API keys, creating a payment controller, implementing a checkout form, and handling webhook events. Feel free to explore more advanced features and customization options provided by Stripe to enhance your payment processing capabilities.

Additional Resources:

Leave a Reply