PayPal Payment Integration using PHP

Intoduction

PayPal provides an easy way to integrate paypal with PHP. If your web application built with CodeIgniter, a library needs to be created for PayPal standard payment gateway integration in CodeIgniter. In this tutorial, we will show you how to integrate PayPal payment gateway in CodeIgniter. Here we will provide the step by step guide on PayPal standard payment gateway integration for CodeIgniter application. Our example code will help you to integrate PayPal payment gateway in CodeIgniter

Don't Miss

In the example CodeIgniter application, the following steps will be followed to integrate PayPal payment gateway in CodeIgniter.

  • Fetch products from the database and list them on the web page.
  • Each product will have a Buy Now button that allows the user to purchase the product.
  • The Buy button redirects the user to the PayPal site for making payment.
  • After the payment on PayPal, the buyer will be redirected back to the website.
  • The payment status with transaction data will be shown to the buyer.
  • The transaction will be validated using PayPal IPN (Instant Payment Notification) service and the payment information will be stored in the database

Create PayPal Sandbox Account

Before making the PayPal payment gateway live, it needs to be tested whether the payment process is working properly. PayPal provides a Sandbox environment to test transaction process before accept payment from the buyers.
To test the PayPal payment gateway, you need to create PayPal sandbox account.

  • Go to the PayPal Developer Portal and Log into the Dashboard using your PayPal account credentials. If you don’t have any PayPal account, sign up for a PayPal account first.
  • In the dashboard, click the Accounts under the Sandbox label from the left side menu panel.

Click the Create Account to create buyer and merchant account. Under the Account type section, select Personal for buyer account or Business for a merchant account.

Create Database Tables

To store product and payment information two tables need to be created in the database.

The following SQL creates a products table with some basic fields in the MySQL database.

CREATE TABLE `products` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `image` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
 `price` float(10,2) NOT NULL,
 `status` enum('1','0') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

The following SQL creates a payments table in the MySQL database to store the transaction information provided by PayPal.

