PayPal Payment Gateway Integration in CodeIgniter

PayPal Payment Gateway Integration in CodeIgniter. Nowadays, many online businesses and service providers use payment gateways to accept payments online. A payment gateway is a tool that allows you to accept payments on your website. Before you integrate a payment gateway into your website, you need to choose the best service provider to ensure that your customers can make payments without any issues.

PayPal is a popular payment gateway that is widely used around the world. It is a great choice if you want to accept payments globally on your website. Integrating PayPal into your website is easy, especially if your website is built with CodeIgniter, a popular PHP framework.

In this tutorial, we will show you how to integrate PayPal into your CodeIgniter website. We will provide a step-by-step guide on how to integrate PayPal’s standard payment gateway. Our example code will help you to integrate PayPal into your CodeIgniter website.

Our example script will do the following things:

  • Fetch products from your database and list them on your website.
  • Each product will have a “Pay with PayPal” button that allows your customers to purchase the product.
  • When a customer clicks the “Buy” button, they will be redirected to the PayPal site to make the payment.
  • After the payment is made on PayPal, the customer will be redirected back to your website.
  • The payment information will be stored in your database, and the transaction details and payment status will be shown to the customer.

Integrating PayPal into your CodeIgniter website is a great way to offer your customers a secure and reliable payment method. With our step-by-step guide and example code, you can easily integrate PayPal into your website and start accepting payments online.

PayPal Payment Gateway Integration in CodeIgniter

Create PayPal Sandbox Account

Before you can start using the PayPal payment gateway for real transactions, it’s important to make sure everything works correctly. PayPal offers a testing environment called the Sandbox where you can try out the payment process before accepting payments from customers.

To test the PayPal payment gateway, you’ll need to create a PayPal Sandbox account. Here’s how you can do it:

  1. Go to the PayPal Developer Portal.
  2. Log into the Dashboard using your PayPal account details. If you don’t have a PayPal account, sign up for one first.
How to Integrate Paypal Payment Gateway in Codeigniter Torque Programming
  • 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.
PayPal Payment Gateway Integration in CodeIgniter Torque Programming
PayPal Payment Gateway Integration in CodeIgniter

Before getting started to integrate PayPal payment gateway in CodeIgniter, take a look at the file structure.

codeigniter_paypal_integration/
├── application/
│   ├── config/
│   │   └── paypal.php
│   ├── controllers/
│   │   ├── Products.php
│   │   └── Paypal.php
│   ├── libraries/
│   │   └── Paypal_lib.php
│   ├── models/
│   │   ├── Product.php
│   │   └── Payment.php
│   ├── views/
│   │   ├── products/
│   │   │   └── index.php
│   │   └── paypal/
│   │       ├── success.php
│   │       └── cancel.php
└── assets/
    └── css/
        ├── bootstrap.min.css
        └── style.css

Create Database Tables

