Classico Posted October 18, 2012 Share Posted October 18, 2012 Hi, I'll try explain this the best I can. I have a PayPal IPN script that works, inserts the the data into my database etc. But i'm having trouble with a custom variable. I can seem to pass it through to paypal. I have my input field <input type="text" name="on0" value=""> . This is where the will insert his/her username. And when the press the button <form action="https://www.paypal.com/cgi-bin/webscr" method="POST"> <center><input type="text" name="on0" value=""> <br /> <?php $on0 = $_POST['on0']; ?> <input type="hidden" name="cmd" value="_xclick"> <input type="hidden" name="business" value="donate@dawncraftmc.com"> <input type="hidden" name="item_name" value="VIP"> <input type="hidden" name="item_number" value="1"> <input type="hidden" name="amount" value="0.01"> <input type="hidden" name="no_shipping" value="1"> <input type="hidden" name="no_note" value="1"> <input type="hidden" name="currency_code" value="GBP"> <input type="hidden" name="lc" value="GB"> <input type="hidden" name="bn" value="PP-BuyNowBF"> <input type="hidden" name="return" value="http://www.dawncraftmc.com/index.html"> <input type="hidden" name="cancel_return" value="http://www.dawncraftmc.com/index.html"> <input type="hidden" name="rm" value="2"> <input type="hidden" name="notify_url" value="http://vip.dawncraftmc.com/ipn.php" /> <input type="hidden" name="on0" value=""> <input type="hidden" name="os0" value="<?php echo $on0; ?>"> <input type="image" src="https://www.paypalobjects.com/en_US/GB/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online."> <img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1"></center> </form> , it takes them to the PayPal page, they pay, and the variables passed through to the IPN goes into the database. Could someone help me please? Tell me if i'm doing something wrong? Here is both my ipn.php and ipnlistener.php: <?php include 'connect_to_mysql.php'; // tell PHP to log errors to ipn_errors.log in this directory ini_set('log_errors', true); ini_set('error_log', dirname(__FILE__).'/ipn_errors.log'); // intantiate the IPN listener include('ipnlistener.php'); $listener = new IpnListener(); // tell the IPN listener to use the PayPal test sandbox $listener->use_sandbox = false; // try to proces try { $listener->requirePostMethod(); $verified = $listener->processIpn(); } catch (Exception $e) { error_log($e->getMessage()); exit(0); } // manually investigate variables from paypal $body = "IPN failed variable check: \n\n"; $body .= $listener->getTextReport(); mail('donate@dawncraftmc.com', 'IPN Variables', $body); if ($verified) { $errmsg = ''; // stores errors from fraud checks // 1. Make sure the payment status is "Completed" if ($_POST['payment_status'] != 'Completed') { // simply ignore any IPN that is not completed exit(0); } // 2. Make sure seller email matches your primary account email. if ($_POST['receiver_email'] != 'donate@dawncraftmc.com') { $errmsg .= "'receiver_email' does not match: "; $errmsg .= $_POST['receiver_email']."\n"; } // 3. Make sure the amount(s) paid match if ($_POST['mc_gross'] != '0.01') { $errmsg .= "'mc_gross' does not match: "; $errmsg .= $_POST['mc_gross']."\n"; } // 4. Make sure the currency code matches if ($_POST['mc_currency'] != 'GBP') { $errmsg .= "'mc_currency' does not match: "; $errmsg .= $_POST['mc_currency']."\n"; } $txn_id = mysql_real_escape_string($_POST['txn_id']); $sql = "SELECT COUNT(*) FROM log WHERE txn_id = '$txn_id'"; $r = mysql_query($sql); if (!$r) { error_log(mysql_error()); exit(0); } $exists = mysql_result($r, 0); mysql_free_result($r); if ($exists) { $errmsg .= "'txn_id' has already been processed: ".$_POST['txn_id']."\n"; } if (!empty($errmsg)) { // manually investigate errors from the fraud checking $body = "IPN failed fraud checks: \n$errmsg\n\n"; $body .= $listener->getTextReport(); mail('donate@dawncraftmc.com', 'IPN Fraud Warning', $body); } else { // add this order to a table of completed orders $payer_email = mysql_real_escape_string($_POST['payer_email']); $mc_gross = mysql_real_escape_string($_POST['mc_gross']); $option_selection1 = ($_POST['option_selection1_1'])?$_POST['option_selection1_1']:$_POST['option_selection1']; $option_selection2 = ($_POST['option_selection2_1'])?$_POST['option_selection2_1']:$_POST['option_selection2']; $sql = "INSERT INTO log VALUES ('', '$txn_id', '$payer_email', '$mc_gross', '$option_selection1', '$option_selection2')"; if (!mysql_query($sql)) { error_log(mysql_error()); exit(0); } // send user an email with a link to their digital download $to = filter_var($_POST['payer_email'], FILTER_SANITIZE_EMAIL); $subject = "Your digital download is ready"; mail($to, "Thank you for your order", "VIP"); $to = filter_var($_POST['receiver_email'], FILTER_SANITIZE_EMAIL); $subject = "Donation Received"; mail($to, "Donation Received", "Donation received from", $_POST['payer_email']); } } else { // manually investigate the invalid IPN mail('donate@dawncraftmc.com', 'Invalid IPN', $listener->getTextReport()); } ?> <?php /** * PayPal IPN Listener * * A class to listen for and handle Instant Payment Notifications (IPN) from * the PayPal server. */ class IpnListener { /** * If true, the recommended cURL PHP library is used to send the post back * to PayPal. If flase then fsockopen() is used. Default true. * * @var boolean */ public $use_curl = true; /** * If true, explicitly sets cURL to use SSL version 3. Use this if cURL * is compiled with GnuTLS SSL. * * @var boolean */ public $force_ssl_v3 = true; /** * If true, cURL will use the CURLOPT_FOLLOWLOCATION to follow any * "Location: ..." headers in the response. * * @var boolean */ public $follow_location = false; /** * If true, an SSL secure connection (port 443) is used for the post back * as recommended by PayPal. If false, a standard HTTP (port 80) connection * is used. Default true. * * @var boolean */ public $use_ssl = true; /** * If true, the paypal sandbox URI www.sandbox.paypal.com is used for the * post back. If false, the live URI www.paypal.com is used. Default false. * * @var boolean */ public $use_sandbox = false; /** * The amount of time, in seconds, to wait for the PayPal server to respond * before timing out. Default 30 seconds. * * @var int */ public $timeout = 30; private $post_data = array(); private $post_uri = ''; private $response_status = ''; private $response = ''; const PAYPAL_HOST = 'www.paypal.com'; const SANDBOX_HOST = 'www.sandbox.paypal.com'; /** * Post Back Using cURL * * Sends the post back to PayPal using the cURL library. Called by * the processIpn() method if the use_curl property is true. Throws an * exception if the post fails. Populates the response, response_status, * and post_uri properties on success. * * @param string The post data as a URL encoded string */ protected function curlPost($encoded_data) { if ($this->use_ssl) { $uri = 'https://'.$this->getPaypalHost().'/cgi-bin/webscr'; $this->post_uri = $uri; } else { $uri = 'http://'.$this->getPaypalHost().'/cgi-bin/webscr'; $this->post_uri = $uri; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->follow_location); curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); if ($this->force_ssl_v3) { curl_setopt($ch, CURLOPT_SSLVERSION, 3); } $this->response = curl_exec($ch); $this->response_status = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE)); if ($this->response === false || $this->response_status == '0') { $errno = curl_errno($ch); $errstr = curl_error($ch); throw new Exception("cURL error: [$errno] $errstr"); } } /** * Post Back Using fsockopen() * * Sends the post back to PayPal using the fsockopen() function. Called by * the processIpn() method if the use_curl property is false. Throws an * exception if the post fails. Populates the response, response_status, * and post_uri properties on success. * * @param string The post data as a URL encoded string */ protected function fsockPost($encoded_data) { if ($this->use_ssl) { $uri = 'ssl://'.$this->getPaypalHost(); $port = '443'; $this->post_uri = $uri.'/cgi-bin/webscr'; } else { $uri = $this->getPaypalHost(); // no "http://" in call to fsockopen() $port = '80'; $this->post_uri = 'http://'.$uri.'/cgi-bin/webscr'; } $fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout); if (!$fp) { // fsockopen error throw new Exception("fsockopen error: [$errno] $errstr"); } $header = "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: ".strlen($encoded_data)."\r\n"; $header .= "Connection: Close\r\n\r\n"; fputs($fp, $header.$encoded_data."\r\n\r\n"); while(!feof($fp)) { if (empty($this->response)) { // extract HTTP status from first line $this->response .= $status = fgets($fp, 1024); $this->response_status = trim(substr($status, 9, 4)); } else { $this->response .= fgets($fp, 1024); } } fclose($fp); } private function getPaypalHost() { if ($this->use_sandbox) return IpnListener::SANDBOX_HOST; else return IpnListener::PAYPAL_HOST; } /** * Get POST URI * * Returns the URI that was used to send the post back to PayPal. This can * be useful for troubleshooting connection problems. The default URI * would be "ssl://www.sandbox.paypal.com:443/cgi-bin/webscr" * * @return string */ public function getPostUri() { return $this->post_uri; } /** * Get Response * * Returns the entire response from PayPal as a string including all the * HTTP headers. * * @return string */ public function getResponse() { return $this->response; } /** * Get Response Status * * Returns the HTTP response status code from PayPal. This should be "200" * if the post back was successful. * * @return string */ public function getResponseStatus() { return $this->response_status; } /** * Get Text Report * * Returns a report of the IPN transaction in plain text format. This is * useful in emails to order processors and system administrators. Override * this method in your own class to customize the report. * * @return string */ public function getTextReport() { $r = ''; // date and POST url for ($i=0; $i<80; $i++) { $r .= '-'; } $r .= "\n[".date('m/d/Y g:i A').'] - '.$this->getPostUri(); if ($this->use_curl) $r .= " (curl)\n"; else $r .= " (fsockopen)\n"; // HTTP Response for ($i=0; $i<80; $i++) { $r .= '-'; } $r .= "\n{$this->getResponse()}\n"; // POST vars for ($i=0; $i<80; $i++) { $r .= '-'; } $r .= "\n"; foreach ($this->post_data as $key => $value) { $r .= str_pad($key, 25)."$value\n"; } $r .= "\n\n"; return $r; } /** * Process IPN * * Handles the IPN post back to PayPal and parsing the response. Call this * method from your IPN listener script. Returns true if the response came * back as "VERIFIED", false if the response came back "INVALID", and * throws an exception if there is an error. * * @param array * * @return boolean */ public function processIpn($post_data=null) { $encoded_data = 'cmd=_notify-validate'; if ($post_data === null) { // use raw POST data if (!empty($_POST)) { $this->post_data = $_POST; $encoded_data .= '&'.file_get_contents('php://input'); } else { throw new Exception("No POST data found."); } } else { // use provided data array $this->post_data = $post_data; foreach ($this->post_data as $key => $value) { $encoded_data .= "&$key=".urlencode($value); } } if ($this->use_curl) $this->curlPost($encoded_data); else $this->fsockPost($encoded_data); if (strpos($this->response_status, '200') === false) { throw new Exception("Invalid response status: ".$this->response_status); } if (strpos($this->response, "VERIFIED") !== false) { return true; } elseif (strpos($this->response, "INVALID") !== false) { return false; } else { throw new Exception("Unexpected response from PayPal."); } } /** * Require Post Method * * Throws an exception and sets a HTTP 405 response header if the request * method was not POST. */ public function requirePostMethod() { // require POST requests if ($_SERVER['REQUEST_METHOD'] && $_SERVER['REQUEST_METHOD'] != 'POST') { header('Allow: POST', true, 405); throw new Exception("Invalid HTTP request method."); } } } ?> I'm testing this on the real PayPal, not the sandbox. Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/ Share on other sites More sharing options...
Beeeeney Posted October 18, 2012 Share Posted October 18, 2012 That's cool, do you have a question? Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386005 Share on other sites More sharing options...
Classico Posted October 18, 2012 Author Share Posted October 18, 2012 That's cool, do you have a question? Could someone help me please? Tell me if i'm doing something wrong? [/code] Can you not read? There's my question. Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386017 Share on other sites More sharing options...
Beeeeney Posted October 18, 2012 Share Posted October 18, 2012 To be fair I didn't see that, maybe would've been more noticeable if you put it at the bottom of your post. Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386019 Share on other sites More sharing options...
Classico Posted October 18, 2012 Author Share Posted October 18, 2012 Sorry about that. It would of been better if it was posted at the bottom of the thread. Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386023 Share on other sites More sharing options...
Beeeeney Posted October 18, 2012 Share Posted October 18, 2012 Now you'll just have to wait for someone who knows how to help. Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386029 Share on other sites More sharing options...
premiso Posted October 18, 2012 Share Posted October 18, 2012 I don't see anywhere in your paypal form where you have the <input name="custom"... being set. How do you expect it to be passed through without setting it? Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386037 Share on other sites More sharing options...
Classico Posted October 18, 2012 Author Share Posted October 18, 2012 Premiso, I got help from someone else on another forum. He told me to use 'on0' and 'os0', and that it should work after I put in <?php $on0 = $_POST['on0']; ?> and: <input type="hidden" name="on0" value=""> <input type="hidden" name="os0" value="<?php echo $on0; ?>"> which it never. I don't want spoon feeding, but would you be able to tell me in some description how I'd go about setting the variable and passing it through to the IPN? Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386045 Share on other sites More sharing options...
premiso Posted October 18, 2012 Share Posted October 18, 2012 Well the question is, do you want it to be on or do you want it to just be "custom". The onX stuff is nice if you need multiple items you want to show up on the invoice. However, if you want it to be more or less hidden the custom field is the way to go. Let me know which you want and I can fix you up. And also, next time post relevant code for your OP, posting ALL your code is just messy and sort of annoying Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386051 Share on other sites More sharing options...
Classico Posted October 18, 2012 Author Share Posted October 18, 2012 I just need it so the user can enter their username in the input field. I'm guessing it'll be custom, since you said the onX stuff is for multiple items? Sorry about posting all of the code, people usually tend to get quite... nasty when you don't Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386053 Share on other sites More sharing options...
premiso Posted October 18, 2012 Share Posted October 18, 2012 (edited) I just need it so the user can enter their username in the input field. I'm guessing it'll be custom, since you said the onX stuff is for multiple items? The onX is for multiple items, but it will also display on the "order page" for that user. Custom will not display on the order page it is essentially hidden. For custom just do: <input type="hidden" name="custom" value="<?php echo $on0; ?>"> Simple as that, for the onX: <input type="hidden" name="on1_1" value="Username" /> <input type="hidden" name="os1_1" value="<?php echo $on0;?>" /> For custom, you should be able to access it on the IPN page as $_POST['custom'] if the os1, should be $_POST['os1'] Sorry about posting all of the code, people usually tend to get quite... nasty when you don't It really depends on the problem, since your paypal script does work, that stuff is not necessary, the problem in this case lies with the form data It can also detract from your original problem as people like to go off on tangents. Edited October 18, 2012 by premiso Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386063 Share on other sites More sharing options...
Classico Posted October 18, 2012 Author Share Posted October 18, 2012 Thank you. I'm getting the custom field through now, it's sending as 'option_name1'. I'm inserting the payment info into my database, I'm needing the custom field too. Since it's sending as 'option_name1', will I need to insert it as 'on0', or 'custom'? Here's how I'm inserting it right now. // add this order to a table of completed orders $payer_email = mysql_real_escape_string($_POST['payer_email']); $mc_gross = mysql_real_escape_string($_POST['mc_gross']); $on0 = mysql_real_escape_string($_POST['custom']); $sql = "INSERT INTO log VALUES ('', '$txn_id', '$payer_email', '$mc_gross', '$on0')"; Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386074 Share on other sites More sharing options...
premiso Posted October 18, 2012 Share Posted October 18, 2012 If it is sending it as option_name1, use that for the post. If you are confused, do a print_r($_POST) and see what the variable name the data you want is attached to and use that in place of 'custom' Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386083 Share on other sites More sharing options...
Classico Posted October 20, 2012 Author Share Posted October 20, 2012 That works fantastic! Thank you I never knew that it was so easy. Looks like I was just using the wrong input fields and passing it through to the IPN script wrong too Quote Link to comment https://forums.phpfreaks.com/topic/269628-paypal-ipn-custom-variable/#findComment-1386579 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.