Проблемы с кодированием секретной строки Amazon Flexible Payments в PHP

Я пытаюсь использовать Amazon Payment Services, и они требуют, чтобы я сделал что-то вроде этого:

Вот полная подпись, так что вы можете видеть, что я добавил метод подписи:

$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";

и затем я шифрую это как ниже.

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

Я делаю это, но потом я получаю сообщение об ошибке:

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

Есть идеи, что здесь может пойти не так?

Вот весь код для этого: (переменным назначены значения выше)

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

Спасибо!!

7 ответов

Проверьте, включены ли вы &SignatureMethod=HmacSHA256 по запросу

Этот тип ошибок имеет 3 основных типа:

  • Недостающие ключи / значения
  • Опечатки на ключи / значения
  • Неправильная кодировка или пробелы в ключах / значениях

Надеюсь, это поможет!

С уважением

Единственное, что не было предложено, было то, что вам нужно использовать rawurlencode() на transactionAmount это часть $string_to_sign,

Большинство других ответов являются частью проблемы. Например, вам нужно добавить новую строку в $string_to_sign после GET (который у вас есть), после authorize.payments-sandbox.amazon.comи после /cobranded-ui/actions/start, Вам также необходимо установить $raw_output параметр для true в hash_hmac() функция.

Я включил полный рабочий переписать ваш код (заменить <Your_Access_Key> а также <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;

Тем не менее, я настоятельно рекомендую вам использовать библиотеку PHP, предоставленную сообществом FPS, которую можно скачать здесь. Я использую это в рабочем коде и никогда не было проблем. Используя библиотеку FPS, ваш код будет выглядеть следующим образом:

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

?>

Вы установили свой метод подписи? из документации AWS:

Вы должны установить параметр запроса SignatureMethod в HmacSHA256 или HmacSHA1, чтобы указать, какой метод подписи вы используете

В вашей переменной $string_to_sign отсутствует знак '?' между началом и SignatureMethod для вашей закодированной подписи.

Signature version 2 - это улучшенный метод подписи для Amazon Simple Pay и Amazon Flexible Payments Service.

Для входящих запросов (из вашего приложения в Amazon Payments) он использует полный URI запроса в качестве основы для подписи с шифрованием на основе уникальных учетных данных для вашей учетной записи.

Для исходящих запросов (от Amazon Payments к вашему приложению) Amazon подписывает ответ, который вы можете проверить с помощью API VerifySignature

РЕДАКТИРОВАТЬ:

Как уже упоминал @Jonathan Spooner, я использую функцию varifySignature() находится в

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

который можно скачать здесь. У этого также есть пример того, как использовать это в

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

Это делает весь процесс намного проще. Это может стоить выстрел...

Я не верю, что вам нужно кодировать base64 хеш (в конце концов, он уже кодируется в urlen-коде) - попробуйте удалить Base64_Encode.

Ты пробовал это

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

Передайте логическое значение, чтобы передать его как необработанный вывод.

Вы определенно пропустите последний параметр для hash_hmac который должен быть установлен true чтобы получить RFC 2104-совместимую подпись HMAC:

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

И в полном примере вам не хватает новых строк в $string_to_sign,

Другие вопросы по тегам