Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems encoding Amazon Flexible Payments secret string in PHP

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

Here is the complete signature so you can see 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 I encrypt it like below.

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

I do that, but then I get an error from them saying:

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

Any idea what might be going wrong here?

Here is the entire code for this: (the variables are assigned 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!!

like image 739
GeekedOut Avatar asked Jan 13 '12 20:01

GeekedOut


4 Answers

Check if you included &SignatureMethod=HmacSHA256 on the request

This kind of errors has 3 basic natures:

  • Missing Keys/Values
  • Typos on Keys/Values
  • Incorrect encoding or spaces on Keys/Values

Hope that helps!

Regards

like image 169
Guilherme Viebig Avatar answered Nov 09 '22 23:11

Guilherme Viebig


The only piece that wasn't suggested was that you need to use rawurlencode() on the transactionAmount that's part of the $string_to_sign.

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

I've included a complete working rewrite of your code (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 that 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 an issue. Using the FPS library, your code would look like the following:

<?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);

?>
like image 21
Jonathan Spooner Avatar answered Nov 09 '22 22:11

Jonathan Spooner


Have you set your signature method? from the AWS documentation:

You must set the SignatureMethod request parameter to either HmacSHA256 or HmacSHA1 to indicate which signing method you're using

like image 21
MrGlass Avatar answered Nov 10 '22 00:11

MrGlass


I don't believe you need to base64 encode the hash (after all, it's already being urlencoded) -- try removing Base64_Encode.

like image 24
mpnk121 Avatar answered Nov 09 '22 23:11

mpnk121