Search code examples
laravelpaypalpaypal-ipn

How to code paypal ipn listener in laravel


I used laravel in my project. In my project using paypal for payment module. Paypal payment transactions successfully done. But i want to integrate ipn listener in laravel. I don't know how to integrate ipn listener in laravel controller.

Thanks advanced, Saran


Solution

  • Follow Bellow Few Step:
    1)Install Laravel Application
    2)Database Configuration
    3)Install Required Packages
    4)configuration paypal.php file
    5)create route
    6)create controller
    7)create view file

    Step 1 : Install Laravel Application
    we are going from scratch, So we require to get fresh Laravel application using bellow command, So open your terminal OR command prompt and run bellow command:

    composer create-project --prefer-dist laravel/laravel blog
    

    Step 2 : Database Configuration
    In this step, we require to make database configuration, you have to add
    following details on your .env file.
    1.Database Username
    1.Database Password
    1.Database Name

    In .env file also available host and port details, you can configure all details as in your system, So you can put like as bellow: .env

    DB_HOST=localhost
    DB_DATABASE=homestead
    DB_USERNAME=homestead
    DB_PASSWORD=secret
    

    Step 3 : Install Required Packages
    We have required following 2 packages for integrate paypal payment in our laravel application. add following two package in your composer.json file.

    "guzzlehttp/guzzle": "~5.4",
    "paypal/rest-api-sdk-php": "*",
    

    then after run following command in your terminal

    php artisan vendor:publish
    

    after run this command, then after automatic create paypal.php file in your config/paypal.php path.

    Step 4 : Configuration paypal.php file

    <?php
    
    return array(
    /** set your paypal credential **/
    'client_id' =>'paypal client_id',
    'secret' => 'paypal secret ID',
    /**
    * SDK configuration 
    */
    'settings' => array(
        /**
        * Available options 'sandbox' or 'live'
        */
        'mode' => 'sandbox',
        /**
        * Specify the max request time in seconds
        */
        'http.ConnectionTimeOut' => 1000,
        /**
        * Whether want to log to a file
        */
        'log.LogEnabled' => true,
        /**
        * Specify the file that want to write on
        */
        'log.FileName' => storage_path() . '/logs/paypal.log',
        /**
        * Available option 'FINE', 'INFO', 'WARN' or 'ERROR'
        *
        * Logging is most verbose in the 'FINE' level and decreases as you
        * proceed towards ERROR
        */
        'log.LogLevel' => 'FINE'
        ),
    );
    

    Step 5: Create Route
    In this is step we need to create route for paypal payment. so open your routes/web.php file and add following route. routes/web.php

    Route::get('paywithpaypal', array('as' => 'addmoney.paywithpaypal','uses' => 'AddMoneyController@payWithPaypal',));
    Route::post('paypal', array('as' => 'addmoney.paypal','uses' => 'AddMoneyController@postPaymentWithpaypal',));
    Route::get('paypal', array('as' => 'payment.status','uses' => 'AddMoneyController@getPaymentStatus',));
    

    Step 6: Create Controller
    In this point, now we should create new controller as AddMoneyController in this path app/Http/Controllers/AddMoneyController.php. this controller will manage layout and payment post request, So run bellow command for generate new controller:

    php artisan make:controller AddMoneyController
    

    Ok, now put below content in controller file:
    app/Http/Controllers/AddMoneyController.php

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Http\Requests;
    use Illuminate\Http\Request;
    use Validator;
    use URL;
    use Session;
    use Redirect;
    use Input;
    
    /** All Paypal Details class **/
    use PayPal\Rest\ApiContext;
    use PayPal\Auth\OAuthTokenCredential;
    use PayPal\Api\Amount;
    use PayPal\Api\Details;
    use PayPal\Api\Item;
    use PayPal\Api\ItemList;
    use PayPal\Api\Payer;
    use PayPal\Api\Payment;
    use PayPal\Api\RedirectUrls;
    use PayPal\Api\ExecutePayment;
    use PayPal\Api\PaymentExecution;
    use PayPal\Api\Transaction;
    
    class AddMoneyController extends HomeController
    {
    
        private $_api_context;
        /**
         * Create a new controller instance.
         *
         * @return void
         */
        public function __construct()
        {
            parent::__construct();
    
            /** setup PayPal api context **/
            $paypal_conf = \Config::get('paypal');
            $this->_api_context = new ApiContext(new OAuthTokenCredential($paypal_conf['client_id'], $paypal_conf['secret']));
            $this->_api_context->setConfig($paypal_conf['settings']);
        }
    
    
    
        /**
         * Show the application paywith paypalpage.
         *
         * @return \Illuminate\Http\Response
         */
        public function payWithPaypal()
        {
            return view('paywithpaypal');
        }
    
        /**
         * Store a details of payment with paypal.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function postPaymentWithpaypal(Request $request)
        {
            $payer = new Payer();
            $payer->setPaymentMethod('paypal');
    
            $item_1 = new Item();
    
            $item_1->setName('Item 1') /** item name **/
                ->setCurrency('USD')
                ->setQuantity(1)
                ->setPrice($request->get('amount')); /** unit price **/
    
            $item_list = new ItemList();
            $item_list->setItems(array($item_1));
    
            $amount = new Amount();
            $amount->setCurrency('USD')
                ->setTotal($request->get('amount'));
    
            $transaction = new Transaction();
            $transaction->setAmount($amount)
                ->setItemList($item_list)
                ->setDescription('Your transaction description');
    
            $redirect_urls = new RedirectUrls();
            $redirect_urls->setReturnUrl(URL::route('payment.status')) /** Specify return URL **/
                ->setCancelUrl(URL::route('payment.status'));
    
            $payment = new Payment();
            $payment->setIntent('Sale')
                ->setPayer($payer)
                ->setRedirectUrls($redirect_urls)
                ->setTransactions(array($transaction));
                /** dd($payment->create($this->_api_context));exit; **/
            try {
                $payment->create($this->_api_context);
            } catch (\PayPal\Exception\PPConnectionException $ex) {
                if (\Config::get('app.debug')) {
                    \Session::put('error','Connection timeout');
                    return Redirect::route('addmoney.paywithpaypal');
                    /** echo "Exception: " . $ex->getMessage() . PHP_EOL; **/
                    /** $err_data = json_decode($ex->getData(), true); **/
                    /** exit; **/
                } else {
                    \Session::put('error','Some error occur, sorry for inconvenient');
                    return Redirect::route('addmoney.paywithpaypal');
                    /** die('Some error occur, sorry for inconvenient'); **/
                }
            }
    
            foreach($payment->getLinks() as $link) {
                if($link->getRel() == 'approval_url') {
                    $redirect_url = $link->getHref();
                    break;
                }
            }
    
            /** add payment ID to session **/
            Session::put('paypal_payment_id', $payment->getId());
    
            if(isset($redirect_url)) {
                /** redirect to paypal **/
                return Redirect::away($redirect_url);
            }
    
            \Session::put('error','Unknown error occurred');
            return Redirect::route('addmoney.paywithpaypal');
        }
    
        public function getPaymentStatus()
        {
            /** Get the payment ID before session clear **/
            $payment_id = Session::get('paypal_payment_id');
            /** clear the session payment ID **/
            Session::forget('paypal_payment_id');
            if (empty(Input::get('PayerID')) || empty(Input::get('token'))) {
                \Session::put('error','Payment failed');
                return Redirect::route('addmoney.paywithpaypal');
            }
            $payment = Payment::get($payment_id, $this->_api_context);
            /** PaymentExecution object includes information necessary **/
            /** to execute a PayPal account payment. **/
            /** The payer_id is added to the request query parameters **/
            /** when the user is redirected from paypal back to your site **/
            $execution = new PaymentExecution();
            $execution->setPayerId(Input::get('PayerID'));
            /**Execute the payment **/
            $result = $payment->execute($execution, $this->_api_context);
            /** dd($result);exit; /** DEBUG RESULT, remove it later **/
            if ($result->getState() == 'approved') { 
    
                /** it's all right **/
                /** Here Write your database logic like that insert record or value in database if you want **/
    
                \Session::put('success','Payment success');
                return Redirect::route('addmoney.paywithpaypal');
            }
            \Session::put('error','Payment failed');
    
            return Redirect::route('addmoney.paywithpaypal');
        }
      }
    

    Step 7: Create View
    In Last step, let's create paywithpaypal.blade.php(resources/views/paywithpaypal.blade.php) for layout and we will write design code here and also form for pay amount by paypal, So put following code: resources/views/paywithpaypal.blade.php

    @extends('layouts.app')
    
    @section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    @if ($message = Session::get('success'))
                    <div class="custom-alerts alert alert-success fade in">
                        <button type="button" class="close" data-dismiss="alert" aria-hidden="true"></button>
                        {!! $message !!}
                    </div>
                    <?php Session::forget('success');?>
                    @endif
    
                    @if ($message = Session::get('error'))
                    <div class="custom-alerts alert alert-danger fade in">
                        <button type="button" class="close" data-dismiss="alert" aria-hidden="true"></button>
                        {!! $message !!}
                    </div>
                    <?php Session::forget('error');?>
                    @endif
                    <div class="panel-heading">Paywith Paypal</div>
                    <div class="panel-body">
                        <form class="form-horizontal" method="POST" id="payment-form" role="form" action="{!! URL::route('addmoney.paypal') !!}" >
                            {{ csrf_field() }}
    
                            <div class="form-group{{ $errors->has('amount') ? ' has-error' : '' }}">
                                <label for="amount" class="col-md-4 control-label">Amount</label>
    
                                <div class="col-md-6">
                                    <input id="amount" type="text" class="form-control" name="amount" value="{{ old('amount') }}" autofocus>
    
                                    @if ($errors->has('amount'))
                                        <span class="help-block">
                                            <strong>{{ $errors->first('amount') }}</strong>
                                        </span>
                                    @endif
                                </div>
                            </div>
    
                            <div class="form-group">
                                <div class="col-md-6 col-md-offset-4">
                                    <button type="submit" class="btn btn-primary">
                                        Paywith Paypal
                                    </button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
    @endsection
    

    Now we are ready to run our example so run bellow command ro quick run:

    php artisan serve
    

    Now you can open below URL on your browser:

    http://localhost:8000/paywithpaypal
    

    please visit this tutorials link...

    https://www.youtube.com/watch?v=ly2xm_NM46g