Amazon Pay SDK InvalidSignatureError
Amazon Pay SDK InvalidSignatureError
我正在集成来自 documentation 的 Amazon Pay php SDK,但出现此错误。
这是我的 php 实现代码:
$amazonpay_config = array(
'public_key_id' => 'XXXXXXXX',
'private_key' => 'my_private_key_path',
'region' => 'US',
'sandbox' => true
);
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'checkoutSession' => null,
'payloadSign' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignPayload = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'checkoutSession' => json_decode($resultCheckOut['response']),
'payloadSign' => $resultSignPayload
];
return $requestResult;
}
下面是生成Amazon Pay按钮的JS实现代码
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: jsonResult['checkoutSession'],
signature: jsonResult['payloadSign'],
publicKeyId: 'XXXXXXXXXXX'
}
});
代码有几个问题,主要是您没有将负载和签名正确传递到前端。对于负载,您使用的是 jsonResult['checkoutSession'],而它应该是 jsonResult['payloadSign']。虽然这不包含有效负载,但从 PHP 代码来看,它显然是您放入其中的签名。完整的代码示例应该更像这样(未测试)。
后端:
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'signature' => null,
'payload' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignature = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'signature' => $resultSignature,
'payload' => $payload
];
return json_encode($requestResult);
}
前端:
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: JSON.stringify(jsonResult['payload']),
signature: jsonResult['signature'],
publicKeyId: 'XXXXXXXXXXX'
}
});
我不确定您是如何将 $requestResult 传回前端的,可能需要一些额外的 JSON encoding/decoding 才能获得正确的字符串。为防止出现签名不匹配错误,请确保后台生成签名的payload字符串与分配给'payloadJSON'参数的payload字符串完全匹配(尤其要注意空格、转义符、换行符)等)。
关于这个问题的两条评论:
- 我已将有效负载定义为字符串(这是当前 AmazonPay 文档声明的方式 - Link)。
$payload = '{
"webCheckoutDetails": {
"checkoutReviewReturnUrl": "https://www.example.com/review",
"checkoutResultReturnUrl": "https://www.example.com/result"
},
"storeId": "amzn1.application-oa2-client.XXXXXXXXX"
}';
代替数组
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
签名已创建,但在渲染按钮并单击它时出现以下错误。
Error Message: Signature Dk4qznkoiTVqjcY8Yn1l0iLbsoIj2pEAHWVtgYrphLtFXR9BKhJJPD53It4qYOswS1T/STYMHRy5jtCHGqvLntDjuy0MrhkpoHTpYEtwdOqGHA2qk+QnSGV5LoYldQ/UkAxSG7m8s2iOr11q2sWxUjrk2M3fgzAIxDeZRjJYeAr97eGANYva3jtGDfM6cJdieInBM4dEWWxKqGIh6HxOrY5K/ga26494vAwZAGvXRhZG48FOVp/XCr0mbu6V5pkEOzRJSc+hN5WKAs/c49UsfKPx75Ce7QbaBCZZT1UiczfyYx/mBuZuysUlGmnXPhLOLTPw4+SIizH/pOQyClOQyw== does not match signedString AMZN-PAY-RSASSA-PSS dfff7a87b93cfa78685a233f2dd59e18ad0451b2e3a90af11e500fcc0ceee924 for merchant XXXXXXXX
过了一段时间我才意识到这是错误的原因。实际上,在写这个的时候,字符串中的新行是原因。如果字符串仅在一行中,则有效。
- 按钮只需要有效载荷和签名的有效载荷。不需要
$client->createCheckoutSession
。此外,resultCheckOut
的checkoutSessionId
与调用checkoutReviewReturnUrl
时得到的checkoutSessionId
不同。
我正在集成来自 documentation 的 Amazon Pay php SDK,但出现此错误。
这是我的 php 实现代码:
$amazonpay_config = array(
'public_key_id' => 'XXXXXXXX',
'private_key' => 'my_private_key_path',
'region' => 'US',
'sandbox' => true
);
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'checkoutSession' => null,
'payloadSign' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignPayload = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'checkoutSession' => json_decode($resultCheckOut['response']),
'payloadSign' => $resultSignPayload
];
return $requestResult;
}
下面是生成Amazon Pay按钮的JS实现代码
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: jsonResult['checkoutSession'],
signature: jsonResult['payloadSign'],
publicKeyId: 'XXXXXXXXXXX'
}
});
代码有几个问题,主要是您没有将负载和签名正确传递到前端。对于负载,您使用的是 jsonResult['checkoutSession'],而它应该是 jsonResult['payloadSign']。虽然这不包含有效负载,但从 PHP 代码来看,它显然是您放入其中的签名。完整的代码示例应该更像这样(未测试)。
后端:
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'signature' => null,
'payload' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignature = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'signature' => $resultSignature,
'payload' => $payload
];
return json_encode($requestResult);
}
前端:
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: JSON.stringify(jsonResult['payload']),
signature: jsonResult['signature'],
publicKeyId: 'XXXXXXXXXXX'
}
});
我不确定您是如何将 $requestResult 传回前端的,可能需要一些额外的 JSON encoding/decoding 才能获得正确的字符串。为防止出现签名不匹配错误,请确保后台生成签名的payload字符串与分配给'payloadJSON'参数的payload字符串完全匹配(尤其要注意空格、转义符、换行符)等)。
关于这个问题的两条评论:
- 我已将有效负载定义为字符串(这是当前 AmazonPay 文档声明的方式 - Link)。
$payload = '{
"webCheckoutDetails": {
"checkoutReviewReturnUrl": "https://www.example.com/review",
"checkoutResultReturnUrl": "https://www.example.com/result"
},
"storeId": "amzn1.application-oa2-client.XXXXXXXXX"
}';
代替数组
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
签名已创建,但在渲染按钮并单击它时出现以下错误。
Error Message: Signature Dk4qznkoiTVqjcY8Yn1l0iLbsoIj2pEAHWVtgYrphLtFXR9BKhJJPD53It4qYOswS1T/STYMHRy5jtCHGqvLntDjuy0MrhkpoHTpYEtwdOqGHA2qk+QnSGV5LoYldQ/UkAxSG7m8s2iOr11q2sWxUjrk2M3fgzAIxDeZRjJYeAr97eGANYva3jtGDfM6cJdieInBM4dEWWxKqGIh6HxOrY5K/ga26494vAwZAGvXRhZG48FOVp/XCr0mbu6V5pkEOzRJSc+hN5WKAs/c49UsfKPx75Ce7QbaBCZZT1UiczfyYx/mBuZuysUlGmnXPhLOLTPw4+SIizH/pOQyClOQyw== does not match signedString AMZN-PAY-RSASSA-PSS dfff7a87b93cfa78685a233f2dd59e18ad0451b2e3a90af11e500fcc0ceee924 for merchant XXXXXXXX
过了一段时间我才意识到这是错误的原因。实际上,在写这个的时候,字符串中的新行是原因。如果字符串仅在一行中,则有效。
- 按钮只需要有效载荷和签名的有效载荷。不需要
$client->createCheckoutSession
。此外,resultCheckOut
的checkoutSessionId
与调用checkoutReviewReturnUrl
时得到的checkoutSessionId
不同。