Help with some PHP Code Understanding

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
legend986
Forum Contributor
Posts: 258
Joined: Sun Jul 15, 2007 2:45 pm

Help with some PHP Code Understanding

Post by legend986 »

The post is big... but please please... Its because of the code... thats all! I promise, my question will be a small one... I'm trying to integrate my site with Paypal's IPN. For that it requires me to send a few variables in the following manner:

Code: Select all

<form action="<?php echo $_config['ec_uri']; ?>" method="post">
			<input type="hidden" name="cmd" value="_xclick"/>
			<input type="hidden" name="business" value="<?php echo $_config['ec_vendor_id']; ?>"/>
			<input type="hidden" name="item_name" value="<?php echo $_GET['combo_name']; ?>"/>
			<input type="hidden" name="item_number" value="<?php echo $_GET['payment_id']; ?>"/>
			<input type="hidden" name="amount" value="<?php echo $_GET['total_cost']; ?>"/>
			<input type="hidden" name="page_style" value="Primary"/>
			<input type="hidden" name="notify_url" value="md/cc/ipn_response.php"/>
			<input type="hidden" name="no_shipping" value="0"/>
			<input type="hidden" name="return" value="md/cc/thanks.php"/>
			<input type="hidden" name="cancel_return" value="md/cc/nothanks.php"/>
			<input type="hidden" name="no_note" value="1"/>
			<input type="hidden" name="currency_code" value="<?php echo $_config['ec_currency']; ?>"/>
			<input type="hidden" name="lc" value="CA"/>
			<input type="submit" border="0" name="submit" value="Pay by PayPal"/>
			<img src="visa_42x27.gif" title="<?php echo _AT('ec_acceptvisa'); ?>" alt="<?php echo _AT('ec_acceptvisa'); ?>" align="middle" /> <img src="<?php echo $_base_path; ?>mods/ecomm/images/mc_42x27.gif" title="<?php echo _AT('ec_acceptmastercard'); ?>" alt="<?php echo _AT('ec_acceptmastercard'); ?>" align="middle" />
		</form>
I'm testing the script using PayPal sandbox.... Everything works fine.. I'm being directed to the PayPal site with the required item with the associated cost. I'm even able to pay. The problem is it returns me to the script I asked it to i.e. thanks.php in this case. The PayPal guys asked me to construct a file ipn_response.php that looks something like this:

Code: Select all

<?php

// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';

foreach ($_GET as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}

// post back to PayPal system to validate
$header = "";
$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.sandbox.paypal.com', 80, $errno, $errstr, 30);

// assign posted variables to local variables
$item_name = $_GET['item_name'];
$item_number = $_GET['item_number'];
$payment_status = $_GET['payment_status'];
$payment_amount = $_GET['mc_gross'];
$payment_currency = $_GET['mc_currency'];
$txn_id = $_GET['txn_id'];
$receiver_email = $_GET['receiver_email'];
$payer_email = $_GET['payer_email'];

if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// check 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) {
// log for manual investigation
}
}
fclose ($fp);
}

?>
I wanted to know the purpose of this file. I've got a little info from some other site but can't understand the purpose of this file:

Code: Select all

The form also includes two URLs, called return and cancel_return. These are used to send the user back to my web site after he completes or cancels the PayPal transaction. I've created two simple web pages called thanks.html and canceled.html for this example.

I could stop right here, slap that HTML on a web page, and start taking orders for doodads. Whenever someone clicks on the PayPal button and buys a doodad, PayPal will email the transaction details and the customer's contact information to me. But, say I want to automatically enter that customer and transaction data into my own database. I can easily extend the above block of HTML to notify my web server of all transactions as they happen. Simply add one more hidden input field to the HTML form:

<input type="hidden" name="notify_url" value="http://alanb.com/doodads/ipn_response.php">

Now PayPal's servers will call my ipn_response.php, with the details of each doodad order as it occurs. This is Instant Payment Notification. PayPal uses the HTTP POST method to send transaction details to notify.cgi. Then notify.cgi echoes that transaction data back to PayPal to confirm the validity of the payment.
I want to do one thing: When I get a confirmation from PayPal, I want to update my own database saying that the user has paid the money. I don't know where to accommodate this code to make it work... I see so many variables txn_id, item_id and so on... that I'm confused as to what all are to be stored in the database and what operations I need to perform to be able to say that the user is not being asked to pay for the second time. I'm new to payments, so please advice me...
User avatar
boo
Forum Commoner
Posts: 42
Joined: Mon Jul 02, 2007 11:30 am
Location: NY

Post by boo »

You will need to add your code within this portion of your IPN script

Code: Select all

if (strcmp ($res, "VERIFIED") == 0) { 
// check 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 
}
You should also do what the comment say. Check if payment is Complete, check the txn_id.....

Within this part of the IPN you have verified that the system you are talking with is PayPal so from here you can start to see if the payment was made and for what transaction it was made for.

As for this part where you are setting the variables

Code: Select all

// assign posted variables to local variables 
$item_name = $_GET['item_name']; 
$item_number = $_GET['item_number']; 
$payment_status = $_GET['payment_status']; 
$payment_amount = $_GET['mc_gross']; 
$payment_currency = $_GET['mc_currency']; 
$txn_id = $_GET['txn_id']; 
$receiver_email = $_GET['receiver_email']; 
$payer_email = $_GET['payer_email'];
The IPN interface has a bunch more values that you can return which you can find more information about here