To store product and payment information two tables are required 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,
 `currency` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'USD',
 `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` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `product_id` int(11) NOT NULL,
 `user_id` int(11) DEFAULT 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_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 `payer_email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `status` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Config

In this file, you can set up some important things for the PayPal library. These are called configuration variables. You can tell the library which environment to use (sandbox), what email to use for your business (business), and what currency code to use (paypal_lib_currency_code).

<?php  defined('BASEPATH') OR exit('No direct script access allowed'); 
 
/* 
| ------------------------------------------------------------------- 
|  PayPal API Configuration 
| ------------------------------------------------------------------- 
| 
| You will get the API keys from Developers panel of the PayPal account 
| Login to PayPal account (https://developer.paypal.com/) 
| and navigate to the SANDBOX » Accounts page 
| Remember to switch to your live business email in production! 
| 
|  sandbox                    boolean  PayPal environment, TRUE for Sandbox and FALSE for live 
|  business                    string   PayPal business email 
|  paypal_lib_currency_code string   Currency code. 
*/ 
 
$config['sandbox'] = TRUE; // FALSE for live environment 
 
$config['business'] = 'test@business.com'; 
 
$config['paypal_lib_currency_code'] = 'USD'; 
 
// Where is the button located at? (optional) 
$config['paypal_lib_button_path'] = 'assets/images/'; 
 
// If (and where) to log ipn response in a file 
$config['paypal_lib_ipn_log'] = FALSE; 
$config['paypal_lib_ipn_log_file'] = BASEPATH . 'logs/paypal_ipn.log';

Library

PayPal (libraries/Paypal_lib.php)
The Paypal CodeIgniter Library helps to integrate PayPal payment gateway in CodeIgniter 3 application. This library (application/libraries/Paypal_lib.php) has a dependency on a configuration file (application/config/paypal.php).

  • __construct() – Load required helpers, set configure variables and initiate the Paypal_lib class.
  • button() – Set value of the PayPal form submit button.
  • image() – Set image to the PayPal form submit button.
  • add_field() – Add field to PayPal form.
  • paypal_auto_form() – Generate an entire HTML page consisting of a form with hidden elements which is submitted to paypal via the BODY element’s onLoad attribute.
  • paypal_form() – Build PayPal form.
  • validate_ipn() – Validate PayPal IPN request.
<?php defined('BASEPATH') OR 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      TorqueProgrammer 
 * @license     http://www.torqueprogramming.co.in/license/ 
 * @link        http://www.torqueprogramming.co.in 
 * @version     2.0 
 */ 
 
class Paypal_lib 
{ 
 
    var $last_error;            // holds the last error encountered 
    var $ipn_log;                // bool: log IPN results to text file? 
 
    var $ipn_log_file;            // filename of the IPN log 
    var $ipn_response;            // holds the IPN response from paypal     
    var $ipn_data = array();    // array contains the POST values for IPN 
    var $fields = array();        // array holds the fields to submit to paypal 
 
    var $submit_btn = '';        // Image/Form button 
    var $button_path = '';        // The path of the buttons 
     
    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. 
        // values can be overwritten by the calling script. 
        $businessEmail = $this->CI->config->item('business'); 
        $this->add_field('business',$businessEmail); 
        $this->add_field('rm','2');    // Return method = POST 
        $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, which is what will be  
        // sent to paypal as POST variables.  If the value is already in the  
        // array, it will be overwritten. 
        $this->fields[$field] = $value; 
    } 
 
    function paypal_auto_form(){ 
        // this function actually generates an entire HTML page consisting of 
        // a form with hidden elements which is submitted to paypal via the  
        // BODY element's onLoad attribute. 
        $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 
        // that are currently defined in the instance of the class using the 
        // add_field() function. 
        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 will be using two controllers, Products and Paypal, to manage the products and payments on our website.

1. Products (controllers/Products.php):

The Products controller handles the product listing and payment request submission process.

<?php defined('BASEPATH') OR exit('No direct script access allowed'); 
 
class Products extends CI_Controller{ 
     
    function  __construct(){ 
        parent::__construct(); 
         
        // Load paypal library 
        $this->load->library('paypal_lib'); 
         
        // Load product model 
        $this->load->model('product'); 
    } 
     
    function index(){ 
        $data = array(); 
         
        // Get products from the database 
        $data['products'] = $this->product->getRows(); 
         
        // Pass product data to the view 
        $this->load->view('products/index', $data); 
    } 
     
    function buy($id){ 
        // Set variables for paypal form 
        $returnURL = base_url().'paypal/success'; //payment success url 
        $cancelURL = base_url().'paypal/cancel'; //payment cancel url 
        $notifyURL = base_url().'paypal/ipn'; //ipn url 
         
        // Get product data from the database 
        $product = $this->product->getRows($id); 
         
        // Get current user ID from the session (optional) 
        $userID = !empty($_SESSION['userID'])?$_SESSION['userID']:1; 
         
        // 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(); 
    } 
}

2. Paypal (controllers/Paypal.php):

The Paypal controller handles the transaction and the IPN validation process.

<?php defined('BASEPATH') OR exit('No direct script access allowed'); 
 
class Paypal extends CI_Controller{ 
     
     function  __construct(){ 
        parent::__construct(); 
         
        // Load paypal library 
        $this->load->library('paypal_lib'); 
         
        // Load product model 
        $this->load->model('product'); 
         
        // Load payment model 
        $this->load->model('payment'); 
     } 
      
    function success(){ 
        // Get the transaction data 
        $paypalInfo = $this->input->get(); 
         
        $productData = $paymentData = array(); 
        if(!empty($paypalInfo['item_number']) && !empty($paypalInfo['tx']) && !empty($paypalInfo['amt']) && !empty($paypalInfo['cc']) && !empty($paypalInfo['st'])){ 
            $item_name = $paypalInfo['item_name']; 
            $item_number = $paypalInfo['item_number']; 
            $txn_id = $paypalInfo["tx"]; 
            $payment_amt = $paypalInfo["amt"]; 
            $currency_code = $paypalInfo["cc"]; 
            $status = $paypalInfo["st"]; 
             
            // Get product info from the database 
            $productData = $this->product->getRows($item_number); 
             
            // Check if transaction data exists with the same TXN ID 
            $paymentData = $this->payment->getPayment(array('txn_id' => $txn_id)); 
        } 
         
        // Pass the transaction data to view 
        $data['product'] = $productData; 
        $data['payment'] = $paymentData; 
        $this->load->view('paypal/success', $data); 
    } 
      
     function cancel(){ 
        // Load payment failed view 
        $this->load->view('paypal/cancel'); 
     } 
      
     function ipn(){ 
        // Retrieve transaction data from PayPal IPN POST 
        $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){ 
                // Check whether the transaction data is exists 
                $prevPayment = $this->payment->getPayment(array('txn_id' => $paypalInfo["txn_id"])); 
                if(!$prevPayment){ 
                    // 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_name']    = trim($paypalInfo["first_name"].' '.$paypalInfo["last_name"], ' '); 
                    $data['payer_email']    = $paypalInfo["payer_email"]; 
                    $data['status'] = $paypalInfo["payment_status"]; 
     
                    $this->payment->insertTransaction($data); 
                } 
            } 
        } 
    } 
}

Setup PayPal Instant Payment Notification (IPN):

Model

1. Product (models/Product.php)

<?php defined('BASEPATH') OR exit('No direct script access allowed'); 
 
class Product extends CI_Model{ 
     
    function __construct() { 
        $this->proTable   = 'products'; 
    } 
     
    /* 
     * 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; 
    } 
     
}

2. Payment (models/Payment.php)

<?php defined('BASEPATH') OR exit('No direct script access allowed'); 
 
class Payment extends CI_Model{ 
     
    function __construct() { 
        $this->transTable = 'payments'; 
    } 
     
    /* 
     * Fetch payment data from the database 
     * @param id returns a single record if specified, otherwise all records 
     */ 
    public function getPayment($conditions = array()){ 
        $this->db->select('*'); 
        $this->db->from($this->transTable); 
         
        if(!empty($conditions)){ 
            foreach($conditions as $key=>$val){ 
                $this->db->where($key, $val); 
            } 
        } 
         
        $result = $this->db->get(); 
        return ($result->num_rows() > 0)?$result->row_array():false; 
    } 
     
    /* 
     * Insert payment data in the database 
     * @param data array 
     */ 
    public function insertTransaction($data){ 
        $insert = $this->db->insert($this->transTable,$data); 
        return $insert?true:false; 
    } 
     
}

View

1. views/products/
1.1. index.php

In this view, all the products are displayed on the web page with the Buy button.

<!-- List all products -->
<?php if(!empty($products)){ foreach($products as $row){ ?>
    <div class="card">
        <img src="<?php echo base_url('assets/images/'.$row['image']); ?>" />
        <div class="card-body">
            <h5 class="card-title"><?php echo $row['name']; ?></h5>
            <p class="card-text">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
            <h6>$<?php echo $row['price'].' '.$row['currency']; ?></h6>
            <a href="<?php echo base_url('products/buy/'.$row['id']); ?>" class="btn"><img src="<?php echo base_url('assets/images/paypal-btn.png'); ?>" /></a>
        </div>
    </div>
<?php } }else{ ?>
    <p>Product(s) not found...</p>
<?php } ?>

2. views/paypal/
2.1. success.php

In this view, the payment status and transaction details are displayed after the payment on PayPal.

<?php if(!empty($payment)){ ?>
    <h1 class="success">Your Payment has been Successful!</h1>
    <h4>Payment Information</h4>
    <p><b>Reference Number:</b> #<?php echo $payment['id']; ?></p>
    <p><b>Transaction ID:</b> <?php echo $payment['txn_id']; ?></p>
    <p><b>Paid Amount:</b> <?php echo $payment['payment_gross'].' '.$payment['currency_code']; ?></p>
    <p><b>Payment Status:</b> <?php echo $payment['status']; ?></p>
	
    <h4>Payer Information</h4>
    <p><b>Name:</b> <?php echo $payment['payer_name']; ?></p>
    <p><b>Email:</b> <?php echo $payment['payer_email']; ?></p>
	
    <h4>Product Information</h4>
    <p><b>Name:</b> <?php echo $product['name']; ?></p>
    <p><b>Price:</b> <?php echo $product['price'].' '.$product['currency']; ?></p>
<?php }else{ ?>
    <h1 class="error">Transaction has been failed!</h1>
<?php } ?>

2.2. cancel.php

<div class="status">
    <h1 class="error">Your transaction was canceled!</h1>
</div>

Make PayPal Payment Gateway Live

In 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 May Also Like

Leave a Reply

Your email address will not be published. Required fields are marked *