На сайте установлена PayPal кнопка мгновенного платежа "Купить сейчас". Оплата реализована через php-скрипт IPN, в результате работы которого в случае успешной транзакции заносятся в БД данные о покупке и на емэйл-адрес покупателя отправляется письмо с данными о совершённой покупке и ссылкой на скачивание купленного файла. В "песочнице" (через sandbox) всё работает отлично - оплата проходит, заносятся данные в БД, генерится ссылка на файл и отправляется письмо, но в реальном режиме работает только оплата, а всё остальное, что должно происходить после успешной оплаты - не работает. Аккаунт PayPal - Премьер, в настройках продавца всё что нужно включено (страница возврата, PDT, IPN). Такое ощущение, что в реальном режиме игнорируется IPN, а срабатывает только PDT, так как на страницу возврата (success.php) редирект происходит успешно и передаёт все необходимые POST-данные о совершённой транзакции в адресной строке. Так же замечено, что номер транзакции в этой адресной строке отличается от кода операции, указанного в квитанции от PayPal, которая приходит после оплаты на емэйл покупателя. Ниже приведён код самой кнопки и фрагмент кода файла ipn.php
Форма оплаты:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"/>
<input type="hidden" name="cmd" value="_xclick"/>
<input type="hidden" name="notify_url" value="http://mysite.com/ipn.php"/>
<input type="hidden" name="cancel_return" id="cancel_return" value="http://mysite.com"/>
<input type="hidden" name="bn" value="Product"/>
<input type="hidden" name="business" value="business@email.com"/>
<input type="hidden" name="item_name" value="Product Name"/>
<input type="hidden" name="currency_code" value="RUB"/>
<input type="hidden" name="custom" value="Product ID>"/>
<input type="hidden" name="image_url" value="http://mysite.com/img/my_logo.jpg"/>
<input type="hidden" name="no_shipping" value="1"/>
<input type="hidden" name="quantity" value="1"/>
<input type="hidden" name="lc" value="RU"/>
<input type="hidden" name="return" value="http://mysite.com/success.php"/>
<input type="hidden" name="charset" value="utf-8"/>
<input type="hidden" name="amount" value="20.00"/>
<input type="submit" id="submit" name="submit" value="Buy Now - 20.00 RUB"/>
</div/>
</form/>
Фрагмент кода файла ipn.php:
<?php
require_once($_SERVER["DOCUMENT_ROOT"].'/config.php');
// initialize swiftmailer
$transport_smtp = Swift_SmtpTransport::newInstance($smtp_server, $smtp_port)
->setUsername($smtp_user)
->setPassword($smtp_pass);
$mailer = Swift_Mailer::newInstance($transport_smtp);
/*--------------------------------------------------------------
RECEIVE POST FROM PAYPAL
--------------------------------------------------------------*/
// 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);
$paypal_post = array();
foreach ($raw_post_array as $keyval) {
$keyval = explode ('=', $keyval);
if (count($keyval) == 2) {
$paypal_post[$keyval[0]] = urldecode($keyval[1]);
}
}
//extract vars
extract($paypal_post, EXTR_OVERWRITE);
// build request
$req = 'cmd=' . urlencode('_notify-validate');
$ipn_vars = 'cmd=' . urlencode('_notify-validate');
foreach ($paypal_post as $k => $v) {
$v = urlencode($v);
$req .= "&$k=$v";
}
// sort array keys (only after building $req var which will be used to send curl to paypal)
ksort($paypal_post);
foreach ($paypal_post as $k => $v) {
$ipn_vars .= "\n$k=" . urldecode($v);
}
/*--------------------------------------------------------------
SEND POST BACK TO PAYPAL
--------------------------------------------------------------*/
// paypal mode
$paypal_mode = 1;
// sandbox on/off
if($paypal_mode == 1) {
$paypal_url = 'https://www.paypal.com/cgi-bin/webscr';
}
// else is production site
else {
$paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $paypal_url);
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, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
$res = curl_exec($ch);
//Check if any error occured
if(curl_errno($ch)) {
$ipn_response = curl_error($ch);
}
// else no curl error
else {
if(strcmp($res, "VERIFIED") == 0 || 1) {
// ipn vars
$business = (isset($_POST['business'])) ? $_POST['business'] : '';
$custom = (isset($_POST['custom'])) ? $_POST['custom'] : '';
$first_name = (isset($_POST['first_name'])) ? $_POST['first_name'] : '';
$item_name = (isset($_POST['item_name'])) ? $_POST['item_name'] : '';
$item_number = (isset($_POST['item_number'])) ? $_POST['item_number'] : '';
$last_name = (isset($_POST['last_name'])) ? $_POST['last_name'] : '';
$mc_currency = (isset($_POST['mc_currency'])) ? $_POST['mc_currency'] : '';
$mc_gross = (isset($_POST['mc_gross'])) ? $_POST['mc_gross'] : '';
$payer_email = (isset($_POST['payer_email'])) ? $_POST['payer_email'] : '';
$payer_id = (isset($_POST['payer_id'])) ? $_POST['payer_id'] : '';
$payment_gross = (isset($_POST['payment_gross'])) ? $_POST['payment_gross'] : '';
$payment_status = (isset($_POST['payment_status'])) ? $_POST['payment_status'] : '';
$receiver_email = (isset($_POST['receiver_email'])) ? $_POST['receiver_email'] : '';
$txn_id = (isset($_POST['txn_id'])) ? $_POST['txn_id'] : '';
$txn_type = (isset($_POST['txn_type'])) ? $_POST['txn_type'] : '';
.......................
//здесь код, добавляющий информацию о покупке в БД, генерирующий
//ссылку на скачивание файла и отправляющий письмо покупателю с этой
//ссылкой и данными о совершенной покупке
.......................
}
?>
В файле config.php служебная инфа для подключения к БД и т.п., не относящаяся к самому процессу оплаты.
В чем может быть проблема и в каком направлении искать её решение?
UPD: В качестве проверки в файле ipn.php в блоке
if(strcmp($res, "VERIFIED") == 0 || 1) {}
написал небольшую функцию по сохранению всех данных, полученных с IPN, в текстовый файл на сервере. В режиме sandbox всё сохраняет и записывает, т.е. проверку (VERIFIED) проходит. Но в лайв режиме файл не создаётся и ничего не записывается, т.е. проверку не проходит. В таком случае не понятно почему проходит оплата и откуда берётся код операции в квитанции от PayPal, отличающийся от того, который возвращается через PDT??
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Здравствуйте, стоит выбор при помощи чего реализовывать поиск по сайту, оператор LIKE, или же FullTextПодскажите пожалуйста что лучше, и желательно...