Skip to main content

CakePHP Paypal payment gateway Integration



How to Integrate Paypal Payment Gateway with Cakephp

How to integrate paypal with CakePHP





Cakephp 3 is a PHP framework that is the most popular for rapid application development and Paypal is the most popular payment gateway. So today we will learn how to integrate Paypal with CakePHP.


For this tutorial, I am using CakePHP 4 which is the latest version of CakePHP but steps will be the same for CakePHP 3x.


So Keep following the below steps.


First, we will create a sandbox account to test our payment gateway later and we need to create both accounts personal and business so we can test, so if you have already created that then skip this step, and if you want to create a new sandbox test account then click here.


Also, we need client id and secret that we can get by creating an app in the PayPal developer account.


Go to the developer website and click on My Apps & Credentials then click on Create App Button

cakephp 4 paypal integration



Then fill the App name and select a business account that we have recently created, like the below screenshot, and then click on Create App button.




And after submit it will show you both, client Id and secret Key like the below screenshot.

Cakephp 4 PayPal payment integration



Ok so now we need to install PHP SDK in our CakePHP Application so open command prompt or Terminal in your root folder .  and run below command:

composer require "paypal/rest-api-sdk-php:*"


thecoderain-cakephp-paypal-payment-gateway-integration

The above command will install the latest REST API PHP SDK of PayPal.



Now open config/bootstrap.php and add below code at the bottom of the file and replace details with your account details

$aSetting = [];
$aSetting['PAYPAL_clientId'] = 'YOUR_CLIENT_ID';
$aSetting['PAYPAL_secret'] = 'YOUR_SECRET_KEY';
$aSetting['PAYPAL_mode'] = 'sandbox';


Configure::write('Site', $aSetting);





Now we will create a controller that will handle all payment actions. You can create a controller by two methods, manually and with the command line, I prefer to create controller, action, modal always with the command line. so to create a controller with the command line, run below command in your project root directory:

bin\cake bake controller Payments

Now after this command CakePHP will create a controller and now create an index.php file in ROOT/templates/Payments/index.php, please note that this is for CakePHP 4 version, if you are using CakePHP 3 then create the file as ROOT/src/templates/Payments/index.ctp

Now paste below form code in it

<?= $this->Form->create(null,['class'=>'cls-form']) ?>
  <h2 class="w3-text-blue">Payment CakePHP Form</h2>
    
  <label class="w3-text-blue"><b>Enter Amount</b></label>
  <?= $this->Form->control('amount',['class'=>'form-control','value'=>100]) ?>    
  <button class="btn btn-primary">Pay with PayPal</button></p>

<?= $this->Form->end() ?>


Now we will create two actions in our Payments controller, index() and status()

index(), in the index we will get a price on the form to submit and then will redirect on payment gateway and status() action we will use to handle the response from PayPal payment gateway.

Copy below code and replace with your controller code (src/Controller/PaymentsController.php)
<?php
declare(strict_types=1);

namespace App\Controller;

use Cake\Routing\Router;
use Cake\Event\Event;
use Cake\Event\EventInterface;
use Cake\Core\Configure;

use PayPal\Api\Payer;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction;

/**
 * Payments Controller
 *
 *
 * @method \App\Model\Entity\Payment[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
 */
class PaymentsController extends AppController
{

    public function beforeFilter(EventInterface $event) {
        parent::beforeFilter($event);
        $this->Auth->allow();
        $this->viewBuilder()->setLayout('user-layout');
    }
    /**
     * Index method
     *
     * @return \Cake\Http\Response|null
     */
    public function index()
    {
        if($this->request->is('post')) {
          $clientId =  Configure::read('Site.PAYPAL_clientId');
          $secret =  Configure::read('Site.PAYPAL_secret');
          $apiContext = new \PayPal\Rest\ApiContext(
             new \PayPal\Auth\OAuthTokenCredential(
             $clientId,  // you will get information about client id and secret once you have created test account in paypal sandbox  
             $secret 
            )
          );

        $price = $this->request->getData('amount');
        $payer = new Payer();
        $payer->setPaymentMethod('paypal');

        $item_1 = new Item();
        $item_1->setName('Membership Plan') /** item name **/
            ->setCurrency('USD')
            ->setQuantity(1)
            ->setPrice($price); /** unit price **/
        $item_list = new ItemList();
        $item_list->setItems(array($item_1));
        $amount = new \PayPal\Api\Amount();
        $amount->setCurrency('USD')
            ->setTotal($price);
        $transaction = new \PayPal\Api\Transaction();
        $transaction->setAmount($amount)
            ->setItemList($item_list)
            ->setDescription('My Membership');
        $redirect_urls = new \PayPal\Api\RedirectUrls();
        $redirect_urls->setReturnUrl(Router::url(['controller' => 'Payments', 'action' => 'status'], true)) /** Specify return URL **/
            ->setCancelUrl(Router::url(['controller' => 'Payments', 'action' => 'status'], true));
        $payment = new \PayPal\Api\Payment();
        $payment->setIntent('Sale')
            ->setPayer($payer)
            ->setRedirectUrls($redirect_urls)
            ->setTransactions(array($transaction));
        /** dd($payment->create($this->_api_context));exit; **/
        try {
            $payment->create($apiContext);
        } catch (\PayPal\Exception\PPConnectionException $ex) {
            $this->Flash->error('Something went wrong! Please try again.');
            return $this->redirect(['action'=>'index']);
            
        }
        foreach ($payment->getLinks() as $link) {
            if ($link->getRel() == 'approval_url') {
                $redirect = $link->getHref();
                break;
            }
        }
        $this->getRequest()->getSession()->write('paypalPaymentId',$payment->getId());
       
        if (isset($redirect)) {
            return $this->redirect($redirect);
        }
         $this->Flash->error('Something went wrong! Please try again.');
         return $this->redirect(['action'=>'index']);

        }

    }

