Paypal payment gateway integration code with PHP, Mysql project

php_paypalToday we are going to integrate paypal payment gateway with core PHP,Mysql . Payment gateway are third party that handle payment transaction between customer and merchants .They have lots of parameter like customer name, email ,product name, model no, total cost, country code etc .

We will integrate in our previous tutorial of core PHP shopping cart project .So if you have not setup it ,do visit this tutorial and follow all steps or if you have your own project ,it’s ok .

Step 1

We have our final page in e-commerce project i.e order_review.php .So , open this file in your favourite PHP editor and put below code to the bottom of the page

 
	 <form action="paypal.php?sandbox=1" method="post"> <?php // remove sandbox=1 for live transactions ?>
    <input type="hidden" name="action" value="process" />
    <input type="hidden" name="cmd" value="_cart" /> <?php // use _cart for cart checkout ?>
    <input type="hidden" name="currency_code" value="INR" />
    <input type="hidden" name="invoice" value="<?php echo date("His").rand(1234, 9632); ?>" />
    <input type="hidden" name="product_id" value="<?php echo $model; ?>" /> <input type="hidden" name="product_name" value="<?php echo $product_name; ?>" /> 
	<input type="hidden" name="product_quantity" value="1" />
	<input type="hidden" name="product_amount" value="<?php echo $total; ?>" />
	<input type="hidden" name="payer_fname" value="<?php  echo $checkout['name'];  ?>" />
 	<input type="hidden" name="payer_email" value="<?php  echo $checkout['email'];  ?>" />
		<input type="hidden" name="payer_address" value="<?php  echo $checkout['address'];  ?>" />

	<input type="submit" name="submit" value="Pay now using Paypal" /> 
    </form>
	 

Check below how our complete order_review.php page looks like

<?php include "includes/header.php"; ?>
    <?php include  "includes/left.php"; ?>
    <!-- end of left content -->
    <div class="center_content">
     <div class="center_title_bar">Profile</div>
	 
	 
	 
	 
	 <?php
 	 
	 $checkout=$_SESSION['checkout'];
	  $mid=$_SESSION['mid'];
	
	 
	 
	 
	 
	 
	 ?>
	  <table width="63%" height="141" border="0">
  <tr>
    <td width="22%">Name</td>
    <td width="78%"> <?php  echo $checkout['name'];  ?> </td>
  </tr>
  <tr>
    <td>Email</td>
    <td> <?php   echo $checkout['email'];  ?> </td>
  </tr>
   
  <tr>
    <td>Contact</td>
    <td> <?php   echo $checkout['contact'];  ?> </td>
  </tr>
  <tr>
    <td>Address</td>
    <td> <?php echo $checkout['address'];   ?> </td>
  </tr>
   
   
