This documentation provides instructions for integrating PayPal payments in Laravel using the srmklive/paypal
package.
Install the package via Composer:
composer require srmklive/paypal
After installation, you can use the following commands to publish the assets:
php artisan vendor:publish --provider "Srmklive\PayPal\Providers\PayPalServiceProvider"
Create config/paypal.php
:
<?php
/**
* PayPal Setting & API Credentials
* Created by Raza Mehdi <srmk@outlook.com>.
*/
return [
'mode' => env('PAYPAL_MODE', 'sandbox'),
'sandbox' => [
'client_id' => env('PAYPAL_SANDBOX_CLIENT_ID', ''),
'client_secret' => env('PAYPAL_SANDBOX_CLIENT_SECRET', ''),
'app_id' => 'APP-80W284485P519543T',
],
'live' => [
'client_id' => env('PAYPAL_LIVE_CLIENT_ID', ''),
'client_secret' => env('PAYPAL_LIVE_CLIENT_SECRET', ''),
'app_id' => env('PAYPAL_LIVE_APP_ID', ''),
],
'payment_action' => env('PAYPAL_PAYMENT_ACTION', 'Sale'),
'currency' => env('PAYPAL_CURRENCY', 'USD'),
'notify_url' => env('PAYPAL_NOTIFY_URL', ''),
'locale' => env('PAYPAL_LOCALE', 'en_US'),
'validate_ssl' => env('PAYPAL_VALIDATE_SSL', true),
];
Add to your .env
:
PAYPAL_MODE=sandbox
PAYPAL_SANDBOX_CLIENT_ID=your_sandbox_client_id
PAYPAL_SANDBOX_CLIENT_SECRET=your_sandbox_secret
PAYPAL_LIVE_CLIENT_ID=your_live_client_id
PAYPAL_LIVE_CLIENT_SECRET=your_live_secret
Add to routes/web.php
:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PayPalController;
Route::get('paypal', [PayPalController::class, 'index'])->name('paypal');
Route::get('paypal/payment', [PayPalController::class, 'payment'])->name('paypal.payment');
Route::get('paypal/payment/success', [PayPalController::class, 'paymentSuccess'])->name('paypal.payment.success');
Route::get('paypal/payment/cancel', [PayPalController::class, 'paymentCancel'])->name('paypal.payment.cancel');
Create app/Http/Controllers/PayPalController.php
:
<?php
namespace App\Http\Controllers;
use Srmklive\PayPal\Services\PayPal as PayPalClient;
use Illuminate\Http\Request;
class PayPalController extends Controller
{
public function index()
{
return view('paypal');
}
public function payment(Request $request)
{
$provider = new PayPalClient;
$provider->setApiCredentials(config('paypal'));
$paypalToken = $provider->getAccessToken();
$response = $provider->createOrder([
"intent" => "CAPTURE",
"application_context" => [
"return_url" => route('paypal.payment.success'),
"cancel_url" => route('paypal.payment.cancel'),
],
"purchase_units" => [
[
"amount" => [
"currency_code" => "USD",
"value" => "100.00"
]
]
]
]);
\Log::info('PayPal API Response:', $response);
if (isset($response['id']) && $response['id'] != null) {
foreach ($response['links'] as $links) {
if ($links['rel'] == 'approve') {
return redirect()->away($links['href']);
}
}
return redirect()
->route('paypal')
->with('error', 'Something went wrong. No approval link found.');
} else {
return redirect()
->route('paypal')
->with('error', $response['message'] ?? 'Something went wrong.');
}
}
public function paymentCancel()
{
return redirect()
->route('paypal')
->with('error', 'You have canceled the transaction.');
}
public function paymentSuccess(Request $request)
{
$provider = new PayPalClient;
$provider->setApiCredentials(config('paypal'));
$provider->getAccessToken();
$response = $provider->capturePaymentOrder($request['token']);
if (isset($response['status']) && $response['status'] == 'COMPLETED') {
return redirect()
->route('paypal')
->with('success', 'Transaction complete.');
} else {
return redirect()
->route('paypal')
->with('error', $response['message'] ?? 'Something went wrong.');
}
}
}
Create resources/views/paypal.blade.php
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>PayPal Integration Example</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row mt-5 mb-5">
<div class="col-10 offset-1 mt-5">
<div class="card">
<div class="card-header bg-primary">
<h3 class="text-white">PayPal Payment Gateway Integration</h3>
</div>
<div class="card-body">
@if ($message = Session::get('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
<strong>{{ $message }}</strong>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
@endif
@if ($message = Session::get('error'))
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<strong>{{ $message }}</strong>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
@endif
<center>
<a href="{{ route('paypal.payment') }}" class="btn btn-success">Pay with PayPal</a>
</center>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
- Visit
/paypal
route - Click "Pay with PayPal" button
- Complete payment in PayPal interface
- You'll be redirected back to:
- Success page on successful payment
- Cancel page if payment is canceled
Note: Make sure to:
- Update PayPal credentials in
.env
- Configure appropriate error handling
- Implement proper success/cancel logic
- Set up logging for debugging