Я работаю над приложением PHP, которое подключается к Protx VSP Direct payment gateway. Для обработки запросов «3D Secure» от компании, занимающейся обработкой кредитных карт, мне нужно перенаправить пользователя на другой веб-сайт, имитируя опубликованную форму. Я пытаюсь использовать библиотеки cURL, но, похоже, столкнулся с проблемой. Мой код следующий:
<?php
$ch = curl_init();
// Set the URL
curl_setopt($ch, CURLOPT_URL, 'http://www.google.com/');
// Perform a POST
curl_setopt($ch, CURLOPT_POST, 1);
// If not set, curl prints output to the browser
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
// Set the "form fields"
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$output = curl_exec($ch);
curl_close($ch);
?>
Все, что это делает, - это захват содержимого переданного URL-адреса и никуда не перенаправляет пользователя. Я пробовал гуглить и читать столько, сколько могу, но не могу понять, что мне не хватает. Есть идеи? Я не хочу создавать HTML-форму, которая автоматически отправляется, если я могу этого избежать.
Спасибо за любую помощь :-)






API 3D Secure не позволяет выполнять запрос в фоновом режиме. Вам необходимо перенаправить пользователя на сайт с 3D-безопасностью. Используйте javascript для автоматической отправки формы. Вот что предлагает наш провайдер:
<html>
<head>
<title>Processing your request...</title>
</head>
<body OnLoad = "OnLoadEvent();">
<form name = "downloadForm" action = "<%=RedirURL%>" method = "POST">
<noscript>
<br>
<br>
<div align = "center">
<h1>Processing your 3-D Secure Transaction</h1>
<h2>JavaScript is currently disabled or is not supported by your browser.</h2><BR>
<h3>Please click Submit to continue the processing of your 3-D Secure transaction.</h3><BR>
<input type = "submit" value = "Submit">
</div>
</noscript>
<input type = "hidden" name = "PaReq" value = "<%=PAREQ%>">
<input type = "hidden" name = "MD" value = "<%=TransactionID%>">
<input type = "hidden" name = "TermUrl" value = "<%=TermUrl%>">
</form>
<SCRIPT LANGUAGE = "Javascript">
<!--
function OnLoadEvent() {
document.downloadForm.submit();
}
//-->
</SCRIPT>
</body>
</html>
Я думаю, вы немного не понимаете, что делает curl. Он делает именно то, что вы объяснили, он действует как браузер, обращается к сайту и возвращает содержимое этого сообщения. Я не знаю, как вы можете перенаправить серверную часть браузера и представить сообщение. Я бы на самом деле создал решение Javascript для этого.
Чтобы перенаправить пользователя на другую страницу в PHP, вы можете отправить header("Location: http://example.com/newpage");. Однако, к сожалению, перенаправление вашей программы приводит к удалению всех переменных POST (по соображениям безопасности). Если вы хотите, чтобы браузер пользователя отправлял запрос POST на другой URL-адрес, вам нужно будет создать форму, которая отправляет сама себя. :(
Я бы предпочел использовать что-то за кулисами, например cURL, поскольку я не могу гарантировать, что у моих пользователей будет включен JS, а отображение формы вызывает некоторые другие проблемы, которых я бы предпочел избежать. Но это мой план Б ;-)
Вы можете использовать fsockopen () для перенаправления на новый веб-сайт с сохранением ваших переменных POST. Есть хорошее руководство о том, как добиться этого здесь.
В случае, если этот веб-сайт будет съеден интернет-монстром, я скопировал и вставил функцию, но я предлагаю проверить исходный веб-сайт для контекста.
function sendToHost($host,$method,$path,$data,$useragent=0)
{
// Supply a default method of GET if the one passed was empty
if (empty($method)) {
$method = 'GET';
}
$method = strtoupper($method);
$fp = fsockopen($host, 80);
if ($method == 'GET') {
$path .= '?' . $data;
}
fputs($fp, "$method $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp,"Content-type: application/x-www-form- urlencoded\r\n");
fputs($fp, "Content-length: " . strlen($data) . "\r\n");
if ($useragent) {
fputs($fp, "User-Agent: MSIE\r\n");
}
fputs($fp, "Connection: close\r\n\r\n");
if ($method == 'POST') {
fputs($fp, $data);
}
while (!feof($fp)) {
$buf .= fgets($fp,128);
}
fclose($fp);
return $buf;
}
Ах, если я неправильно понял, что делает cURL, думаю, я соглашусь на HTML-форму с автоматической отправкой JS. Это создает для меня немного больше работы, но если это единственный способ, мне придется это сделать.
Всем спасибо за помощь.
Думаю, в этом случае нужно использовать форму. Веб-сайт компании, занимающейся платежными картами, должен посещаться браузером пользователя, а не серверным кодом.
Да, 3dsecure и т. д. Довольно неприятны для интеграции, но они действительно обеспечивают повышение безопасности - используйте его по назначению.
Может я что-то упускаю; похоже, вы пытаетесь получить данные пользователя, переслать их через cURL обработчику платежей, а затем куда-то перенаправить пользователя. Правильно?
Если это так, все, что вам нужно сделать, это просто поместить это в конец вашего кода:
заголовок («Местоположение: http://www.yoursite.com/yoururl»);
Однако, чтобы это работало, сценарий НЕ МОЖЕТ отправлять что-либо клиенту во время обработки; это означает, что скрипт не должен выполняться в середине шаблона, а другая ошибка - это пробел в начале файла перед открывающим тегом.
Если вам нужно сохранить данные из исходной транзакции POST, используйте сеанс для их сохранения.
Это должно работать для решения без JS.
Я не могу использовать сеанс для хранения данных, поскольку данные необходимо отправить на другой веб-сайт, а пользователю нужно показать форму, ввести текст и т. д. Подумав об этом, другая форма, предлагающая пользователю продолжить, - это лучший вариант, так как по крайней мере они осведомлены о том, что происходит.
Возможно, я совершенно ошибаюсь, но похоже, что вы пытаетесь сделать что-то похожее на шаблон прокси.
Я реализовал аналогичные шаблоны для других сайтов, с которыми работал, и для этого нужно немного поработать.
Я бы установил для RETURN_TRANSFER значение TRUE, чтобы вы могли анализировать полученный ответ и выполнять действия на уровне приложения в зависимости от него.
http://en.wikipedia.org/wiki/Proxy_pattern
Удачи.
Я нашел вышеупомянутую функцию sendToHost () очень полезной, но в источнике есть опечатка, отладка которой заняла некоторое время: значение заголовка Content-type содержит пробел между 'form-' и 'urlencoded' - должно быть 'application / x-www-form-urlencoded '
Вы не можете сделать 3D-безопасность «за кулисами», так как пользователя нужно перенаправить. Решение, которое я описал выше, - лучший способ сделать это, по крайней мере, так думает наш поставщик платежей.