Laravel 9 - Stripe payment gateway
Laravel 9 - Stripe payment gateway
In this tutorial, we'll explore integrating the Stripe payment gateway in Laravel 9, a platform for secure and easy online payment management.
If you're a video person, feel free to skip the post and check out the video instead!
Quick Overview
In this guide, we walk you through integrating Stripe payment processing into a Laravel 9 application. We start by creating a fresh Laravel 9 project and installing all necessary dependencies, including the official Stripe PHP SDK. After setting up the project and running the development server, we configure Stripe credentials using the .env file and generate a dedicated CheckoutController to handle payment logic. Next, we define the required routes and build a clean, responsive checkout view using Blade and Bootstrap. The view leverages Stripe Elements to securely collect card information and process payments with JavaScript. Finally, we test the integration using Stripe’s test card credentials to ensure everything works smoothly. By the end, you’ll have a fully functional Stripe checkout flow set up and ready to accept payments in test mode.
Step # 1 : Set Up a Laravel 9 Project.
You can either start with a brand new Laravel 9 project or continue with an existing one if you’ve already got it set up. To create a fresh project using the Laravel installer (if it's installed globally), run the command below.
laravel new stripe
Alternatively, if you prefer using Composer, you can run the following command.
composer create-project laravel/laravel --prefer-dist stripe
This lays the groundwork for your Stripe integration by setting up a Laravel 9 environment. Whether you start fresh or work with an existing project, the goal is to ensure you're working within a clean and compatible Laravel 9 setup.
Step # 2 : Access Your Project and Run the Dev Server.
Once your Laravel 9 project is set up, open your terminal (such as Git Bash or your preferred CLI) and navigate to the project directory.
cd c:xampp/htdocs/stripe
Now it's time to install the front-end dependencies and start the Vite development server. Run the following command to handle both.
npm install && npm run dev
You can now open another terminal window or tab (in the same project directory) to continue running Laravel commands without interrupting the dev server.
Step # 3 : Install the Stripe PHP Package.
Next, we’ll install the official Stripe client library for PHP. This package provides all the necessary classes and methods to create charges, manage customers, handle webhooks, and more, making it the core tool for connecting your Laravel app with Stripe’s payment platform. Run the following command in your terminal.
composer require stripe/stripe-php
Once installed, you’ll be ready to start working with Stripe's powerful API directly within your Laravel application.
Step # 4 : Create a Stripe Account.
To start working with Stripe in your Laravel application, you’ll need a Stripe account. Head over to the official website and sign up: https://stripe.com/. Once your account is created, log in to the Stripe Dashboard. You can find your Publishable Key and Secret Key by navigating to Dashboard → Developers → API keys. These keys are required to authenticate requests and securely handle payments in your Laravel app.
Step # 5: Add Your Stripe Keys to the .env File.
Now that you have your Stripe keys, it’s time to connect them to your Laravel app. Open your project’s .env file and add the following lines.
STRIPE_KEY=your_publishable_key
STRIPE_SECRET=your_secret_key
Replace your_publishable_key and your_secret_key with the actual keys from your Stripe Dashboard.
Step # 6 : Create the CheckoutController.
Next, let’s generate a controller to handle the Stripe checkout process. Run the following Artisan command.
php artisan make:controller CheckoutController
Once the controller is created, open the newly generated file and update it with the following code.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class CheckoutController extends Controller
{
public function checkout()
{
\Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
$amount = 100 * 100; // Amount in the smallest currency unit (e.g., 100 AED)
$payment_intent = \Stripe\PaymentIntent::create([
'description' => 'Stripe Test Payment',
'amount' => $amount,
'currency' => 'AED',
'payment_method_types' => ['card'],
]);
$intent = $payment_intent->client_secret;
return view('checkout.credit-card', compact('intent'));
}
public function afterPayment()
{
return 'Payment received. Thank you for using our services.';
}
}
This controller handles the backend logic for initiating Stripe payments. It sets your Stripe secret key, creates a PaymentIntent with the desired amount and currency, and returns the client_secret to the view, which is required for securely processing the payment on the frontend. The afterPayment method simply confirms the transaction once it’s complete.
Step # 7 : Define Checkout Routes.
Now it’s time to set up the necessary routes for handling the Stripe checkout process. First, import the CheckoutController at the top of your routes/web.php file.
use App\Http\Controllers\CheckoutController;
Then, add the following routes.
Route::get('/checkout', [CheckoutController::class, 'checkout']);
Route::post('/checkout', [CheckoutController::class, 'afterPayment'])->name('checkout.credit-card');
These routes handle the initial display of the checkout page (GET /checkout) and the payment confirmation logic when the form is submitted (POST /checkout).
Step # 8 : Create the Checkout View.
Now it’s time to build the front-end interface for processing payments. Inside the resources/views directory, create a new folder named checkout, and within it, create a Blade file named credit-card.blade.php. Your file structure should look like this (resources/views/checkout/credit-card.blade.php). Now, paste the following code into credit-card.blade.php.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Stripe Payment</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container" style="margin-top:10%;margin-bottom:10%">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="">
<p>Your Total Amount is 100 AED</p>
</div>
<div class="card">
<form action="{{ route('checkout.credit-card') }}" method="post" id="payment-form">
@csrf
<div class="form-group">
<div class="card-header">
<label for="card-element">Enter your credit card information</label>
</div>
<div class="card-body">
<div id="card-element">
<!-- A Stripe Element will be inserted here. -->
</div>
<!-- Used to display form errors. -->
<div id="card-errors" role="alert"></div>
<input type="hidden" name="plan" value="" />
</div>
</div>
<div class="card-footer">
<button
id="card-button"
class="btn btn-dark"
type="submit"
data-secret="{{ $intent }}"
> Pay </button>
</div>
</form>
</div>
</div>
</div>
</div>
<script src="https://js.stripe.com/v3/"></script>
<script>
var style = {
base: {
color: '#32325d',
lineHeight: '18px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
const stripe = Stripe('{{ env('STRIPE_KEY') }}', { locale: 'en' });
const elements = stripe.elements();
const cardElement = elements.create('card', { style: style });
const cardButton = document.getElementById('card-button');
const clientSecret = cardButton.dataset.secret;
cardElement.mount('#card-element');
cardElement.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.handleCardPayment(clientSecret, cardElement, {
payment_method_data: {
//billing_details: { name: cardHolderName.value }
}
})
.then(function(result) {
if (result.error) {
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
form.submit();
}
});
});
</script>
</body>
</html>
This view provides a styled credit card form using Stripe Elements and Bootstrap. It securely collects the card information from the user and sends it to Stripe for processing via the client secret we passed from the controller. The form handles validation, displays error messages, and submits the payment seamlessly using JavaScript.
Step # 9 : Test the Stripe Integration.
Now that everything is in place, Run the Laravel server.
php artisan serve
Visit url : 127.0.0.1/checkout. It’s time to test your Stripe checkout process using the following test card details
Card Number - 4242 4242 4242 4242
EXP - 12/32
CVV - 123
ZIP - 12345
If everything is set up correctly, submitting the payment form should redirect you and display the message.
This confirms that your Laravel 9 Stripe integration is working as expected in test mode.
Conclusion
By following this guide, you’ve successfully integrated Stripe into your Laravel 9 project using the official Stripe PHP SDK. You set up your Stripe account, added API keys to your environment file, built a checkout controller, defined routes, and created a secure credit card payment form using Stripe Elements. Your Laravel app is now equipped to process payments in a streamlined and secure way.
For more advanced use cases such as recurring payments, webhooks, or detailed billing management, be sure to explore the Stripe PHP and Laravel documentation.
Share this with friends!
To engage in commentary, kindly proceed by logging in or registering
Subscribe to Our Newsletter
Stay ahead of the curve! Join our newsletter to see what everyone’s talking about.
0 Comments