    public function status()
    {
        $clientId =  Configure::read('Site.PAYPAL_clientId');
          $secret =  Configure::read('Site.PAYPAL_secret');
          $apiContext = new \PayPal\Rest\ApiContext(
             new \PayPal\Auth\OAuthTokenCredential(
             $clientId,  
             $secret 
            )
          );

        $paymentSessionId = $this->getRequest()->getSession()->read('paypalPaymentId');
                   
        //$this->getRequest()->getSession()->delete('paypalPaymentId');
        $getPayeerId = $this->request->getQuery('PayerID');
        $token = $this->request->getQuery('token');

      
        if (empty($getPayeerId) || empty($token)) {
            $this->Flash->error('Something went wrong! Please try again.');
            return $this->redirect(['action'=>'index']);
        }
        $payment = Payment::get($paymentSessionId, $apiContext);
        $execution = new \PayPal\Api\PaymentExecution();
        $execution->setPayerId($getPayeerId);

        try { 
            $result = $payment->execute($execution, $apiContext);
        }  catch (PayPal\Exception\PPConnectionException $ex) {
            //echo '<pre>';print_r(json_decode($ex->getData()));exit;
           
        }
          
        // echo '<pre>'; print_r($result); echo '</pre>';
              
        if($result->getState() == 'approved') {
          $this->Flash->success('Payment Successfull.');
          return $this->redirect(['action'=>'index']);
        }
         $this->Flash->error('Payment failed.');
         return $this->redirect(['action'=>'index']);
    }

} 
 

Code explanation:
we are submitting the form and getting the price and then we are adding details that is required for gateway request and then we are saving Payment ID in a session so we can get after success and can fetch results by using that Payment ID and then we are redirecting to gateway page.

status()
In status(), we are getting payer ID by using getQuery() and also getting session payment ID that we have saved in session in the index(). Now then we are passing both values in PayPal API and getting a response and then we matching getState() output is equal to approved or not, if it's matched then its transaction is successful and if it's not matched then its failed, you can check all other values by printing $result variable after a try-catch function.


And now you can test it with your sandbox account and later you can off sandbox mode and then it will work for a real account too. Thanks


Important Links


CakePHP 4 Paypal Integration

CakePHP 3 paypal payment gateway

CakePHP tutorials

CakePHP PayPal tutorial

PHP: How to use PayPal API




Comments

  1. This comment has been removed by a blog administrator.

    ReplyDelete

Post a Comment

Popular posts from this blog

Run and compile sass scss file to css using node

  Today we learn how to use scss and generate css using node  or Run and compile sass scss file to css using node   So please follow simple  steps :-   Today we will create a project that can read scss file and generates css with it  Note: Make sure you have installed node in your system. If you want to help to install node js based on your system then check our other tutorial or check node js official website. Now create a blank folder and open  terminal(linux) or cmd(windows) and navigate to your current project folder by using cd command Now run below command npm init after enter it will ask you some package info that you can fill according to you or just keep enter until it finished. The above command will generate package.json file Now  we will install npm module that will convert our scss to css Run below command: npm install node-sass So we have installed node-sass package . Now open package.json file in your editor and add below code into it into

How to retrieve Facebook Likes, share , comment Counts

function facebook_count($url){     // Query in FQL     $fql  = "SELECT share_count, like_count, comment_count ";     $fql .= " FROM link_stat WHERE url = '$url'";     $fqlURL = "https://api.facebook.com/method/fql.query?format=json&query=" . urlencode($fql);     // Facebook Response is in JSON     $response = file_get_contents($fqlURL);     return json_decode($response); } $fb = facebook_count('https://www.facebook.com/BahutHoGyiPadhai'); // facebook share count echo $fb[0]->share_count;  echo "like"; // facebook like count echo $fb[0]->like_count ; echo "comment"; // facebook comment count echo $fb[0]->comment_count;  ?>

jQuery Datatable add date range filter

jQuery Datatable add date range filter Datatable is most useful jQuery plugin that helps to make our html tables more powerful and give powers to user to filter , search, sort, pagination etc, But Data table provides a common filter only and yes we can customize and add filter for each column, but still sometimes we need an advance filter like show results only between a date range, So today we will learn how to create a minimum and maximum date range fields and show date picker on it, and user can fill dates by selecting dates and data table will auto filter records based on it. Keep follow below steps :- I am using Bootstrap if you want to use any other framework then you can use. Create a new index.php file  and paste below code in it, i have used all required CDN like bootstrap, datatable, datepicker etc. <!DOCTYPE html> <html> <head>     <title>Datatable Date Range Filter Example</title>     <link rel="stylesheet" href="https://maxcd