</table>
	 
	 
	 <br />
	 <br />
	 <table width="100%" border="0">
  <tr>
     <td>Image</td>
    <td>Title</td>
	<td>Qty</td>
    <td>Sub Total</td>
     </tr>



			 <?php
			 
			 
			 $r=$mysqli->query("SELECT * FROM products p INNER JOIN cart c 
			 ON c.pid=p.pid WHERE c.mid='$mid' ");
			 
			 
			 $n=1;
			 
			 $total=0;
			 $model='';
			 $product_name='';
			while($row=$r->fetch_assoc()){
				$model.=" ".$row['model'];
				$product_name.=" ".$row['title'];
				?>
				
				  <tr>
 					<td><img width="40" src="uploads/<?php echo $row['image']; ?>" /></td>
					<td><?php echo $row['title']; ?></td>
					
					<td> <?php echo $row['qty']; ?></td>
					

					
					<td><?php echo $row['qty']*$row['cost']; 
					$total=$total+$row['qty']*$row['cost'];
					
					?></td>
				  </tr>
				<?php
				$n++;
			}
			
			
			
			 ?>
			 
			 <tr>
     <td> </td>
    <td> </td>
	<td> </td>
    <td>Net Total :<?php echo $total; ?></td>
     </tr>
			</table>	 
			 
	 
	 
	 
	 <form action="paypal.php?sandbox=1" method="post"> <?php // remove sandbox=1 for live transactions ?>
    <input type="hidden" name="action" value="process" />
    <input type="hidden" name="cmd" value="_cart" /> <?php // use _cart for cart checkout ?>
    <input type="hidden" name="currency_code" value="INR" />
    <input type="hidden" name="invoice" value="<?php echo date("His").rand(1234, 9632); ?>" />
    <input type="hidden" name="product_id" value="<?php echo $model; ?>" /> <input type="hidden" name="product_name" value="<?php echo $product_name; ?>" /> 
	<input type="hidden" name="product_quantity" value="1" />
	<input type="hidden" name="product_amount" value="<?php echo $total; ?>" />
	<input type="hidden" name="payer_fname" value="<?php  echo $checkout['name'];  ?>" />
 	<input type="hidden" name="payer_email" value="<?php  echo $checkout['email'];  ?>" />
	<input type="hidden" name="payer_address" value="<?php  echo $checkout['address'];  ?>" />
	<input type="submit" name="submit" value="Pay now using Paypal" /> 
    </form>
	 
	 
	 
	 
	 
    </div>
    <!-- end of center content -->
    <?php include "includes/right.php"; ?>
    <!-- end of right content -->
  </div>
  <!-- end of main content -->
 <?php include "includes/footer.php"; ?>

Step 2

in above we have a form action i.e paypal.php . Find below this file

<?php
require_once("includes/config.php"); // include the DB config file

require_once("paypal_class.php"); // include the DB config file






define('EMAIL_ADD', 'notification@gmail.com'); // define any notification email

define('PAYPAL_EMAIL_ADD', 'owner_email@gmail.com'); // facilitator email which will receive payments change this email to a live paypal account id when the site goes live


$p 				= new paypal_class(); // paypal class
$p->admin_mail 	= EMAIL_ADD; // set notification email
$action 		= $_REQUEST["action"];

switch($action){
	case "process": // case process insert the form data in DB and process to the paypal
		$mysqli->query("INSERT INTO purchases (invoice, product_id, product_name, product_quantity, product_amount, payer_fname, payer_address,payer_email, payment_status, posted_date) VALUES ('".$_POST["invoice"]."', '".$_POST["product_id"]."', '".$_POST["product_name"]."', '".$_POST["product_quantity"]."', '".$_POST["product_amount"]."', '".$_POST["payer_fname"]."','".$_POST["payer_address"]."','".$_POST["payer_email"]."', 'pending', NOW())");
		
		$this_script = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
		
		$p->add_field('business', PAYPAL_EMAIL_ADD); // Call the facilitator eaccount
		$p->add_field('cmd', $_POST["cmd"]); // cmd should be _cart for cart checkout
		$p->add_field('upload', '1');
		$p->add_field('return', $this_script.'?action=success'); // return URL after the transaction got over
		$p->add_field('cancel_return', $this_script.'?action=cancel'); // cancel URL if the trasaction was cancelled during half of the transaction
		$p->add_field('notify_url', $this_script.'?action=ipn'); // Notify URL which received IPN (Instant Payment Notification)
		$p->add_field('currency_code', $_POST["currency_code"]);
		$p->add_field('invoice', $_POST["invoice"]);
		$p->add_field('item_name_1', $_POST["product_name"]);
		$p->add_field('item_number_1', $_POST["product_id"]);
		$p->add_field('quantity_1', $_POST["product_quantity"]);
		$p->add_field('amount_1', $_POST["product_amount"]);
		$p->add_field('first_name', $_POST["payer_fname"]);
 		$p->add_field('address1', $_POST["payer_address"]);
 		$p->add_field('email', $_POST["payer_email"]);
		$p->submit_paypal_post(); // POST it to paypal
		//$p->dump_fields(); // Show the posted values for a reference, comment this line before app goes live
	break;
	
	case "success": // success case to show the user payment got success
		echo '<title>Payment Done Successfully</title>';
		echo '<style>.as_wrapper{
	font-family:Arial;
	color:#333;
	font-size:14px;
	padding:20px;
	border:2px dashed #17A3F7;
	width:600px;
	margin:0 auto;
}</style>
';		echo '<div class="as_wrapper">';
		echo "<h1>Payment Transaction Done Successfully</h1>";
		echo '<h4><a href="profile.php">Click here </a>to go profile page</h4>';
 		echo '</div>';
	break;
	
	case "cancel": // case cancel to show user the transaction was cancelled
		echo "<h1>Transaction Cancelled ";
	break;
	
	case "ipn": // IPN case to receive payment information. this case will not displayed in browser. This is server to server communication. PayPal will send the transactions each and every details to this case in secured POST menthod by server to server. 
		$trasaction_id  = $_POST["txn_id"];
		$payment_status = strtolower($_POST["payment_status"]);
		$invoice		= $_POST["invoice"];
		$log_array		= print_r($_POST, TRUE);
		$log_query		= "SELECT * FROM paypal_log WHERE txn_id = '$trasaction_id'";
		$log_check 		= $mysqli->query($log_query);
		if( $log_check->num_rows <= 0){
			$mysqli->query("INSERT INTO paypal_log (txn_id, log, posted_date) VALUES ('$trasaction_id', '$log_array', NOW())");
		}else{
			$mysqli->query("UPDATE paypal_log SET log = '$log_array' WHERE txn_id = '$trasaction_id'");
		} // Save and update the logs array
		
		$paypal_log_fetch 	= mysql_fetch_array($mysqli->query($log_query));
		$paypal_log_fetch 	=  $mysqli->query($log_query)->fetch_assoc(); ;
		 
		
		
		$paypal_log_id		= $paypal_log_fetch["id"];
		if ($p->validate_ipn()){ // validate the IPN, do the others stuffs here as per your app logic
			$mysqli->query("UPDATE purchases SET trasaction_id = '$trasaction_id ', log_id = '$paypal_log_id', payment_status = '$payment_status' WHERE invoice = '$invoice'");
			$subject = 'Instant Payment Notification - Recieved Payment';
			$p->send_report($subject); // Send the notification about the transaction
		}else{
			$subject = 'Instant Payment Notification - Payment Fail';
			$p->send_report($subject); // failed notification
		}
	break;
}
?>