CREATE TABLE `payments` (
 `payment_id` int(11) NOT NULL AUTO_INCREMENT,
 `user_id` int(11) NOT NULL,
 `product_id` int(11) NOT NULL,
 `txn_id` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `payment_gross` float(10,2) NOT NULL,
 `currency_code` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
 `payer_email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `payment_status` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (`payment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Config

paypal.php:
The configuration variables of the PayPal library are defined in this file. Specify the PayPal environment, business email, and currency code

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

// ------------------------------------------------------------------------
// Paypal library configuration
// ------------------------------------------------------------------------

// PayPal environment, Sandbox or Live
$config['sandbox'] = TRUE; // FALSE for live environment

// PayPal business email
$config['business'] = 'Your_PayPal_Email';

// What is the default currency?
$config['paypal_lib_currency_code'] = 'USD';

// Where is the button located at?
$config['paypal_lib_button_path'] = 'assets/images/';

// If (and where) to log ipn response in a file
$config['paypal_lib_ipn_log'] = TRUE;
$config['paypal_lib_ipn_log_file'] = BASEPATH . 'logs/paypal_ipn.log';

Library

Paypal_lib.php:
The Paypal CodeIgniter Library helps to integrate PayPal payment gateway in CodeIgniter 3 application. This library has a dependency of a configuration file called paypal.php. Place the Paypal_lib.php file in the application/libraries/ directory and paypal.php file in the application/config/ directory.

It used to

  • Generate the PayPal form and submit the form to PayPal.
  • Validate IPN response using cURL in PHP.
  • Log the IPN response data in a file.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * PayPal Library for CodeIgniter 3.x
 *
 * Library for PayPal payment gateway. It helps to integrate PayPal payment gateway
 * in the CodeIgniter application.
 *
 * It requires PayPal configuration file and it should be placed in the config directory.
 *
 * @package     CodeIgniter
 * @category    Libraries
 * @author      Abhishek Awasthi
 * @license     
 * @link        
 */

class Paypal_lib{

    var $last_error;
    var $ipn_log;
    var $ipn_log_file;
    var $ipn_response;    
    var $ipn_data = array();
    var $fields = array();
    var $submit_btn = '';
    var $button_path = '';
    var $CI;
    
    function __construct(){
        $this->CI =& get_instance();
        $this->CI->load->helper('url');
        $this->CI->load->helper('form');
        $this->CI->load->config('paypal');
        
        $sanbox = $this->CI->config->item('sandbox');
        $this->paypal_url = ($sanbox == TRUE)?'https://www.sandbox.paypal.com/cgi-bin/webscr':'https://www.paypal.com/cgi-bin/webscr';
                
        $this->last_error = '';
        $this->ipn_response = '';

        $this->ipn_log_file = $this->CI->config->item('paypal_lib_ipn_log_file');
        $this->ipn_log = $this->CI->config->item('paypal_lib_ipn_log'); 
        
        $this->button_path = $this->CI->config->item('paypal_lib_button_path');
        
        // populate $fields array with a few default values.
        $businessEmail = $this->CI->config->item('business');
        $this->add_field('business',$businessEmail);
        $this->add_field('rm','2');
        $this->add_field('cmd','_xclick');

        $this->add_field('currency_code', $this->CI->config->item('paypal_lib_currency_code'));
        $this->add_field('quantity', '1');
        $this->button('Pay Now!');
    }

    function button($value){
        // changes the default caption of the submit button
        $this->submit_btn = form_submit('pp_submit', $value);
    }

    function image($file){
        $this->submit_btn = '<input type="image" name="add" src="'.base_url(rtrim($this->button_path, '/').'/'. $file).'" border="0" />';
    }

    function add_field($field, $value){
        // adds a key=>value pair to the fields array
        $this->fields[$field] = $value;
    }

    function paypal_auto_form(){
        // form with hidden elements which is submitted to paypal
        $this->button('Click here if you\'re not automatically redirected...');

        echo '<html>' . "\n";
        echo '<head><title>Processing Payment...</title></head>' . "\n";
        echo '<body style="text-align:center;" onLoad="document.forms[\'paypal_auto_form\'].submit();">' . "\n";
        echo '<p style="text-align:center;">Please wait, your order is being processed and you will be redirected to the paypal website.</p>' . "\n";
        echo $this->paypal_form('paypal_auto_form');
        echo '</body></html>';
    }

    function paypal_form($form_name='paypal_form'){
        $str = '';
        $str .= '<form method="post" action="'.$this->paypal_url.'" name="'.$form_name.'"/>' . "\n";
        foreach ($this->fields as $name => $value)
            $str .= form_hidden($name, $value) . "\n";
        $str .= '<p>'. $this->submit_btn . '</p>';
        $str .= form_close() . "\n";

        return $str;
    }
    
    function validate_ipn($paypalReturn){
        $ipn_response = $this->curlPost($this->paypal_url, $paypalReturn);
        
        if(preg_match("/VERIFIED/i", $ipn_response)){
            // Valid IPN transaction.
            return true;
        }else{
            // Invalid IPN transaction.  Check the log for details.
            $this->last_error = 'IPN Validation Failed.';
            $this->log_ipn_results(false);    
            return false;
        }
    }

    function log_ipn_results($success){
        if (!$this->ipn_log) return;  // is logging turned off?

        // Timestamp
        $text = '['.date('m/d/Y g:i A').'] - '; 

        // Success or failure being logged?
        if ($success) $text .= "SUCCESS!\n";
        else $text .= 'FAIL: '.$this->last_error."\n";

        // Log the POST variables
        $text .= "IPN POST Vars from Paypal:\n";
        foreach ($this->ipn_data as $key=>$value)
            $text .= "$key=$value, ";

        // Log the response from the paypal server
        $text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response;

        // Write to log
        $fp=fopen($this->ipn_log_file,'a');
        fwrite($fp, $text . "\n\n"); 

        fclose($fp);  // close file
    }

    function dump(){
        // Used for debugging, this function will output all the field/value pairs
        ksort($this->fields);
        echo '<h2>ppal->dump() Output:</h2>' . "\n";
        echo '<code style="font: 12px Monaco, \'Courier New\', Verdana, Sans-serif;  background: #f9f9f9; border: 1px solid #D0D0D0; color: #002166; display: block; margin: 14px 0; padding: 12px 10px;">' . "\n";
        foreach ($this->fields as $key => $value) echo '<strong>'. $key .'</strong>:    '. urldecode($value) .'<br/>';
        echo "</code>\n";
    }
    
    function curlPost($paypal_url, $paypal_return_arr){
        $req = 'cmd=_notify-validate';
        foreach($paypal_return_arr as $key => $value){
            $value = urlencode(stripslashes($value));
            $req .= "&$key=$value";
        }
            
        $ipn_site_url = $paypal_url;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $ipn_site_url);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
        $result = curl_exec($ch);
        curl_close($ch);
    
        return $result;
    }

}

