YouTube Icon

Code Playground.

How to Implement PayPal Payment Gateway in CodeIgniter

CFG

How to Implement PayPal Payment Gateway in CodeIgniter

These days the payment gateway is gigantically utilized for the web based business and online specialist organizations. It assists with tolerating payment online in the web application. Before incorporating an payment door into the site, you have to pick the best payment passage specialist co-op to acknowledge online payment with no interference. PayPal is one of the world's most well known web payment arrangement. In the event that you need to acknowledge payment comprehensively on your site, PayPal is the best decision for coordinating the payment passage in your web venture. 

PayPal gives a simple way to integrate standard payment gateway in PHP. On the off chance that your web application worked with CodeIgniter, a library should be made for PayPal standard payment passage coordination in CodeIgniter. Right now, will give you how to integrate PayPal payment entryway in CodeIgniter. Here we will give the bit by bit manage on PayPal standard payment passage mix for CodeIgniter application. Our model code will assist you with integrating PayPal payment passage in CodeIgniter.

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 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');

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() – 
  • Recover the items information from the database utilizing getRows() capacity of the Product model. 
  • Pass information to the view and burden the view document to list the items. 
  • buy() – 
  • Bring the item information from the database dependent on the mentioned item ID. 
  • Create the PayPal structure with HTML factors utilizing the PayPal library. 
  • Render PayPal frame and divert purchaser to the PayPal site for installment.
<?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 confirms every exchange and embeds the installment information into the database. The PayPal IPN must be empowered in PayPal business record to make the IPN working. You have to determine the IPN URL (http://www.example.com/paypal/ipn/) in the Notification URL field where the PayPal will send the IPN messages. 

Follow this bit by bit manual for empower IPN in PayPal –  How to empower PayPal Instant Payment Notification 

Note that: The exchange information won't be embedded in the database without PayPal IPN arrangement.

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';
    }
    
    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;
    }

    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/items) on the program. 
  • The items will be recorded with the Buy button. 
  • Snap on the Buy button. You will be diverted to the PayPal site for the installment. 
  • Sign into the PayPal with your Sandbox individual record and complete the installment. 
  • On installment achievement, you will be diverted back to the site's installment achievement page and the exchange subtleties will be appeared.

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';

You are done! Now you can accept payment online from the buyers with PayPal account.




CFG