In above file 1st line it’s calling database config file , then on 2 lines we have declared paypal merchant’e email id and notification email id. The first email should be registered with paypal as a merchant account to accept payment from website . Currently we are in testing mode (sandbox account) ,so we can put anything here .
After it handle Paypal payment process .While on this step it insert the form data in database table ‘purchases’ and process to the paypal .

Step 3

in step 2 we discussed regarding a database table i.e ‘purchases’ .So , let’s create it , execute below code to sql on your phpmyadmin for your database .

CREATE TABLE `purchases` (
  `id` int(10) NOT NULL auto_increment,
  `invoice` varchar(300) NOT NULL,
  `trasaction_id` varchar(600) NOT NULL,
  `log_id` int(10) NOT NULL,
  `product_id` varchar(300) NOT NULL,
  `product_name` varchar(300) NOT NULL,
  `product_quantity` varchar(300) NOT NULL,
  `product_amount` varchar(300) NOT NULL,
  `payer_fname` varchar(300) NOT NULL,
  `payer_lname` varchar(300) NOT NULL,
  `payer_address` varchar(300) NOT NULL,
  `payer_city` varchar(300) NOT NULL,
  `payer_state` varchar(300) NOT NULL,
  `payer_zip` varchar(300) NOT NULL,
  `payer_country` varchar(300) NOT NULL,
  `payer_email` text NOT NULL,
  `payment_status` varchar(300) NOT NULL,
  `posted_date` datetime NOT NULL,
  PRIMARY KEY  (`id`)
) 

Step 4

Now create a file ‘paypal_class.php’ and put below code in it .This file provides clean and simple method to validate the paid result with Paypal IPN

<?php
 

/** filename of the IPN log */
define('LOG_FILE', '.ipn_results.log');

define('SSL_P_URL', 'https://www.paypal.com/cgi-bin/webscr');
define('SSL_SAND_URL','https://www.sandbox.paypal.com/cgi-bin/webscr');

class paypal_class {
	
	private $ipn_status;                // holds the last status
	public $admin_mail; 				// receive the ipn status report pre transaction
	public $paypal_mail;				// paypal account, if set, class need to verify receiver
	public $txn_id;						// array: if the txn_id array existed, class need to verified the txn_id duplicate
	public $ipn_log;                    // bool: log IPN results to text file?
	private $ipn_response;              // holds the IPN response from paypal   
	public $ipn_data = array();         // array contains the POST values for IPN
	private $fields = array();          // array holds the fields to submit to paypal
	private $ipn_debug; 				// ipn_debug
	
	// initialization constructor.  Called when class is created.
	function __construct() {

		$this->ipn_status = '';
		$this->admin_mail = null;
		$this->paypal_mail = null;
		$this->txn_id = null;
		$this->tax = null;
		$this->ipn_log = true;
		$this->ipn_response = '';
		$this->ipn_debug = false;
	}

