Skip to content

Commit

Permalink
Update paypal_receipt to not need login and work with the now-mandato…
Browse files Browse the repository at this point in the history
…ry https IPN endpoint
  • Loading branch information
jfharden committed Sep 15, 2018
1 parent 2c8ce96 commit fb96601
Showing 1 changed file with 122 additions and 72 deletions.
194 changes: 122 additions & 72 deletions paypal_receipt.php
Expand Up @@ -21,22 +21,67 @@
| Bitsand. If not, see <http://www.gnu.org/licenses/>.
+---------------------------------------------------------------------------*/

// This page is for Paypal to call back to, there is no login for a user on this endpoint
$bLoginCheck = False;

include ('inc/inc_head_db.php');
$db_prefix = DB_PREFIX;

// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
function paypalIPNVerification() {
// Taken from Paypal example https://developer.paypal.com/docs/classic/ipn/ht_ipn/#do-it
// and modified just a little for readability

foreach ($_POST as $key => $value) {
$value = urlencode (stripslashes ($value));
$req .= "&$key=$value";
}
// STEP 1: read POST data
// Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.
// Instead, read raw POST data from the input stream.
$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 IPN message sent from PayPal and prepend 'cmd=_notify-validate'
$req = 'cmd=_notify-validate';

if (function_exists('get_magic_quotes_gpc')) {
$get_magic_quotes_exists = true;
}

// 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 ('www.paypal.com', 80, $errno, $errstr, 30);
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";
}

// Step 2: POST IPN data back to PayPal to validate
$ch = curl_init('https://ipnpb.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, array('Connection: Close'));

$res = curl_exec($ch);

if ($res === false) {
LogError("CURL ERROR with Paypal " . curl_error($ch) . " when processing IPN data");
curl_close($ch);
return false;
}
curl_close($ch);

return $res;
}

// assign posted variables to local variables
$item_name = $_POST ['item_name'];
Expand All @@ -49,73 +94,78 @@
$payer_email = $_POST ['payer_email'];
$custom = $_POST['custom'];

