<?php
// STEP 1: Read raw POST data to avoid serialization issues
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = [];
foreach ($raw_post_array as $keyval) {
$keyval = explode('=', $keyval);
if (count($keyval) === 2) {
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
}
// Prepare the request by adding 'cmd' and encoding values
$req = 'cmd=_notify-validate';
foreach ($myPost as $key => $value) {
$value = urlencode($value);
$req .= "&$key=$value";
}
// STEP 2: Post IPN data back to PayPal for validation
// Use the live URL by default; uncomment sandbox for testing
$ch = curl_init('https://ipnpb.paypal.com/cgi-bin/webscr');
// $ch = curl_init('https://ipnpb.sandbox.paypal.com/cgi-bin/webscr');
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);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Connection: Close']);
// If your environment lacks root CA certificates (e.g., WAMP), download 'cacert.pem' from
// https://curl.se/docs/caextract.html and uncomment the line below, adjusting the path.
// curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/cacert.pem');
$res = curl_exec($ch);
if ($res === false) {
// Optional: Log curl error if needed, but avoid terminating
// error_log("Curl error: " . curl_error($ch));
curl_close($ch);
exit;
}
curl_close($ch);
// STEP 3: Inspect IPN validation result and log accordingly
if (strcmp($res, "VERIFIED") === 0) {
// Extract relevant POST variables (assuming they exist; no additional validation as per original)
$first_name = $_POST['first_name'] ?? '';
$last_name = $_POST['last_name'] ?? '';
$item_number = $_POST['item_number'] ?? '';
$payment_date = $_POST['payment_date'] ?? '';
$payer_status = $_POST['payer_status'] ?? '';
$payment_status = $_POST['payment_status'] ?? '';
$mc_fee = $_POST['mc_fee'] ?? '';
$payment_amount = $_POST['mc_gross'] ?? '';
$payment_currency = $_POST['mc_currency'] ?? '';
$txn_type = $_POST['txn_type'] ?? '';
$txn_id = $_POST['txn_id'] ?? '';
$receiver_email = $_POST['receiver_email'] ?? '';
$payer_email = $_POST['payer_email'] ?? '';
// Log to ipnhits.txt in CSV format
$content = implode(',', [
$first_name,
$last_name,
$item_number,
$payment_date,
$payer_status,
$payment_status,
$mc_fee,
$payment_amount,
$payment_currency,
$txn_type,
$txn_id,
$receiver_email,
$payer_email
]) . "\n";
$this_directory = __DIR__;
$fp = fopen($this_directory . '/ipnhits.txt', 'a');
if ($fp) {
fwrite($fp, $content);
fclose($fp);
}
// Note: In production, handle file write failures gracefully (e.g., error_log)
} elseif (strcmp($res, "INVALID") === 0) {
// Log timestamp to ipnfails.txt for investigation
$content = date("Y-m-d H:i:s") . "\n";
$this_directory = __DIR__;
$fp = fopen($this_directory . '/ipnfails.txt', 'a');
if ($fp) {
fwrite($fp, $content);
fclose($fp);
}
// Note: In production, handle file write failures gracefully (e.g., error_log)
}