【问题标题】:Amazon Flexible Payments Exception: Caller Input Exception: Invalid Signature亚马逊灵活付款异常:来电者输入异常:无效签名
【发布时间】:2012-02-12 08:11:54
【问题描述】:

我正在尝试使用 PHP API 来实现亚马逊的灵活支付。

这是我的 PHP sn-p 发送付款请求:

<?php

$string_to_sign = 'GET
authorize.payments-sandbox.amazon.com
/cobranded-ui/actions/start
SignatureMethod=HmacSHA256&SignatureVersion=2&callerKey=my_access_key&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;

// When it goes to the url, it gets the invalid signature error
header('Location: '.$amazon_request_sandbox); 
?>

这似乎是按照他们的指示进行的,但我无法克服那个错误。

谢谢!!

【问题讨论】:

  • 我不确定你是否看到我的回答,但我想知道它是否有帮助。

标签: php amazon-web-services amazon-pay


【解决方案1】:
<?php

$method = 'GET';
$host   = 'authorize.payments-sandbox.amazon.com';
$path   = '/cobranded-ui/actions/start';

$params = array( 
    'signatureMethod'  => 'HmacSHA256',
    'signatureVersion' => '2',
    'currencyCode'     => 'USD',
    'callerKey' => 'Your_Key_ID',
    'callerReference'  => 'YourCallerReference',
    'paymentReason'    => 'donation',
    'pipelineName'     => 'SingleUse',
    'returnUrl'        => 'http://yourcallback.com',
    'transactionAmount'=> '5',
    'version'          => '2009-01-09',
);


$params = array_map('rawurlencode', $params);


$paramStringArray = array();

foreach($params as $key => $value){

    $paramStringArray[] = $key . '=' . $value;

}




$paramString = implode('&', $paramStringArray);

$string_to_sign = $method . "\n"
        . $host . "\n"
        . $path  . "\n"
        . $paramString;
    

$signature = base64_encode(hash_hmac(
    'sha256',
    $string_to_sign,
    'Your_Super_Secret_Key',
    true
));



$amazon_request_sandbox = "https://{$host}{$path}?" . $paramString .
    '&signature=' . rawurlencode($signature);

header('Location: '.$amazon_request_sandbox); 

?>

好的...使用下面代码中的结构,我终于通过上面的代码弄清楚了整个事情。在形成您的签名/URL 时需要注意三件事...

  1. 似乎参数“transactionAmount”对于有效的联合品牌 UI 管道是必需的,即使没有具体说明暗示该问题。

  2. 如果您的任何参数中包含/包含空格,并且您尝试在除最新 (5.4) 版本的 PHP 之外的所有版本中使用 html_build_query(),您将获得一个编码方案,其中包含空格的“+”标记而不是亚马逊似乎喜欢的“%20”。我上面的代码通过在整个参数数组上实现 rawurlencode() 来解决这个问题。

  3. 参数的顺序在签名的构造中是最重要的。键(不是值)需要按不区分大小写的字母顺序排列。还值得注意的是,尽管文档对 API 进行了说明,但在创建签名的查询字符串时必须同时存在与号 (&) 和等号 (=)。

例如:

签名查询字符串:callerKey=1111111111111&currencyCode=USD&signatureVersion=2

我注意到的其他一些事情......

在 PHP SDK (2010-8-28) 包含的示例代码中,文件“CBUISingleUsePipelineSample.php”中的“paymentReason”属性被列为“HarryPotter 1-5 DVD set”。由于此属性中包含空格,因此当您尝试访问生成的链接时,它会抛出令人讨厌的“无效签名”错误,因为 html_build_query() 用于生成 URL 的查询字符串。要解决此问题,请打开“CBUIPipeline.php”,并在constructUrl() 方法中查找以下行...

$queryString = http_build_query($parameters, '', '&');

替换为:

$queryString = str_replace('+', '%20', http_build_query($parameters, '', '&'));

这将解决旧版本 PHP (

最后的事情最后...

这是我在 StackOverflow 上的第一篇文章,所以如果我破坏了协议,请不要杀了我。希望对您有所帮助!

【讨论】:

    【解决方案2】:

    试试这段代码:

    <?php
    
    $method = 'GET';
    $host   = 'authorize.payments-sandbox.amazon.com';
    $path   = '/cobranded-ui/actions/start';
    
    $params = array(
        'SignatureMethod'  => 'HmacSHA256'
        'SignatureVersion' => 2,
        'callerKey'        => 'my_access_key',
        'callerReference'  => 'YourCallerReference',
        'paymentReason'    => 'donation',
        'pipelineName'     => 'SingleUse',
        'returnUrl'        => 'http://problemio.com&transactionAmount=4.0',
    );
    
    $string_to_sign = $method . "\n"
        . $host . "\n"
        . $path . "\n"
        . http_build_query($params);
    
    $signature = base64_encode(hash_hmac(
        'sha256',
        $string_to_sign,
        'my_secret_key'
    ));
    
    $params['Signature'] = $signature;
    
    $amazon_request_sandbox = "https://{$host}{$path}?" . http_build_query($params);
    
    header('Location: ' . $amazon_request_sandbox);
    

    所以我做了一些改变:

    • PHP 的http_build_query() 构建查询字符串(确保编码正确)
    • 尝试重用您的 var 与重复努力(更容易发现错误等)
    • 显式\n - 也许你的编辑输入了\r\r\n

    HTH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-06
      • 2016-02-18
      • 2013-10-11
      • 2015-10-15
      • 1970-01-01
      • 2015-03-22
      相关资源
      最近更新 更多