if (!$fp) {
// HTTP ERROR
LogError ("There was a problem validating a PayPal payment. (HTTP error when trying to POST to www.paypal.com)\n $item_name");
$paypalResponse = paypalIPNVerification();

if ($paypalResponse === false) {
LogError ("There was a problem validating a PayPal payment. (HTTP error when trying to POST to https://ipnpb.paypal.com/cgi-bin/webscr)\n $item_name");
fnMailer ("There was a problem validating a PayPal payment.\n" .
"Payment will have to be manually processed\n $item_name", True);
}
else {
fputs ($fp, $header . $req);
while (!feof ($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
if (strtolower ($payment_status) == 'completed' && $receiver_email == PAYPAL_EMAIL) {
//Payment received. Send e-mail to event contact
fnMailer ("Payment received:\n$item_name\n$payment_amount $payment_currency");

//Only mark as paid if configured to do so.
if (PAYPAL_AUTO_MARK_PAID)
{
//Mark as paid.
//Custom value is the bookingid
//Don't set bkAmountExpected, and we add to amount paid, allowing potential for partial payments in future.
$custom = (int)$custom;
$sql = "UPDATE {$db_prefix}bookings SET bkDatePaymentConfirmed = '" . date ('Y-m-d') . "', bkAmountPaid = bkAmountPaid + ".$payment_amount." WHERE bkID = " . $custom;
//Run UPDATE query to set paid date
ba_db_query ($link, $sql);

//Mark bunk as allocated if one was requested
$sql = "UPDATE {$db_prefix}bookings SET bkBunkAllocated = 1 WHERE bkBunkRequested = 1 and bkID = " . $custom;
//Run UPDATE query to set assign bunk
ba_db_query ($link, $sql);
}

//Get details for e-mail
$sql_select = "SELECT plFirstName, plSurname, plEmail FROM {$db_prefix}players WHERE plPlayerID = " . $item_number;
$result = ba_db_query ($link, $sql_select);
$row = ba_db_fetch_assoc ($result);
//Send e-mail
$sBody = "Your payment for the upcoming event has been received.\n";
if (PAYPAL_AUTO_MARK_PAID)
{
$sBody .= "You are now fully booked.\n\n";
}
else
{
$sBody .= "You will be fully booked once your booking has been confirmed by a system administrator.\n\n";
}
$sBody .= "Thank you.\n\n";
$sBody .= "Player ID: " . PID_PREFIX . sprintf ('%03s', $iPlayerID) . "\n";
$sBody .= "OOC Name: " . $row ['plFirstName'] . " " . $row ['plSurname'];
if ($bEmailPaymentReceived)
mail ($row ['plEmail'], SYSTEM_NAME . ' - payment received', $sBody, "From:" . SYSTEM_NAME . " <" . EVENT_CONTACT_MAIL . ">");

//Clear any payment requests for this booking
$sql = "delete from {$db_prefix}paymentrequests where prBookingID = ".$custom;
$result = ba_db_query($link, $sql);
if (strcmp ($paypalResponse, "VERIFIED") == 0) {
if (strtolower ($payment_status) == 'completed' && $receiver_email == PAYPAL_EMAIL) {
//Payment received. Send e-mail to event contact
fnMailer ("Payment received:\n$item_name\n$payment_amount $payment_currency");

//Only mark as paid if configured to do so.
if (PAYPAL_AUTO_MARK_PAID)
{
//Mark as paid.
//Custom value is the bookingid
//Don't set bkAmountExpected, and we add to amount paid, allowing potential for partial payments in future.
$custom = (int)$custom;
$sql = "UPDATE {$db_prefix}bookings SET bkDatePaymentConfirmed = '" . date ('Y-m-d') . "', bkAmountPaid = bkAmountPaid + ".$payment_amount." WHERE bkID = " . $custom;
//Run UPDATE query to set paid date
ba_db_query ($link, $sql);

//Mark bunk as allocated if one was requested
$sql = "UPDATE {$db_prefix}bookings SET bkBunkAllocated = 1 WHERE bkBunkRequested = 1 and bkID = " . $custom;
//Run UPDATE query to set assign bunk
ba_db_query ($link, $sql);
}

//Get details for e-mail
$sql_select = "SELECT plFirstName, plSurname, plEmail FROM {$db_prefix}players WHERE plPlayerID = " . $item_number;
$result = ba_db_query ($link, $sql_select);
$row = ba_db_fetch_assoc ($result);
//Send e-mail
$sBody = "Your payment for the upcoming event has been received.\n";
if (PAYPAL_AUTO_MARK_PAID)
{
$sBody .= "You are now fully booked.\n\n";
}
else
{
$sBody .= "You will be fully booked once your booking has been confirmed by a system administrator.\n\n";
}
$sBody .= "Thank you.\n\n";
$sBody .= "Player ID: " . PID_PREFIX . sprintf ('%03s', $iPlayerID) . "\n";
$sBody .= "OOC Name: " . $row ['plFirstName'] . " " . $row ['plSurname'];
if ($bEmailPaymentReceived)
mail ($row ['plEmail'], SYSTEM_NAME . ' - payment received', $sBody, "From:" . SYSTEM_NAME . " <" . EVENT_CONTACT_MAIL . ">");

//Clear any payment requests for this booking
$sql = "delete from {$db_prefix}paymentrequests where prBookingID = ".$custom;
$result = ba_db_query($link, $sql);
}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
LogError ("There was a problem with PayPal payment - PayPal returned 'INVALID' when verifying payment.\n" .
"Item name; '$item_name'");
fnMailer ("There was a problem with PayPal payment - PayPal returned 'INVALID' when verifying payment." .
"Payment will have to be manually processed.\n" .
"Item name; '$item_name'", True);
}
}
fclose ($fp);
else if (strcmp ($paypalResponse, "INVALID") == 0) {
// log for manual investigation
LogError ("There was a problem with PayPal payment - PayPal returned 'INVALID' when verifying payment.\n" .
"Item name; '$item_name'");
fnMailer ("There was a problem with PayPal payment - PayPal returned 'INVALID' when verifying payment." .
"Payment will have to be manually processed.\n" .
"Item name; '$item_name'", True);
}
else {
LogError ("There was a problem with PayPal payment - PayPal returned an unknown response when verifying payment.\n" .
"Item name; '$item_name'\n" .
"Paypal response was: \n-------------------------------\n" . $paypalResponse
);
fnMailer ("There was a problem with PayPal payment - PayPal returned an unknown response when verifying payment." .
"Payment will have to be manually processed.\n" .
"Item name; '$item_name'", True);
}
}

include ('inc/inc_foot.php');
include ('inc/inc_foot.php');

0 comments on commit fb96601

Please sign in to comment.