2

Amazon のフレキシブル ペイメント用の PHP API を使用しようとしています。

支払いリクエストを送信するための PHP スニペットは次のとおりです。

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

これは彼らの指示に従っているようですが、そのエラーを乗り越えることはできません。

ありがとう!!

4

2 に答える 2

8
<?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 を作成する際に注意すべき点が 3 つあります。

  1. この問題をほのめかす具体的な指示はありませんが、有効な共同ブランド UI パイプラインにはパラメーター「transactionAmount」が必要なようです。

  2. パラメータのいずれかにスペースが含まれていて、PHP の最新 (5.4) バージョンを除くすべてのバージョンで html_build_query() を使用しようとすると、" %20" は、Amazon が気に入っているようです。上記の私のコードは、パラメーター配列全体に rawurlencode() を実装することでそれを処理します。

  3. パラメータの順序は、署名の構築において最も重要です。キー (値ではない) は、大文字と小文字を区別しないアルファベット順である必要があります。また、API に関するドキュメントの内容にかかわらず、署名のクエリ文字列の作成にはアンパサンド (&) と等号 (=) の両方が必要であることにも注意してください。

例:

署名のクエリ文字列: callerKey=1111111111111¤cyCode=USD&signatureVersion=2

その他気になった点を...

PHP SDK (2010-8-28) に含まれるサンプル コードでは、ファイル「CBUISingleUsePipelineSample.php」の「paymentReason」属性が「HarryPotter 1-5 DVD セット」としてリストされています。この属性にはスペースが含まれているため、生成されたリンクにアクセスしようとすると、常に迷惑な「無効な署名」エラーがスローされます。これは、html_build_query() を使用して URL のクエリ文字列を生成するためです。この問題を解決するには、「CBUIPipeline.php」を開き、constructUrl() メソッドで次の行を探します...

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

それを次のように置き換えます。

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

これにより、古いバージョンの PHP (< 5.4) のスペース エンコーディングの問題が解決されます。最新バージョンでは、設定できる「enc_type」フラグがあります。

最後のこと 最後...

これは StackOverflow に関する私の最初の投稿なので、プロトコルを破ったとしても私を殺さないでください。それが役に立てば幸い!

于 2012-04-22T01:25:26.987 に答える
0

このコードを試してください:

<?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()(正しいエンコーディングを確認してください)
  • vars を再利用しようとするか、努力を複製するか (間違いを見つけやすくするなど)
  • 明示的\n- おそらく編集者が入力した\rか、\r\n

HTH

于 2012-02-26T01:18:42.610 に答える