API help please

wait… what’re you encrypting? not just the word “secret”, surely?

I still get the same problem if I remove the line

This is what I’m using inlace of where is says ‘secret’

$purchare_ID = $_GET['purchaseContractId'];
		$signature_date = gmdate("Y-m-d\TH:i:s", time());
		$secret_key = "https://payments-sandbox.amazon.co.uk/cba/api/purchasecontract/?AWSAccessKeyId=AKIAIJAA6VJAXAJ4QVHQ&Action=SetPurchaseItems&PurchaseContractId=" . $purchare_ID . "&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=" . $signature_date . "&Version=2010-08-31";

And this is the full code

https://payments-sandbox.amazon.co.uk/cba/api/purchasecontract/?AWSAccessKeyId=AWS_ACCESS_KEY&Action=SetPurchaseItems&PurchaseContractId=<?php echo $_GET['purchaseContractId']; ?>&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=<?php echo gmdate("Y-m-d\TH:i:s", time()); ?>&Version=2010-08-31&Signature=<?php echo urlencode(hash_hmac('SHA256','AWS_SECRET_KEY','$secret_key')); ?>

So you shouldnt be encrypting the URL, just the name/value pairs…

I changed it to this:

$secret_key = "AWSAccessKeyId=AKIAIJAA6VJAXAJ4QVHQ&Action=SetPurchaseItems&PurchaseContractId=" . $purchare_ID . "&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=" . $signature_date . "&Version=2010-08-31";

but still got the same error, I’m confused though because I thought this was telling me to include the URL? http://amazonpayments.s3.amazonaws.com/documents/Inline_Checkout_API_Reference_Guide_UK.pdf - Page 11, Steps for Building a Signature

Or should I send everything like that, included all of the products?

Okay. Let’s just assume that, despite being told not to, you’re going to use the document you’ve insisted on using.

I’m just going to copy and paste.
From the VERY PAGE you pointed at:

Create the string to sign according to the following grammar (the “\n” represents an ASCII newline character).
Literal values are in plain text; values you replace are in italics:
Code Explanation
HTTP Verb Use an HTTP verb such as “GET” or “POST”

  • “\n” + New line
    Value of host header in lowercase For example, “payments-sandbox.amazon.co.uk
    Notice it is all lowercase and does not have port as it
    uses standard port 443
  • “\n” + New line
    HTTP Request URI For example, “/cba/api/purchasecontract/”
  • “\n” + New line
    Canonicalized Query String Get this from the previous step

It then gives an example.

POST
payments-sandbox.amazon.co.uk
/cba/api/purchasecontract/
AWSAccessKeyId=0GS7553JW74RRM612K02EXAMPLE&Action=GetPurchaseContract
&PurchaseContractId=amzn1.contract.1.1.2.b9173045932801221f107a83429e5a69
&SignatureMethod=HmacSHA256&SignatureVersion=2
&Timestamp=2010-08-31T11%3A45%3A50.582Z&Version=2010-08-31

Your string was:

I would suggest, that if you insist on using this document as a guide, you actually read the document.

I know you think I’m not meaning to be stubborn or awkward by still using that document but I spoke to Amazon and they told me to use it, but I just don’t understand. I’m sure I’m being really dumb but I honestly don’t know where I’m going wrong. Maybe I’m just worrying too much about it (and my job) and now can’t see the wood for the trees. I really do appreciate you helping and am not meaning to be annoying.

The code I’m using is:

