Created
July 5, 2010 18:24
-
-
Save iloveitaly/464570 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* PHP Paypal IPN Integration Class Demonstration File | |
* 6.25.2008 - Eric Wang, http://code.google.com/p/paypal-ipn-class-php/ | |
* | |
* This file demonstrates the usage of paypal.class.php, a class designed | |
* to aid in the interfacing between your website, paypal, and the instant | |
* payment notification (IPN) interface. This single file serves as 4 | |
* virtual pages depending on the "action" varialble passed in the URL. It's | |
* the processing page which processes form data being submitted to paypal, it | |
* is the page paypal returns a user to upon success, it's the page paypal | |
* returns a user to upon canceling an order, and finally, it's the page that | |
* handles the IPN request from Paypal. | |
* | |
* If you want submit a payment form to Paypal sandbox. Please add the | |
* _GET[sandbox=1] parameter to link. ie: paypal.php?sandbox=1. | |
* | |
* I tried to comment this file, aswell as the acutall class file, as well as | |
* I possibly could. Please email me with questions, comments, and suggestions. | |
* See the header of paypal.class.php for additional resources and information. | |
*/ | |
require_once('paypal_class.php'); | |
$p = new paypal_class(); | |
$p->sandbox = true; | |
if($p->sandbox) { | |
$p->admin_mail = 'notification@gmail.com'; | |
$p->paypal_mail = 'owner@softwarebusiness.com'; // equivilent to: $p->add_field('business', 'email@domain.com') | |
} else { | |
} | |
// $p->admin_mail = EMAIL_ADD; | |
//$p -> paypal_mail = PAYPAL_EMAIL_ADD; // If set, class will verify the receiver. | |
switch ($_GET['action']) { | |
default: | |
// There should be no output at this point. To process the POST data, | |
// the submit_paypal_post() function will output all the HTML tags which | |
// contains a FORM which is submited instantaneously using the BODY onload | |
// attribute. In other words, don't echo or printf anything when you're | |
// going to be calling the submit_paypal_post() function. | |
// adds or edits a "$p->add_field(key, value);" in following, which is what will be | |
// sent to paypal as POST variables. Refer to PayPal HTML Variables: | |
// https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables | |
// This is where you would have your form validation and all that jazz. | |
// You would take your POST vars and load them into the class like below, | |
// only using the POST values instead of constant string expressions. | |
// setup a current URL variable for this script | |
$this_script = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']; | |
$p->add_field('return', $this_script.'?action=success'); | |
$p->add_field('cancel_return', $this_script.'?action=cancel'); | |
$p->add_field('notify_url', $this_script.'?action=ipn'); | |
$p->add_field('item_name', 'Paypal Test Transaction'); | |
$p->add_field('cmd', '_donations'); | |
$p->add_field('custom', 9); | |
$p->add_field('rm', '2'); // Return method = POST | |
$p->submit_paypal_post(); // submit the fields to paypal | |
$p->dump_fields(); // for debugging, output a table of all the fields | |
break; | |
case 'success': // Order was successful... | |
// This is where you would probably want to thank the user for their order | |
// or what have you. The order information at this point is in POST | |
// variables. However, you don't want to "process" the order until you | |
// get validation from the IPN. That's where you would have the code to | |
// email an admin, update the database with payment status, activate a | |
// membership, etc. | |
echo "<html><head><title>Success</title></head><body><h3>Thank you for your order.</h3>"; | |
foreach ($_POST as $key => $value) { echo "$key: $value<br>"; } | |
echo "</body></html>"; | |
// You could also simply re-direct them to another page, or your own | |
// order status page which presents the user with the status of their | |
// order based on a database (which can be modified with the IPN code | |
// below). | |
break; | |
case 'cancel': // Order was canceled... | |
// The order was canceled before being completed. | |
echo "<html><head><title>Canceled</title></head><body><h3>The order was canceled.</h3>"; | |
echo "</body></html>"; | |
break; | |
case 'ipn': | |
if ($p->validate_ipn()) { | |
$subject = 'Instant Payment Notification - Received Payment'; | |
$p->send_report($subject); | |
} else { | |
$subject = 'Instant Payment Notification - Payment Fail'; | |
$p->send_report ( $subject ); | |
} | |
break; | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* PHP Paypal IPN Integration Class | |
* 6.25.2008 - Eric Wang, http://code.google.com/p/paypal-ipn-class-php/ | |
* | |
* This file provides neat and simple method to validate the paid result with Paypal IPN. | |
* It's NOT intended to make the paypal integration "plug 'n' play". | |
* It still requires the developer to understand the paypal process and know the variables | |
* you want/need to pass to paypal to achieve what you want. | |
* | |
* @author Eric Wang <eric.wzy@gmail.com> | |
* @copyright (C) 2008 - 2009 Eric.Wang | |
* | |
*/ | |
define('LOG_FILE', 'ipn_results.log'); | |
define('DEBUG_LOG_FILE', 'ipn_results_debug.log'); | |
class paypal_class { | |
private $ipn_status; | |
public $admin_mail; // receive the ipn status report pre transaction | |
public $paypal_mail; // paypal account, if set, class need to verify receiver | |
public $txn_id; // array: if the txn_id array existed, class need to verified the txn_id duplicate | |
private $ipn_response; // holds the IPN response from paypal | |
public $ipn_data = array(); // array contains the POST values for IPN | |
private $fields = array(); // array holds the fields to submit to paypal | |
public $sandbox = false; | |
private $ipn_debug = false; | |
public $ipn_log = true; | |
function __construct() { | |
$this->ipn_status = ''; | |
$this->admin_mail = null; | |
$this->paypal_mail = null; | |
$this->txn_id = null; | |
$this->tax = null; | |
$this->ipn_response = ''; | |
} | |
// adds a key=>value pair to the fields array, which is what will be | |
// sent to paypal as POST variables. | |
public function add_field($field, $value) { | |
$this->fields["$field"] = $value; | |
} | |
// this function actually generates an entire HTML page consisting of | |
// a form with hidden elements which is submitted to paypal via the | |
// BODY element's onLoad attribute. We do this so that you can validate | |
// any POST vars from you custom form before submitting to paypal. So | |
// basically, you'll have your own form which is submitted to your script | |
// to validate the data, which in turn calls this function to create | |
// another hidden form and submit to paypal. | |
// The user will briefly see a message on the screen that reads: | |
// "Please wait, your order is being processed..." and then immediately | |
// is redirected to paypal. | |
public function submit_paypal_post() { | |
echo "<html>\n"; | |
echo "<head><title>Processing Payment...</title></head>\n"; | |
echo "<body onLoad=\"document.forms['paypal_form'].submit();\">\n"; | |
echo "<center><h2>Please wait, your order is being processed and you"; | |
echo " will be redirected to the paypal website.</h2></center>\n"; | |
echo "<form method=\"post\" name=\"paypal_form\" "; | |
echo "action=\"".$this->getPaypalURL()."\">\n"; | |
if(isset($this->paypal_mail)) { | |
echo "<input type=\"hidden\" name=\"business\" value=\"$this->paypal_mail\"/>\n"; | |
} | |
foreach ($this->fields as $name => $value) { | |
echo "<input type=\"hidden\" name=\"$name\" value=\"$value\"/>\n"; | |
} | |
echo "<center><br/><br/>If you are not automatically redirected to "; | |
echo "paypal within 5 seconds...<br/><br/>\n"; | |
echo "<input type=\"submit\" value=\"Click Here\"></center>\n"; | |
echo "</form>\n"; | |
echo "</body></html>\n"; | |
} | |
public function validate_ipn() { | |
$hostname = gethostbyaddr ( $_SERVER ['REMOTE_ADDR'] ); | |
if (! preg_match ( '/paypal\.com$/', $hostname )) { | |
$this->ipn_status = 'Validation post isn\'t from PayPal'; | |
$this->log_ipn_results ( false ); | |
return false; | |
} | |
if (isset($this->paypal_mail) && strtolower ( $_POST['receiver_email'] ) != strtolower(trim( $this->paypal_mail ))) { | |
$this->ipn_status = "Receiver Email Not Match"; | |
$this->log_ipn_results ( false ); | |
return false; | |
} | |
if (isset($this->txn_id) && in_array($_POST['txn_id'],$this->txn_id)) { | |
$this->ipn_status = "txn_id have a duplicate"; | |
$this->log_ipn_results ( false ); | |
return false; | |
} | |
// parse the paypal URL | |
$url_parsed = parse_url($this->getPaypalURL()); | |
// generate the post string from the _POST vars aswell as load the | |
// _POST vars into an arry so we can play with them from the calling | |
// script. | |
$post_string = ''; | |
foreach ($_POST as $field=>$value) { | |
$this->ipn_data["$field"] = $value; | |
$post_string .= $field.'='.urlencode(stripslashes($value)).'&'; | |
} | |
$post_string.="cmd=_notify-validate"; // append ipn command | |
// open the connection to paypal | |
if($this->sandbox) { | |
$fp = fsockopen('ssl://www.sandbox.paypal.com', "443", $err_num, $err_str, 60 ); | |
} else { | |
$fp = fsockopen('ssl://www.paypal.com', "443", $err_num, $err_str, 60 ); | |
} | |
if(!$fp) { | |
// could not open the connection. If loggin is on, the error message | |
// will be in the log. | |
$this->ipn_status = "fsockopen error no. $err_num: $err_str"; | |
$this->log_ipn_results(false); | |
return false; | |
} else { | |
// Post the data back to paypal | |
fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n"); | |
fputs($fp, "Host: $url_parsed[host]\r\n"); | |
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); | |
fputs($fp, "Content-length: ".strlen($post_string)."\r\n"); | |
fputs($fp, "Connection: close\r\n\r\n"); | |
fputs($fp, $post_string . "\r\n\r\n"); | |
// loop through the response from the server and append to variable | |
while(!feof($fp)) { | |
$this->ipn_response .= fgets($fp, 1024); | |
} | |
fclose($fp); | |
} | |
// Invalid IPN transaction. Check the $ipn_status and log for details. | |
if (stristr($this->ipn_response, "VERIFIED") === FALSE) { | |
$this->ipn_status = 'IPN Validation Failed'; | |
$this->log_ipn_results(false); | |
return false; | |
} else { | |
$this->ipn_status = "IPN VERIFIED"; | |
$this->log_ipn_results(true); | |
return true; | |
} | |
} | |
private function log_ipn_results($success) { | |
$hostname = gethostbyaddr ( $_SERVER ['REMOTE_ADDR'] ); | |
// Timestamp | |
$text = '[' . date ( 'm/d/Y g:i A' ) . '] - '; | |
// Success or failure being logged? | |
if ($success) | |
$this->ipn_status = $text . 'SUCCESS:' . $this->ipn_status . "!\n"; | |
else | |
$this->ipn_status = $text . 'FAIL: ' . $this->ipn_status . "!\n"; | |
// Log the POST variables | |
$this->ipn_status .= "[From:" . $hostname . "|" . $_SERVER ['REMOTE_ADDR'] . "]IPN POST Vars Received By Paypal_IPN Response API:\n"; | |
foreach ( $this->ipn_data as $key => $value ) { | |
$this->ipn_status .= "$key=$value \n"; | |
} | |
// Log the response from the paypal server | |
$this->ipn_status .= "IPN Response from Paypal Server:\n" . $this->ipn_response; | |
$this->write_to_log(); | |
} | |
private function write_to_log() { | |
if (! $this->ipn_log) | |
return; // is logging turned off? | |
$fp = fopen ( LOG_FILE , 'a' ); | |
fwrite ( $fp, $this->ipn_status . "\n\n" ); | |
fclose ( $fp ); // close file | |
chmod ( LOG_FILE , 0600 ); | |
} | |
public function send_report($subject) { | |
$body .= "from " . $this->ipn_data ['payer_email'] . " on " . date ( 'm/d/Y' ); | |
$body .= " at " . date ( 'g:i A' ) . "\n\nDetails:\n" . $this->ipn_status; | |
mail ( $this->admin_mail, $subject, $body ); | |
} | |
public function print_report() { | |
$find [] = "\n"; | |
$replace [] = '<br/>'; | |
$html_content = str_replace ( $find, $replace, $this->ipn_status ); | |
echo $html_content; | |
} | |
public function getPaypalURL() { | |
return $this->sandbox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr'; | |
} | |
public function dump_fields() { | |
// Used for debugging, this function will output all the field/value pairs | |
// that are currently defined in the instance of the class using the | |
// add_field() function. | |
echo "<h3>paypal_class->dump_fields() Output:</h3>"; | |
echo "<table width=\"95%\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\"> | |
<tr> | |
<td bgcolor=\"black\"><b><font color=\"white\">Field Name</font></b></td> | |
<td bgcolor=\"black\"><b><font color=\"white\">Value</font></b></td> | |
</tr>"; | |
ksort($this->fields); | |
foreach ($this->fields as $key => $value) {echo "<tr><td>$key</td><td>".urldecode($value)." </td></tr>";} | |
echo "</table><br>"; | |
} | |
private function debug($msg) { | |
if(!$this->ipn_debug) | |
return; | |
$today = date ( "Y-m-d H:i:s " ); | |
$fh = fopen (DEBUG_LOG_FILE, 'a' ) or die ( "Can't open debug file. Please manually create the 'debug.log' file and make it writable." ); | |
$ua_simple = preg_replace ( "/(.*)\s\(.*)/", "\\1", $_SERVER ['HTTP_USER_AGENT'] ); | |
fwrite ( $fh, $today . " [from: " . $_SERVER ['REMOTE_ADDR'] . "|$ua_simple] - " . $msg . "\n" ); | |
fclose ( $fh ); | |
chmod (DEBUG_LOG_FILE, 0600 ); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment