Pregunta

Estoy tratando de reescribir una solicitud de publicación Fopen () para trabajar con un proxy.

El código se basa en un ejemplo en el sitio de PayPal (https://www.x.com/developers/paypal/documentation-tools/code-sample/216632).

Mis soluciones predeterminadas para Fopen (), así como para file_get_contents () y curl lib no funcionan para el encabezado y el contenido de Post relativamente complejo. (O no pasar por proxy o obtener una solicitud no válida: {0}, incluso cuando no Proxy está establecido) Aquí está el código de ejemplo (simplificado) de publicación:

$url = trim('https://svcs.sandbox.paypal.com/AdaptiveAccounts/AddBankAccount');
$API_UserName = "sbapi_1287090601_biz_api1.paypal.com"; //TODO
$API_Password = "1287090610"; //TODO
$API_Signature = "ANFgtzcGWolmjcm5vfrf07xVQ6B9AsoDvVryVxEQqezY85hChCfdBMvY"; //TODO
$API_SANDBOX_EMAIL_ADDRESS = "rishaque@paypal.com"; //TODO
$API_DEVICE_IPADDRESS = "127.0.0.1"; //TODO
$API_AppID = "APP-80W284485P519543T";
$API_RequestFormat = "XML";
$API_ResponseFormat = "XML";

$xml = simplexml_load_string($xml_str);
$contents = $xml->asXML();

try
{
    $params = array("http" => array(
                                    "method" => 'POST',
                                    "content" => $contents,
                                    'header' =>  'X-PAYPAL-SECURITY-USERID: ' . $API_UserName ."\r\n" .
                                            'X-PAYPAL-SECURITY-PASSWORD: ' . $API_Password . "\r\n" .
                                            'X-PAYPAL-SECURITY-SIGNATURE: ' . $API_Signature . "\r\n" .
                                            'X-PAYPAL-REQUEST-DATA-FORMAT: ' . $API_RequestFormat . "\r\n" .
                                            'X-PAYPAL-RESPONSE-DATA-FORMAT: ' . $API_ResponseFormat . "\r\n" .
                                            'X-PAYPAL-APPLICATION-ID: ' . $API_AppID . "\r\n" .
                                            'X-PAYPAL-SANDBOX-EMAIL-ADDRESS: ' . $API_SANDBOX_EMAIL_ADDRESS . "\r\n" .
                                            'X-PAYPAL-DEVICE-IPADDRESS: ' . $API_DEVICE_IPADDRESS . "\r\n" ));

     $ctx = stream_context_create($params);

     $fp = @fopen($url, 'r', false, $ctx); // PROXIFY!
     $response = stream_get_contents($fp);
     if ($response === false) {
        throw new Exception("php error message = " . "$php_errormsg");
     }
     fclose($fp);

     // ... handle the response content ...
 }
 catch(Exception $e)
 {
     echo 'Message: ||' .$e->getMessage().'||';
 }

?>

Mi proxy file_get_contents ():

        if (!empty($_context_params)) {
            $http_arr = $_context_params['http'];
            $http_arr['proxy'] = $proxy_path;
            $http_arr['request_fulluri'] = true;
            $_context_params['http'] = $http_arr;
        }
        else
        {
            $_context_params = array( 'http' => array( 'proxy' => $proxy_path, 'request_fulluri' => true ) );
        }
        return file_get_contents( $_url, false, stream_context_create( $_context_params ) );

Mi fopen apropiado:

        $parsed_proxy_path = parse_url($proxy_path);
        $_proxy_name = $parsed_proxy_path['host'];
        $_proxy_port = $parsed_proxy_path['port'];
        $proxy_fp = fsockopen( $_proxy_name, $_proxy_port );
        if ( !$proxy_fp )
            return false;
        $parsed_url = parse_url($_url);
        $host = $parsed_url['host'];

        $request = "GET $_url HTTP/1.0\r\nHost:$host\r\n\r\n";

        fputs( $proxy_fp, $request );

        return $proxy_fp;

Mi experimento curl: (Codeigniter curl lib se encarga de poder para mí)

$http_params = $params['http'];
$this->curl->create($this->cfg->paypal_req_url);
$this->curl->option('header', true);$this->curl->option('verbose', true);
$this->curl->option('useragent', 'cURL/PHP');

$this->curl->http_header($http_params['header']);
$this->curl->http_header("Content-length: ".strlen($contents));
$this->curl->post(array("content"=> $contents));
$res = $this->curl->execute();

¿Alguna idea a dónde ir desde aquí? Estoy un poco atascado ..

¿Cómo depuggo la solicitud que sale de Curl? ¿La solicitud es incluso reproducible con Curl? ¿Funcionará con Get en lugar de Post? ¿Es XMLRPC una opción?

Nota: El código de ejemplo funciona para mí cuando no está detrás de un proxy.

Gracias por adelantado,

Alex

¿Fue útil?

Solución

Aquí está el código que solía hacer que funcionara con Curl.

Nota: Utiliza el CodeInigniter curl lib de Phil Sturgeon.

Nota: resolví cambiar de XML a una cadena de consulta para el contenido.

    $contents = array(
                        "actionType"=>"PAY",
                        "cancelUrl"=>$cancel_url,
                        "returnUrl"=>$return_url,
                        "currencyCode"=>$currency,
                        "sender"=>$sendingmail,
                        "memo"=>$memo,
                        "requestEnvelope.errorLanguage"=>$error_lang,
                        "receiverList.receiver.amount"=>$amount,
                        "receiverList.receiver.email"=>$receivingmail,
    );
    if (isset($notification_url)) { $contents["ipnNotificationUrl"]=$notification_url; }
    if ($receivingmail == $this->cfg->paypal_email) { $contents["feesPayer"]="SENDER"; }
    if ($sendingmail == $this->cfg->paypal_email) { $contents["senderEmail"]=$sendingmail; }

    // ------------------------------
    // create request and add headers
    // ------------------------------
    $options = array( "useragent" => "cURL/PHP" );
    $this->curl->create($this->cfg->paypal_req_url);
    $this->curl->http_header("Content-type", "application/x-www-form-urlencoded");
    $this->curl->http_header("X-PAYPAL-SECURITY-USERID", $this->cfg->paypal_user_name);
    $this->curl->http_header("X-PAYPAL-SECURITY-SIGNATURE", $this->cfg->paypal_signature);
    $this->curl->http_header("X-PAYPAL-SECURITY-PASSWORD", $this->cfg->paypal_password);
    $this->curl->http_header("X-PAYPAL-APPLICATION-ID", $this->cfg->paypal_app_id);
    $this->curl->http_header("X-PAYPAL-REQUEST-DATA-FORMAT", "NV");
    $this->curl->http_header("X-PAYPAL-RESPONSE-DATA-FORMAT", "XML");
    $this->curl->post($contents, $options);
    $response = $this->curl->execute();

Para aquellos atrapados con PHP4, ¿podría ser útil responder a la pregunta original de hacer que funcione a través del proxy con Fopen?

Salud,

Alex

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