2015-09-24 3 views
1

Обновление - я удалил проверку и добавил $ item_id = $ _POST ['option_selection1']; к моему полю, и вдруг это сработало!Действительно борется с Paypal IPN

У меня есть сайт для фотографа, и она продает временные интервалы в течение дня. Я пытаюсь настроить ее так, чтобы кто-то выбирал временной интервал, покупал его через paypal, а затем, когда данные возвращаются через IPN, я беру адрес электронной почты, используемый для совершения покупки, а также идентификатор, который я связал с временным интервалом. С этим ID я устанавливаю переключатель в базе данных, который заставляет этот временной интервал больше не заполняться в форме, поэтому другие не могут приобрести тот же временной интервал. Каждый раз, когда я делаю тестовую транзакцию, база данных не обновляется, и я не знаю, почему. Когда я вручную устанавливаю значения переменных $ payer_email и $ item_number, база данных делает то, что я ожидаю от нее. Из-за этого у меня создается впечатление, что PayPal не проверяет данные или не отправляет данные так, как я ожидал.

Вот мой код для формы, которая проходит через PayPal:

// Create connection 
$conn = new mysqli($servername, $username, $password, $dbname); 
// Check connection 
if ($conn->connect_error) { 
    die("Connection failed: " . $conn->connect_error); 
} 

$sql = "SELECT id,hour,minute,toggle FROM mini ORDER BY id ASC"; 
$result = $conn->query($sql); 
echo '<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">'; 
echo '<input type="hidden" name="cmd" value="_s-xclick"> 
<input type="hidden" name="hosted_button_id" value="B6XDLRPVAUBQJ"> 
<input type="hidden" name="on0" value="item_number"> 
<select name="os0">'; 
if ($result->num_rows > 0) { 
    // output data of each row 
    while($row = $result->fetch_assoc()) { 
      if ($row["toggle"] == 0){ 
       echo '<option value="'.$row["id"].'">'.$row["hour"].':'.$row["minute"].' '; //id is what I'm trying to extract from paypal via IPN 
       if ($row["id"] < 13){echo 'AM';}else{echo 'PM';}; //if-then statement determines if it is AM or PM based on id 
       echo '</option>'; 
      }; 
    } 
} else { 
    echo "Sorry, I'm fully booked!"; 
} 

?> 
</select> 
<input type="submit" name="submit" value="Book Your Session"> 
</form> 

Вот мой код для СПИ

<?php 
// 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; 
} 
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://www.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')); 
// In wamp-like environments that do not come bundled with root authority certificates, 
// please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set 
// the directory path of the certificate as shown below: 
// curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); 
if(!($res = curl_exec($ch))) { 
    // error_log("Got " . curl_error($ch) . " when processing IPN data"); 
    curl_close($ch); 
    exit; 
} 
curl_close($ch); 

// STEP 3: Inspect IPN validation result and act accordingly 
if (strcmp ($res, "VERIFIED") == 0) { 
    // The IPN is verified, process it: 
    // check whether the payment_status is Completed 
    // check that txn_id has not been previously processed 
    // check that receiver_email is your Primary PayPal email 
    // check that payment_amount/payment_currency are correct 
    // process the notification 
    // 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']; 
    // IPN message values depend upon the type of notification sent. 
    // To loop thffrough the &_POST array and print the NV pairs to the screen: 
    foreach($_POST as $key => $value) { 
     echo $key." = ". $value."<br>"; 
    } 
} else if (strcmp ($res, "INVALID") == 0) { 
    // IPN invalid, log for manual investigation 
    echo "The response from IPN was: <b>" .$res ."</b>"; 
} 

//database credentials intentionally omitted :) 
// Create connection 
$conn = new mysqli($servername, $username, $password, $dbname); 
// Check connection 
if ($conn->connect_error) { 
    die("Connection failed: " . $conn->connect_error); 
} 

$sql = "UPDATE mini SET toggle='1',email='".$payer_email."' WHERE id=('".$item_number."')"; 


if ($conn->query($sql) === TRUE) { 
    echo "<br/> - Record updated successfully"; 
} else { 
    echo "Error updating record: " . $conn->error; 
} 


?> 
+0

Вы проверили 'error.log' в журналах apache? ('/ var/log/apache2/error.log' на большинстве Linux-серверов) –

+0

Вы должны сократить свой код до минимума. Является ли проблема с завихрением не возвращать нужные данные или не обновлять db? Выберите один и избавьтесь от избыточного шума. –

+2

Посмотрев ваш код чуть-чуть, я вижу, что вы задаете два разных запроса '$ sql' var без выполнения первого. Может быть, это ваша проблема? –

ответ

0

Я хотел бы предложить вам попробовать использовать PaymentDetails API для отладки состояния платежей, которые вы тестируете.

https://developer.paypal.com/docs/classic/api/adaptive-payments/PaymentDetails_API_Operation/

Также с PayPal песочнице немного отличается, медленнее и buggier - так что вы должны использовать некоторые протоколирования. Зарегистрируйте все, что отправлено, и ответ проверки. После этого вы могли бы сосредоточиться на логике приложения.