amazon-pay-api-sdk-php icon indicating copy to clipboard operation
amazon-pay-api-sdk-php copied to clipboard

Use of stripcslashes breaks Amazon/Pay/API/Client::generateButtonSignature

Open jdart opened this issue 4 years ago • 2 comments
trafficstars

I tried using this library today and was getting errors like below when clicking the checkout button in the browser:

Error Code: InvalidSignatureError

I was following the documentation here. After struggling with this issue I tried removing the call to stripcslashes on the line below.

https://github.com/amzn/amazon-pay-api-sdk-php/blob/master/Amazon/Pay/API/Client.php#L404

Without stripcslashes it looked like $hashedButtonRequest = self::AMAZON_SIGNATURE_ALGORITHM . "\n" . $this->hexAndHash($payload);. With that change suddenly my checkouts were working. I also found that mangling the value passed to payloadJSON with stripcslashes got things working as an alternative to editing the library.

Anyway, the stripcslashes seems to be causing issues.

jdart avatar Jun 18 '21 03:06 jdart

Hi Thanks for the issue, We need to use stripcslashes($payload) to unescape sequences in payload but it will not cause any issue in terms of creating signature. Let us know about complete error/issues faced from your side

shangamesh avatar Jun 20 '21 07:06 shangamesh

So this works for me, note I have to escape the payload before turning it into a js string

<?php

require '../vendor/autoload.php';

use Amazon\Pay\API\Client;

$publicKeyId = '...';

$payload =  json_encode([
    'storeId' => '...',
    'webCheckoutDetails' => [
        'checkoutReviewReturnUrl' => 'https://.../review',
    ],
]);

$client = new Client([
    'private_key' => file_get_contents('...pem'),
    'public_key_id' => $publicKeyId,
    'region' => 'US',
]);

$signature = $client->generateButtonSignature($payload);

?>
<html>
    <body>
    <div id="AmazonPayButton"></div>
    <script src="https://static-na.payments-amazon.com/checkout.js"></script>
    <script type="text/javascript" charset="utf-8">
        amazon.Pay.renderButton('#AmazonPayButton', {
            // set checkout environment
            merchantId: '...',
            publicKeyId: <?php echo json_encode($publicKeyId) ?>,
            ledgerCurrency: 'USD',
            checkoutLanguage: 'en_US',
            placement: 'Cart',
            buttonColor: 'Gold',
            createCheckoutSessionConfig: {
                payloadJSON: <?php echo json_encode(stripcslashes($payload)) ?>, // <--- the interesting bit
                signature: <?php echo json_encode($signature) ?>,
            }
        });
    </script>
    </body>
</html>

But this doesn't

<?php

require '../vendor/autoload.php';

use Amazon\Pay\API\Client;

$publicKeyId = '...';

$payload =  json_encode([
    'storeId' => '...',
    'webCheckoutDetails' => [
        'checkoutReviewReturnUrl' => 'https://.../review',
    ],
]);

$client = new Client([
    'private_key' => file_get_contents('...pem'),
    'public_key_id' => $publicKeyId,
    'region' => 'US',
]);

$signature = $client->generateButtonSignature($payload);

?>
<html>
    <body>
    <div id="AmazonPayButton"></div>
    <script src="https://static-na.payments-amazon.com/checkout.js"></script>
    <script type="text/javascript" charset="utf-8">
        amazon.Pay.renderButton('#AmazonPayButton', {
            // set checkout environment
            merchantId: '...',
            publicKeyId: <?php echo json_encode($publicKeyId) ?>,
            ledgerCurrency: 'USD',
            checkoutLanguage: 'en_US',
            placement: 'Cart',
            buttonColor: 'Gold',
            createCheckoutSessionConfig: {
                payloadJSON: <?php echo json_encode($payload) ?>, // <--- no strip cslashes
                signature: <?php echo json_encode($signature) ?>,
            }
        });
    </script>
    </body>
</html>

jdart avatar Jun 21 '21 15:06 jdart