Amazon Flexible Payments Secret Encoding Issues in PHP

I try to use Amazon Payment Services, and they require me to do something like this:

Here is the full signature, so you can see that I added the signature method:

$string_to_sign = "GET\n authorize.payments-sandbox.amazon.com\n cobranded-ui/actions/start? SignatureMethod=HmacSHA256&SignatureVersion=2&callerKey=my_key&callerReference=YourCallerReference&paymentReason=donation&pipelineName=SingleUse&returnUrl=http%3A%2F%2Fyourwebsite.com%2Freturn.html&transactionAmount=4.0"; 

and then encrypt it as shown below.

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

I do this, but then I get an error from them:

 Caller Input Exception: The following input(s) are either invalid or absent:[signatureMethod] 

Any idea what might be wrong here?

Here is the whole code for this: (the variables are assigned the values ​​above)

 <?php $string_to_sign = 'GET authorize.payments-sandbox.amazon.com/cobranded-ui/actions/startSignatureMethod=HmacSHA256&SignatureVersion=2&callerKey=AKIAJENBYSJCJX2IDWDQ&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; //echo $amazon_request_sandbox; - use this if you want to see the resulting request and paste it into the browser header('Location: '.$amazon_request_sandbox); ?> 

Thanks!!

+7
source share
7 answers

Check if you included &SignatureMethod=HmacSHA256 in the request

This type of error has 3 main properties:

  • Missing Keys / Values
  • Typos on Keys / Values
  • Incorrect coding or spaces in keys / values

Hope this helps!

Hi

+5
source

The only thing that has not been suggested is that you need to use rawurlencode() in transactionAmount that part of $string_to_sign .

Most of the other answers are part of the problem. For example, you need to add a new line to $string_to_sign after the GET (which you have) after authorize.payments-sandbox.amazon.com and after /cobranded-ui/actions/start . You also need to set the $raw_output parameter to true in the hash_hmac() function.

I turned on full code rework (replace <Your_Access_Key> and <Your_Secret_Key> ):

 $return_url = rawurlencode('http://problemio.com'); $payment_reason = 'donation'; $transaction_amount = rawurlencode('4.0'); $secret_key = '<Your_Secret_Key>'; $my_access_key_id = '<Your_Access_Key>'; $string_to_sign = 'GET authorize.payments-sandbox.amazon.com /cobranded-ui/actions/start SignatureMethod=HmacSHA256&SignatureVersion=2&callerKey=' . $my_access_key_id . '&callerReference=YourCallerReference&paymentReason=' . $payment_reason . '&pipelineName=SingleUse&returnUrl=' . $return_url . '&transactionAmount=' . $transaction_amount; $encoded_string_to_sign = URLEncode(Base64_Encode(hash_hmac("sha256", $string_to_sign, $secret_key, true))); $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; 

However, I strongly suggest you use the PHP library provided by the FPS community, which can be downloaded here . I use this in production code and have never had a problem. Using the FPS library, your code will look like this:

 <?php require_once 'CBUISingleUsePipeline.php'; require_once 'CBUIPipeline.php'; $secret_key = '<Your_Secret_Key>'; $my_access_key_id = '<Your_Access_Key>'; $return_url = 'http://problemio.com'; $transaction_amount = '4.0'; $caller_reference = '<Your_Caller_Reference>'; $payment_reason = 'donation'; $base = 'https://authorize.payments-sandbox.amazon.com/cobranded-ui/actions/start'; $pipeline = new Amazon_FPS_CBUISingleUsePipeline($my_access_key_id, $secret_key); $pipeline->setMandatoryParameters($caller_reference, $return_url, $transaction_amount); $pipeline->addParameter('paymentReason', $payment_reason); $uRL = $pipeline->getURL($base); ?> 
+3
source

Have you set your signature method? from AWS Documentation :

You must set the SignatureMethod request parameter for HmacSHA256 or HmacSHA1 to indicate which subscription method you use

+2
source

I do not believe that you need base64 to encode a hash (after all, it was already urlencoded) - try removing Base64_Encode.

+2
source

The variable $ string_to_sign is missing the character ?? between start and SignatureMethod for your encoded signature.

Signature Version 2 is an improved signature method for Amazon. Easy payment and Amazon flexible payment service.

For incoming requests (from your application to Amazon Payments), this uses the entire request URI as the basis for the signature, with encryption based on the unique security credentials for your account.

For outgoing requests (from Amazon Payments to your application), Amazon signs a response that you can verify using the VerifySignature API

EDIT:

As @Jonathan Spooner already mentioned, and I use the varifySignature() function located in

/amazon-fps-2010-08-28-php5-library/src/Amazon/FPS/Samples/Client.php

which can be downloaded here . He also has an example of how to use it in

/amazon-fps-2010-08-28-php5-library/src/Amazon/FPS/Samples/VerifySignatureSample.php

This makes the whole process easier. It might be worth it ...

+2
source

Have you tried it

base64_encode (hash_hmac ('sha256', $ Request, $ AmazonSecretKey, true));

Pass a boolean to pass it as the source output.

+1
source

You are definitely missing the last parameter for hash_hmac , which must be set to true in order to get an HMAC signature compatible with RFC 2104:

 base64_encode( hash_hmac($hash, $data, $key, true) ); 

And in the full example, you are missing new lines in $string_to_sign .

+1
source

All Articles