http://www.paypal.com/cgi-bin/webscr?cm ... ro-outside

Hope this helps
User avatar
legend986
Forum Contributor
Posts: 258
Joined: Sun Jul 15, 2007 2:45 pm

Post by legend986 »

Thanks a lot... I did something like this:

Code: Select all

if (strcmp ($res, "VERIFIED") == 0) {
// check 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

$sql = "SOME STATEMENT HERE TO UPDATE THE DATABASE";
$result = mysql_query($sql);
} 
Now, after someone pays me the amount, they are being directed to thanks.php and then according to the script, this script will be called and if the payment was successful, this ipn_response.php will be executed in the background and the statements above will be executed.. Am i right?

I have a problem understanding the txn_id and other parameters... Will you be kind enough to give me an example flow of how I should go about assuming that I'm trying to sell a product x, that has its own product_id and cost associated with it?
User avatar
boo
Forum Commoner
Posts: 42
Joined: Mon Jul 02, 2007 11:30 am
Location: NY

Post by boo »

Yes this is where you would do any SQL statements to update your database that a payment has been made.

The TXN_ID is a value that you can pass in on your form when the customer clicks on your buy now button. You use this to prevent fraud so you pass in a transaction number, this is something that uniquely identifies this transaction (something like an order number) when PayPal passes this value back to you, you should verify that this transaction (or order number) is one that is in already in your system and that a payment has not already been made for this order. By doing this you can have a little added security that the transaction is a valid one.

Here is a little flow of the transaction

Customer clicks on payment button
Customer is sent to paypal with all of the needed information
Customer makes the payment
Paypal calls your IPN script (the 2 talk for a little bit)
Your script then verifies that this is a valid payment
Your script adds this payment to your system (and does whatever other process you would like ie send email to you that payment made...)
Paypal then sends the customer to your thankyou page

On the link above they do have a little demo on how this works which covers the above process.
User avatar
legend986
Forum Contributor
Posts: 258
Joined: Sun Jul 15, 2007 2:45 pm

Post by legend986 »

Oh... So TXN_ID is a unique number that I have to generate...? How would I generate that? Would it be random number? The flow is something like this:
  1. 1. I display the product
    2. I generate a random transaction id and then associate it with that product for the time being or probably keep going in a sequential way so that overlapping never occurs maybe by declaring that field as an auto_increment in MySQL
    3. When the user clicks on the Buy button, I send out the following to the PayPal URL:
    • cmd
      business
      item_name
      item_number
      amount
      page-style
      notify_url
      no_shipping
      return
      cancel_return
      currency_code
      txn_id - Should this be sent too?
    4. Now the user goes to the PayPal website and then buys whatever he wants and then confirms payment
    5. At this point, PayPal processes his order and then displays the final page - from where he is asked to click on a link to go back to the thanks page and the PayPal site in the background contacts my ipn_response.php script where I need to get back the txn_id and then check with my database that such an id exists and that the payment has not been made. If the payment is not made, I'll update the database. But what will I do if it says the payment has already been made? I wouldn't update anything in the database is it?
    6. Also at this point, if the payment was not made before, after updating the payment status, I'll do whatever else is pending, maybe add him into the members list or whatever.
So is my flow right? I am a little confused because in one of the other scripts that I saw, there was a payment_id and another transaction_id... I didn't understand what the difference between two is... Thats the only thing that led me to the whole confusion...
Begby
Forum Regular
Posts: 575
Joined: Wed Dec 13, 2006 10:28 am

Post by Begby »

The Ids are generated by paypal and are unique. All you need to do is check the transaction ID against your database to make sure it hasn't already been used. If it has already been used then its a fraudster. If it hasn't been used then save it with a record of the transaction.

You can always do print_r($_POST) for testing as well to see what paypal is sending you and take a look at the ids.

This link has info on the things you have to check every time a request comes in.

https://www.paypal.com/cgi-bin/webscr?c ... ew-outside
User avatar
legend986
Forum Contributor
Posts: 258
Joined: Sun Jul 15, 2007 2:45 pm

Post by legend986 »

I'm trying everything that was advised in the above posts... Just a weird doubt... Will ipn_response.php script work even if I am testing the system using EasyPHP? I mean, there was a different payment system that everyone said worked but then it didn't work in my computer... I mean, the database update didn't take place => PayPal couldn't communicate with my ipn_response.php but is able to call my thanks.php without a problem...
User avatar
legend986
Forum Contributor
Posts: 258
Joined: Sun Jul 15, 2007 2:45 pm

Post by legend986 »

Done!! I've actually changed the return_url to ipn_response.php and it was able to recognize that the payment was made (atleast I hope so because the conditions were executed correctly)... Now I need to just use that notify_url and see if it works... Will keep posted if it does... :D
User avatar
legend986
Forum Contributor
Posts: 258
Joined: Sun Jul 15, 2007 2:45 pm

Post by legend986 »

:( Unless I ask it to contact the ipn_response.php file directly, it is not able to contact through the notify_url... So instead of the thanks.php, is it ok if i put up the ipn_response.php in the following code?

Code: Select all

<input type="hidden" name="notify_url" value="http://www.something.com/mods/course_combos/ipn_response.php"/>
			<input type="hidden" name="no_shipping" value="0"/>
			<input type="hidden" name="return" value="http://www.something.com/mods/course_combos/thanks.php"/>
Post Reply