0
votes

I'm trying to get Amazon seller data using the MWS API.The Scratchpad works fine, but when I try my own code, I get errors that indicate my signature isn't quite write. I've tried both GET and post with no luck. Any suggestions?

ERROR: SignatureDoesNotMatch The request signature we calculated does not match the signature you provided

AMAZON RECENT LIST ORDER REQUEST

<?php

$secretKey = '**************************';

$parameters = array();

// required parameters
$parameters['Action']               = 'ListOrders';
$parameters['AWSAccessKeyId']       = '*************';
$parameters['SellerId']             = '*************';
$parameters['SignatureMethod']      = 'HmacSHA256';
$parameters['SignatureVersion']     = '2';
$parameters['Timestamp']            = gmdate("Y-m-d\TH:i:s.\\0\\0\\0\\Z", time());
$parameters['Version']              = '2013-09-01';

// optional parameters
$parameters['MarketplaceId.Id.1']   = 'ATVPDKIKX0DER';
$parameters['CreatedAfter']         = '2017-10-04T04%3A00%3A00Z';

/**
 * Calculate String to Sign
 * 
 * @param array $parameters request parameters
 * @return String to Sign
 */
function _calculateStringToSign(array $parameters) {
    $data = "GET\n";
    $data .= "mws.amazonservices.com\n";
    $data .= "/Orders/2013-09-01\n";        
    $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);
1

1 Answers

0
votes

I'd very highly recommend using the Amazon Orders SDK. Amazons API can be quite unusual, when not outright broken. The SDK they provide is ugly, but reliable at authenticating and catching errors.

https://developer.amazonservices.com/doc/orders/orders/v20130901/php.html/138-9647438-2994968