Controller

We’ll create two controllers, Products and Paypal to handle the product listing and payment process.

Products (Products.php):
The Products controller contains 3 functions, __construct(), index() and buy().

  • __construct() – Loads the PayPal library and Product model.
  • index() –
    • Retrieve the products data from the database using getRows() function of the Product model.
    • Pass data to the view and load the view file to list the products.
  • buy() –
    • Fetch the product data from the database based on the requested product ID.
    • Generate the PayPal form with HTML variables using the PayPal library.
    • Render PayPal form and redirect buyer to the PayPal site for payment.
<?php defined('BASEPATH') OR exit('No direct script access allowed');

class Products extends CI_Controller{
    
    function  __construct(){
        parent::__construct();
        
        // Load paypal library & product model
        $this->load->library('paypal_lib');
        $this->load->model('product');
    }
    
    function index(){
        $data = array();
        
        // Get products data from the database
        $data['products'] = $this->product->getRows();
        
        // Pass products data to the view
        $this->load->view('products/index', $data);
    }
    
    function buy($id){
        // Set variables for paypal form
        $returnURL = base_url().'paypal/success';
        $cancelURL = base_url().'paypal/cancel';
        $notifyURL = base_url().'paypal/ipn';
        
        // Get product data from the database
        $product = $this->product->getRows($id);
        
        // Get current user ID from the session
        $userID = $_SESSION['userID'];
        
        // Add fields to paypal form
        $this->paypal_lib->add_field('return', $returnURL);
        $this->paypal_lib->add_field('cancel_return', $cancelURL);
        $this->paypal_lib->add_field('notify_url', $notifyURL);
        $this->paypal_lib->add_field('item_name', $product['name']);
        $this->paypal_lib->add_field('custom', $userID);
        $this->paypal_lib->add_field('item_number',  $product['id']);
        $this->paypal_lib->add_field('amount',  $product['price']);
        
        // Render paypal form
        $this->paypal_lib->paypal_auto_form();
    }
}

