2015-12-02 44 views
1

我想轉換一個亞馬遜MWS暫存器飼料查詢到PHP的捲曲請求(更新價),但出現以下錯誤:亞馬遜MWS飼料到PHP捲曲的請求 - 更新價格

the Content-MD5 HTTP header you passed for your feed did not match the Content-MD5 we calculated for your feed

問題是我不知道如何將xml數據($ feed)包含到curl請求中。

該代碼適用於不需要提要的其他請求,但是如何將提要包含在請求中?

$feed = <<< EOD 
     <?xml version="1.0" encoding="utf-8"?> 
     <AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd"> 
     <Header> 
     <DocumentVersion>1.01</DocumentVersion> 
     <MerchantIdentifier>$merchant_token</MerchantIdentifier> 
     </Header> 
     <MessageType>Price</MessageType> 
     <Message> 
      <MessageID>$i</MessageID> 
      <Price> 
      <SKU>$sku</SKU> 
      <StandardPrice currency="$currency">$new_price</StandardPrice> 
      </Price> 
     </Message> 
     </AmazonEnvelope> 
EOD; 

    $feedHandle = @fopen('php://temp', 'rw+'); 
    fwrite($feedHandle, $feed); 
    rewind($feedHandle); 

    $params = array(
     'AWSAccessKeyId' => $this->awsAccessKeyId, 
     'Action' => "SubmitFeed", 
     'Merchant' => $this->sellerId, 
     'SignatureMethod' => "HmacSHA256", 
     'SignatureVersion' => "2", 
     'Timestamp'=> gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time()), 
     'Version'=> "2009-01-01", 
     'MarketplaceIdList.Id.1' => $this->markedplaceId, 
     'FeedType' => '_POST_PRODUCT_PRICING_DATA_', 
     //'FeedContent' => $feedHandle, 
     'PurgeAndReplace' => 'false', //Leave this PurgeAndReplace to false so that it want replace whole product in amazon inventory 
     //'Content-Md5' => base64_encode(md5(stream_get_contents($feedHandle), true)) 
    ); 

    $md5 = base64_encode(md5(stream_get_contents($feedHandle), true)); 

    // Sort the URL parameters 
    $url_parts = array(); 
    foreach(array_keys($params) as $key) 
     $url_parts[] = $key . "=" . str_replace('%7E', '~', rawurlencode($params[$key])); 

    sort($url_parts); 

    // Construct the string to sign 
    $url_string = implode("&", $url_parts); 
    $string_to_sign = "GET\nmws.amazonservices.de\n/Feeds/2009-01-01\n" . $url_string; 

    // Sign the request 
    $signature = hash_hmac("sha256", $string_to_sign, $this->awsSecretAccessKey, TRUE); 

    // Base64 encode the signature and make it URL safe 
    $signature = urlencode(base64_encode($signature)); 

    $url = "https://mws.amazonservices.de/Feeds/2009-01-01" . '?' . $url_string . "&Signature=" . $signature; 
    //var_dump($url); 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL,$url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 15); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
     'Content-Type: text/xml', 
     'Content-MD5: '.$md5, 
     'FeedContent: '.$feedHandle 
     ) 
    ); 

    $response = curl_exec($ch); 

    $parsed_xml = simplexml_load_string($response); 

    return $parsed_xml; 

回答

2

好吧,我終於把它工作。問題是在字符串簽名,它應該是這樣的POST:

$string_to_sign = "POST\nmws.amazonservices.de\n/Feeds/2009-01-01\n" . $url_string; 

而另一個問題是,我需要修剪$飼料。這裏是工作代碼:

$feed = <<< EOD 
     <?xml version="1.0" encoding="utf-8"?> 
     <AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd"> 
     <Header> 
     <DocumentVersion>1.01</DocumentVersion> 
     <MerchantIdentifier>$merchant_token</MerchantIdentifier> 
     </Header> 
     <MessageType>Price</MessageType> 
     <Message> 
      <MessageID>$i</MessageID> 
      <Price> 
      <SKU>$sku</SKU> 
      <StandardPrice currency="$currency">$new_price</StandardPrice> 
      </Price> 
     </Message> 
     </AmazonEnvelope> 
EOD; 

    $feedHandle = @fopen('php://temp', 'rw+'); 
    fwrite($feedHandle, trim($feed)); 
    rewind($feedHandle); 

    $params = array(
     'AWSAccessKeyId' => $this->awsAccessKeyId, 
     'Action' => "SubmitFeed", 
     'Merchant' => $this->sellerId, 
     'SignatureVersion' => "2", 
     'Timestamp'=> gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time()), 
     'Version'=> "2009-01-01", 
     'SignatureMethod' => "HmacSHA256", 
     'FeedType' => '_POST_PRODUCT_PRICING_DATA_', 
     'MarketplaceIdList.Id.1' => $this->markedplaceId, 
     'PurgeAndReplace' => 'false' 
    ); 

    // Sort the URL parameters 
    $url_parts = array(); 
    foreach(array_keys($params) as $key) 
     $url_parts[] = $key . "=" . str_replace('%7E', '~', rawurlencode($params[$key])); 

    sort($url_parts); 

    // Construct the string to sign 
    $url_string = implode("&", $url_parts); 
    $string_to_sign = "POST\nmws.amazonservices.de\n/Feeds/2009-01-01\n" . $url_string; 

    // Sign the request 
    $signature = hash_hmac("sha256", $string_to_sign, $this->awsSecretAccessKey, TRUE); 

    // Base64 encode the signature and make it URL safe 
    $signature = urlencode(base64_encode($signature)); 

    $url = "https://mws.amazonservices.de/Feeds/2009-01-01" . '?' . $url_string . "&Signature=" . $signature; 

    $md5 = base64_encode(md5(trim($feed), true)); 

    $httpHeader=array(); 
    $httpHeader[]='Transfer-Encoding: chunked'; 
    $httpHeader[]='Content-Type: text/xml'; 
    $httpHeader[]='Content-MD5: ' . $md5; 
    $httpHeader[]='Expect:'; 
    $httpHeader[]='Accept:'; 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 15); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
    curl_setopt($ch, CURLOPT_INFILE, $feedHandle); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader); 
    curl_setopt($ch, CURLOPT_POST, true); 

    $response = curl_exec($ch); 

    if(curl_errno($ch)) 
    { 
     var_dump(curl_error($ch)); 
    } 

    $parsed_xml = simplexml_load_string($response); 

    return $parsed_xml;