Page 1 of 1

Paypal ipn return delay

Posted: Wed Feb 04, 2015 12:37 pm
by jonnyfortis
i have two pages
notify.php (contains stock updates and emailers) this is the page used for the IPN

Code: Select all

<?php require_once('Connections/wiz.php'); ?>
<?php
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
  $value = urlencode(stripslashes($value));
  $req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= 'Content-Length: ' . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
// assign posted variables to local variables
// note: additional IPN variables also available -- see IPN documentation
$itemNumber = $_POST['item_number'];
$paymentStatus = $_POST['payment_status'];
$payerStatus = $_POST['payer_status'];
$pendingReason = $_POST['pending_reason'];
$txnID = $_POST['txn_id'];
$receiverEmail = $_POST['receiver_email'];

if (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") 
{
  if (PHP_VERSION < 6) {
    $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
  }

  $theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);

  switch ($theType) {
    case "text":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;    
    case "long":
    case "int":
      $theValue = ($theValue != "") ? intval($theValue) : "NULL";
      break;
    case "double":
      $theValue = ($theValue != "") ? doubleval($theValue) : "NULL";
      break;
    case "date":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;
    case "defined":
      $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
      break;
  }
  return $theValue;
}
}

mysql_select_db($database_wiz, $wiz); // find Txn ID
$query_rsTxnId = "SELECT TransactID FROM wiz_orders WHERE TransactID = '" . $txnID . "'";
$rsTxnId = mysql_query($query_rsTxnId, $wiz) or die(mysql_error());
$row_rsTxnId = mysql_fetch_assoc($rsTxnId);
$totalRows_rsTxnId = mysql_num_rows($rsTxnId);

// Check notification validation
if (!$fp) {
  $errmsg = "$errstr ($errno)";
} else {
  fputs ($fp, $header . $req);
  while (!feof($fp)) {
    $res = fgets ($fp, 1024);
    if (strcmp ($res, "VERIFIED") == 0) {
      if ($paymentStatus != "Completed") {
        $errmsg = "Payment is " . $paymentStatus . " (" . $pendingReason . ")";
      } else
      if ($totalRows_rsTxnId > 0) {
        $errmsg = "This Txn ID has been used";
      } else
      if ($receiverEmail != "hello@email.com") {
        $errmsg = "The receiver email is incorrect";
      } else
      {
        $errmsg = "";
      }
    }
    else if (strcmp ($res, "INVALID") == 0) {
      $errmsg = "Request is INVALID";
    }
  }
  fclose ($fp);
}
// last check
if ($errmsg != "") {
  $status = 0;
} else {
  $status = 1;
}

// update orders table
if ($itemNumber != "" && $txnID != "" && $paymentStatus != "") {
  mysql_select_db($database_wiz, $wiz);
  $IPN_upd = "UPDATE wiz_orders SET Fulfilled = " . $status . ", TransactID = '" . $txnID . "', TransactResult = '" . $paymentStatus . "', ResponseMsg = '" . $errmsg . "' WHERE OrderID = " . $itemNumber;
  $IPN_rsId = mysql_query($IPN_upd, $wiz) or die(mysql_error());
  $IPN_rsId = null;
}


mysql_select_db($database_wiz, $wiz);
$query_rsUpdate = "SELECT * FROM wiz_orders, wiz_orderdetails, wiz_Stock WHERE wiz_orderdetails.OrderID = wiz_orders.OrderID AND wiz_orderdetails.StockID = wiz_Stock.StockID AND wiz_orders.TransactID = '" . $txnID . "'";
$rsUpdate = mysql_query($query_rsUpdate, $wiz) or die(mysql_error());
while ($row_rsUpdate = mysql_fetch_assoc($rsUpdate)) {

//stock update
if ($row_rsUpdate['Fulfilled'] == 1)  {       

$oldStock = $row_rsUpdate['Stock'];
$stockSold = $row_rsUpdate['Quantity'];
$newStock = $oldStock - $stockSold;
$stockID = $row_rsUpdate['StockID'];

$UpdateQuery="UPDATE wiz_Stock SET Stock = Stock - {$row_rsUpdate['Quantity']} WHERE wiz_Stock.StockID = '$stockID'";
$result = mysql_query($UpdateQuery);
}
}

function DoFormatCurrency($theObject,$NumDigitsAfterDecimal,$DecimalSeparator,$GroupDigits,$CurrencySymbol) { 
	$currencyFormat=$CurrencySymbol.number_format($theObject,$NumDigitsAfterDecimal,$DecimalSeparator,$GroupDigits);
	return ($currencyFormat);
}

