Проблемы с кодированием секретной строки 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
,