Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 9 of 9
  1. #1
    Regular Coder
    Join Date
    Mar 2009
    Posts
    107
    Thanks
    15
    Thanked 0 Times in 0 Posts

    Paypal IPN problems

    Hey Guys,
    Im having trouble with a paypal IPN script,
    origionally , it was passing all the informationt to paypal
    and then entering the transaction into the database once complete.

    This worked fine, i then decided that i wanted to pass the session id
    as a hidden field to paypal and then "update" an already existing entry in the database by the session id.

    this way all the users info could be logged before he/she went to paypal.

    how ever i can not seem to get this to work, am i write in thinking that this is possible?

    I would REALLY appreciate any help anybody can provide.


    Code:
    <form class="paypal" action="" method="post" id="paypal_form" target="_blank">    
    	<input type="hidden" name="cmd" value="_xclick" /> 
        <input type="hidden" name="no_note" value="1" />
        <input type="hidden" name="lc" value="UK" />
        <input type="hidden" name="currency_code" value="GBP" />
        <input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynow_LG.gif:NonHostedGuest" />
        <input type="hidden" name="first_name" value="<? echo $forename ; ?>"  />
        <input type="hidden" name="address_street" value="<? echo $address ; ?>"  />
        <input type="hidden" name="address_zip" value="<? echo $postcode ; ?>"  />
        <input type="hidden" name="last_name" value="<? echo $surname ; ?>"  />
        <input type="hidden" name="payer_email" value="<? echo $email ; ?>"  />
        <input type="hidden" name="custom" value="<? echo $key ; ?>"  />
        <input type="hidden" name="item_number" value="1" / >
        <input type="submit"  value="Submit Payment"/>
    </form>
    I Think the problem could be that my sql code is incorrect.
    PHP Code:
    }

    function 
    updatePayments($data){    
        global 
    $link;
        if(
    is_array($data)){    
        
        
    $sql mysql_query("UPDATE payments SET txnid='".$data['txn_id']."' , payment_amount='".$data['payment_amount']."' , payment_status='$".$data['payment_status']."' , itemid='".$data['item_number']."', createdtime='".date("Y-m-d H:i:s")."' , email='".$data['payer_email']."', session='".$data['key']."' WHERE session='".$data['key']."'") ;
                
        return 
    mysql_insert_id($link);
        }


    Any pointers would be massivley appreciated , been trying to fix this all night!
    Last edited by IamHe; 04-27-2012 at 01:06 PM.

  • #2
    Regular Coder
    Join Date
    Mar 2009
    Posts
    107
    Thanks
    15
    Thanked 0 Times in 0 Posts
    Thanks in advance!
    Last edited by IamHe; 04-27-2012 at 01:06 PM.

  • #3
    Regular Coder
    Join Date
    Mar 2009
    Posts
    107
    Thanks
    15
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by iBall View Post
    I don't see the point of sending the user's personal details (name, address etc) to PayPal, even as pass through variables because PayPal doesn't need all that info at all. And if the personal details are hijacked in transit by some remote chance by a malicious hacker then you might even face legal liabilities.

    I would suggest that when the user clicks your checkout button, you first create an order number in your database and then present a form to the user that collects their personal details and their payment method (credit card, PayPal, direct credit or whatever) . You then store their order number, personal details and shopping cart contents in your database before anything even goes to PayPal. Then if they selected credit card or PayPal as their payment option, you send the order number and shopping cart contents to PayPal to handle the online payment.

    When you receive the verified notice at your IPN script, that means the user completed the payment for the order number and so you can update the payment status in your database for the order number you received from PayPal in the IPN data and organise the delivery of the goods and/or services.

    After a set period of time (you decide how long) if you don't receive an IPN payment confirmation from PayPal, you can delete from your database the details for the order number you took at the checkout form because you can assume the user never went through with the payment at PayPal.
    This is what i am trying to achieve (storeing the users details prior and updating after payment is completed, if its not then delete from database)

    and i aggree about passing the users details, i supposes its not really needed.

    i will remove them from the form , do you have any idea why the update is not working?

  • #4
    Regular Coder
    Join Date
    Mar 2009
    Posts
    107
    Thanks
    15
    Thanked 0 Times in 0 Posts
    I have set the script so all information stores before the user goes to paypal , a unique is created and then the idea was to pass that to paypal as custom and then update by that feild.

    however it dose not seem to update, i just cant figure it out.

  • #5
    Super Moderator
    Join Date
    May 2002
    Location
    Perth Australia
    Posts
    4,073
    Thanks
    11
    Thanked 98 Times in 96 Posts
    you need to see the error that mysql is giving you (if any) to help debug...

    PHP Code:
    <?
    $sql
    ="UPDATE `payments` SET etc etc";
    mysql_query($sql)or die($sql.' '.mysql_error());
    ?>
    if your query is failing the above should tell you why, just remember to remove that before production use, if the above gives you no output then print_r($data) at the start of your function to make sure its actually getting called.
    resistance is...

    MVC is the current buzz in web application architectures. It comes from event-driven desktop application design and doesn't fit into web application design very well. But luckily nobody really knows what MVC means, so we can call our presentation layer separation mechanism MVC and move on. (Rasmus Lerdorf)

  • #6
    Senior Coder
    Join Date
    Feb 2011
    Location
    Your Monitor
    Posts
    4,341
    Thanks
    60
    Thanked 527 Times in 514 Posts
    Blog Entries
    4
    Quote Originally Posted by IamHe View Post
    This is what i am trying to achieve (storeing the users details prior and updating after payment is completed, if its not then delete from database)

    and i aggree about passing the users details, i supposes its not really needed.

    i will remove them from the form , do you have any idea why the update is not working?
    There is no need to remove the users details from the form - you may need them in the future. Just don't transmit them to paypal.

    Also I wouldn't delete failed purchases from your database. Depending on your country there may be laws regarding the storage of financial transactions (completed and failed). In the UK you have to keep these records for 6 years for audit purposes. Deleting them will serve you no purpose if a customer emails you complaining that their order hasn't been processed either - you'll have no records of it and could have received their money with no idea who it's from. At that point your customer will accuse you of being a theif etc.

    Keep the records but don't transmit more than is necessary to paypal.
    See my new CodingForums Blog: http://www.codingforums.com/blogs/tangoforce/

    Many useful explanations and tips including: Cannot modify headers - already sent, The IE if (isset($_POST['submit'])) bug explained, unexpected T_CONSTANT_ENCAPSED_STRING, debugging tips and much more!

  • #7
    Regular Coder
    Join Date
    Mar 2009
    Posts
    107
    Thanks
    15
    Thanked 0 Times in 0 Posts
    Ill paste the entire script below , its in two parts, payments.php & functions.php

    i would GREATLY appeciate any help anybody could give me , i have a website thats been waiting to go live for a week because i cant figure this out :/

    Payments.php
    PHP Code:
    <?php
    // Database variables
    $host "localhost"//database location
    $user ""//database username
    $pass ""//database password
    $db_name ""//database name

    // PayPal settings
    $paypal_email 'paypal@example.com';
    $return_url 'http://example.com/payment-successful.htm';
    $cancel_url 'http://example.com/payment-cancelled.htm';
    $notify_url 'http://example.com/paypal/payments.php';

    $item_name 'Test Item';
    $item_amount 5.00;

    // Include Functions
    include("functions.php");

    //Database Connection
    $link mysql_connect($host$user$pass);
    mysql_select_db($db_name);

    // Check if paypal request or response
    if (!isset($_POST["txn_id"]) && !isset($_POST["txn_type"])){

        
    // Firstly Append paypal account to querystring
        
    $querystring .= "?business=".urlencode($paypal_email)."&";    
        
        
    // Append amount& currency (£) to quersytring so it cannot be edited in html
        
        //The item name and amount can be brought in dynamically by querying the $_POST['item_number'] variable.
        
    $querystring .= "item_name=".urlencode($item_name)."&";
        
    $querystring .= "amount=".urlencode($item_amount)."&";
        
        
    //loop for posted values and append to querystring
        
    foreach($_POST as $key => $value){
            
    $value urlencode(stripslashes($value));
            
    $querystring .= "$key=$value&";
        }
        
        
    // Append paypal return addresses
        
    $querystring .= "return=".urlencode(stripslashes($return_url))."&";
        
    $querystring .= "cancel_return=".urlencode(stripslashes($cancel_url))."&";
        
    $querystring .= "notify_url=".urlencode($notify_url);
        
        
    // Append querystring with custom field
        //$querystring .= "&custom=".USERID;
        
        // Redirect to paypal IPN
        
    header('location:https://www.sandbox.paypal.com/cgi-bin/webscr'.$querystring);
        exit();

    }else{
        
        
    // Response from Paypal

        // read the post from PayPal system and add 'cmd'
        
    $req 'cmd=_notify-validate';
        foreach (
    $_POST as $key => $value) {
            
    $value urlencode(stripslashes($value));
            
    $value preg_replace('/(.*[^%^0^D])(%0A)(.*)/i','${1}%0D%0A${3}',$value);// IPN fix
            
    $req .= "&$key=$value";
        }
        
        
    // assign posted variables to local variables
        
    $data['item_name']            = $_POST['item_name'];
        
    $data['item_number']         = $_POST['item_number'];
        
    $data['payment_status']     = $_POST['payment_status'];
        
    $data['payment_amount']     = $_POST['mc_gross'];
        
    $data['payment_currency']    = $_POST['mc_currency'];
        
    $data['txn_id']                = $_POST['txn_id'];
        
    $data['receiver_email']     = $_POST['receiver_email'];
        
    $data['payer_email']         = $_POST['payer_email'];
        
    $data['custom']             = $_POST['custom'];
            
        
    // 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 ('ssl://www.sandbox.paypal.com'443$errno$errstr30);    
        
        if (!
    $fp) {
            
    // HTTP ERROR
        
    } else {    

            
    fputs ($fp$header $req);
            while (!
    feof($fp)) {
                
    $res fgets ($fp1024);
                if (
    strcmp($res"VERIFIED") == 0) {
                
                    
    // Used for debugging
                    //@mail("you@youremail.com", "PAYPAL DEBUGGING", "Verified Response<br />data = <pre>".print_r($post, true)."</pre>");
                            
                    // Validate payment (Check unique txnid & correct price)
                    
    $valid_txnid check_txnid($data['txn_id']);
                    
    $valid_price check_price($data['payment_amount'], $data['item_number']);
                    
    // PAYMENT VALIDATED & VERIFIED!
                    
    if($valid_txnid && $valid_price){                
                        
    $orderid updatePayments($data);        
                        if(
    $orderid){                    
                            
    // Payment has been made & successfully inserted into the Database                                
                        
    }else{                                
                            
    // Error inserting into DB
                            // E-mail admin or alert user
                        
    }
                    }else{                    
                        
    // Payment made but data has been changed
                        // E-mail admin or alert user
                    
    }                        
                
                }else if (
    strcmp ($res"INVALID") == 0) {
                
                    
    // PAYMENT INVALID & INVESTIGATE MANUALY! 
                    // E-mail admin or alert user
                    
                    // Used for debugging
                    //@mail("you@youremail.com", "PAYPAL DEBUGGING", "Invalid Response<br />data = <pre>".print_r($post, true)."</pre>");
                
    }        
            }        
        
    fclose ($fp);
        }    
    }
    ?>
    Functions.php
    PHP Code:
    <?php
    // functions.php
    function check_txnid($tnxid){
        global 
    $link;
        return 
    true;
        
    $valid_txnid true;
        
    //get result set
        
    $sql mysql_query("SELECT * FROM `payments` WHERE txnid = '$tnxid'"$link);        
        if(
    $row mysql_fetch_array($sql)) {
            
    $valid_txnid false;
        }
        return 
    $valid_txnid;
    }

    function 
    check_price($price$id){
        
    $valid_price false;
        
    //you could use the below to check whether the correct price has been paid for the product
        
        /* 
        $sql = mysql_query("SELECT amount FROM `products` WHERE id = '$id'");        
        if (mysql_numrows($sql) != 0) {
            while ($row = mysql_fetch_array($sql)) {
                $num = (float)$row['amount'];
                if($num == $price){
                    $valid_price = true;
                }
            }
        }
        return $valid_price;
        */
        
    return true;
    }

    function 
    updatePayments($data){    
        global 
    $link;
        if(
    is_array($data)){                
            
    $sql mysql_query("INSERT INTO `payments` (txnid, payment_amount, payment_status, itemid, createdtime) VALUES (
                    '"
    .$data['txn_id']."' ,
                    '"
    .$data['payment_amount']."' ,
                    '"
    .$data['payment_status']."' ,
                    '"
    .$data['item_number']."' ,
                    '"
    .date("Y-m-d H:i:s")."' 
                    )"
    $link);
        return 
    mysql_insert_id($link);
        }
    }
    ?>
    that all works GREAT , however , when i came to try and alter it...to update the database instead of updating , i couldnt get it to work.

    i tried:

    PHP Code:
    }

    function 
    updatePayments($data){    
        global 
    $link;
        if(
    is_array($data)){    
        
        
    $sql mysql_query("UPDATE payments SET payment_status='complete' , createdtime='".date("Y-m-d H:i:s")."'  , WHERE uniqueid=''".$data['custom']."'") ;
        return 
    mysql_insert_id($link);
        }


  • #8
    Super Moderator
    Join Date
    May 2002
    Location
    Perth Australia
    Posts
    4,073
    Thanks
    11
    Thanked 98 Times in 96 Posts
    you have an extra single quote in your $sql WHERE uniqueid=''".$d and an unneeded comma b4 the WHERE statement

    if you are in a rush you should heed the advice already given and show us the actual error you are getting..... the code posted earlier would have shown you these errors

    PHP Code:
    $q="UPDATE `payments` SET `payment_status`= 'complete' , `createdtime`='".date("Y-m-d H:i:s")."' WHERE `uniqueid`='{$data['custom']}'";
    $sql mysql_query($q) or die($sql.'<br />'.mysql_error()); 
    resistance is...

    MVC is the current buzz in web application architectures. It comes from event-driven desktop application design and doesn't fit into web application design very well. But luckily nobody really knows what MVC means, so we can call our presentation layer separation mechanism MVC and move on. (Rasmus Lerdorf)

  • #9
    Regular Coder
    Join Date
    Mar 2009
    Posts
    107
    Thanks
    15
    Thanked 0 Times in 0 Posts
    no error comes back from the script.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •