How to Integrate Stripe Payment Gateway In Laravel 2022
Stripe is the most popular and secure payment gateway. In this article, we will integrate stripe(server-side) in laravel step by step.
1. Let's create a new laravel project.
composer create-project laravel/laravel laravel-stripe
2. Install stripe-php package.
composer require stripe/stripe-php
3. Create a stripe.php file inside the config folder and add this code.
<?php
return [
'api_keys' => [
'secret_key' => env('STRIPE_SECRET_KEY', null)
]
];
4. Open .env file and add the stripe secret key environment variable.
STRIPE_SECRET_KEY= // your secret key
Stripe API Keys - https://dashboard.stripe.com/account/apikeys
Note:- For sandbox keys click on test mode option on the stripe dashboard.
Stripe API
Stripe API provides a bunch of methods to simplify the integration process. stripe payment is divided into two steps.
(a). Tokenization:- In this step stripe collects sensitive card or bank account details and returns a token.
$stripe = new \Stripe\StripeClient(
'sk_test_0CaAJrFqtvoLO3pfWUayDGgK'
);
$stripe->tokens->create([
'card' => [
'number' => '4242424242424242',
'exp_month' => 2,
'exp_year' => 2023,
'cvc' => '314',
],
]);
Ref:- Stripe API Reference - Create a card token
(b). Charge:- In this step stripe will charge the amount using the token created during tokenization
$stripe = new \Stripe\StripeClient(
'sk_test_0CaAJrFqtvoLO3pfWUayDGgK'
);
$stripe->charges->create([
'amount' => 2000,
'currency' => 'usd',
'source' => 'tok_mastercard',
'description' => 'My First Test Charge',
]);
Note:- amount should be passed in the smallest currency unit. In the above example, 2000 is 20USD. description is optional.
you can also pass extra data in form of key-value pair in metadata field.
Ref:-Stripe API Reference - Create a charge
So let's continue with the integration...
5. Create a payment.blade.php inside the resources/views directory and this code.
<main>
<div class="row">
<aside class="col-sm-6 offset-3">
<article class="card">
<div class="card-body p-5">
<ul class="nav bg-light nav-pills rounded nav-fill mb-3" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#nav-tab-card">
<i class="fa fa-credit-card"></i> Credit Card</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade show active" id="nav-tab-card">
@foreach (['danger', 'success'] as $status)
@if(Session::has($status))
<p class="alert alert-{{$status}}">{{ Session::get($status) }}</p>
@endif
@endforeach
<form role="form" method="POST" id="paymentForm" action="{{ url('/payment')}}">
@csrf
<div class="form-group">
<label for="username">Full name (on the card)</label>
<input type="text" class="form-control" name="fullName" placeholder="Full Name">
</div>
<div class="form-group">
<label for="cardNumber">Card number</label>
<div class="input-group">
<input type="text" class="form-control" name="cardNumber" placeholder="Card Number">
<div class="input-group-append">
<span class="input-group-text text-muted">
<i class="fab fa-cc-visa fa-lg pr-1"></i>
<i class="fab fa-cc-amex fa-lg pr-1"></i>
<i class="fab fa-cc-mastercard fa-lg"></i>
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label><span class="hidden-xs">Expiration</span> </label>
<div class="input-group">
<select class="form-control" name="month">
<option value="">MM</option>
@foreach(range(1, 12) as $month)
<option value="{{$month}}">{{$month}}</option>
@endforeach
</select>
<select class="form-control" name="year">
<option value="">YYYY</option>
@foreach(range(date('Y'), date('Y') + 10) as $year)
<option value="{{$year}}">{{$year}}</option>
@endforeach
</select>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label data-toggle="tooltip" title=""
data-original-title="3 digits code on back side of the card">CVV <i
class="fa fa-question-circle"></i></label>
<input type="number" class="form-control" placeholder="CVV" name="cvv">
</div>
</div>
</div>
<button class="subscribe btn btn-primary btn-block" type="submit"> Confirm </button>
</form>
</div>
</div>
</div>
</article>
</aside>
</div>
</main>
Note:- please checkout github repo - https://github.com/ultimateakash/laravel-stripe
6. Create a PaymentController
php artisan make:controller PaymentController
7. Open PaymentController.php and add this code.
<?php
namespace App\Http\Controllers;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Stripe\Exception\CardException;
use Stripe\StripeClient;
class PaymentController extends Controller
{
private $stripe;
public function __construct()
{
$this->stripe = new StripeClient(config('stripe.api_keys.secret_key'));
}
public function index()
{
return view('payment');
}
public function payment(Request $request)
{
$validator = Validator::make($request->all(), [
'fullName' => 'required',
'cardNumber' => 'required',
'month' => 'required',
'year' => 'required',
'cvv' => 'required'
]);
if ($validator->fails()) {
$request->session()->flash('danger', $validator->errors()->first());
return response()->redirectTo('/');
}
$token = $this->createToken($request);
if (!empty($token['error'])) {
$request->session()->flash('danger', $token['error']);
return response()->redirectTo('/');
}
if (empty($token['id'])) {
$request->session()->flash('danger', 'Payment failed.');
return response()->redirectTo('/');
}
$charge = $this->createCharge($token['id'], 2000);
if (!empty($charge) && $charge['status'] == 'succeeded') {
$request->session()->flash('success', 'Payment completed.');
} else {
$request->session()->flash('danger', 'Payment failed.');
}
return response()->redirectTo('/');
}
private function createToken($cardData)
{
$token = null;
try {
$token = $this->stripe->tokens->create([
'card' => [
'number' => $cardData['cardNumber'],
'exp_month' => $cardData['month'],
'exp_year' => $cardData['year'],
'cvc' => $cardData['cvv']
]
]);
} catch (CardException $e) {
$token['error'] = $e->getError()->message;
} catch (Exception $e) {
$token['error'] = $e->getMessage();
}
return $token;
}
private function createCharge($tokenId, $amount)
{
$charge = null;
try {
$charge = $this->stripe->charges->create([
'amount' => $amount,
'currency' => 'usd',
'source' => $tokenId,
'description' => 'My first payment'
]);
} catch (Exception $e) {
$charge['error'] = $e->getMessage();
}
return $charge;
}
}
Note:- You can store $charge['id'] as a transaction id and later you can fetch the charge data using this id.
Ref:- Stripe API Reference - Retrieve a charge
8. Open web.php and add this code.
<?php
use App\Http\Controllers\PaymentController;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', [PaymentController::class, 'index']);
Route::post('/payment', [PaymentController::class, 'payment']);
9. Finally open http://localhost/laravel-stripe/public and test the integration.
For Testing:-
Card Number: 4242424242424242
Month/Year: Any future date
CVV: Any 3 digits
Ref:- Testing Cards | Stripe
If you facing any issues. please post a comment. I will be happy to help you,
Thanks
Leave Your Comment