<?php
		$purchare_ID = $_GET['purchaseContractId'];
		$signature_date = gmdate("Y-m-d\TH:i:s", time());
		$secret_key = base64_encode("POST
		payments-sandbox.amazon.co.uk
		/cba/api/purchasecontract/
		AWSAccessKeyId=AWS_ACCESS_KEY&Action=SetPurchaseItems
		&PurchaseContractId=" . $purchare_ID . "
		&SignatureMethod=HmacSHA256&SignatureVersion=2
		&Timestamp=" . $signature_date . "&Version=2010-08-31");
?>
         <form action="https://payments-sandbox.amazon.co.uk/cba/api/purchasecontract/?AWSAccessKeyId=AWS_ACCESS_KEY&Action=SetPurchaseItems&PurchaseContractId=<?php echo $_GET['purchaseContractId']; ?>&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=<?php echo gmdate("Y-m-d\TH:i:s", time()); ?>&Version=2010-08-31&Signature=<?php echo urlencode(hash_hmac('SHA256','AWS_SECRET_KEY','$secret_key')); ?>" method="post">
<?php
$counter = 1;
foreach( $order_line as $key=>$value ) { ?>
<input type="hidden" name="PurchaseItems.PurchaseItem.<?php echo $counter; ?>.FulfillmentNetwork" value="MERCHANT" />
<input type="hidden" name="PurchaseItems.PurchaseItem.<?php echo $counter; ?>.MerchantId" value="MERCHANT_ID" />
<input type="hidden" name="PurchaseItems.PurchaseItem.<?php echo $counter; ?>.MerchantItemId" value="<?php echo $products_all[$value['product_id']]['id'] ?>" />
<input type="hidden" name="PurchaseItems.PurchaseItem.<?php echo $counter; ?>.Title" value="<?php echo htmldisplay( $products_all[$value['product_id']]['name'] ) ?>" />
<input type="hidden" name="PurchaseItems.PurchaseItem.<?php echo $counter; ?>.Quantity" value="<?php echo $value['product_qty'] ?>" />
<input type="hidden" name="PurchaseItems.PurchaseItem.<?php echo $counter; ?>.UnitPrice.Amount" value="<?php if( $value['price_total']<0.01 ) { echo "00.00"; } else { echo (number_format( $value['price_total']/$value['product_qty']*$companydetails['exchange'],2 )); } ?>" />
<input type="hidden" name="PurchaseItems.PurchaseItem.<?php echo $counter; ?>.UnitPrice.CurrencyCode" value="<?php echo htmldisplay( $companydetails['currency_iso']); ?>" />
<?php if( count( $value['detail'] ) ) { ?>
<?php if( is_array( $product_detail ) ) { foreach( $product_detail as $key2=>$value2 ) { if( isset( $value['detail'][$key2] ) ) { ?>
<input type="hidden" name="PurchaseItems.PurchaseItem.<?php echo $counter; ?>.Description" value="Option: <?php echo htmldisplay( $value2['name'] ) ?>" /><?php } } ?>
<?php } } $counter++; } ?>
<input type="hidden" name="DeliveryMethod.ServiceLevel" value="None" />
<input type="hidden" name="Shipping.Amount" value="<?php if( $_GET['delivery']>=0.01 ) { ?><?php echo $_GET['delivery']; ?><?php } else { ?>0.00<?php } ?>" />
<input type="hidden" name="Shipping.CurrencyCode" value="<?php echo htmldisplay( $companydetails['currency_iso']); ?>" />
<input type="submit" class="input_button input_red" value="Complete order" />
</form>

This gives me the result of this:

Try using an explicit \n instead of the enter key. PHP may not be translating it correctly.

I changed it to this and got the same error:

POST\npayments-sandbox.amazon.co.uk\n/cba/api/purchasecontract/\nAWSAccessKeyId=AWS_ACCESS_KEY&Action=SetPurchaseItems&PurchaseContractId=".$purchare_ID."&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=".$signature_date."&Version=2010-08-31

urlencode the date?

That’s what I thought Amazon was asking for, am I wrong?

The document you’re referencing URLEncodes the date before hashing. Your vaunted Page 11. Step 1. Section B.

I’ve changed it so that it’s now like this:

<?php
		$purchare_ID = $_GET['purchaseContractId'];
		$signature_date = gmdate("Y-m-d\TH:i:s", time());
		$secret_key = "POST\npayments-sandbox.amazon.co.uk\n/cba/api/purchasecontract/\nAWSAccessKeyId= AWS_ACCESS_KEY&Action=SetPurchaseItems&PurchaseContractId=".urlencode($purchare_ID)."&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=".urlencode($signature_date)."&Version=2010-08-31";
?>
         <form action="https://payments-sandbox.amazon.co.uk/cba/api/purchasecontract/?AWSAccessKeyId=AWS_ACCESS_KEY&Action=SetPurchaseItems&PurchaseContractId=<?php echo $_GET['purchaseContractId']; ?>&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=<?php echo gmdate("Y-m-d\TH:i:s", time()); ?>&Version=2010-08-31&Signature=<?php echo urlencode(hash_hmac('SHA256','AWS_SECRECT_KEY','$secret_key')); ?>" method="post">

but again I’m still getting the same SignatureDoesNotMatch error

Only a wild thought. But might the signature have “expired”?

How do I tell if the signature has expired? I only started to do this a month ago

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.