Paypal (Paypal.php):
The Paypal controller contains 4 functions, __construct(), success(), cancel(), and ipn().

  • __construct() – Loads the PayPal library and Product model.
  • success() – Get the transaction data from the URL and show the payment success to the buyer.
  • cancel() – Show the payment failed notification to the user.
  • ipn() – This method is called by the PayPal IPN (Instant Payment Notification).
    • Validate the transaction using validate_ipn() method of PayPal library.
    • Insert the payment information in the database using insertTransaction() function of Product model.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Paypal extends CI_Controller{
    
     function  __construct(){
        parent::__construct();
        
        // Load paypal library & product model
        $this->load->library('paypal_lib');
        $this->load->model('product');
     }
     
    function success(){
        // Get the transaction data
        $paypalInfo = $this->input->get();

        $data['item_name']      = $paypalInfo['item_name'];
        $data['item_number']    = $paypalInfo['item_number'];
        $data['txn_id']         = $paypalInfo["tx"];
        $data['payment_amt']    = $paypalInfo["amt"];
        $data['currency_code']  = $paypalInfo["cc"];
        $data['status']         = $paypalInfo["st"];
        
        // Pass the transaction data to view
        $this->load->view('paypal/success', $data);
    }
     
     function cancel(){
        // Load payment failed view
        $this->load->view('paypal/cancel');
     }
     
     function ipn(){
        // Paypal posts the transaction data
        $paypalInfo = $this->input->post();
        
        if(!empty($paypalInfo)){
            // Validate and get the ipn response
            $ipnCheck = $this->paypal_lib->validate_ipn($paypalInfo);

            // Check whether the transaction is valid
            if($ipnCheck){
                // Insert the transaction data in the database
                $data['user_id']        = $paypalInfo["custom"];
                $data['product_id']        = $paypalInfo["item_number"];
                $data['txn_id']            = $paypalInfo["txn_id"];
                $data['payment_gross']    = $paypalInfo["mc_gross"];
                $data['currency_code']    = $paypalInfo["mc_currency"];
                $data['payer_email']    = $paypalInfo["payer_email"];
                $data['payment_status'] = $paypalInfo["payment_status"];

                $this->product->insertTransaction($data);
            }
        }
    }
}