	// adds a key=>value pair to the fields array, which is what will be 
	// sent to paypal as POST variables. 
	public function add_field($field, $value) {
		$this->fields["$field"] = $value;
	}


	// 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.  We do this so that you can validate
	// any POST vars from you custom form before submitting to paypal.  So 
	// basically, you'll have your own form which is submitted to your script
	// to validate the data, which in turn calls this function to create
	// another hidden form and submit to paypal.
		
	// The user will briefly see a message on the screen that reads:
	// "Please wait, your order is being processed..." and then immediately
	// is redirected to paypal.
	public function submit_paypal_post() {

		$paypal_url = ($_GET['sandbox'] == 1) ? SSL_SAND_URL : SSL_P_URL;
		echo "<html>\n";
		echo "<head><title>Processing Payment...</title></head>\n";
		echo "<body onLoad=\"document.forms['paypal_form'].submit();\">\n";
		echo "<h2>Please wait, your order is being processed and you";
		echo " will be redirected to the paypal website.</h2>\n";
		echo "<form method=\"post\" name=\"paypal_form\" ";
		echo "action=\"".$paypal_url."\">\n";
		if (isset($this->paypal_mail))echo "<input type=\"hidden\" name=\"business\" value=\"$this->paypal_mail\"/>\n";
		foreach ($this->fields as $name => $value) {
			echo "<input type=\"hidden\" name=\"$name\" value=\"$value\"/>\n";
		}
		echo "<br/><br/>If you are not automatically redirected to ";
		echo "paypal within 5 seconds...<br/><br/>\n";
		echo "<input type=\"submit\" value=\"Click Here\">\n";
		
		echo "</form>\n";
		echo "</body></html>\n";
	}
   
/**
 * validate the	IPN
 * 
 * @return bool IPN validation result
 */
	public function validate_ipn() {
		
		$hostname = gethostbyaddr ( $_SERVER ['REMOTE_ADDR'] );
		if (! preg_match ( '/paypal\.com$/', $hostname )) {
			$this->ipn_status = 'Validation post isn\'t from PayPal';
			$this->log_ipn_results ( false );
			return false;
		}
		
		if (isset($this->paypal_mail) && strtolower ( $_POST['receiver_email'] ) != strtolower(trim( $this->paypal_mail ))) {
			$this->ipn_status = "Receiver Email Not Match";
			$this->log_ipn_results ( false );
			return false;
		}
		
		if (isset($this->txn_id)&& in_array($_POST['txn_id'],$this->txn_id)) {
			$this->ipn_status = "txn_id have a duplicate";
			$this->log_ipn_results ( false );
			return false;
		}

		// parse the paypal URL
		$paypal_url = ($_POST['test_ipn'] == 1) ? SSL_SAND_URL : SSL_P_URL;
		$url_parsed = parse_url($paypal_url);        
		
		// generate the post string from the _POST vars aswell as load the
		// _POST vars into an arry so we can play with them from the calling
		// script.
		$post_string = '';    
		foreach ($_POST as $field=>$value) { 
			$this->ipn_data["$field"] = $value;
			$post_string .= $field.'='.urlencode(stripslashes($value)).'&'; 
		}
		$post_string.="cmd=_notify-validate"; // append ipn command
		
		// open the connection to paypal
		if (isset($_POST['test_ipn']) )
			$fp = fsockopen ( 'ssl://www.sandbox.paypal.com', "443", $err_num, $err_str, 60 );
		else
			$fp = fsockopen ( 'ssl://www.paypal.com', "443", $err_num, $err_str, 60 );
 
		if(!$fp) {
			// could not open the connection.  If loggin is on, the error message
			// will be in the log.
			$this->ipn_status = "fsockopen error no. $err_num: $err_str";
			$this->log_ipn_results(false);       
			return false;
		} else { 
			// Post the data back to paypal
			fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n"); 
			fputs($fp, "Host: $url_parsed[host]\r\n"); 
			fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); 
			fputs($fp, "Content-length: ".strlen($post_string)."\r\n"); 
			fputs($fp, "Connection: close\r\n\r\n"); 
			fputs($fp, $post_string . "\r\n\r\n"); 
		
			// loop through the response from the server and append to variable
			while(!feof($fp)) { 
		   	$this->ipn_response .= fgets($fp, 1024); 
		   } 
		  fclose($fp); // close connection
		}
		
