Laravel 12 Stripe Payment Gateway Integration

Hey, Laravel enthusiasts! I’m thrilled to guide you through integrating the Stripe payment gateway into your Laravel 12 application. Stripe is a popular, secure, and developer-friendly platform for processing online payments, perfect for e-commerce stores, subscription services, or any app requiring payment functionality.

In this beginner-friendly tutorial, I’ll walk you through setting up a simple payment form to process a $10 payment using Stripe’s API and the stripe/stripe-php package. The steps are clear, and I’ve improved upon the original instructions for better clarity and modern practices.

laravel-12-stripe-payment-gateway-integration

Prerequisites

Before we begin, ensure you have:

  • A Laravel 12 project set up.
  • Composer installed.
  • A Stripe account (free developer account is fine).

Step 1: Install Laravel 12

If you already have a Laravel 12 project, skip this step. Otherwise, run:

composer create-project laravel/laravel example-app

Navigate to your project directory:

cd example-app

Step 2: Install stripe-php Package

Install the stripe/stripe-php package to interact with Stripe’s API:

composer require stripe/stripe-php

This package provides a convenient PHP interface for Stripe’s payment processing features.

Step 3: Set Up Stripe Account and API Keys

You’ll need Stripe API keys to process payments. Follow these steps:

  1. Visit Stripe’s website and sign up for a free developer account.
  2. Log in and navigate to Developers > API Keys in the Stripe Dashboard.
  3. Copy the Publishable Key (starts with pk_test_) and Secret Key (starts with sk_test_).

Add these keys to your env file in the project root:

STRIPE_KEY=pk_test_your_publishable_key
STRIPE_SECRET=sk_test_your_secret_key

Example:

STRIPE_KEY=pk_test_reFxwbsm9cdCKASdTfxARXXXXXX
STRIPE_SECRET=sk_test_oQMFWteJiPd4wj4AtgApYXXXXXXX

For security, ensure your env file is not publicly accessible (it’s ignored by .gitignore by default).

Step 4: Create Stripe Payment Controller

Create a controller to handle the payment form and payment processing:

php artisan make:controller StripePaymentController

Open app/Http/Controllers/StripePaymentController.php and update it with:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Stripe\Stripe;
use Stripe\Charge;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;

class StripePaymentController extends Controller
{
    /**
     * Display the payment form.
     */
    public function index(): View
    {
        return view('stripe');
    }

    /**
     * Process the Stripe payment.
     */
    public function store(Request $request): RedirectResponse
    {
        try {
            Stripe::setApiKey(env('STRIPE_SECRET'));

            Charge::create([
                'amount' => 10 * 100, // $10 in cents
                'currency' => 'usd',
                'source' => $request->stripeToken,
                'description' => 'Test payment from Laravel 12 app',
            ]);

            return back()->with('success', 'Payment successful!');
        } catch (\Exception $e) {
            return back()->with('error', 'Payment failed: ' . $e->getMessage());
        }
    }
}

Step 5: Define Routes

Open routes/web.php and add routes for displaying the payment form and processing payments:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\StripePaymentController;

Route::controller(StripePaymentController::class)->group(function () {
    Route::get('/stripe', 'index')->name('stripe.index');
    Route::post('/stripe', 'store')->name('stripe.store');
});

Step 6: Create Blade View

Create a Blade file at resources/views/stripe.blade.php with the following code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Laravel 12 Stripe Payment Integration</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
    <style>
        #card-element {
            height: 50px;
            padding-top: 16px;
            border: 1px solid #ced4da;
            border-radius: 0.25rem;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card mt-5">
                    <h3 class="card-header p-3">Laravel 12 Stripe Payment Integration</h3>
                    <div class="card-body">
                        @if (session('success'))
                            <div class="alert alert-success" role="alert">
                                {{ session('success') }}
                            </div>
                        @endif
                        @if (session('error'))
                            <div class="alert alert-danger" role="alert">
                                {{ session('error') }}
                            </div>
                        @endif

                        <form id="checkout-form" method="POST" action="{{ route('stripe.store') }}">
                            @csrf
                            <div class="mb-3">
                                <label for="name" class="form-label"><strong>Name</strong></label>
                                <input type="text" class="form-control" name="name" placeholder="Enter Name" required>
                            </div>
                            <input type="hidden" name="stripeToken" id="stripe-token-id">
                            <div class="mb-3">
                                <div id="card-element" class="form-control"></div>
                            </div>
                            <button id="pay-btn" class="btn btn-success w-100 mt-3" type="button" onclick="createToken()">
                                Pay $10
                            </button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://js.stripe.com/v3/"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        var stripe = Stripe('{{ env('STRIPE_KEY') }}');
        var elements = stripe.elements();
        var cardElement = elements.create('card');
        cardElement.mount('#card-element');

        function createToken() {
            document.getElementById('pay-btn').disabled = true;
            stripe.createToken(cardElement).then(function (result) {
                if (result.error) {
                    document.getElementById('pay-btn').disabled = false;
                    alert(result.error.message);
                } else {
                    document.getElementById('stripe-token-id').value = result.token.id;
                    document.getElementById('checkout-form').submit();
                }
            });
        }
    </script>
</body>
</html>

Step 7: Run the Application

Start your Laravel server:

php artisan serve

Visit http://localhost:8000/stripe in your browser. You’ll see a payment form where you can enter a name and card details.

Testing with Stripe

Use Stripe’s test cards for safe testing:

  • Success: 4242 4242 4242 4242, any future expiry, any CVC.
  • Failure: 4000 0000 0000 0002 (declined card).
  • Check the Stripe Dashboard (Payments section) to verify transactions.

Optional: Laravel Cashier

For advanced features like subscriptions, consider using Laravel Cashier (Stripe), which simplifies recurring billing, coupons, and invoice generation. Install it with:

composer require laravel/cashier

See the Laravel documentation for setup details.

Conclusion

Integrating Stripe into Laravel 12 is straightforward with the stripe/stripe-php package! This tutorial showed you how to set up a simple payment form to process a $10 charge, complete with a clean UI and error handling. Whether you’re building an e-commerce platform or a small service, Stripe and Laravel make payments secure and seamless. I hope this guide was clear and inspires you to add payment functionality to your projects.

Frequently Asked Questions (FAQs)

Q1: Why use Stripe for payments?
A: Stripe is secure, developer-friendly, and supports multiple payment methods (cards, Apple Pay, etc.) with robust APIs for one-time or recurring payments.

Q2: What if I get a “Payment failed” error?
A: Check your Stripe API keys in env, ensure the test card details are correct, and verify your internet connection. The error message will provide clues.

Q3: Can I use Stripe for subscriptions?
A: Yes, use Laravel Cashier for easy subscription management or Stripe’s Subscription API directly for custom setups.

Q4: Is this integration PCI-compliant?
A: Yes, using Stripe’s client-side tokenization (via stripe.js) ensures sensitive card data never hits your server, maintaining PCI compliance.

Q5: How do I switch to live payments?
A: Replace pk_test_ and sk_test_ keys with live keys (pk_live_, sk_live_) from your Stripe Dashboard and test thoroughly in production.


You might also like :

techsolutionstuff

Techsolutionstuff | The Complete Guide

I'm a software engineer and the founder of techsolutionstuff.com. Hailing from India, I craft articles, tutorials, tricks, and tips to aid developers. Explore Laravel, PHP, MySQL, jQuery, Bootstrap, Node.js, Vue.js, and AngularJS in our tech stack.

RECOMMENDED POSTS

FEATURE POSTS