Click Below to subscribe

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