Pregunta

estoy trabajando en un PHP aplicación que enlaza con el Protx VSP Direct payment gateway.Para manejar las solicitudes "3D Secure" de la empresa procesadora de tarjetas de crédito, necesito reenviar al usuario a un sitio web diferente, imitando un formulario que se ha publicado.Estoy tratando de usar el cURL bibliotecas, pero parecen haber tenido un problema.Mi código es el siguiente:

<?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 lo que esto hace es capturar el contenido de la URL pasada y no reenvía al usuario a ninguna parte.Intenté buscar en Google y leer todo lo que pude, pero no puedo entender 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 :-)

¿Fue útil?

Solución

La API 3D Secure no le permite realizar la solicitud en segundo plano.Debe reenviar al usuario al sitio seguro 3D.Utilice javascript para enviar automáticamente su formulario.Esto es lo que sugiere nuestro proveedor:

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

Otros consejos

Creo que estás un poco confundido sobre lo que hace curl.Hace exactamente lo que usted explicó, actúa como un navegador, realiza una llamada al sitio y devuelve el contenido de esa publicación.No conozco ninguna forma de redirigir el lado del servidor del navegador y representar una publicación.De hecho, crearía una solución Javascript para hacer tal cosa.

Para redirigir a un usuario a otra página en PHP puedes enviar un header("Location: http://example.com/newpage");.Sin embargo, desafortunadamente para la redirección de su programa, se eliminarán todas las variables POST (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 solo.:(

Preferiría usar algo detrás de escena como cURL, ya que no puedo garantizar que mis usuarios tengan JS habilitado y mostrar un formulario causa otros problemas que prefiero evitar.Aunque es mi plan B ;-)

Puede utilizar fsockopen() para redirigir al nuevo sitio web conservando sus variables POST.Hay un buen tutorial sobre cómo lograr esto. aquí.

En caso de que el monstruo de Internet se coma ese sitio web, copié y pegué la función, pero sugiero consultar el sitio web original para conocer 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;
}

Ah, si no he entendido bien lo que hace cURL, supongo que me conformaré con un formulario HTML con envío automático JS.Me crea bastante más trabajo, pero si es la única manera, tendré que hacerlo.

Gracias por toda la ayuda.

Creo que en este caso necesitas usar un formulario.El sitio web de las empresas de pago con tarjeta debe ser visitado por el navegador del usuario, no por el código del lado del servidor.

Sí, es bastante molesto integrar 3dsecure, etc., pero brindan un verdadero impulso de seguridad: úselo como está previsto.

Quizás me estoy perdiendo algo;parece que estás intentando recibir los datos del usuario, reenviarlos mediante cURL al procesador de pagos y luego redirigir al usuario a alguna parte.¿Bien?

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

encabezado("Ubicación: http://www.yoursite.com/yoururl");

Sin embargo, para que esto funcione, el script NO PUEDE enviar nada al cliente mientras se procesa;eso significa que el script no debe ejecutarse en medio de una plantilla, y otro problema es el espacio en blanco al principio del archivo antes de la etiqueta de apertura.

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

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

Puede que esté completamente equivocado, pero parece que estás intentando hacer algo similar al patrón proxy.

He implementado patrones similares para otros sitios con los que he trabajado y es necesario hacer algunos retoques para hacerlo bien.

Establecí RETURN_TRANSFER en TRUE para que pueda analizar la respuesta recuperada y realizar acciones a nivel de aplicación dependiendo de ella.

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

Buena suerte.

La función sendToHost() anterior me pareció muy útil, pero hay un error tipográfico en la fuente que tomó algo de tiempo para depurar:el valor del encabezado del tipo de contenido contiene un espacio entre 'formulario-' y 'urlencoded'; debe ser 'application/x-www-form-urlencoded'

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top