//new mail

// multiple recipients
$to  = 'my@email.com. ', '; // note the comma
//$to .= 'wez@example.com';

// subject testing emails to see what is emailed
$subject = 'successful stock update from wiz notify OrderID'.$row_rsUpdate['OrderID'].'';

// message
$message = '
<html>
<head>
  <title>successful stock update - notify</title>
</head>
<body>
  <p>successful stock update - notify</p>
  <table>
    <tr>
      <td>successful stock update for order ID '.$row_rsUpdate['OrderID'].'</td>
	  <td>old stock number'.$oldStock.'</td>
	  <td>new stock number '.$newStock.'</td>
		<td>transacation id from row_rsUpdate '. $txnID .'</td>
    </tr>
  </table>
</body>
</html>
';

// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

// Additional headers
$headers .= 'To: webmaster <webmaster@email.com>' . "\r\n";
$headers .= 'From: wiz website <webmaster@email.com>' . "\r\n";
//$headers .= 'Cc: hello@email.com' . "\r\n";
//$headers .= 'Bcc: hello@email.com' . "\r\n";

// Mail it
mail($to, $subject, $message, $headers);
// send email if success or failed

if ($row_rsUpdate['Fulfilled'] == 1)  {
	// multiple recipients
$to  = 'my@email.com' . ', '; // note the comma
//$to .= 'wez@example.com';

// subject
$subject = 'successful stock update for order '.$row_rsUpdate['OrderID'].'';

// message
$message = '
<html>
<head>
  <title>successful stock update</title>
</head>
<body>
  <p>successful stock update</p>
  <table>
    <tr>
      <td>successful stock update for order '.$row_rsUpdate['OrderID'].'</td>
    </tr>
  </table>
</body>
</html>
';

// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

// Additional headers
$headers .= 'To: webmaster <webmaster@email.com>' . "\r\n";
$headers .= 'From: wiz website <webmaster@email.com>' . "\r\n";
//$headers .= 'Cc: hello@email.com' . "\r\n";
//$headers .= 'Bcc: hello@email.com' . "\r\n";

// Mail it
mail($to, $subject, $message, $headers);
}
else{
	
//new mail for testing purpose

// multiple recipients
$to  = 'my@email.com'. ', '; // note the comma
//$to .= 'wez@example.com';

// subject
$subject = 'failed order stock update order id '.$row_rsUpdate['OrderID'].'';

// message
$message = '
<html>
<head>
  <title>failed order stock update order id '.$row_rsUpdate['OrderID'].'</title>
</head>
<body>
  <p>failed order stock update order id '.$row_rsUpdate['OrderID'].'</p>
</body>
</html>
';

// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

// Additional headers
$headers .= 'To: webmaster <webmaster@email.com>' . "\r\n";
$headers .= 'From: wiz website <hello@email.com>' . "\r\n";
//$headers .= 'Cc: hello@email.com' . "\r\n";
//$headers .= 'Bcc: hello@email.com' . "\r\n";

// Mail it
mail($to, $subject, $message, $headers);
}
?>
return.php (this contains a notification to show if the order completed or failed)this page is set in paypal in the return page

Code: Select all

<?php require_once('Connections/wiz.php'); ?>
<?php
session_start();
sleep(5);

$colname_rsReturn = "-1";
if (isset($_SESSION['OrderID'])) {
  $colname_rsReturn = $_SESSION['OrderID'];
}
mysql_select_db($database_wiz, $wiz);
$query_rsReturn = sprintf("SELECT * FROM wiz_orders WHERE OrderID = %s", GetSQLValueString($colname_rsReturn, "int"));
$rsReturn = mysql_query($query_rsReturn, $wiz) or die(mysql_error());
$row_rsReturn = mysql_fetch_assoc($rsReturn);
$totalRows_rsReturn = mysql_num_rows($rsReturn);
?>
in the body of the return page

Code: Select all

<?php if ($row_rsReturn['TransactResult'] == 'Completed'):?>
order complete
<?php endif ; ?>
<?php if ($row_rsReturn['TransactResult'] != 'Completed'):?>
failed
<?php endif ; ?>

so it should just read that the order is complete ( which it is) but the first time it reads its awaiting....

the notify page works, it updates stock, populates the correct fields in the database and sends emails(emails have some details missing)

but
when the user is sent back to the return.php it says the order has failed even though it hasn't then if you refresh it shows it is complete so i put a 5 second sleep on the page but it still fails.

i was thinking of putting a refresh on it to see if that help but want to find out why is not quicker to update the table

Re: Paypal ipn return delay

