PayPal Pro Payment Gateway Integration in CodeIgniter

PayPal provides various types of API to integrate payment gateway in the web application. Mostly, the Standard Payment Gateway is used to accept payment online with PayPal. PayPal standard payment gateway can be easily integrated into the website using PHP. But, if you want to accept credit card payment on your website, PayPal Payments Pro is the best option for this job. The PayPal Pro payment gateway allows you to accept payment online with credit or debit card.

The main advantage of using the PayPal Payments Pro is that the customer can make the payment using their credit card without a PayPal account. Also, the payment can be completed within your website, the customer doesn’t need to leave your website to make the payment. You can easily integrate PayPal Pro payment gateway using PHP library in the web application. If your website built with the CodeIgniter framework, PayPal Pro PHP library needs to be integrated into the CodeIgniter. In this tutorial, we will show you how to integrate PayPal Pro payment gateway in CodeIgniter for accepting credit or debit card payment in the website.

Create PayPal Sandbox Account

Before making the PayPal payment gateway live, you must check whether the payment process is working properly. PayPal Sandbox environment allows testing the transaction and payment process with demo PayPal account. At first, you need to create a PayPal Sandbox account on PayPal Developer panel. In the PayPal sandbox business account, you will get the API credentials. To use the PayPal Pro payment gateway API your business account must be a Website Payments Pro account. If you want to accept credit card payment, upgrade your PayPal business account to Website Payments Pro account.

After the PayPal business pro account creation, you will get the NVP/SOAP Sandbox API Credentials under the API Credentials tab.

paypal-pro-business-account-nvp-soap-api-credentials-codexworld

The API credentials need to be specified at the time of calling the PayPal Pro payment gateway API. Copy the API credentials (Username, Password, and Signature) for later use in the script.

Before getting started to implement PayPal Pro payment gateway in CodeIgniter, take a look at the files structure.

codeigniter_paypal_pro_integration/
├── application/
│   ├── controllers/
│   │   └── Products.php
│   ├── libraries/
│   │   └── PaypalPro.php
│   ├── models/
│   │   └── Product.php
│   └── views/
│       └── products/
│           ├── index.php
│           └── purchase.php
└── assets/
    ├── css/
    │	└── style.css
    └── js/
    	├── jquery.min.js
    	└── creditCardValidator.js

Create Database Table

To store the products and transaction details, two tables need to be created in the database.

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

CREATE TABLE `products` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `number` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
 `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `price` float(10,2) NOT NULL,
 `currency` varchar(10) COLLATE utf8_unicode_ci 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 an orders table with some basic fields in the MySQL database for storing the payment information.

CREATE TABLE `orders` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `product_id` int(11) NOT NULL,
 `buyer_name` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
 `buyer_email` varchar(25) COLLATE utf8_unicode_ci DEFAULT NULL,
 `card_num` bigint(20) NOT NULL,
 `card_cvc` int(5) NOT NULL,
 `card_exp_month` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
 `card_exp_year` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
 `paid_amount` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
 `paid_amount_currency` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
 `payment_txn_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 `payment_status` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
 `created` datetime NOT NULL,
 `modified` datetime NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Config

autoload.php:
Specify the commonly used library (database) and helper (url) to load automatically.

$autoload['libraries'] = array('database'); 
 
$autoload['helper'] = array('url');

paypal.php:
The configuration variables of the PayPal Pro library are defined in this file. Specify the API credentials (Username, Password, and Signature) as per your PayPal Business Pro account.

  • sandbox – Specify whether you use Sandbox or Live environment (TRUE/FALSE).
  • paypal_api_username – Specify the API username of the PayPal Business Pro account.
  • paypal_api_password – Specify the API password of the PayPal Business Pro account.
  • paypal_api_signature – Specify the API signature of the PayPal Business Pro account.
<?php 
defined('BASEPATH') OR exit('No direct script access allowed'); 
 
// ------------------------------------------------------------------------ 
// PayPalPro library configuration 
// ------------------------------------------------------------------------ 
 
// PayPal environment, Sandbox or Live 
$config['sandbox'] = TRUE// FALSE for live environment 
 
// PayPal API credentials 
$config['paypal_api_username']  = 'PayPal_API_Username'; 
$config['paypal_api_password']  = 'PayPal_API_Password'; 
$config['paypal_api_signature'] = 'PayPal_API_Signature';

Library (PaypalPro.php)

The PaypalPro CodeIgniter Library helps to integrate PayPal Pro payment gateway in CodeIgniter 3 application. This library has a dependency on a configuration file called paypal.php. Place the PaypalPro.php file in the application/libraries/ directory and paypal.php file in the application/config/ directory. You don’t need to download the PayPal Pro CodeIgniter library separately, it is included in the source code.

