Jump to content

How do I create a signature?


unplugged_web

Recommended Posts

I'm trying to add 'Checkout With Amazon' to our website and have got to the section where I need to create a signature but I'm not sure how to do this.

It says I need a canonicalized query string, what does that mean? I've been trying to follow page 10 (Create the Signature) of this document
I'd be really grateful for any help please.
Link to comment
Share on other sites

Canonicalized is similar to standardized. The bullet points under that first item tell you how to build the canonical query string. They basically just want the parameters sorted and encoded.

I'm sorry but I still don't understand? What do I do with the parameters, do I just save them or send them to Amazon?

 

I tried pasting this into the browser:

but all I got was <b><UnknownOperationException/></b>
I also tried using Amazon's scratchpad but it didn't have any options for 'payments', 'purchase contract' or 'SetPurchaseItems'
If it helps the full code for sending the order to amazon is:
<form action="https://payments.amazon.co.uk/cba/api/purchasecontract/" method="get"><input type="hidden" name="Action" value="SetPurchaseItems" /><input type="hidden" name="AWSAccessKeyId" value="SAMPLE" /><input type="hidden" name="PurchaseContractId" value="<?php echo $_GET['purchaseContractId']; ?>" /><?php foreach( $order_line as $key=>$value ) { ?><input type="hidden" name="PurchaseItems.PurchaseItem.1.FulfillmentNetwork" value="MERCHANT" /><input type="hidden" name="PurchaseItems.PurchaseItem.1.MerchantId" value="SAMPLE" /><input type="hidden" name="PurchaseItems.PurchaseItem.1.MerchantItemId" value="<?php echo $products_all[$value['product_id']]['id'] ?>" /><input type="hidden" name="PurchaseItems.PurchaseItem.1.Quantity" value="<?php echo $value['product_qty'] ?>" /><input type="hidden" name="PurchaseItems.PurchaseItem.1.Title" value="<?php echo htmldisplay( $products_all[$value['product_id']]['name'] ) ?>" /><?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.1.Description" value="Option: <?php echo htmldisplay( $value2['name'] ) ?>" /><?php } } ?><input type="hidden" name="PurchaseItems.PurchaseItem.1.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.1.UnitPrice.CurrencyCode" value="<?php echo htmldisplay( $companydetails['currency_iso']); ?>" /><input type="hidden" name="PurchaseItems.PurchaseItem.1.URL" value="product/<?php echo $products_all[$value['product_id']]['linkword'] ?>" /><?php } } } ?><input type="hidden" name="SignatureSignature" value="SAMPLE" /><input type="hidden" name="SignatureMethod" value="METHOD" /><input type="hidden" name="SignatureVersion" value="SIGNATUREVERSION" />
<input type="hidden" name="Timestamp" value="<?php echo gmdate("Y-m-dTH:i:s.000Z", time()); ?>" />
<input type="hidden" name="Version" value="VERSION" /> <input type="submit" class="input_button input_red" value="Complete order" /> </form>

If I try to send that to Amazon the next page says this:

 

<ErrorResponse xmlns="http://payments.amazon.com/checkout/v2/2010-08-31/">

<Error>
<Type>Sender</Type>
<Code>IncompleteSignature</Code>
<Message>
Request must contain a signature that conforms to AWS standards
</Message>
</Error>
<RequestId>996fbf92-640c-11e4-8312-a14373064631</RequestId>
</ErrorResponse>
Edited by unplugged_web
Link to comment
Share on other sites

I'm sorry but I still don't understand? What do I do with the parameters, do I just save them or send them to Amazon?

According to that PDF, they want the parameters sorted. So, in PHP, one option would be to load all of the parameters and their values into an array, sort the array in alphabetic order of the parameters, then loop through the array and add each parameter and value. That way they will be sorted. That's what they mean by canonical. You can also use this function to encode the parameter names and values:http://www.php.net/manual/en/function.rawurlencode.php
Link to comment
Share on other sites

Sorry to be so dumb but what parameters do they want? Whenever I enter them manually and then test the button I get the InvalidSignature error message.

 

I thought I had the right details:

 

Action=SetPurchaseItem

SignatureMethod=HmacSHA256
PurchaseContractId=amzn1.contract.1.1.2.b9173045932801221f107a83429e5a69
AWSAccessKeyId=AWS_ACCESS_KEY_ID
SignatureSignate=SECRET_ACCESS_KEY
SignatureVersion=2
Version=2010-08-31
Timestamp=2010-08-31T11:45:50.582Z
I've also just found that this is the newest reference guide: http://amazonpayments.s3.amazonaws.com/documents/Inline_Checkout_API_Reference_Guide_UK.pdf
Edited by unplugged_web
Link to comment
Share on other sites

I don't know what parameters they expect for the request you're trying to send. That list contains some of the same ones I see in the PDF. It's not sorted by the parameter name though, they want it to be sorted for the signature. Page 11 of the original PDF shows a more detailed version of the steps they want you to take to create the signature.

Link to comment
Share on other sites

I don't know what parameters they expect for the request you're trying to send. That list contains some of the same ones I see in the PDF. It's not sorted by the parameter name though, they want it to be sorted for the signature. Page 11 of the original PDF shows a more detailed version of the steps they want you to take to create the signature.

Thanks, I'm probably just being really dumb and not reading it properly, I don't understand these two lines:

 

3. Calculate an RFC 2104-compliant HMAC with the string you just created, your Secret Access Key as the key, and SHA256 or SHA1 as the hash algorithm.

4. Convert the resulting value to base64.
For example, 5nB7nu7PFbCiDg+vYyWMj1JzEH3S+IzFoVgwHGjG5Ms=
Edited by unplugged_web
Link to comment
Share on other sites

Check the PHP manual for the things you're not understanding. Here's how to calculate the HMAC, for example:http://php.net/manual/en/function.hash-hmac.phpThere's another function to base64-encode a string. You could probably even search for PHP code to use Amazon's system. That document assumes you are already familiar with PHP, if you don't know PHP then you won't be able to use a document like that without a lot of research.

Link to comment
Share on other sites

I've followed that an changed the code to this
<form action="https://payments-sandbox.amazon.co.uk/cba/api/purchasecontract/?AWSAccessKeyId=AWS_ACCESS_KEY_ID&Action=SetPurchaseItems&PurchaseContractId=amzn1.contract.1.1.1.e51e9a391b97ad59eabe0ab82a9370bc&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=<2014-11-04T10:25:53&Version=2010-08-31&Signature=<?php echo base64_encode(hash_hmac('SHA256','AWS_SECRET_KEY','secret')); ?>" method="post">........</form>
but now get this error:
AWSAccessKeyId= AWS_ACCESS_KEY_ID&Action=SetPurchaseItems&PurchaseContractId=amzn1.contract.1.1.1.e51e9a391b97ad59eabe0ab82a9370bc&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2014-11-12T16:31:19&Version=2010-08-31&Signature=NWI5MWI1NWI0MzkzODAwMTlkOTFlOGI1ODAwMGYxYTk1MWZmZGQ3ZDA4M2IzMTI2Y2Y5YmU4ZmUxOGU2YTllYQ==&PurchaseItems.PurchaseItem.1.FulfillmentNetwork=MERCHANT&PurchaseItems.PurchaseItem.1.MerchantId=A2PBOQNHNISJLT&PurchaseItems.PurchaseItem.1.MerchantItemId=344&PurchaseItems.PurchaseItem.1.Title=Lemon+500g+sample&PurchaseItems.PurchaseItem.1.Quantity=2&PurchaseItems.PurchaseItem.1.UnitPrice.Amount=10.79&PurchaseItems.PurchaseItem.1.UnitPrice.CurrencyCode=GBP&DeliveryMethod.ServiceLevel=None&DeliveryMethod.DisplayableShippingLabel=11.99%3D%3D20%3D%3D3&Shipping.Amount=11.99&Shipping.CurrencyCode=GBP is not valid; the value of a query string parameter may not contain a '=' delimiter

 

I think the problem is with the Signature as it's adding two '=' to it. but if I remove them both then the error says the signature doesn't match. I'm sure I'm missing the obvious but I'm so stuck with this.
Edited by unplugged_web
Link to comment
Share on other sites

URL-encoding will convert the equal sign to its numeric entity. You are base64-encoding, you are not URL-encoding. URL-encode the base64 value, which will be padded with equal signs if necessary.

I've now URL encoded the signature but I'm still getting a SignatureDoesNotMatch error. Ive to this for the for action and method:

 

<form action="https://payments-sandbox.amazon.co.uk/cba/api/purchasecontract/?AWSAccessKeyId=AWS_ACCESS_KEY&Action=SetPurchaseItems&PurchaseContractId=amzn1.contract.1.1.2.5a49fd0d6fab162cdd34dc868c8735db&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=<?php echo gmdate("Y-m-dTH:i:s", time()); ?>&Version=2010-08-31&Signature=<?php echo urlencode(hash_hmac('SHA256','AWS_SECRET_KEY','secret')); ?>" method="post">
Link to comment
Share on other sites

You're telling it to hash the text "AWS_SECRET_KEY". Maybe you have something else there in your actual code, but the PDF document says what they want you to hash. They want you to hash the canonical query string, not the text "AWS_SECRET_KEY".

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...