Nowadays the payment gateway is hugely used for the e-commerce business and online service providers. It helps to accept payment online in the web application. Before integrating a payment gateway into the website, you need to choose the best payment gateway service provider to accept online payment without any interruption. PayPal is one of the world’s most popular internet payment solution. If you want to accept payment globally on your website, PayPal is the best choice for integrating the payment gateway in your web project.
PayPal provides an easy way to integrate standard payment gateway in 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.
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 aproducts
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 calledpaypal.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 CodexWorld * @license http://www.codexworld.com/license/ * @link http://www.codexworld.com * @version 2.0 */ 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. Theproducts/
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> <p>See more snippets like this online store item at <a href="http://www.codexworld.com">CodexWorld</a>.</p> </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 theapplication/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';