2010-05-02 3 views
0

все. У меня проблемы с интеграцией IPN PayPal, где кажется, что я не могу получить мое решение для чтения переменных сеанса.PayPal IPN - проблема с доступом к данным сеанса?

В основном, в моем сценарии модуля магазина я храню данные клиента, как это предусмотрено PayPal, в таблице заказов. Однако я также хочу сохранить продукты, заказанные в транзакции, в отдельную таблицу, связанную идентификатором заказа.

Однако это вторая часть скрипта, который не работает, где я просматриваю продукты в сеансе, а затем сохраняю их в таблице orders_products.

Есть ли причина, по которой данные сеанса не читаются?

Код в shop.php выглядит следующим образом:

if ($paypal->validate_ipn()) { 
    $name = $paypal->ipn_data['address_name']; 
    $street_1 = $paypal->ipn_data['address_street']; 
    $street_2 = ""; 
    $city = $paypal->ipn_data['address_city']; 
    $state = $paypal->ipn_data['address_state']; 
    $zip = $paypal->ipn_data['address_zip']; 
    $country = $paypal->ipn_data['address_country']; 
    $txn_id = $paypal->ipn_data['txn_id']; 
    $sql = "INSERT INTO orders (name, street_1, street_2, city, state, zip, country, txn_id) 
      VALUES (:name, :street_1, :street_2, :city, :state, :zip, :country, :txn_id)"; 
    $smt = $this->pdo->prepare($sql); 
    $smt->bindParam(':name', $name, PDO::PARAM_STR); 
    $smt->bindParam(':street_1', $street_1, PDO::PARAM_STR); 
    $smt->bindParam(':street_2', $street_2, PDO::PARAM_STR); 
    $smt->bindParam(':city', $city, PDO::PARAM_STR); 
    $smt->bindParam(':state', $state, PDO::PARAM_STR); 
    $smt->bindParam(':zip', $zip, PDO::PARAM_STR); 
    $smt->bindParam(':country', $country, PDO::PARAM_STR); 
    $smt->bindParam(':txn_id', $txn_id, PDO::PARAM_INT); 
    $smt->execute(); 
    // save products to orders relationship 
    $order_id = $this->pdo->lastInsertId(); 
    // $cart = $this->session->get('cart'); 
    $cart = $this->session->get('cart'); 
    foreach ($cart as $product_id => $item) { 
     $quantity = $item['quantity']; 
     $sql = "INSERT INTO orders_products (order_id, product_id, quantity) VALUES ('$order_id', '$product_id', '$quantity')"; 
     $res = $this->pdo->query($sql); 
    } 
    $this->session->del('cart'); 
    mail('[email protected]', 'IPN result', 'IPN was successful on wrestling-wear.com'); 
} else { 
    mail('[email protected]', 'IPN result', 'IPN failed on wrestling-wear.com'); 
} 

И я использую класс PayPal IPN для PHP, как здесь: http://www.micahcarrick.com/04-19-2005/php-paypal-ipn-integration-class.html, но содержание метода validate_ipn() выглядит следующим образом:

public function validate_ipn() 
{ 
    $url_parsed = parse_url($this->paypal_url); 
    $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], "80", $err_num, $err_str, 30); 
    if (!$fp) { 
     // could not open the connection. If logging 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 
    } 
    if (eregi("VERIFIED", $this->ipn_response)) { 
     // 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; 
    } 
} 

ответ

1

Если я правильно помню, IP-адрес PayPal отправляет уведомление прямо на ваш скрипт. Поскольку уведомление поступает от PayPal - НЕ клиент, который разместил заказ - их сеанс в этом контексте не существует. Поэтому все данные их корзины не существуют в сеансе.

Когда я использовал IPN в прошлом, я сохранил все о своем заказе в базе данных и создал TransactionID. Это одна из сквозных переменных, которые я могу отправить с остальной частью заказа в PayPal, и они передадут ее обратно. Как только я получил IPN от PayPal, я повторно увлажнил их заказ на основе TransactionID и продолжил все бизнес-правила, которым я должен был следовать: отправить электронное письмо, создать пароли и т. Д.

+0

По существу, сохраните сеанс в базе данных, а не в файле tmp? Приветствия. –

+0

@Martin Я полагаю, вы можете покинуть сеанс, где захотите, но вам нужно скопировать данные транзакций в какое-то время, чтобы вы могли сопоставить его с ответом от PayPal. Если session_unset() вызывается неожиданно (потерянный файл cookie, возможно?), Транзакция не обязательно исчезает. – cbednarski

0

В настоящее время я работаю над этим - скажем, вы пытаетесь получить сеанс user_id вставить в свои таблицы транзакций, лучше всего отправить user_id в Paypal вместе с заказом. Потому что, если вы пишете в БД, как только они перенаправляются в Paypal, у вас нет гарантии, что они действительно выполнили заказ. Кроме того, я думаю, что PayPal отправляет информацию о товаре/заказе в строку, разделенную запятой, поэтому вам нужно будет просмотреть количество уникальных предметов, которые вы продали, и динамически получить item_id1, item_id2, item_id3 ... так ваш запрос всегда меняется. Исправьте меня, если я ошибаюсь, я собираюсь начать реализацию этого, но без использования классов.

Смежные вопросы