PayPal IPN - у вас проблемы с доступом к данным сеанса? - PullRequest
0 голосов
/ 03 мая 2010

все. У меня проблемы с интеграцией 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('martin@mcbwebdesign.co.uk', 'IPN result', 'IPN was successful on wrestling-wear.com');
} else {
    mail('martin@mcbwebdesign.co.uk', '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;
    }
}

Ответы [ 2 ]

1 голос
/ 03 мая 2010

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

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

0 голосов
/ 01 марта 2012

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

...