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 into your web project.
PayPal provides an easy way to integrate standard payment gateway in PHP. If your web application built with CodeIgniter, PayPal PHP library and API needs to be integrated in the CodeIgniter application. 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 this example script, the following functionality will be implemented to integrate PayPal payment gateway in CodeIgniter application.
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 the transaction process before accept payment from the buyers.
To test the PayPal payment gateway, you need to create PayPal sandbox account.
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
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;
paypal.php
The configuration variables of the PayPal library are defined in this file.
sandbox
), business email (business
), and currency code (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'] = 'Your_PayPal_Email';
$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';
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
).
<?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 CodexWorld
* @license http://www.codexworld.com/license/
* @link http://www.codexworld.com
* @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;
}
}
The Products and Paypal controllers will be used to handle the product listing and payment process.
1. Products (controllers/Products.php
):
The Products controller handles the product listing and payment request submission process.
add_field()
and paypal_auto_form()
methods of the PayPal library.<?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):
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.
The Product and Payment models handle the database related operations (fetch and insert).
1. Product (models/Product.php
)
products
table and returns as an array.
<?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
)
payments
table and returns as an array.payments
table.<?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;
}
}
The products and paypal directories hold the view files of Products and Paypal controllers.
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
If the user cancels the payment, the transaction failed notification is displayed.
<div class="status">
<h1 class="error">Your transaction was canceled!</h1>
</div>
When the payment flow testing process is completed with a sandbox account, do the following changes to make the PayPal payment gateway live.
In the application/config/paypal.php
file, specify the PayPal environment and business email.
$config['sandbox'] = FALSE;
$config['business'] = 'live_paypal@email.com';
PayPal Express Checkout Integration in PHP
Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request
Thanks
How i can send 2-3 product
Means add to Cart ..n 2-3 products Pls help Need badly in ci3
how can i give papal developer key in codeiginiter? in laravel we can give key in .env where can we give key in codeiginter
thanks you soooooo much guys it,s really help