简体   繁体   中英

Amazon Flexible Payments Exception: Caller Input Exception: Invalid Signature

I am trying to work with the PHP API for Amazon's Flexible Payments.

Here is my PHP snippet to send a payment request:

<?php

$string_to_sign = 'GET
authorize.payments-sandbox.amazon.com
/cobranded-ui/actions/start
SignatureMethod=HmacSHA256&SignatureVersion=2&callerKey=my_access_key&callerReference=YourCallerReference&paymentReason=donation&pipelineName=SingleUse&returnUrl=http%3A%2F%2Fproblemio.com&transactionAmount=4.0';

$encoded_string_to_sign = URLEncode(Base64_Encode(hash_hmac('sha256', $string_to_sign, 'my_secret_key')));

$amazon_request_sandbox = 'https://authorize.payments-sandbox.amazon.com/cobranded-ui/actions/start?SignatureVersion=2&returnUrl='.$return_url.'&paymentReason='.$payment_reason.'&callerReference=YourCallerReference&callerKey='.$my_access_key_id.'&transactionAmount=4.0&pipelineName=SingleUse&SignatureMethod=HmacSHA256&Signature='.$encoded_string_to_sign;

// When it goes to the url, it gets the invalid signature error
header('Location: '.$amazon_request_sandbox); 
?>

This seems to be following their instructions, but I can't get past that error.

Thanks!!

<?php

$method = 'GET';
$host   = 'authorize.payments-sandbox.amazon.com';
$path   = '/cobranded-ui/actions/start';

$params = array( 
    'signatureMethod'  => 'HmacSHA256',
    'signatureVersion' => '2',
    'currencyCode'     => 'USD',
    'callerKey' => 'Your_Key_ID',
    'callerReference'  => 'YourCallerReference',
    'paymentReason'    => 'donation',
    'pipelineName'     => 'SingleUse',
    'returnUrl'        => 'http://yourcallback.com',
    'transactionAmount'=> '5',
    'version'          => '2009-01-09',
);


$params = array_map('rawurlencode', $params);


$paramStringArray = array();

foreach($params as $key => $value){

    $paramStringArray[] = $key . '=' . $value;

}




$paramString = implode('&', $paramStringArray);

$string_to_sign = $method . "\n"
        . $host . "\n"
        . $path  . "\n"
        . $paramString;


$signature = base64_encode(hash_hmac(
    'sha256',
    $string_to_sign,
    'Your_Super_Secret_Key',
    true
));



$amazon_request_sandbox = "https://{$host}{$path}?" . $paramString .
    '&signature=' . rawurlencode($signature);

header('Location: '.$amazon_request_sandbox); 

?>

Okay... using the structure from the code below, I've finally figured this whole thing out via the code above. There are three things of note to keep track of while forming your signature/URL...

  1. It seems that the parameter "transactionAmount" is necessary for a valid Co-branded UI Pipeline, even though there's no specific instruction alluding to the issue.

  2. If any of your parameters have/had spaces in them, and you tried to use html_build_query() in all but the latest (5.4) version of PHP, you would be given an encoding scheme that featured "+" marks for spaces instead of "%20" which is what Amazon appears to like. My code above takes care of that by implementing rawurlencode() on the entire parameter array.

  3. The ordering of the parameters is paramount in the construction of the signature. The keys (not the values) need to be in case-insensitive alphabetical order. It's also worth noting that despite what the documentation says for the API, both the ampersands (&) and the equals (=) must be present in the creation of the query string for the signature.

Ex:

Query String for Signature: callerKey=1111111111111&currencyCode=USD&signatureVersion=2

Some Other Things I Noticed...

In the sample code included with the PHP SDK (2010-8-28), the "paymentReason" attribute in the file "CBUISingleUsePipelineSample.php" is listed as "HarryPotter 1-5 DVD set". Since this attribute has spaces in it, it throws that ever-annoying "invalid signature" error when you try to visit the generated link because html_build_query() is used to generate the query string for the URL. To fix this issue, open up "CBUIPipeline.php", and look for the following line in the constructUrl() method...

$queryString = http_build_query($parameters, '', '&');

replace it with:

$queryString = str_replace('+', '%20', http_build_query($parameters, '', '&'));

That'll solve the space-encoding problem for older versions of PHP (< 5.4). With the latest version, there's an "enc_type" flag you can set.

Last things Last...

This is my first post on StackOverflow so don't kill me if I broke protocol. Hope it helps!

Try this piece of code:

<?php

$method = 'GET';
$host   = 'authorize.payments-sandbox.amazon.com';
$path   = '/cobranded-ui/actions/start';

$params = array(
    'SignatureMethod'  => 'HmacSHA256'
    'SignatureVersion' => 2,
    'callerKey'        => 'my_access_key',
    'callerReference'  => 'YourCallerReference',
    'paymentReason'    => 'donation',
    'pipelineName'     => 'SingleUse',
    'returnUrl'        => 'http://problemio.com&transactionAmount=4.0',
);

$string_to_sign = $method . "\n"
    . $host . "\n"
    . $path . "\n"
    . http_build_query($params);

$signature = base64_encode(hash_hmac(
    'sha256',
    $string_to_sign,
    'my_secret_key'
));

$params['Signature'] = $signature;

$amazon_request_sandbox = "https://{$host}{$path}?" . http_build_query($params);

header('Location: ' . $amazon_request_sandbox);

So I made a few changes:

  • PHP's http_build_query() to build the query string (ensure correct encoding)
  • trying to re-use your vars vs. duplicating the efforts (makes it easier to spot mistakes, etc.)
  • explicit \\n - maybe your editor entered \\r or \\r\\n

HTH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM