Skip to content
Advertisement

Amazon Pay SDK InvalidSignatureError

I’m integrating Amazon Pay php SDK from documentation, but getting this error. enter image description here

Here’s my php implementation code:

$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;
}

Here’s JS implementation code for generating Amazon Pay button.

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'
    }
});

Advertisement

Answer

Couple of problems with the code, mainly that you aren’t passing the payload and signature to the front-end correctly. For the payload, you’re using jsonResult[‘checkoutSession’], while it should be jsonResult[‘payloadSign’]. This doesn’t contain the payload though but from the PHP code it’s apparently the signature that you have put in there. The full code sample should more like this (not tested).

Back-end:

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

Front-end:

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'
    }
});

I’m not sure how you’re passing $requestResult back to the front-end, potentially there’s some additional JSON encoding/decoding required to get the right string. To prevent a signature mismatch error, please make sure that the payload string used for the signature generation in the backend, and the payload string assigned to the ‘payloadJSON’ parameter match exactly (especially pay attention to whitespaces, escape characters, line breaks, etc.).

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement