如何使用PHP调用亚马逊MWS订单?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用PHP调用亚马逊MWS订单?相关的知识,希望对你有一定的参考价值。

我正在设置对亚马逊MWS的订单部分进行API调用时遇到很多麻烦和挫折。

当我使用Amazon MWS Scratchpad时,我能够得到一个成功的响应,但当我自己打电话时,我得到错误:

The request signature we calculated does not match the signature you provided.
Check your AWS Secret Access Key and signing method.
Consult the service documentation for details.

我可能是错的,但我认为我实际打电话的方式肯定有问题,因为即使我使用通过Scratchpad创建的确切调用,我仍然会收到相同的错误。

尽管如此,这是我试图建立请求的代码:

<?php

$secretKey = '<MY SECRET KEY>';

$parameters = array();

// required parameters
$parameters['Action']               = 'ListOrders';
$parameters['AWSAccessKeyId']       = '<MY ACCESS KEY>';
$parameters['MWSAuthToken']         = '<MY AUTH TOKEN>';
$parameters['SellerId']             = '<MY SELLER ID>';
$parameters['SignatureMethod']      = 'HmacSHA256';
$parameters['SignatureVersion']     = '2';
$parameters['Timestamp']            = gmdate("Y-m-dTH:i:s.\0\0\0\Z", time());
$parameters['Version']              = '2013-09-01';

// optional parameters
$parameters['MarketplaceId.Id.1']   = '<MARKETPLACE ID>';
$parameters['CreatedAfter']         = '2015-10-04T04%3A00%3A00Z';

/**
 * Calculate String to Sign
 * 
 * @param array $parameters request parameters
 * @return String to Sign
 */
function _calculateStringToSign(array $parameters) {
    $data = "POST
";
    $data .= "mws.amazonservices.com
";
    $data .= "/Orders/2013-09-01
";        
    $data .= _getParametersAsString($parameters);
    return $data;
}


/**
 * Convert paremeters to Url encoded query string
 */
function _getParametersAsString(array $parameters)
{
    uksort($parameters, 'strcmp');
    $queryParameters = array();
    foreach ($parameters as $key => $value) {
        $queryParameters[] = $key . '=' . _urlencode($value);
    }
    return implode('&', $queryParameters);
}

function _urlencode($value) {
    return str_replace('%7E', '~', rawurlencode($value));
}

/**
 * Computes RFC 2104-compliant HMAC signature.
 */
function _sign($stringToSign, $secretKey)
{
    $hash = 'sha256';

    return urlencode(base64_encode(
        hash_hmac($hash, $stringToSign, $secretKey, true)
    ));
}

/**
 * Builds up the request.
 */
function buildRequest(array $parameters, $secretKey) {
    $endpoint = 'https://mws.amazonservices.com/Orders/2013-09-01';

    $signature = _sign(_calculateStringToSign($parameters), $secretKey);
    $parameters['Signature'] = $signature;

    uksort($parameters, 'strcmp');
    return $endpoint . '?' . _getParametersAsString($parameters);
}

以下是实际调用的代码:

$request = buildRequest($parameters, $secretKey);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) chrome/39.0.2171.71 Safari/537.36');
$page = curl_exec($ch);
curl_close($ch);
var_dump($page);

我需要帮助确定这个脚本出错的地方以及为什么我无法获得成功的响应。

答案

这听起来很愚蠢,但是根据您目前的代码,您正在制作GET请求,但您将其签名为POST

将签名的第一行从POST更改为GET,签名应该完美无缺。

另一答案

解:

$secretKey = 'ENTERVALUE';

$parameters = array();

// required parameters
$parameters['AWSAccessKeyId']       = 'ENTERVALUE';
$parameters['Action']               = 'GetOrder';
$parameters['AmazonOrderId.Id.1']   = 'ENTERVALUE';
$parameters['SellerId']             = 'ENTERVALUE';
$parameters['SignatureMethod']      = 'HmacSHA256';
$parameters['SignatureVersion']     = '2';
$parameters['Timestamp']            = gmdate("Y-m-dTH:i:s.\0\0\0\Z", time());
$parameters['Version']              = '2013-09-01';




/**
 * Calculate String to Sign
 * 
 * @param array $parameters request parameters
 * @return String to Sign
 */
function _calculateStringToSign(array $parameters) {
    $data = "POST
";
    $data .= "mws.amazonservices.com
";
    $data .= "/Orders/2013-09-01
";        
    $data .= _getParametersAsString($parameters);
    return $data;
}


/**
 * Convert paremeters to Url encoded query string
 */
function _getParametersAsString(array $parameters)
{
    uksort($parameters, 'strcmp');
    $queryParameters = array();
    foreach ($parameters as $key => $value) {
        $queryParameters[] = $key . '=' . _urlencode($value);
    }
    return implode('&', $queryParameters);
}

function _urlencode($value) {
    return str_replace('%7E', '~', rawurlencode($value));
}

/**
 * Computes RFC 2104-compliant HMAC signature.
 */
function _sign($stringToSign, $secretKey)
{
    //HmacSHA1
    $hash = 'sha256';

    return base64_encode(
        hash_hmac($hash, $stringToSign, $secretKey, true)
    );
}

/**
 * Builds up the request.
 */
function buildRequest(array $parameters, $secretKey) {
    //$endpoint = 'https://mws.amazonservices.com/Orders/2013-09-01';

    $signature = _sign(_calculateStringToSign($parameters), $secretKey);
    $parameters['Signature'] = $signature;

    uksort($parameters, 'strcmp');
    return _getParametersAsString($parameters);
}

$request = buildRequest($parameters, $secretKey);



$allHeaders = array();
    $allHeaders['Content-Type'] = "application/x-www-form-urlencoded; charset=utf-8"; // We need to make sure to set utf-8 encoding here
    $allHeaders['Expect'] = null; // Don't expect 100 Continue
    $allHeadersStr = array();
    foreach($allHeaders as $name => $val) {
        $str = $name . ": ";
        if(isset($val)) {
            $str = $str . $val;
        }
        $allHeadersStr[] = $str;
    }


//complete string
//echo $endpoint . '?' .$request;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://mws.amazonservices.com/Orders/2013-09-01');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_HTTPHEADER, $allHeadersStr);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) chrome/39.0.2171.71 Safari/537.36');
$response = curl_exec($ch);
echo $response;
$xml = simplexml_load_string( $response );
echo curl_error($ch);
curl_close($ch);

以上是关于如何使用PHP调用亚马逊MWS订单?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过“亚马逊MWS订单API”获取“非亚马逊”销售渠道订单

亚马逊 MWS Feed API 更新订单状态的问题

亚马逊 MWS 集成

在亚马逊 MWS 中更新订单状态后出现“无法履行订单”错误

亚马逊费用未显示在 MWS 订单 API 上

亚马逊 MWS 提要 API 问题,取消订单