Setup PayPal Instant Payment Notification (IPN):
The ipn() function of the Paypal controller verifies each transaction and inserts the payment data into the database. The PayPal IPN must be enabled in PayPal business account to make the IPN working. You need to specify the IPN URL (http://www.example.com/paypal/ipn/) in the Notification URL field where the PayPal will send the IPN messages.

Follow this step-by-step guide to enable IPN in PayPal – How to enable PayPal Instant Payment Notification

Note that: The transaction data will not be inserted in the database without PayPal IPN setup.

Model (Product.php)

The Product model contains 3 functions, __construct()getRows() and insertTransaction().

  • __construct() – Defines the database table names.
  • getRows() – Fetch the records from the products table and returns as an array.
  • insertTransaction() – Insert the transaction data in the payments table.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Product extends CI_Model{
    
    function __construct() {
        $this->proTable   = 'products';
        $this->transTable = 'payments';
    }
    
    /*
     * Fetch products data from the database
     * @param id returns a single record if specified, otherwise all records
     */
    public function getRows($id = ''){
        $this->db->select('*');
        $this->db->from($this->proTable);
        $this->db->where('status', '1');
        if($id){
            $this->db->where('id', $id);
            $query  = $this->db->get();
            $result = $query->row_array();
        }else{
            $this->db->order_by('name', 'asc');
            $query  = $this->db->get();
            $result = $query->result_array();
        }
        
        // return fetched data
        return !empty($result)?$result:false;
    }
    
    /*
     * Insert data in the database
     * @param data array
     */
    public function insertTransaction($data){
        $insert = $this->db->insert($this->transTable,$data);
        return $insert?true:false;
    }
    
}

View

Two view directory will be created, products and paypal. The products/ directory holds the view files of the Products controller and paypal/ directory holds the view files of Paypal controller.
products/index.php:
All the products are fetched from the database and listed with the buy button.

<div class="col-lg-12">
<!-- List all products -->
<?php if(!empty($products)){ foreach($products as $row){ ?>
    <div class="col-sm-4 col-lg-4 col-md-4">
        <div class="thumbnail">
            <img src="<?php echo base_url('assets/images/'.$row['image']); ?>" />
            <div class="caption">
                <h4 class="pull-right">$<?php echo $row['price']; ?> USD</h4>
                <h4><a href="javascript:void(0);"><?php echo $row['name']; ?></a></h4>
         
            </div>
            <div class="ratings">
                <a href="<?php echo base_url('products/buy/'.$row['id']); ?>">
                    <img src="<?php echo base_url('assets/images/x-click-but01.gif'); ?>" />
                </a>
                <p class="pull-right">15 reviews</p>
                <p>
                    <span class="glyphicon glyphicon-star"></span>
                    <span class="glyphicon glyphicon-star"></span>
                    <span class="glyphicon glyphicon-star"></span>
                    <span class="glyphicon glyphicon-star"></span>
                    <span class="glyphicon glyphicon-star"></span>
                </p>
            </div>
        </div>
    </div>
<?php } }else{ ?>
    <p>Product(s) not found...</p>
<?php } ?>
</div>

paypal/success.php:
After the payment on PayPal, the success notification and transaction data are displayed.

<div class="col-lg-12">
    <h4 class="success">Thank you! Your payment was successful.</h4>
    <p>Item Name : <span><?php echo $item_name; ?></span></p>
    <p>Item Number : <span><?php echo $item_number; ?></span></p>
    <p>TXN ID : <span><?php echo $txn_id; ?></span></p>
    <p>Amount Paid : <span>$<?php echo $payment_amt.' '.$currency_code; ?></span></p>
    <p>Payment Status : <span><?php echo $status; ?></span></p>
    
    <a href="<?php echo base_url('products'); ?>">Back to Products</a>
</div>

paypal/cancel.php:
If the user cancels the payment or transaction failed, the notification is displayed.

<div class="col-lg-12">
    <h4 class="error">We are sorry! Your transaction was canceled.</h4>
    
    <a href="<?php echo base_url('products'); ?>">Back to Products</a>
</div>

Test PayPal Transaction

  • Open the Products controller URL (http://example.com/application_folder/products) on the browser.
  • The products will be listed with the Buy button.
  • Click on the Buy button. You will be redirected to the PayPal site for the payment.
  • Log into the PayPal with your Sandbox personal account and complete the payment.
  • On payment success, you will be redirected back to the website’s payment success page and the transaction details will be shown.

Make PayPal Payment Gateway Live

When your application payment flow testing is completed with sandbox account, do the following modification to make the PayPal payment gateway live.
Open the application/config/paypal.php file, specify the PayPal environment and business email.

  • Set sandbox to FALSE for live environment.$config[‘sandbox’] = FALSE;
  • Specify your live PayPal business email.$config[‘business’] = ‘live_paypal@email.com’;

LEAVE A REPLY

Please enter your comment!
Please enter your name here

564FansLike

Recent Posts

Concept of Session in Laravel Tutorial

Sessions are used to store details about the user throughout the requests. Laravel supplies various drivers like file, cookie, apc, array, Memcached, Redis, and database to handle session data. By default, file driver is used as a result of it's light-weight....

Laravel Url Generation Tutorial

Our web application revolves around routes and URLs. After all, they're what direct our users to our pages. At the end of the day, serving pages is what any web application should do. Our users may...

Concept of Laravel Views Tutorial

In MVC framework, the letter "V" stands for Views. It separates the application logic and presentation logic. Views are saved in resources/views listing. Generally, the view contains the HTML which might be served by the application.

Related Articles

Concept of Session in Laravel Tutorial

Sessions are used to store details about the user throughout the requests. Laravel supplies various drivers like file, cookie, apc, array, Memcached, Redis, and database to handle session data. By default, file driver is used as a result of it's light-weight....

Laravel Url Generation Tutorial

Our web application revolves around routes and URLs. After all, they're what direct our users to our pages. At the end of the day, serving pages is what any web application should do. Our users may...

Concept of Laravel Views Tutorial

In MVC framework, the letter "V" stands for Views. It separates the application logic and presentation logic. Views are saved in resources/views listing. Generally, the view contains the HTML which might be served by the application.
WP2Social Auto Publish Powered By : XYZScripts.com