This PaypalPro library class is used to

  • Make the API call to PayPal using an API signature.
  • Validate the API response.
  • Store the API response in an associative array.

Controller (Products.php)

The Products controller handles the products listing and payment process using PayPal Pro CodeIgniter library.

  • __construct() – Load the Product model.
  • index()
    • Retrieve the products data from the database using getRows() function of the Product model.
    • Pass data to the view for products listing on the web page.
  • purchase()
    • Fetch a specific product data from the database based on the product ID.
    • Pass data to the view to display product details on the payment page.
  • payment() – This method is requested by the Ajax request, it handles the credit card payment process using PaypalPro PHP library.
    • Fetch the product details using getRows() function of the Product model based on the ID.
    • Retrieve the buyer information (name, country, city, zip code) from the POST method.
    • Retrieve the credit card information (Card Number, Card Type, Expiry Month, Expiry Date, and CVV number) from the POST method.
    • Load the PaypalPro library for CodeIgniter.
    • Call the paypalCall() function of PaypalPro class and pass the required information as an array ($paypalParams).
    • If the charge is successful, insert the transaction data in the MySQL database.
    • The payment status is returned as JSON format to the Ajax request.
<?php 
defined('BASEPATH') OR exit('No direct script access allowed'); 
 
class Products extends CI_Controller { 
     
    function  __construct(){ 
        parent::__construct(); 
         
        // Load product model 
        $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 purchase($id){ 
        // Get product data from the database 
        $data['product'] = $this->product->getRows($id); 
         
        // Pass product data to the view 
        $this->load->view('products/purchase'$data); 
    } 
     
    function payment($id){ 
        $data = array(); 
         
        // Get product data from the database 
        $product $this->product->getRows($id); 
         
        if(!empty($product) && $_SERVER['REQUEST_METHOD'] == 'POST'){ 
            // Buyer information 
            $name $_POST['name_on_card']; 
            $nameArr explode(' '$name); 
            $firstName = !empty($nameArr[0])?$nameArr[0]:''; 
            $lastName = !empty($nameArr[1])?$nameArr[1]:''; 
            $city 'Charleston'; 
            $zipcode '25301'; 
            $countryCode 'US'; 
             
            // Card details 
            $creditCardNumber trim(str_replace(" ","",$_POST['card_number'])); 
            $creditCardType $_POST['card_type']; 
            $expMonth $_POST['expiry_month']; 
            $expYear $_POST['expiry_year']; 
            $cvv $_POST['cvv']; 
             
            // Load PaypalPro library 
            $this->load->library('paypalpro'); 
             
            // Payment details 
            $paypalParams = array( 
                'paymentAction' => 'Sale', 
                'itemName' => $product['name'], 
                'itemNumber' => $product['number'], 
                'amount' => $product['price'], 
                'currencyCode' => $product['currency'], 
                'creditCardType' => $creditCardType, 
                'creditCardNumber' => $creditCardNumber, 
                'expMonth' => $expMonth, 
                'expYear' => $expYear, 
                'cvv' => $cvv, 
                'firstName' => $firstName, 
                'lastName' => $lastName, 
                'city' => $city, 
                'zip'    => $zipcode, 
                'countryCode' => $countryCode, 
            ); 
            $response $this->paypalpro->paypalCall($paypalParams); 
            $paymentStatus strtoupper($response["ACK"]); 
            if($paymentStatus == "SUCCESS"){ 
                // Transaction info 
                $transactionID $response['TRANSACTIONID']; 
                $paidAmount $response['AMT']; 
                $currency $response['CURRENCYCODE']; 
                 
                // Insert the transaction data in the database 
                $txnData['product_id'] = $id; 
                $txnData['buyer_name'] = $name; 
                $txnData['buyer_email']    = ''; 
                $txnData['card_num'] = $creditCardNumber; 
                $txnData['card_cvc'] = $cvv; 
                $txnData['card_exp_month'] = $expMonth; 
                $txnData['card_exp_year'] = $expYear; 
                $txnData['paid_amount'] = $paidAmount; 
                $txnData['paid_amount_currency'] = $currency; 
                $txnData['payment_txn_id'] = $transactionID; 
                $txnData['payment_status'] = $paymentStatus; 
 
                $insert $this->product->insertOrder($txnData); 
                 
                $data['status'] = 1; 
                $data['orderID'] = $transactionID; 
            }else{ 
                 $data['status'] = 0; 
            } 
        } 
         
        // Transaction status 
        echo json_encode($data); 
    } 
}

Model (Product.php)

The Product model handles the database related works (fetch and insert).

  • __construct() – Defines the database table names.
  • getRows() – Fetch the records from the products table and returns as an array.
  • insertOrder() – Insert the payment and order information in the orders table.
<?php 
defined('BASEPATH') OR exit('No direct script access allowed'); 
 
class Product extends CI_Model{ 
     
    function __construct() { 
        $this->proTable 'products'; 
        $this->ordTable 'orders'; 
    } 
     
    /* 
     * 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 insertOrder($data){ 
        if(empty($data['created'])){ 
            $data['created'] = date("Y-m-d H:i:s"); 
        } 
        if(empty($data['modified'])){ 
            $data['modified'] = date("Y-m-d H:i:s"); 
        } 
        $insert $this->db->insert($this->ordTable$data); 
        return $insert?true:false; 
    } 
     
}

View (products)

The products/ directory holds the view files of the Product controller.

1. products/index.php
All the products are fetched from the database and listed in the webpage with the Purchase button.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Products - PayPal Pro Integration in CodeIgniter</title>

<!-- stylesheet file -->
<link rel="stylesheet" href="<?php echo base_url('assets/css/style.css'); ?>">
</head>
<body>
<div class="container">
    <!-- List all products -->
    <?php if(!empty($products)){ foreach($products as $row){ ?>
        <div class="pro-box">
            <h4>Product Number: <b><?php echo $row['number']; ?></b></h4>
            <h4>Product Name: <b><?php echo $row['name']; ?></b></h4>
            <h4>Price: <b>$<?php echo $row['price'].' '.$row['currency']; ?></b></h4>
            <div class="buy">
                <a href="<?php echo base_url('products/purchase/'.$row['id']); ?>">Purchase</a>
            </div>
        </div>
    <?php } }else{ ?>
        <p>Product(s) not found...</p>
    <?php ?>
</div>
</body>
</html>

2. products/purchase.php
In the purchase page, the credit card information is collected from the buyer and send to the payment() method via Ajax request for payment processing.

Credit Card Form:

  • The selected product details are displayed.
  • An HTML form is displayed to provide the credit card information (Card Number, Expiration Date, CVC Number, and Card Holder Name).
<div class="card-payment">
    <h3>PayPal Pro Integration in CodeIgniter</h3>
	
    <!-- Card from -->
    <div id="paymentSection">
        <form method="post" id="paymentForm">
            <h4>Item: <b><?php echo $product['name']; ?></b></h4>
            <h4>Payable amount: <b>$<?php echo $product['price'].' '.$product['currency']; ?></b></h4>
            <ul>
                <li>
                    <label>Card Number</label>
                    <input type="text" placeholder="1234 5678 9012 3456" maxlength="20" id="card_number" name="card_number">
                </li>
	
                <li class="vertical">
                    <ul>
                        <li>
                            <label>Expiry Month</label>
                            <input type="text" placeholder="MM" maxlength="5" id="expiry_month" name="expiry_month">
                        </li>
                        <li>
                            <label>Expiry Year</label>
                            <input type="text" placeholder="YYYY" maxlength="5" id="expiry_year" name="expiry_year">
                        </li>
                        <li>
                            <label>CVV</label>
                            <input type="text" placeholder="123" maxlength="3" id="cvv" name="cvv">
                        </li>
                    </ul>
                </li>
                <li>
                    <label>Name on Card</label>
                    <input type="text" placeholder="John Doe" id="name_on_card" name="name_on_card">
                </li>
                <li>
                    <input type="hidden" name="card_type" id="card_type" value=""/>
                    <input type="button" name="card_submit" id="cardSubmitBtn" value="Proceed" class="payment-btn" disabled="true" >
                </li>
            </ul>
        </form>
    </div>
    <div class="flink">
        <a href="<?php echo base_url('products/'); ?>">Back to Products</a>
    </div>
</div>

Card Form Validation:
Include the jQuery and credit card validator plugin library.

<!-- jQuery library -->
<script src="<?php echo base_url('assets/js/jquery.min.js'); ?>"></script>

<!-- Card validation library -->
<script src="<?php echo base_url('assets/js/creditCardValidator.js'); ?>"></script>

The creditCardValidator jQuery plugin is used to validate the credit card number. The cardFormValidate() method helps to validate card details using jQuery.

/* Credit card validation code */
function cardFormValidate(){
    var cardValid = 0;
      
    // Card number validation
    $('#card_number').validateCreditCard(function(result) {
        var cardType = (result.card_type == null)?'':result.card_type.name;
        if(cardType == 'Visa'){
            var backPosition = result.valid?'2px -163px, 260px -87px':'2px -163px, 260px -61px';
        }else if(cardType == 'MasterCard'){
            var backPosition = result.valid?'2px -247px, 260px -87px':'2px -247px, 260px -61px';
        }else if(cardType == 'Maestro'){
            var backPosition = result.valid?'2px -289px, 260px -87px':'2px -289px, 260px -61px';
        }else if(cardType == 'Discover'){
            var backPosition = result.valid?'2px -331px, 260px -87px':'2px -331px, 260px -61px';
        }else if(cardType == 'Amex'){
            var backPosition = result.valid?'2px -121px, 260px -87px':'2px -121px, 260px -61px';
        }else{
            var backPosition = result.valid?'2px -121px, 260px -87px':'2px -121px, 260px -61px';
        }
        $('#card_number').css("background-position", backPosition);
        if(result.valid){
            $("#card_type").val(cardType);
            $("#card_number").removeClass('required');
            cardValid = 1;
        }else{
            $("#card_type").val('');
            $("#card_number").addClass('required');
            cardValid = 0;
        }
    });
      
    // Card details validation
    var cardName = $("#name_on_card").val();
    var expMonth = $("#expiry_month").val();
    var expYear = $("#expiry_year").val();
    var cvv = $("#cvv").val();
    var regName = /^[a-z ,.'-]+$/i;
    var regMonth = /^01|02|03|04|05|06|07|08|09|10|11|12$/;
    var regYear = /^2017|2018|2019|2020|2021|2022|2023|2024|2025|2026|2027|2028|2029|2030|2031$/;
    var regCVV = /^[0-9]{3,3}$/;
    if(cardValid == 0){
        $("#card_number").addClass('required');
        $("#card_number").focus();
        return false;
    }else if(!regMonth.test(expMonth)){
        $("#card_number").removeClass('required');
        $("#expiry_month").addClass('required');
        $("#expiry_month").focus();
        return false;
    }else if(!regYear.test(expYear)){
        $("#card_number").removeClass('required');
        $("#expiry_month").removeClass('required');
        $("#expiry_year").addClass('required');
        $("#expiry_year").focus();
        return false;
    }else if(!regCVV.test(cvv)){
        $("#card_number").removeClass('required');
        $("#expiry_month").removeClass('required');
        $("#expiry_year").removeClass('required');
        $("#cvv").addClass('required');
        $("#cvv").focus();
        return false;
    }else if(!regName.test(cardName)){
        $("#card_number").removeClass('required');
        $("#expiry_month").removeClass('required');
        $("#expiry_year").removeClass('required');
        $("#cvv").removeClass('required');
        $("#name_on_card").addClass('required');
        $("#name_on_card").focus();
        return false;
    }else{
        $("#card_number").removeClass('required');
        $("#expiry_month").removeClass('required');
        $("#expiry_year").removeClass('required');
        $("#cvv").removeClass('required');
        $("#name_on_card").removeClass('required');
        $('#cardSubmitBtn').prop('disabled', false);  
        return true;
    }
}

Process Payment using jQuery and Ajax:
The Ajax request is initiated to validate and process the card transaction through PayPal Pro CodeIgniter Library.

  • The given card information is sent to the payment() method of Products controller via Ajax.
  • The specified charge is created and the transaction status is returned.
  • Based on the response, the order info or error message is shown to the user.
/* Submit card details and make payment */ 
$(document).ready(function(){
    // Initiate validation on input fields
    $('#paymentForm input[type=text]').on('keyup',function(){
        cardFormValidate();
    });
    
    // Submit card form
    $("#cardSubmitBtn").on('click',function(){
        $('.status-msg').remove();
        if(cardFormValidate()){
            var formData = $('#paymentForm').serialize();
            $.ajax({
                type:'POST',
                url:'<?php echo base_url('products/payment/'.$product['id']); ?>',
                dataType: "json",
                data:formData,
                beforeSend: function(){
                    $("#cardSubmitBtn").prop('disabled', true);
                    $("#cardSubmitBtn").val('Processing....');
                },
                success:function(data){
                    if(data.status == 1){
                        $('#paymentSection').html('<p class="status-msg success">The transaction was successful. Order ID: <span>'+data.orderID+'</span></p>');
                    }else{
                        $("#cardSubmitBtn").prop('disabled', false);
                        $("#cardSubmitBtn").val('Proceed');
                        $('#paymentSection').prepend('<p class="status-msg error">Transaction has been failed, please try again.</p>');
                    }
                }
            });
        }
    });
});

Make PayPal Pro Payment Gateway Live

Once the payment flow testing is completed and the transaction is working properly on the Sandbox environment, make the PayPal Pro payment gateway live for production use. Do the following changes to make the PayPal Pro payment gateway live in CodeIgniter application.

In the application/config/paypal.php file,

  • Set PayPal environment (sandbox) to FALSE.
  • Change the API credentials (paypal_api_username, paypal_api_password, and paypal_api_signature) as per your PayPal Business Pro account.

PayPal Payment Gateway Integration in CodeIgniter

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

Leave a reply

keyboard_double_arrow_up