PHP ::Эмулировать <form method="“post”">, перенаправляя пользователя на страницу
Вопрос
Я работаю над 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-форму, которая автоматически отправляет себя, если я могу избежать этого.
Спасибо за любую помощь :-)
Решение
3D Secure API не позволяет вам выполнять запрос в фоновом режиме.Вам необходимо перенаправить пользователя на сайт 3D secure.Используйте 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"