In the past, I published an article on PayPal Payment Gateway Integration in PHP. One of our readers asked about integrating the PayPal payment gateway in Laravel. Though Laravel is built using PHP, they follow their own standards. You have to adjust your plain PHP code as per Laravel standards. In this article, I show you how to integrate the PayPal payment gateway into your Laravel application.
PayPal is one of the most trusted brands to accept online payment. PayPal provides different services to integrate its payment system into web applications. One of the services is PayPal Rest API which I’ll use for this tutorial. It requires you to grab your client id and client secret.
Head over to your PayPal developer account and login into it. In the developer dashboard, click on the menu ‘My Apps & Credentials’ menu. Then click on the ‘Create App’ button.
Follow the steps as prompted and you will get your sandbox and live credentials. For now, copy the client id and client secret of sandbox mode. You should first test payments in sandbox mode and if it works then switch to live mode.
Basic Setup in Laravel to Accept Payment using PayPal
To integrate the PayPal system in Laravel, you need to perform certain steps.
- Set up the environment required – install packages, store API credentials, etc.
- Build a payment flow.
- Store successful transactions in the database.
Let’s create a database table to hold the transaction details. I’ll name the table as ‘payments’. Create a migration for the ‘payments’ table using the Artisan command:
php artisan make:migration create_payments_table
Open the migration file and specify the columns in the up()
method as follows.
<?php
...
...
public function up()
{
Schema::create('payments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('payment_id');
$table->string('payer_id');
$table->string('payer_email');
$table->float('amount', 10, 2);
$table->string('currency');
$table->string('payment_status');
$table->timestamps();
});
}
Execute this migration using the command:
php artisan migrate
This command will create a ‘payments’ table in your database. Next, create a model corresponding to the ‘payments’ table.
php artisan make:model Payment
After this, add your PayPal API credentials in your .env
file.
PAYPAL_CLIENT_ID=PASTE_HERE_CLIENT_ID
PAYPAL_CLIENT_SECRET=PASTE_HERE_CLIENT_SECRET
PAYPAL_CURRENCY=USD
For the demo purposes, I have passed the ‘USD’ currency. The user can change the currency as per their requirements.
Clear the configuration cache using the command:
php artisan config:cache
Now to build a PayPal payment flow, the system requires to have few routes. Define them in the routes/web.php
file.
Route::get('payment', 'PaymentController@index');
Route::post('charge', 'PaymentController@charge');
Route::get('success', 'PaymentController@success');
Route::get('error', 'PaymentController@error');
Of course, I’ll create PaymentController
in the next steps.
PayPal Payment Gateway Integration in Laravel
Integrating payment gateways in the application is quite complex stuff. Fortunately, Omnipay library makes the developer’s life easy. Omnipay is the most popular payment processing library for PHP. It gives an easy and clean approach to integrating different payment gateways. You don’t need to read payment gateway documentation thoroughly. All you need to do is use the guidelines provided by Omnipay and you are done.
That being said, install the Omnipay library using the command:
composer require league/omnipay omnipay/paypal
After this, create a controller PaymentController
and define the methods mentioned in the route file.
php artisan make:controller PaymentController
This controller is responsible to initiate and complete the PayPal flow for your users.
- Call the view.
- Take the user inputs.
- Process the amount towards PayPal.
- Authorize the payment and charge the customer.
- Insert transaction details into the database.
Let’s add a code to the PaymentController
to perform all these above steps.
PaymentController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Omnipay\Omnipay;
use App\Models\Payment;
class PaymentController extends Controller
{
private $gateway;
public function __construct()
{
$this->gateway = Omnipay::create('PayPal_Rest');
$this->gateway->setClientId(env('PAYPAL_CLIENT_ID'));
$this->gateway->setSecret(env('PAYPAL_CLIENT_SECRET'));
$this->gateway->setTestMode(true); //set it to 'false' when go live
}
/**
* Call a view.
*/
public function index()
{
return view('payment');
}
/**
* Initiate a payment on PayPal.
*
* @param \Illuminate\Http\Request $request
*/
public function charge(Request $request)
{
if($request->input('submit'))
{
try {
$response = $this->gateway->purchase(array(
'amount' => $request->input('amount'),
'currency' => env('PAYPAL_CURRENCY'),
'returnUrl' => url('success'),
'cancelUrl' => url('error'),
))->send();
if ($response->isRedirect()) {
$response->redirect(); // this will automatically forward the customer
} else {
// not successful
return $response->getMessage();
}
} catch(Exception $e) {
return $e->getMessage();
}
}
}
/**
* Charge a payment and store the transaction.
*
* @param \Illuminate\Http\Request $request
*/
public function success(Request $request)
{
// Once the transaction has been approved, we need to complete it.
if ($request->input('paymentId') && $request->input('PayerID'))
{
$transaction = $this->gateway->completePurchase(array(
'payer_id' => $request->input('PayerID'),
'transactionReference' => $request->input('paymentId'),
));
$response = $transaction->send();
if ($response->isSuccessful())
{
// The customer has successfully paid.
$arr_body = $response->getData();
// Insert transaction data into the database
$payment = new Payment;
$payment->payment_id = $arr_body['id'];
$payment->payer_id = $arr_body['payer']['payer_info']['payer_id'];
$payment->payer_email = $arr_body['payer']['payer_info']['email'];
$payment->amount = $arr_body['transactions'][0]['amount']['total'];
$payment->currency = env('PAYPAL_CURRENCY');
$payment->payment_status = $arr_body['state'];
$payment->save();
return "Payment is successful. Your transaction id is: ". $arr_body['id'];
} else {
return $response->getMessage();
}
} else {
return 'Transaction is declined';
}
}
/**
* Error Handling.
*/
public function error()
{
return 'User cancelled the payment.';
}
}
We have called a blade file in the index
method. So, create a blade file called payment.blade.php
and add the code below to it.
<form action="{{ url('charge') }}" method="post">
@csrf
<input type="text" name="amount" value="10.00" />
<input type="submit" name="submit" value="Pay Now" />
</form>
When you submit this form, control goes to the charge
function in the PaymentController
and the controller processes the rest payment flow.
Test Payment in Sandbox Mode
While testing a payment, you will require fake card details. Visit this link to generate your dummy credit card. These card details can be used on your PayPal sandbox account.
Make Payment Live
Once you are done with sandbox testing, you are ready to switch to production mode. To make your payment live, update your live PayPal client id and client secret in the environment file.
Next, in the constructor method of a PaymentController, set the false value to the setTestMode()
method.
$this->gateway->setTestMode(false);
Send Product Information to PayPal
In the previous steps, we are sending only the amount on PayPal. You may also want to send product information. The user can see these product details on the payment page before making a payment.
To send the product information, pass the ‘items’ array to the purchase
method as follows.
$response = $this->gateway->purchase(array(
'amount' => $request->input('amount'),
'items' => array(
array(
'name' => 'Course Subscription',
'price' => $request->input('amount'),
'description' => 'Get access to premium courses.',
'quantity' => 1
),
),
'currency' => env('PAYPAL_CURRENCY'),
'returnUrl' => url('success'),
'cancelUrl' => url('error'),
))->send();
Here I am passing the product details statically. You should make it dynamic depending on your flow.
I hope you understand PayPal payment gateway integration in Laravel. This tutorial should help you to add the PayPal system to your Laravel application. It will allow you to receive online payments through PayPal.
Related Articles
- Authorize.Net Payment Gateway Integration in Laravel
- Stripe Payment Gateway Integration in Laravel
- PayKun Payment Gateway Integration in Laravel
If you liked this article, then please subscribe to our YouTube Channel for video tutorials.
I get ‘transaction is declined’ whenever I try to pay for it…HELP!
i try but receiving error on methods SetClientId(), setSecret() and setTestMode() using laravel 8
How can I pass custom addresses?
Hi Sajid, thanks for your answer!
Everything is ok, but I receive this error:
“Call to a member function completePurchase() on null ”
Ii I dd(‘$this->gateway’)
it prints null..
Is this strange, what am I missing?
Hi Sajid, thanks a lot for your nice tutorial!
I followed the tutorial for Stripe payment too and because I need to implement both payments;
I’m creating a unique PaymentController.
I noticed a slight difference between the two tutorials, here you declare the “public $gateway;”
before the function, in Stripe no.
Which approach is better to follow?
Thanks a lot for your support 🙂
If you want to use both payments then use the different variables – $paypal_gateway, $stripe_gateway. Pass credentials to these variables in the constructor(like I did for PayPal). Then use a specific variable as per the payment option.
this is not help full
composer require league/omnipay omnipay/paypal
packege is not install
How to set logo and store name? Thank you.
Thank you for your video. Tell me please, how I can send/get information about product? Thank you.
try {
$response = $this->gateway->purchase(array(
‘amount’ => $request->input(‘amount’),
‘items’ => array(
array(
‘name’ => $request->input(‘category’),
‘price’ => $request->input(‘amount’),
‘description’ => ‘t-shirt’,
‘quantity’ => 1
),
),
‘currency’ => env(‘PAYPAL_CURRENCY’),
‘returnUrl’ => url(‘paymentsuccess’),
‘cancelUrl’ => url(‘paymenterror’),
))->send();
if ($response->isRedirect()) {
$response->redirect(); // this will automatically forward the customer
} else {
// not successful
return $response->getMessage();
}
}
InvalidArgumentException
Empty number is invalid
when
$response = $this->gateway->purchase(array(
‘amount’ => $request->input(‘amount’),
‘items’ => array(
array(
‘name’ => ‘Course Subscription’,
‘price’ => $request->input(‘amount’),
‘description’ => ‘Get access to premium courses.’,
‘quantity’ => 1
),
),
‘currency’ => env(‘PAYPAL_CURRENCY’),
‘returnUrl’ => url(‘paymentsuccess’),
‘cancelUrl’ => url(‘paymenterror’),
))->send();
no permission for the requested operation
The Above errors occurs while i am trying to pay amount.
I want to add product information to the payment. How can I enter product information?
cURL error 60: (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
hi all! if you have the error about authentication, run the command
php artisan config:clear
I run the command
php artisan config:clear
but the error continue
Authentication failed due to invalid authentication credentials or a missing Authorization header.
Is the laravel or ommipay version?
I like that its straight to the point. Thank you
helllo I am getting error,
Authentication failed due to invalid authentication credentials or a missing Authorization header.
When you added new constants in the environment file, you may sometimes need to clear configuration cache. You can do this by running the command:
Authentication failed due to invalid authentication credentials or a missing Authorization header.
I am getting this error please help
I just tested it and it’s working without any issues for me.
Hi Bishal,
I have the same problem as you – did you manage to resolve it? Thanks in advance
this is because the paypal credentials couldnt get from the .env file… try
$this->gateway->setClientId(‘client id’);
$this->gateway->setSecret(‘secret id’);
directly on the PaymentController and comment the previous things..thank me later
does not help how you can fix
Tbis is the first time I subscribe for a newsletter !
Your articles are always straight to the point!
Can you please write an article on how to integrate Stripe with Laravel?
Thanks for the appreciation. I will try to publish an article on Stripe with Laravel soon.
Here is the article on Stripe gateway integration https://artisansweb.net/stripe-payment-gateway-integration-in-laravel