		// Invalid IPN transaction.  Check the $ipn_status and log for details.
		if (! eregi("VERIFIED",$this->ipn_response)) {
			$this->ipn_status = 'IPN Validation Failed';
			$this->log_ipn_results(false);   
			return false;
		} else {
			$this->ipn_status = "IPN VERIFIED";
			$this->log_ipn_results(true); 
			return true;
		}
	} 
   
	private function log_ipn_results($success) {
		$hostname = gethostbyaddr ( $_SERVER ['REMOTE_ADDR'] );
		// Timestamp
		$text = '[' . date ( 'm/d/Y g:i A' ) . '] - ';
		// Success or failure being logged?
		if ($success)
			$this->ipn_status = $text . 'SUCCESS:' . $this->ipn_status . "!\n";
		else
			$this->ipn_status = $text . 'FAIL: ' . $this->ipn_status . "!\n";
			// Log the POST variables
		$this->ipn_status .= "[From:" . $hostname . "|" . $_SERVER ['REMOTE_ADDR'] . "]IPN POST Vars Received By Paypal_IPN Response API:\n";
		foreach ( $this->ipn_data as $key => $value ) {
			$this->ipn_status .= "$key=$value \n";
		}
		// Log the response from the paypal server
		$this->ipn_status .= "IPN Response from Paypal Server:\n" . $this->ipn_response;
		$this->write_to_log ();
	}
	
	private function write_to_log() {
		if (! $this->ipn_log)
			return; // is logging turned off?

		// Write to log
		$fp = fopen ( LOG_FILE , 'a' );
		fwrite ( $fp, $this->ipn_status . "\n\n" );
		fclose ( $fp ); // close file
		chmod ( LOG_FILE , 0600 );
	}

	public function send_report($subject) {
		$body .= "from " . $this->ipn_data ['payer_email'] . " on " . date ( 'm/d/Y' );
		$body .= " at " . date ( 'g:i A' ) . "\n\nDetails:\n" . $this->ipn_status;
		mail ( $this->admin_mail, $subject, $body );
	}

	public function print_report(){
		$find [] = "\n";
		$replace [] = '<br/>';
		$html_content = str_replace ( $find, $replace, $this->ipn_status );
		echo $html_content;
	}
	
	public function dump_fields() {
 
		// 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.
		echo "<h3>paypal_class->dump_fields() Output:</h3>";
		echo "<table width=\"95%\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\">
            <tr>
               <td bgcolor=\"black\"><b><font color=\"white\">Field Name</font></b></td>
               <td bgcolor=\"black\"><b><font color=\"white\">Value</font></b></td>

            </tr>"; 
		ksort($this->fields);
		foreach ($this->fields as $key => $value) {echo "<tr><td>$key</td><td>".urldecode($value)."&nbsp;</td></tr>";}
		echo "</table><br>"; 
	}

	private function debug($msg) {
		
		if (! $this->ipn_debug)
			return;
		
		$today = date ( "Y-m-d H:i:s " );
		$myFile = ".ipn_debugs.log";
		$fh = fopen ( $myFile, 'a' ) or die ( "Can't open debug file. Please manually create the 'debug.log' file and make it writable." );
		$ua_simple = preg_replace ( "/(.*)\s\(.*/", "\\1", $_SERVER ['HTTP_USER_AGENT'] );
		fwrite ( $fh, $today . " [from: " . $_SERVER ['REMOTE_ADDR'] . "|$ua_simple] - " . $msg . "\n" );
		fclose ( $fh );
		chmod ( $myFile, 0600 );
	}

}         


 


Now open order_review.php on your browser ex: http://localhost/my_php/order_review.php .Click button ‘Pay now using Paypal’ .It redirect to next page .Check there if all required parameter value are passing correctly . After 5 sec it redirect to paypal.com .Do check if all product name ,model and total cost are correct . well, this is paypal sandbox ,means paypal provide for developer for test integration on this mode.

After successful integration ,Remove query string ‘?sandbox=1’ from form action on order_review.php file and put actual merchant email id in paypal.php file . if you have any query feel free to write below ,I will try to reply soon . Do check our advance PHP training syllabus

  • tt

    okkk

Online Web Development Training,Video Tutorials