<?php
/*******************************************************************************
* DESCRIPTION:
*
* NOTE: See www.micahcarrick.com for the most recent version of this class
* along with any applicable sample files and other documentaion.
*
* This file provides a neat and simple method to interface with paypal and
* The paypal Instant Payment Notification (IPN) interface. This file is
* NOT intended to make the paypal integration "plug 'n' play". It still
* requires the developer (that should be you) to understand the paypal
* process and know the variables you want/need to pass to paypal to
* achieve what you want.
*
* This class handles the submission of an order to paypal aswell as the
* processing an Instant Payment Notification.
*
* This code is based on that of the php-toolkit from paypal. I've taken
* the basic principals and put it in to a class so that it is a little
* easier--at least for me--to use. The php-toolkit can be downloaded from
* http://sourceforge.net/projects/paypal.
*
* To submit an order to paypal, have your order form POST to a file with:
*
* $p = new paypal_class;
* $p->add_field('business', 'somebody@domain.com');
* $p->add_field('first_name', $_POST['first_name']);
* ... (add all your fields in the same manor)
* $p->submit_paypal_post();
*
* To process an IPN, have your IPN processing file contain:
*
* $p = new paypal_class;
* if ($p->validate_ipn()) {
* ... (IPN is Completed. Details are in the ipn_data() array)
* }
*
*
* In case you are new to paypal, here is some information to help you:
*
* 1. Download and read the Merchant User Manual and Integration Guide from
* http://www.paypal.com/en_US/pdf/integration_guide.pdf. This gives
* you all the information you need including the fields you can pass to
* paypal (using add_field() with this class) aswell as all the fields
* that are returned in an IPN post (stored in the ipn_data() array in
* this class). It also diagrams the entire transaction process.
*
* 2. Create a "sandbox" account for a buyer and a seller. This is just
* a test account(s) that allow you to test your site from both the
* seller and buyer perspective. The instructions for this is available
* at https://developer.paypal.com/ as well as a great forum where you
* can ask all your paypal integration questions. Make sure you follow
* all the directions in setting up a sandbox test environment, including
* the addition of fake bank accounts and credit cards.
*
*******************************************************************************
*/
class paypal_class {
var $last_error; // holds the last error encountered
var $ipn_log; // bool: log IPN results to text file?
var $ipn_log_file; // filename of the IPN log
var $ipn_response; // holds the IPN response from paypal
var $ipn_data = array(); // array contains the POST values for IPN
var $fields = array(); // array holds the fields to submit to paypal
function paypal_class() {
// initialization constructor. Called when class is created.
$this->paypal_url = 'ssl://www.sandbox.paypal.com';
$this->last_error = 'includes/error_paypal.log';
$this->ipn_log_file = '../../ipn.log';
$this->ipn_log = false;
$this->ipn_response = '../../ipn.log';
// populate $fields array with a few default values. See the paypal
// documentation for a list of fields and their data types. These defaul
// values can be overwritten by the calling script.
$this->add_field('rm','2'); // Return method = POST
$this->add_field('cmd','_xclick');
}
function add_field($field, $value) {
// adds a key=>value pair to the fields array, which is what will be
// sent to paypal as POST variables. If the value is already in the
// array, it will be overwritten.
$this->fields["$field"] = $value;
}
function validate_ipn() {
// parse the paypal URL
$url_parsed=parse_url($this->paypal_url);
// 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
$fp = fsockopen($url_parsed[host],"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->last_error = "fsockopen error no. $errnum: $errstr";
$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); // close connection
}
$pos2 = stripos($this->ipn_response, "SUCCESS");
if ($pos2 !== false) {
// Valid IPN transaction.
$this->log_ipn_results(true);
return true;
} else {
// Invalid IPN transaction. Check the log for details.
$this->last_error = 'IPN Validation Failed.';
$this->log_ipn_results(false);
return false;
}
}
function log_ipn_results($success) {
if (!$this->ipn_log) return; // is logging turned off?
// Timestamp
$text = '['.date('m/d/Y g:i A').'] - ';
// Success or failure being logged?
if ($success) $text .= "SUCCESS!\n";
else $text .= 'FAIL: '.$this->last_error."\n";
// Log the POST variables
$text .= "IPN POST Vars from Paypal:\n";
foreach ($this->ipn_data as $key=>$value) {
$text .= "$key=$value, ";
}
// Log the response from the paypal server
$text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response;
// Write to log
$fp=fopen($this->ipn_log_file,'a');
fwrite($fp, $text . "\n\n");
fclose($fp); // close file
}
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>";
}
}
?>
<?php
require_once(ROOT_PATH . 'includes/classes/class.paypal.php');
class ShowPaypalPage extends AbstractPage
{
const MAIL = 'aldezomj@gmail.com';
public $pattern = array(
120000 => '5.00',
300000 => '10.00',
850000 => '25.00',
1750000 => '50.00',
4000000 => '80.00',
);
public $cost = '0';
public $amount = '0';
function __construct() {
parent::__construct();
$action = HTTP::_GP('action', '');
switch ($action)
{
case 'success':
$this->Success();
break;
case 'cancel':
$this->Cancel();
break;
case 'ipn':
$this->IPN();
break;
default:
$this->CallOrder();
break;
}
}
function Success()
{
message(pretty_number(HTTP::_GP('amount', 0)).' Anti matter where is on your account. <br><br><a href="?page=overview">Continue</a>');
}
function Cancel()
{
message('Your Order where Cancelled.</h3><br><a href="?page=overview">Continue</a><br>');
}
/*
It's important to remember that paypal calling this script. There
is no output here. This is where you validate the IPN data and if it's
valid, update your database to signify that the user has payed. If
you try and use an echo or printf function here it's not going to do you
a bit of good. This is on the "backend". That is why, by default, the
class logs all IPN data to a text file.
*/
function CallOrder()
{
global $USER, $CONF, $UNI;
$this->amount = str_replace(".","",HTTP::_GP('ik_payment_amount',0));
$this->amountbis = HTTP::_GP('ik_payment_amount',0);
if($this->amount < 10000){
$this->printMessage('You have to buy minimum 10.000 AM!', true, array('game.php?page=donate', 3));
}
if($this->amount >= 10000 && $this->amount < 20000) $this->amount *= 1.05;
elseif($this->amount >= 20000 && $this->amount < 50000) $this->amount *= 1.10;
elseif($this->amount >= 50000 && $this->amount < 100000) $this->amount *= 1.20;
elseif($this->amount >= 100000 && $this->amount < 150000) $this->amount *= 1.30;
elseif($this->amount >= 150000 && $this->amount < 200000) $this->amount *= 1.40;
elseif($this->amount >= 200000) $this->amount *= 1.50;
$INFO1 = $GLOBALS['DATABASE']->uniquequery("SELECT * FROM `uni1_users` WHERE `id` = ".$GLOBALS['DATABASE']->sql_escape($USER['id']).";");
if($INFO1['lp_points'] == 0)
$text = 0;
if($INFO1['lp_points'] > 0)
$text = 0;
if($INFO1['lp_points'] >= 125)
$text = 5;
if($INFO1['lp_points'] >= 625)
$text = 10;
if($INFO1['lp_points'] >= 2500)
$text = 15;
if($INFO1['lp_points'] >= 7000)
$text = 20;
$bonuses = 0;
if($CONF['purchase_bonus_timer'] > TIMESTAMP){
$bonuses = $CONF['purchase_bonus'];
}
$this->amount = round($this->amount + ($this->amount / 100 * $text));
$this->amount = $this->amount + ($this->amount / 100 * $bonuses);
$this->cost = round($this->amountbis * 0.00013131);
$this_p = new paypal_class;
$this_p->add_field('business', $this::MAIL);
if($UNI==1){
$this_p->add_field('return', 'http://aldezo.bplaced.net/omega4/game.php?page=overview');
$this_p->add_field('cancel_return', 'http://aldezo.bplaced.net/omega4/game.php?page=overview');
$this_p->add_field('notify_url', 'http://aldezo.bplaced.net/omega4/ipns.php');
}else{
$this_p->add_field('return', 'http://aldezo.bplaced.net/omega4/game.php?page=overview');
$this_p->add_field('cancel_return', 'http://aldezo.bplaced.net/omega4/game.php?page=overview');
$this_p->add_field('notify_url', 'http://aldezo.bplaced.net/omega4/ipns.php');
}
$this_p->add_field('item_name', $this->amount.' AM-User('.$USER['username'].').');
$this_p->add_field('item_number', $this->amount);
$this_p->add_field('amount', $this->cost);
//$this_p->add_field('action', $action); ?
$this_p->add_field('currency_code', 'EUR');
$this_p->add_field('custom', $USER['id']);
$this_p->add_field('rm', '2');
//$this_p->dump_fields();
foreach ($this_p->fields as $name => $value) {
$field[] = array('text'=>'<input type="hidden" name="'.$name.'" value="'.$value.'">');
}
$this->tplObj->assign_vars(array(
'fields' => $field,
));
$this->display('paypal_class.tpl');
}
}
?>
<?php
#Example PHP Postback Script
// Your Database Connection Details
$host = 'localhost';
$db_name = '';
$db_user = '';
$db_password = '';
mysql_connect($host, $db_user, $db_password);
mysql_select_db($db_name);
function pretty_number($n, $dec = 0)
{
return number_format(floattostring($n, $dec), $dec, ',', '.');
}
function floattostring($Numeric, $Pro = 0, $Output = false){
return ($Output) ? str_replace(",",".", sprintf("%.".$Pro."f", $Numeric)) : sprintf("%.".$Pro."f", $Numeric);
}
function SendSimpleMessage($Owner, $Sender, $Time, $Type, $From, $Subject, $Message)
{
$SQL = "INSERT INTO uni1_messages SET
message_owner = ".(int) $Owner.",
message_sender = ".(int) $Sender.",
message_time = ".(int) $Time.",
message_type = ".(int) $Type.",
message_from = '". $From ."',
message_subject = '". $Subject ."',
message_text = '".$Message."',
message_unread = '1',
message_universe = '1';";
$SQ = "INSERT INTO uni1_messages_copy SET
message_owner = ".(int) $Owner.",
message_sender = ".(int) $Sender.",
message_time = ".(int) $Time.",
message_type = ".(int) $Type.",
message_from = '". $From ."',
message_subject = '". $Subject ."',
message_text = '".$Message."',
message_unread = '1',
message_universe = '1';";
mysql_query($SQL);
mysql_query($SQ);
}
function _rewardPurchase($userId, $currency, $mc_gross) {
// Make userid safe to use in query
$userId = mysql_real_escape_string($userId);
$timer = time();
$INFO1 = mysql_query("SELECT * FROM `uni1_users` WHERE `id` = ".$userId.";");
if($INFO1['lp_points'] >= 0)
{$tex = 1;}
elseif($INFO1['lp_points'] >= 125)
{$tex = 2;}
elseif($INFO1['lp_points'] >= 625)
{$tex = 4;}
elseif($INFO1['lp_points'] >= 2500)
{$tex = 6;}
elseif($INFO1['lp_points'] >= 7000)
{$tex = 8;}
mysql_query("UPDATE `uni1_users` SET `lp_points` = `lp_points` + ".($mc_gross * $tex).", `antimatter` = `antimatter` + ".$currency." WHERE `id` = '".$userId."';");
if($INFO1['ref_id'] != 0){
mysql_query("UPDATE `uni1_users` SET `antimatter` = `antimatter` + ".($currency / 100 * 5)." WHERE `id` = '".$INFO1['ref_id']."';");
SendSimpleMessage($INFO1['ref_id'], '', $timer, 4, 'System', 'Anti Matter Order', 'Referal PayPal payment was successful. <br>'.pretty_number($currency / 100 * 5).' anti matter have been credited to your account.');
}
SendSimpleMessage($userId, '', $timer, 4, 'System', 'Anti Matter Order', 'PayPal payment was successful. <br>'.pretty_number($currency).' anti matter have been credited to your account.');
SendSimpleMessage(1, '', $timer, 4, 'System', 'Anti Matter Order', 'PayPal payment was successful. <br>'.pretty_number($currency).' Anti Matter Units have been credited to '.$userId.' account.');
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
}
}
//-------------------------- Don't change anything below this! ----------------------------- //
define("DEBUG", 1);
// Set to 0 once you're ready to go live
define("USE_SANDBOX", 1);
define("LOG_FILE", "ipn.log");
// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
$keyval = explode ('=', $keyval);
if (count($keyval) == 2)
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
if(function_exists('get_magic_quotes_gpc')) {
$get_magic_quotes_exists = true;
}
foreach ($myPost as $key => $value) {
if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
$value = urlencode(stripslashes($value));
} else {
$value = urlencode($value);
}
$req .= "&$key=$value";
}
// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data
if(USE_SANDBOX == true) {
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
if ($ch == FALSE) {
return FALSE;
}
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
if(DEBUG == true) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}
// CONFIG: Optional proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
// Set TCP timeout to 30 seconds
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.
//$cert = __DIR__ . "./cacert.pem";
//curl_setopt($ch, CURLOPT_CAINFO, $cert);
$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
{
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
}
curl_close($ch);
exit;
} else {
// Log the entire HTTP response if debug is switched on.
if(DEBUG == true) {
error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
// Split response headers and payload
list($headers, $res) = explode("\r\n\r\n", $res, 2);
}
curl_close($ch);
}
// Inspect IPN validation result and act accordingly
// check whether the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your PayPal email
// check that payment_amount/payment_currency are correct
// process payment and mark item as paid.
// assign posted variables to local variables
//$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'];
$userId = isset($_POST['custom']) ? $_POST['custom'] : null;
$currency = isset($_POST['item_number']) ? $_POST['item_number'] : null;
$mc_gross = isset($_POST['mc_gross']) ? $_POST['mc_gross'] : null;
$payment_status = isset($_POST['payment_status']) ? $_POST['payment_status'] : null;
$result = false;
if ($payment_status == 'SUCCESS') {
$result = true;
_rewardPurchase($userId, $currency, $mc_gross);
}
if ($result) {
echo 'OK';
}
//Close Connection
mysql_close();
?>