Laravel 12 - How to Integrate Stripe Payment Gateway.

Touseef Afridi
12 Feb 26

Laravel 12 - How to Integrate Stripe Payment Gateway.

In this tutorial we will learn how to integrate Stripe payment gateway in Laravel 12 to securely accept online payments and offer a smooth checkout experience for your users.

Quick Overview

This guide walks you through integrating Stripe payment processing into a Laravel 12 application. You start by setting up a fresh Laravel project and installing the Stripe PHP package, then configure your Stripe API keys in the .env file. A CheckoutController is created to handle the payment flow, generating a PaymentIntent for a specified amount in AED. The frontend uses a Blade view with Stripe Elements to collect card information, and routes are defined to display the checkout form and handle the post-payment confirmation. Upon successful payment, a success message is displayed to the user, completing the payment process.

Step # 1 : Set Up a New Laravel 12 Project named Stripe.

To begin, you can either create a new Laravel project or use an existing application. If you already have the Laravel Installer installed globally, run.
laravel new stripe
If you don’t have the installer, you can create the project using Composer.
composer create-project laravel/laravel --prefer-dist stripe
When using Composer, Laravel starts with a clean default setup. If you use the Laravel Installer, it will guide you through a short interactive configuration. Select the following options when prompted.
  • Starter kit installation: Select None for now so the project remains clean and minimal.
  • Testing framework: Use Pest as it provides a modern and expressive testing experience.
  • Database: Choose MySQL since it is widely used and works seamlessly with Laravel.
  • Run default migrations: Allow Laravel to run the initial migrations so the basic database structure is ready.
  • Frontend dependency installation: When prompted, type yes to let Laravel run npm install and npm run build, which will automatically install and compile all frontend dependencies.

After the setup is complete, you will have a fresh Laravel 12 application named stripe, configured based on the above selection.

Step # 2 : Navigate to Your Project Directory.

Open your terminal (such as Git Bash, Command Prompt, or Terminal) and move to the root folder of your Laravel project using the cd command.
cd c:xampp/htdocs/stripe
Make sure you are inside the project’s main directory, as all upcoming commands will be executed from here.

Step # 3 : Install the Stripe PHP Package.

To connect Stripe with your Laravel application, you need to install the official Stripe PHP SDK. Run the following Composer command.
composer require stripe/stripe-php
This package enables your Laravel application to securely communicate with Stripe’s API and manage payments, customers, and transactions programmatically. It also provides the necessary tools to create payment intents, process charges, and interact with Stripe services directly from your application.

Step # 4 : Create Your Stripe Account.

To start accepting payments, you need a Stripe account. Visit: https://stripe.com/ and sign up for a new account.
After completing the registration, open your Stripe Dashboard and locate your Publishable Key and Secret Key. These API keys will be used to connect your Laravel application with Stripe securely.

Step # 5: Add Stripe API Keys to Your Environment File.

Next, open the .env file in the root of your Laravel project and add the following configuration.
STRIPE_KEY=YOUR_PUBLISHABLE_KEY
STRIPE_SECRET=YOUR_SECRET_KEY
Replace the placeholder values with the actual keys from your Stripe Dashboard. These credentials allow your application to securely communicate with Stripe and process payments safely through the Stripe API.

Step # 6 : Create the Checkout Controller.

Generate a new controller by running the following Artisan command.
php artisan make:controller CheckoutController
This command will create a CheckoutController.php file inside the app/Http/Controllers directory. This controller will contain the logic responsible for handling the checkout process and Stripe payments. Now, replace the contents of CheckoutController.php with the following code.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class CheckoutController extends Controller
{
    // Initiates the checkout process and creates a Stripe PaymentIntent
    public function checkout()
    {
        // Set Stripe secret key from .env
        \Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
        // Stripe expects the smallest currency unit (for AED: 1 AED = 100 fils)
        $amount = 200 * 100; // Convert 200 AED to fils
        try {
            // Create a new PaymentIntent with Stripe
            $payment_intent = \Stripe\PaymentIntent::create([
                // Payment description
                'description' => 'Code Shotcut Stripe Test Payment',
                // Payment amount in fils
                'amount' => $amount,
                // Currency (AED)
                'currency' => 'aed',
                // Payment method type (card)
                'payment_method_types' => ['card'],
            ]);
            // Get the client secret to authenticate the payment on the frontend
            $intent = $payment_intent->client_secret;
            // Return view with the payment intent client secret
            return view('credit-card', compact('intent'));
        } catch (\Exception $e) {
            // Handle any errors during the payment creation process
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }
    // Handles the post-payment process
    public function afterPayment()
    {
        // Display a message confirming the payment was successful
        return 'Payment received. Thank you for using our services.';
    }
}
The CheckoutController handles the complete Stripe checkout flow using Stripe’s PaymentIntent API. It converts the payment amount into the smallest currency unit (fils for AED), securely communicates with Stripe to create a payment intent, and passes the client secret to the frontend to complete the payment process. After a successful payment, it returns a confirmation message to the user.

Step # 7 : Define Checkout Routes.

First, open your routes/web.php file and import the CheckoutController at the top.
use App\Http\Controllers\CheckoutController;
Next, define the routes for handling the checkout and payment process.
// Route to display the checkout page and initiate payment
Route::get('/checkout', [CheckoutController::class, 'checkout']);
// Route to handle the post-payment process after payment completion
Route::post('/checkout', [CheckoutController::class, 'afterPayment'])->name('credit-card');
The GET request to /checkout triggers the checkout process and creates a Stripe PaymentIntent, while the POST request to the same route handles the response after the payment is completed and confirms the transaction.

Step # 8 : Create the Checkout View.

Create a new Blade view named credit-card.blade.php and use the following code.
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Laravel 12 - Code Shotcut Stripe Payment</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-950 flex items-center justify-center min-h-screen">
    <div class="w-full max-w-2xl space-y-8">
        <!-- Payment Container -->
        <div id="payment-container">
            <!-- Total Amount -->
            <div class="text-center text-2xl font-semibold text-gray-200 mb-6">
                Your Total Amount is 200 AED
            </div>
            <!-- Payment Form Card -->
            <div class="bg-gray-900 p-8 rounded-2xl shadow-xl border border-gray-800">
                <form action="{{ route('credit-card') }}" method="post" id="payment-form" class="space-y-6">
                    @csrf
                    <!-- Card Input -->
                    <div>
                        <label for="card-element" class="block mb-2 font-medium text-gray-200">
                            Enter your credit card information
                        </label>
                        <div id="card-element" class="bg-gray-800 border border-gray-700 rounded-xl p-5 shadow-inner">
                            <!-- Stripe Element injected here -->
                        </div>
                        <div id="card-errors" class="text-red-500 text-sm mt-2" role="alert"></div>
                        <input type="hidden" name="plan" value="" />
                    </div>
                    <!-- Pay Button -->
                    <button
                        id="card-button"
                        data-secret="{{ $intent }}"
                        type="submit"
                        class="w-full bg-white text-gray-900 py-3 rounded-xl font-semibold shadow-lg hover:bg-gray-100 transition-colors"
                    >
                        Pay
                    </button>
                </form>
            </div>
        </div>
        <!-- Success Message -->
        <div id="success-container" class="hidden bg-gray-900 border-l-4 border-green-500 text-green-400 p-6 rounded-xl shadow-lg">
            <h2 class="text-2xl font-semibold">Payment Successful!</h2>
            <p class="mt-2">Thank you for your payment. Your transaction has been processed successfully.</p>
        </div>
    </div>
    <!-- Stripe JS -->
    <script src="https://js.stripe.com/v3/"></script>
    <script>
        // Initialize Stripe with your publishable key from .env
        const stripe = Stripe('{{ env('STRIPE_KEY') }}');
        const elements = stripe.elements();
        // Create a Stripe Card Element with custom styling
        const cardElement = elements.create('card', {
            style: {
                base: {
                    color: '#f5f5f5',
                    fontSize: '16px',
                    '::placeholder': { color: '#b0b0b0' },
                    fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
                    iconColor: '#ffffff'
                },
                invalid: {
                    color: '#ff6b6b',
                    iconColor: '#ffffff'
                }
            }
        });
        // Mount the card input inside the DOM
        cardElement.mount('#card-element');
        // Get form and payment button elements
        const form = document.getElementById('payment-form');
        const cardButton = document.getElementById('card-button');
        const clientSecret = cardButton.dataset.secret;
        // Display real-time validation errors from the Card Element
        cardElement.on('change', event => {
            const displayError = document.getElementById('card-errors');
            displayError.textContent = event.error ? event.error.message : '';
        });
        // Handle form submission to confirm card payment
        form.addEventListener('submit', async event => {
            event.preventDefault();
            // Confirm the payment using Stripe PaymentIntent
            const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
                payment_method: { card: cardElement }
            });
            if (error) {
                // Show error message if payment fails
                document.getElementById('card-errors').textContent = error.message;
            } else {
                // Hide the payment form and show success message
                document.getElementById('payment-container').classList.add('hidden');
                document.getElementById('success-container').classList.remove('hidden');
            }
        });
    </script>
</body>
</html>
This view provides a dark-themed checkout form using Stripe’s Elements for secure card input. It processes payments in real time and dynamically shows errors or a success message, offering a clean and user-friendly payment experience.

Step # 9 : Test the Stripe Integration.

Now it’s time to verify that everything is working. Start your Laravel development server by running.
php artisan serve
Once the server is running, open your browser and go to: 127.0.0.1:8000/checkout. You should see the checkout form you just created. To test the Stripe integration, use the following dummy card details.
Card Number: 4242 4242 4242 4242
Expiration Date: 12/32
CVV: 123
ZIP: 12345
Submit the form with this test data. If everything is set up correctly, the payment will be processed, and the success message will appear. You can also verify the transaction by logging into your Stripe Dashboard and checking under Transactions.




Conclusion

By following this guide, you can fully integrate Stripe payments into your Laravel application, enabling a smooth and reliable checkout experience. The step-by-step instructions cover setting up the project, configuring API keys, creating a checkout controller, and building a payment form, making it easy to handle transactions and display success messages. This integration provides a solid foundation for processing payments and can be extended to support advanced features like subscriptions, multiple currencies, or different payment methods, making it suitable for e-commerce, service platforms, or donation applications.
For more details, please refer to the Stripe documentation.
Share this with friends!


"Give this post some love and slap that 💖 button as if it owes you money! 💸😄"
0

0 Comments

To engage in commentary, kindly proceed by logging in or registering