在PHP中编码Amazon Flexible Payments秘密字符串时出现问题



我正在尝试使用亚马逊支付服务,他们要求我做这样的事情:

这是完整的签名,所以你可以看到我添加了签名方法:

$string_to_sign = "GETn
authorize.payments-sandbox.amazon.comn
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);
?>

谢谢!!

检查请求中是否包含&SignatureMethod=HmacSHA256

这种错误有三个基本性质:

  • 缺少键/值
  • 键入键/值
  • 键/值的编码不正确或有空格

希望能有所帮助!

问候

唯一没有建议的是,您需要在作为$string_to_sign一部分的transactionAmount上使用rawurlencode()

大多数其他答案都是问题的一部分。例如,您需要在GET(您有)之后、authorize.payments-sandbox.amazon.com之后和/cobranded-ui/actions/start之后向$string_to_sign添加新行。您还需要在hash_hmac()函数中将$raw_output参数设置为true

我已经包含了对您代码的完整工作重写(替换<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;

但是,我强烈建议您使用FPS社区提供的PHP库,可以在这里下载。我在生产代码中使用这个,从来没有遇到过问题。使用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来指示您使用的是哪种签名方法

我认为您不需要对哈希进行base64编码(毕竟,它已经被url编码了)——尝试删除base64_encode。

$string_to_sign变量缺少"?"在编码签名的start和SignatureMethod之间。

签名版本2是一种增强的签名方法,适用于亚马逊简单支付和亚马逊灵活支付服务。

对于入站请求(从您的应用程序到亚马逊支付)使用整个请求URI作为签名的基础基于帐户的唯一安全凭据进行加密。

对于出站请求(从亚马逊支付到您的应用程序),亚马逊签署响应,您可以使用验证签名API

编辑:

正如@Jonathan Spooner已经提到的,我使用的是位于中的函数varifySignature()

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

可以在这里下载。它还有一个关于如何在中使用它的例子

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

这让整个过程变得容易多了。也许值得一试。。。

你试过这个吗

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

传递布尔值以将其作为原始输出进行传递。

您肯定缺少hash_hmac的最后一个参数,必须将其设置为true才能获得符合RFC 2104的HMAC签名:

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

在完整的示例中,$string_to_sign中缺少新行。

最新更新