2008-09-19 15 views
5

Estoy trabajando en una aplicación PHP que enlaza con el . Para manejar las solicitudes de "3D Secure" de la compañía de procesamiento de tarjetas de crédito, debo reenviar al usuario a un sitio web diferente, imitando un formulario que se ha publicado. Intento utilizar las bibliotecas cURL, pero parece que he encontrado un problema. Mi código es el siguiente:PHP :: Emular <form method = "post">, reenviando usuario a la página

<?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); 
?> 

Todo esto hace es agarrar el contenido de la URL pasada a través, y no reenvía el usuario en cualquier lugar. Intenté buscar en Google y leer todo lo que pude, pero no puedo darme cuenta de lo que me estoy perdiendo. ¿Algunas ideas? No quiero tener que crear un formulario HTML que se envíe automáticamente si puedo evitarlo.

Gracias por cualquier ayuda :-)

Respuesta

2

La API 3D Secure no permite que haga la solicitud en el fondo. Debe reenviar al usuario al sitio seguro 3D. Use javascript para enviar automáticamente su formulario. Esto es lo que nuestro proveedor sugiere:

<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> 
0

Creo que está un poco confundido en cuanto a qué curvatura hace. Hace exactamente lo que usted explicó, actúa como un navegador y realiza la llamada al sitio y devuelve el contenido de esa publicación. No sé de ninguna manera que puedas redireccionar el lado del servidor del navegador y representar una publicación. De hecho, crearía una solución de Javascript para hacer tal cosa.

0

Para redirigir a un usuario a otra página en PHP puede enviar un header("Location: http://example.com/newpage");. Sin embargo, desafortunadamente para su redirección de programa causa que todas las variables POST sean eliminadas (por razones de seguridad). Si desea que el navegador del usuario envíe una solicitud POST a una URL diferente, deberá crear un formulario que se envíe a sí mismo. :(

0

Prefiero usar algo entre bastidores como cURL, ya que no puedo garantizar que mis usuarios tengan habilitado JS, y mostrar un formulario causa algunos otros problemas que preferiría evitar. Es mi plan B aunque ;-)

+0

No se puede hacer seguridad 3D "detrás de escena", ya que el usuario necesita ser reenviado. La solución que describí anteriormente es la mejor manera de hacerlo, al menos eso es lo que piensa nuestro proveedor de pagos. – neu242

0

Puede usar fsockopen() para redirigir al nuevo sitio web mientras conserva sus variables POST. Hay un buen tutorial sobre cómo lograr esto here.

En caso de que el sitio web sea comido por el monstruo de Internet, he copiado y pegado la función, pero sugiero que revise el sitio web original para el contexto.

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; 
} 
0

Ah, si he entendido mal lo que hace cURL, supongo que me conformaré con un formulario HTML con JS auto-submit. Crea un poco más de trabajo para mí, pero si es la única manera, tendré que hacerlo.

Gracias por la ayuda a todos.

0

Creo que en este caso necesita utilizar un formulario. El sitio web de las compañías de pago con tarjeta debe ser visitado por el navegador del usuario, no por su código del lado del servidor.

Sí, 3Dsecure, etc., son bastante molestas para integrarse, pero proporcionan un verdadero refuerzo de seguridad: úselo como está previsto.

0

Quizás me falta algo; parece que estás tratando de recibir los datos del usuario, reenviarlos a través de cURL al procesador de pagos y luego redirigir al usuario a alguna parte. ¿Derecha?

Si es así, todo lo que tiene que hacer es poner esto al final de su código:

header ("Location: http://www.yoursite.com/yoururl");

Sin embargo, para que esto funcione, la secuencia de comandos NO PUEDE enviar nada al cliente mientras se está procesando; eso significa que el script no se debe ejecutar en el medio de una plantilla, y otro gotcha es un espacio en blanco al principio del archivo antes de la etiqueta de apertura.

Si necesita guardar los datos de la transacción POST original, use una sesión para guardarlos.

Eso debería funcionar para una solución sin JS.

+0

No puedo usar una sesión para almacenar datos, ya que los datos deben enviarse a otro sitio web, y el usuario debe mostrar un formulario, ingresar texto, etc. Al pensar en ello, otro formulario que le pide al usuario continuar es la mejor opción, ya que al menos están al tanto de lo que está sucediendo. – fistameeny

0

Puedo estar totalmente equivocado, pero parece que estás tratando de hacer algo similar al Patrón Proxy.

He implementado patrones similares para otros sitios con los que he trabajado y requiere un poco de retoques para hacerlo bien.

Establecería el RETURN_TRANSFER en TRUE para que pueda analizar la respuesta recuperada y realizar acciones de nivel de aplicación en función de ello.

http://en.wikipedia.org/wiki/Proxy_pattern

Buena suerte.

0

Encontré muy útil la función sendToHost(), pero hay un error tipográfico en la fuente que demoró tiempo en depurarse: el valor del encabezado Content-type contiene un espacio entre 'form-' y 'urlencoded' - should ser 'application/x-www-form-urlencoded'

Cuestiones relacionadas