Easy Paypal Question for Someone Who Knows What They're Doing

While I'm supremely confident this is cake and ice cream for someone who's been down this road before, I'm like a pig on roller skates right about now so I'm hoping someone can help me.

This much I know: I want to use Paypal's IPN and a custom field as part of the "handshake" that occurs between my database and Paypal's notification of a valid transaction.

I'm using a hosted button that looks like this:

<div align="center"><form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="K9AU4PN9N6JMS">
<input type="hidden" name="custom" value="<?php echo $novie_id; ?>">
<input type="image" src="images/no_ads.png" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
<input type="hidden" name="notify_url" value=”http://www.brucegust.com/paypal_listener.php">

Notice the "custom" field which I'm including based on the IPN simulator including a custom field and the "notify_url" field which I'm including based on the counsel I received from a helpful Paypal support agent.

I'll run my code through the simulator and I'll get a successful response, but there's no change to my database. By that I mean, I need to update the "paid" field with today's date. Here's the code that I'm using to make that happen:

include ("carter.inc");
$cxn = mysqli_connect($host,$user,$password,$database)
or die ("couldn't connect to server");

  // Read the notification from PayPal and create the acknowledgement response
  $req = 'cmd=_notify-validate';               // add 'cmd' to beginning of the acknowledgement you send back to PayPal

  foreach ($_POST as $key => $value) {         // Loop through the notification NV pairs
    $value = urlencode(stripslashes($value));  // Encode the values
    $req .= "&$key=$value";                    // Add the NV pairs to the acknowledgement

$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
$payer_id= $_POST['custom'];

//Set up the acknowledgement request headers
  $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";

  //Open a socket for the acknowledgement request
  $fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

  // Post request back to PayPal for validation
  fputs ($fp, $header . $req);

  while (!feof($fp)) {                     // While not EOF
    $res = fgets ($fp, 1024);              // Get the acknowledgement response
    if (strcmp ($res, "VERIFIED") == 0) {  // Response is VERIFIED

      // Send an email announcing the IPN message is VERIFIED
      $mail_From = "IPN@example.com";
      $mail_To = "bruce@brucegust.com";
      $mail_Subject = "VERIFIED IPN";
      $mail_Body = $req;
      mail($mail_To, $mail_Subject, $mail_Body, $mail_From);

	  //I'm going to update my database here
	  $bruce="update links set paid = '$today' where id='$payer_id'";
	  $bruce_query=mysqli_query($cxn, $bruce);
	  $nuts=mysqli_errno($cxn).': '.mysqli_error($cxn);
      // Notification protocol is complete, OK to process notification contents

      // Possible processing steps for a payment might include the following:

      // Check that the payment_status is Completed
      // Check that txn_id has not been previously processed
      // Check that receiver_email is your Primary PayPal email
      // Check that payment_amount/payment_currency are correct
      // Process payment

    else if (strcmp ($res, "INVALID") == 0) { // Response is INVALID

      // Notification protocol is NOT complete, begin error handling

      // Send an email announcing the IPN message is INVALID
      $mail_From = "IPN@example.com";
      $mail_To = "bruce@brucegust.com";
      $mail_Subject = "INVALID IPN";
      $mail_Body = $req;
      mail($mail_To, $mail_Subject, $mail_Body, $mail_From);
   fclose ($fp);  //close file pointer

Open in new window

Based on the fact that my database is not being updated, despite what appears to be a successfully completed transaction, I'm lost as to what I'm missing. So, here are my two questions:

Am I passing my customer's id correctly by using the hidden "custom" field within my button?
Is that information being included in my IPN? Is there a way I can "echo" the script so I can see what's going on under the hood?

Thanks in advance for the help!
brucegustPHP DeveloperAsked:
Who is Participating?
Cornelia YoderConnect With a Mentor ArtistCommented:
Can you check (echo it out before the call to paypal) and see if


has the value you expect you are sending in the custom field?  Perhaps that value isn't set and thus you are getting nothing back from PayPal.

Also you could check your PayPal account directly and see if that custom value is correct there.

Otherwise, your method looks fine to me.

By the way, an email works, but I prefer to use a special database table I call PayPalDebug and update that with all the values I get back (at least when I am testing), so I can see them and store them easily.
Marco GasiConnect With a Mentor FreelancerCommented:
First, I would try to pass a hardcoded id to see if the script updates the database:

$bruce="update links set paid = '$today' where id='1'";

Second, you can send an email to you to see how the query is formed:

$bruce="update links set paid = '$today' where id='$payer_id'";
mail('your_email_address', 'test query', $bruce);

Hope this helps.
brucegustPHP DeveloperAuthor Commented:
MarqusG, I ran the test code like you suggested and it worked and I got the email with the syntax to confirm it.

So, we're good to go there. The thing that's gnawing at me is the whole "custom" field. Am I passing that correctly in my button code? Does Paypal see that hidden "custom" field and send it back to me? That's the disconnect that's got me concerned.

What do you think?
Ray PaseurConnect With a Mentor Commented:
I would try this... Do the same email thing, but do it at line 13, like this:

mail('your_email_address', 'test request', $req);

Then you can look in the email and see if "custom" is coming through.

But it looks like you're already getting the $req mailed to you, right?  In an async script like the PayPal IPN, a die() statement with a message is not useful -- it has no way to get the message to you, so you have to use a log file or email or something similar.
Marco GasiFreelancerCommented:
Also, if $payer_id grabs the custom field returned by Paypal, emailing to you $bruce should give you the ability to see if $payewr_id is what it is expected to be. If it is, then we can think you're passing that value correctly and it is correclty processed and returned by Paypal, isn't it?
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.