Posted: Wed Feb 04, 2015 3:04 pm
by jonnyfortis
jonnyfortis wrote:i have two pages
notify.php (contains stock updates and emailers) this is the page used for the IPN

Code: Select all

<?php require_once('Connections/wiz.php'); ?>
<?php
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
  $value = urlencode(stripslashes($value));
  $req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= 'Content-Length: ' . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
// assign posted variables to local variables
// note: additional IPN variables also available -- see IPN documentation
$itemNumber = $_POST['item_number'];
$paymentStatus = $_POST['payment_status'];
$payerStatus = $_POST['payer_status'];
$pendingReason = $_POST['pending_reason'];
$txnID = $_POST['txn_id'];
$receiverEmail = $_POST['receiver_email'];

if (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") 
{
  if (PHP_VERSION < 6) {
    $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
  }

  $theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);

  switch ($theType) {
    case "text":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;    
    case "long":
    case "int":
      $theValue = ($theValue != "") ? intval($theValue) : "NULL";
      break;
    case "double":
      $theValue = ($theValue != "") ? doubleval($theValue) : "NULL";
      break;
    case "date":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;
    case "defined":
      $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
      break;
  }
  return $theValue;
}
}

mysql_select_db($database_wiz, $wiz); // find Txn ID
$query_rsTxnId = "SELECT TransactID FROM wiz_orders WHERE TransactID = '" . $txnID . "'";
$rsTxnId = mysql_query($query_rsTxnId, $wiz) or die(mysql_error());
$row_rsTxnId = mysql_fetch_assoc($rsTxnId);
$totalRows_rsTxnId = mysql_num_rows($rsTxnId);

// Check notification validation
if (!$fp) {
  $errmsg = "$errstr ($errno)";
} else {
  fputs ($fp, $header . $req);
  while (!feof($fp)) {
    $res = fgets ($fp, 1024);
    if (strcmp ($res, "VERIFIED") == 0) {
      if ($paymentStatus != "Completed") {
        $errmsg = "Payment is " . $paymentStatus . " (" . $pendingReason . ")";
      } else
      if ($totalRows_rsTxnId > 0) {
        $errmsg = "This Txn ID has been used";
      } else
      if ($receiverEmail != "hello@email.com") {
        $errmsg = "The receiver email is incorrect";
      } else
      {
        $errmsg = "";
      }
    }
    else if (strcmp ($res, "INVALID") == 0) {
      $errmsg = "Request is INVALID";
    }
  }
  fclose ($fp);
}
// last check
if ($errmsg != "") {
  $status = 0;
} else {
  $status = 1;
}

// update orders table
if ($itemNumber != "" && $txnID != "" && $paymentStatus != "") {
  mysql_select_db($database_wiz, $wiz);
  $IPN_upd = "UPDATE wiz_orders SET Fulfilled = " . $status . ", TransactID = '" . $txnID . "', TransactResult = '" . $paymentStatus . "', ResponseMsg = '" . $errmsg . "' WHERE OrderID = " . $itemNumber;
  $IPN_rsId = mysql_query($IPN_upd, $wiz) or die(mysql_error());
  $IPN_rsId = null;
}


mysql_select_db($database_wiz, $wiz);
$query_rsUpdate = "SELECT * FROM wiz_orders, wiz_orderdetails, wiz_Stock WHERE wiz_orderdetails.OrderID = wiz_orders.OrderID AND wiz_orderdetails.StockID = wiz_Stock.StockID AND wiz_orders.TransactID = '" . $txnID . "'";
$rsUpdate = mysql_query($query_rsUpdate, $wiz) or die(mysql_error());
while ($row_rsUpdate = mysql_fetch_assoc($rsUpdate)) {

//stock update
if ($row_rsUpdate['Fulfilled'] == 1)  {       

$oldStock = $row_rsUpdate['Stock'];
$stockSold = $row_rsUpdate['Quantity'];
$newStock = $oldStock - $stockSold;
$stockID = $row_rsUpdate['StockID'];

$UpdateQuery="UPDATE wiz_Stock SET Stock = Stock - {$row_rsUpdate['Quantity']} WHERE wiz_Stock.StockID = '$stockID'";
$result = mysql_query($UpdateQuery);
}
}

function DoFormatCurrency($theObject,$NumDigitsAfterDecimal,$DecimalSeparator,$GroupDigits,$CurrencySymbol) { 
	$currencyFormat=$CurrencySymbol.number_format($theObject,$NumDigitsAfterDecimal,$DecimalSeparator,$GroupDigits);
	return ($currencyFormat);
}

//new mail

