Introduction
L'intégration de Stripe avec Laravel est une tâche essentielle pour les développeurs d'applications web souhaitant offrir des solutions de paiement flexibles et sécurisées. Cet article guide pas à pas pour intégrer Stripe v3 dans un projet Laravel. Suivez attentivement ces instructions pour une intégration fluide et efficace.
Prérequis
Avant de commencer, assurez-vous que les éléments suivants sont installés :
-
PHP version 8.1 ou ultérieure
Étape 1 : Créer un projet Laravel avec Composer
Pour démarrer, créez un nouveau projet Laravel en utilisant Composer :
composer create-project laravel/laravel shopping-cart --prefer-dist
Étape 2 : Installer Livewire
Ajoutez Livewire à votre projet Laravel pour une interaction utilisateur réactive :
composer require livewire/livewire
Étape 3 : Installer Alpine.js
Installez Alpine.js pour une manipulation DOM simplifiée :
npm install alpinejs
Ensuite, dans resources/js/app.js
, ajoutez :
Alpine = require('alpinejs');
import './bootstrap';
window.Alpine = Alpine;
Alpine.start();
Étape 4 : Installer Stripe
Ajoutez la bibliothèque Stripe à votre projet Laravel :
composer require stripe/stripe-php
Puis, ajoutez les clés API Stripe dans le fichier .env
:
STRIPE_SECRET=sk_test_key
STRIPE_KEY=pk_test_key
Étape 5 : Créer un layout default avec Livewire
Utilisez la commande artisan pour créer un layout par défaut :
php artisan livewire:layout
Ajoutez ensuite le code suivant dans resources/views/components/layouts/app.blade.php
:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Intégration de Stripe avec Laravel - {{ env('APP_NAME') }}</title>
@vite(['resources/css/app.css'])
<script src="https://js.stripe.com/v3/"></script>
@livewireStyles
</head>
<body>
{{ $slot }}
</body>
@vite(['resources/js/app.js'])
@livewireScripts
</html>
Étape 6 : Créer un composant Livewire
Générez un composant Livewire pour le checkout :
php artisan make:livewire Checkout
Modifiez le fichier app/Livewire/Checkout.php
comme suit :
<?php
namespace App\Livewire;
use Exception;
use Livewire\Component;
use Stripe\StripeClient;
class Checkout extends Component
{
public $output = [];
public $amount;
public $currency = 'eur';
public array $cartProducts;
public array $basket = [];
public function mount()
{
$this->createPaymentIntents();
}
public function createPaymentIntents()
{
$cartTotal = 200;
$stripe = new StripeClient(env('STRIPE_SECRET'));
try {
if (session()->has('payment_output') && session('amount') == $cartTotal) {
$this->output = session('payment_output');
$this->amount = session('amount');
} else {
$this->amount = $cartTotal;
$paymentIntent = $stripe->paymentIntents->create([
'amount' => str_replace([',', '.'], ['', ''], $this->amount),
'currency' => $this->currency,
'automatic_payment_methods' => ['enabled' => true],
]);
$this->output = [
'clientSecret' => $paymentIntent->client_secret,
'dpmCheckerLink' => "https://dashboard.stripe.com/settings/payment_methods/review?transaction_id={$paymentIntent->id}",
];
session(['payment_output' => $this->output]);
session(['amount' => $cartTotal]);
}
} catch (Exception $e) {
http_response_code(500);
dd(['error' => $e->getMessage()]);
}
}
public function render()
{
return view('livewire. Checkout');
}
}
Ajoutez ensuite le code suivant dans resources/views/livewire/checkout.blade.php
:
<div class="w-full h-screen grid place-items-center">
<div x-data="stripePayment" x-init="initialize" @submit.prevent="handleSubmit">
<form id="payment-form" class="w-full md:min-w-[500px] self-center shadow-sm border border-gray-200 rounded-md p-10 my-auto">
<div id="payment-element" class="mb-6"></div>
<button id="submit" class="bg-blue-600 font-sans text-white rounded-md border-0 p-3 text-lg font-semibold cursor-pointer w-full transition-all ease-in-out shadow-md hover:contrast-115 disabled:opacity-50 disabled:cursor-not-allowed">
<div class="spinner hidden" id="spinner"></div>
<span id="button-text">Payez {{ $amount }} euros maintenant</span>
</button>
<div id="payment-message" class="hidden text-gray-500 text-base leading-5 pt-3 text-center"></div>
</form>
<div id="dpm-annotation" class="self-center text-gray-700 w-[30vw] min-w-[500px] leading-5 mb-5">
<p>
Les méthodes de paiement sont affichées de manière dynamique en fonction de l'emplacement du client, du montant de la commande et de la devise.
<a href="#" target="_blank" rel="noopener noreferrer" id="dpm-integration-checker" class="inline text-primary-600">Aperçu des modes de paiement par transaction</a>
</p>
</div>
</div>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('stripePayment', () => ({
elements: null,
stripe: Stripe("{{ env('STRIPE_KEY') }}"),
initialize() {
this.elements = this.stripe.elements({ clientSecret: "{{ $output['clientSecret'] }}" });
const paymentElement = this.elements.create("payment", { layout: "tabs" });
paymentElement.mount("#payment-element");
this.setDpmCheckerLink("{{ $output['dpmCheckerLink'] }}");
},
async handleSubmit() {
this.setLoading(true);
const { error } = await this.stripe.confirmPayment({
elements: this.elements,
confirmParams: { return_url: "{{ route('success') }}" },
});
if (error.type === "card_error" || error.type === "validation_error") {
this.showMessage(error.message);
} else {
this.showMessage("An unexpected error occurred.");
}
this.setLoading(false);
},
showMessage(messageText) {
const messageContainer = document.querySelector("#payment-message");
messageContainer.classList.remove("hidden");
messageContainer.textContent = messageText;
setTimeout(() => {
messageContainer.classList.add("hidden");
messageContainer.textContent = "";
}, 4000);
},
setLoading(isLoading) {
const submitButton = document.querySelector("#submit");
const spinner = document.querySelector("#spinner");
const buttonText = document.querySelector("#button-text");
if (isLoading) {
submitButton.disabled = true;
spinner.classList.remove("hidden");
buttonText.classList.add("hidden");
} else {
submitButton.disabled = false;
spinner.classList.add("hidden");
buttonText.classList.remove("hidden");
}
},
setDpmCheckerLink(url) {
document.querySelector("#dpm-integration-checker").href = url;
}
}));
});
</script>
La dernière étape consiste à configurer les routes dans routes\web.php
:
<?php
use App\Livewire\Checkout;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/', Checkout::class)->name('checkout');
Route::get('/success', function (Request $request) {
$request->session()->flush();
return 'Payment Success!';
})->name('success');
Avec ces étapes, vous aurez une intégration complète de Stripe v3 avec Laravel utilisant Livewire et Alpine Testez toujours votre intégration en mode test de Stripe avant de passer en production. Bonne intégration et que vos paiements soient sans souci !
Code soure sur GitHub : https://github.com/Soule73/laravel-stripe-checkout