In this article, we will walk through integrating PayPal subscription plans in a Laravel application. We will focus on setting up the PayPal SDK, creating payments using PayPal subscription plans, and handling payment notifications via PayPal Webhooks.
Install PayPal SDK
To start using PayPal services in your Laravel application, we need to install the srmklive/paypal
package.
composer require srmklive/paypal
After installation, publish the configuration file for PayPal.
php artisan vendor:publish --provider="Srmklive\PayPal\PayPalServiceProvider" --tag="config"
This will create a config/paypal.php
file, where you can configure your PayPal settings. However, we’ll be fetching these configurations directly from the .env
file.
Set Up PayPal Credentials in .env
To keep your credentials secure, we will use Laravel’s .env
file for storing the PayPal API credentials.
Add the following lines to your .env
file:
PAYPAL_CLIENT_ID=your-client-id
PAYPAL_CLIENT_SECRET=your-client-secret
PAYPAL_MODE=sandbox # or 'live' for production
PAYPAL_APP_ID=your-app-id # Optional, if required by your PayPal app
PAYPAL_NOTIFY_URL=https://your-domain.com/paypal/notify # Webhook notification URL
Create the PayPal Payment Controller
Now, let’s create the controller to handle PayPal payments and subscription creation. We will use the PayPal
service to interact with the PayPal API.
Here is a sample implementation:
namespace App\Http\Controllers\Payments;
use App\Http\Controllers\Controller;
use App\Models\Payment;
use Srmklive\PayPal\Services\PayPal;
use Illuminate\Http\Request;
class PaypalPaymentController extends Controller
{
private $provider;
public function __construct()
{
$this->provider = new PayPal;
$conf = [
'mode' => env('PAYPAL_MODE', 'sandbox'),
'live' => [
'client_id' => env('PAYPAL_CLIENT_ID'),
'client_secret' => env('PAYPAL_CLIENT_SECRET'),
'app_id' => env('PAYPAL_APP_ID', ''),
],
'payment_action' => 'Sale',
'currency' => 'USD',
'notify_url' => env('PAYPAL_NOTIFY_URL', ''),
'locale' => 'en_US',
'validate_ssl' => false,
];
// Set PayPal credentials
$this->provider->setApiCredentials($conf);
// Get access token to use the PayPal API
$this->provider->getAccessToken();
}
public function createPayment(Request $request)
{
$order = $request->order;
$price = $order->total;
$customerId = $order->customer_id;
$payment = Payment::create([
'price' => $price,
'order_id' => $order->id,
'status' => 'incompleted',
'payment_method' => 'paypal',
]);
$successUrl = route('paypal.success', ['orderId' => $order->id, 'paymentId' => $payment->id]);
$cancelUrl = route('paypal.cancel', ['orderId' => $order->id]);
$data = [
'intent' => 'CAPTURE',
'purchase_units' => [
[
'amount' => [
'currency_code' => 'USD',
'value' => $price,
],
],
],
'application_context' => [
'locale' => 'en-US',
'shipping_preference' => 'NO_SHIPPING',
'user_action' => 'PAY_NOW',
'payment_method' => [
'payer_selected' => 'PAYPAL',
'payee_preferred' => 'IMMEDIATE_PAYMENT_REQUIRED',
],
'return_url' => $successUrl,
'cancel_url' => $cancelUrl,
],
];
try {
$response = $this->provider->createOrder($data);
return response()->json(['payment_url' => $response['links'][1]['href'], 'payment_id' => $payment->id]);
} catch (\Throwable $th) {
return response()->json(['error' => 'Error creating payment'], 500);
}
}
public function success(Request $request)
{
// Handle successful payment
$paymentId = $request->input('paymentId');
$orderId = $request->input('orderId');
$payment = Payment::find($paymentId);
$payment->update(['status' => 'completed']);
return view('payment.success', compact('orderId', 'paymentId'));
}
public function cancel(Request $request)
{
// Handle canceled payment
$paymentId = $request->input('paymentId');
$payment = Payment::find($paymentId);
$payment->update(['status' => 'canceled']);
return view('payment.cancel');
}
}
Add PayPal Webhook for Payment Notifications
PayPal Webhooks allow you to receive notifications about payment events, such as successful transactions or failed payments. Here, we’ll add a route and a handler to process the webhook.
- Configure Webhook Route:
Add the following route in your routes/web.php
file.
Route::post('/paypal/notify', [PaypalPaymentController::class, 'handleWebhook']);
- Handle the Webhook in Controller:
In the PaypalPaymentController
, add a method to process the webhook.
public function handleWebhook(Request $request)
{
$data = $request->all();
// Check the PayPal event type
$eventType = $data['event_type'] ?? null;
if ($eventType === 'PAYMENT.SALE.COMPLETED') {
$paymentId = $data['resource']['id'];
$payment = Payment::where('payment_id', $paymentId)->first();
if ($payment) {
$payment->status = 'completed';
$payment->save();
}
}
return response()->json(['status' => 'success']);
}
PayPal will send notifications to this route whenever an event (like a completed payment) occurs. We will check the event type (PAYMENT.SALE.COMPLETED
) and update the payment status accordingly.
This article has covered the basic steps of integrating PayPal subscription plans into your Laravel application. We’ve shown how to configure PayPal credentials, create payment orders, and handle successful and canceled payments. Additionally, we added a webhook handler to process payment notifications.
With this setup, you can easily integrate PayPal as a payment gateway for your application and ensure that you receive real-time updates about your transactions through Webhooks.