// multiple recipients
$to  = 'my@email.com. ', '; // note the comma
//$to .= 'wez@example.com';

// subject testing emails to see what is emailed
$subject = 'successful stock update from wiz notify OrderID'.$row_rsUpdate['OrderID'].'';

// message
$message = '
<html>
<head>
  <title>successful stock update - notify</title>
</head>
<body>
  <p>successful stock update - notify</p>
  <table>
    <tr>
      <td>successful stock update for order ID '.$row_rsUpdate['OrderID'].'</td>
	  <td>old stock number'.$oldStock.'</td>
	  <td>new stock number '.$newStock.'</td>
		<td>transacation id from row_rsUpdate '. $txnID .'</td>
    </tr>
  </table>
</body>
</html>
';

// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

// Additional headers
$headers .= 'To: webmaster <webmaster@email.com>' . "\r\n";
$headers .= 'From: wiz website <webmaster@email.com>' . "\r\n";
//$headers .= 'Cc: hello@email.com' . "\r\n";
//$headers .= 'Bcc: hello@email.com' . "\r\n";

// Mail it
mail($to, $subject, $message, $headers);
// send email if success or failed

if ($row_rsUpdate['Fulfilled'] == 1)  {
	// multiple recipients
$to  = 'my@email.com' . ', '; // note the comma
//$to .= 'wez@example.com';

// subject
$subject = 'successful stock update for order '.$row_rsUpdate['OrderID'].'';

// message
$message = '
<html>
<head>
  <title>successful stock update</title>
</head>
<body>
  <p>successful stock update</p>
  <table>
    <tr>
      <td>successful stock update for order '.$row_rsUpdate['OrderID'].'</td>
    </tr>
  </table>
</body>
</html>
';

// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

// Additional headers
$headers .= 'To: webmaster <webmaster@email.com>' . "\r\n";
$headers .= 'From: wiz website <webmaster@email.com>' . "\r\n";
//$headers .= 'Cc: hello@email.com' . "\r\n";
//$headers .= 'Bcc: hello@email.com' . "\r\n";

// Mail it
mail($to, $subject, $message, $headers);
}
else{
	
//new mail for testing purpose

// multiple recipients
$to  = 'my@email.com'. ', '; // note the comma
//$to .= 'wez@example.com';

// subject
$subject = 'failed order stock update order id '.$row_rsUpdate['OrderID'].'';

// message
$message = '
<html>
<head>
  <title>failed order stock update order id '.$row_rsUpdate['OrderID'].'</title>
</head>
<body>
  <p>failed order stock update order id '.$row_rsUpdate['OrderID'].'</p>
</body>
</html>
';

// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

// Additional headers
$headers .= 'To: webmaster <webmaster@email.com>' . "\r\n";
$headers .= 'From: wiz website <hello@email.com>' . "\r\n";
//$headers .= 'Cc: hello@email.com' . "\r\n";
//$headers .= 'Bcc: hello@email.com' . "\r\n";

// Mail it
mail($to, $subject, $message, $headers);
}
?>
return.php (this contains a notification to show if the order completed or failed)this page is set in paypal in the return page

Code: Select all

<?php require_once('Connections/wiz.php'); ?>
<?php
session_start();
sleep(5);

$colname_rsReturn = "-1";
if (isset($_SESSION['OrderID'])) {
  $colname_rsReturn = $_SESSION['OrderID'];
}
mysql_select_db($database_wiz, $wiz);
$query_rsReturn = sprintf("SELECT * FROM wiz_orders WHERE OrderID = %s", GetSQLValueString($colname_rsReturn, "int"));
$rsReturn = mysql_query($query_rsReturn, $wiz) or die(mysql_error());
$row_rsReturn = mysql_fetch_assoc($rsReturn);
$totalRows_rsReturn = mysql_num_rows($rsReturn);
?>
in the body of the return page

Code: Select all

<?php if ($row_rsReturn['TransactResult'] == 'Completed'):?>
order complete
<?php endif ; ?>
<?php if ($row_rsReturn['TransactResult'] != 'Completed'):?>
failed
<?php endif ; ?>

so it should just read that the order is complete ( which it is) but the first time it reads its awaiting....

the notify page works, it updates stock, populates the correct fields in the database and sends emails(emails have some details missing)

but
when the user is sent back to the return.php it says the order has failed even though it hasn't then if you refresh it shows it is complete so i put a 5 second sleep on the page but it still fails.

i was thinking of putting a refresh on it to see if that help but want to find out why is not quicker to update the table
i have got the emails working correctly by using the information from the POST variables and i have added a refresh on the return page as a quick fix