【问题标题】:Problems encoding Amazon Flexible Payments secret string in PHP在 PHP 中编码 Amazon Flexible Payments 密码字符串的问题
【发布时间】:2012-01-21 14:38:00
【问题描述】:

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

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

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

谢谢!!

【问题讨论】:

  • 我编辑了我的原始 Q 以显示我包含 SignatureMethod=HmacSHA256 字符串,但它没有帮助:(
  • 你确定没有空格进入你的查询字符串,比如在“开始”之后?
  • 如果你还是 URLEncoding 的话,我还能问你为什么要在 returnUrl 中编码 : 和 / 字符吗?
  • 请提供用于生成请求的所有代码。您没有为我们提供足够的代码来重现该问题。如果无法重现此问题,我们将无法解决此问题。您可以期待的最佳答案是基于提供的错误代码的推测。正如我在您之前的两个与 FPS 相关的问题中向您建议的那样,您需要使用此处提供的 FPS 库aws.amazon.com/code/Amazon-FPS/4094948623747680,或者至少您需要学习代码作为示例。
  • @JonathanSpooner 刚刚添加了所有代码来生成请求。感谢您的帮助:)

标签: php sha256 amazon-fps


【解决方案1】:

检查您是否在请求中包含&amp;SignatureMethod=HmacSHA256

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

  • 缺少键/值
  • 键/值的拼写错误
  • 键/值上的编码或空格不正确

希望有帮助!

问候

【讨论】:

    【解决方案2】:

    唯一没有被建议的是你需要在transactionAmount 上使用rawurlencode(),这是$string_to_sign 的一部分。

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

    我已经对您的代码进行了完整的工作重写(替换 &lt;Your_Access_Key&gt;&lt;Your_Secret_Key&gt;):

    $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 库,可以是 downloaded here。我在生产代码中使用它并且从未遇到过问题。使用 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);
    
    ?>
    

    【讨论】:

      【解决方案3】:

      你设置了你的签名方式吗?来自AWS documentation

      您必须将 SignatureMethod 请求参数设置为 HmacSHA256 或 HmacSHA1 以指示您正在使用哪种签名方法

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

          对于入站请求(从您的应用程序到 Amazon Payments),它 使用整个请求 URI 作为签名的基础, 基于您帐户的唯一安全凭证进行加密。

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

          编辑:

          正如@Jonathan Spooner 已经提到的,我使用的是位于

          中的函数varifySignature()

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

          可以在here下载。它还有一个关于如何在

          中使用它的示例

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

          它使整个过程变得更加容易。可能值得一试...

          【讨论】:

          • 这也是我的想法,但他们在文档中的示例没有?特点。我会用 ?字符只是为了确保。
          • 您的签名仍然与您的请求 URI 不同...我注意到您的签名 URI 中缺少您的 pipelineName 参数,并且您的参数与请求 URI 的顺序不同。我建议尝试使您的签名成为您的请求 URI 的克隆 - 显然没有在您的签名 URI 末尾添加签名;)
          【解决方案6】:

          你试过了吗

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

          传递一个布尔值以将其作为原始输出传递。

          【讨论】:

          • 现在试试...马上报告。
          • 不幸的是,这没有帮助:(
          【解决方案7】:

          您肯定错过了hash_hmac 的最后一个参数,该参数必须设置为true 才能获得符合 RFC 2104 的 HMAC 签名:

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

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

          【讨论】:

          • 另一位评论者建议我不应该有空格字符:) 我有点迷失了它应该是怎样的。你有类似的工作吗?你是怎么编码的?
          猜你喜欢
          • 2019-11-17
          • 1970-01-01
          • 2010-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-14
          相关资源
          最近更新 更多