unplugged_web Posted November 3, 2014 Share Posted November 3, 2014 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 More sharing options...
justsomeguy Posted November 3, 2014 Share Posted November 3, 2014 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. Link to comment Share on other sites More sharing options...
unplugged_web Posted November 4, 2014 Author Share Posted November 4, 2014 (edited) 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: 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&Version=2010-08-31 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 November 4, 2014 by unplugged_web Link to comment Share on other sites More sharing options...
justsomeguy Posted November 4, 2014 Share Posted November 4, 2014 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 More sharing options...
unplugged_web Posted November 5, 2014 Author Share Posted November 5, 2014 (edited) 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 November 5, 2014 by unplugged_web Link to comment Share on other sites More sharing options...
justsomeguy Posted November 5, 2014 Share Posted November 5, 2014 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 More sharing options...
unplugged_web Posted November 6, 2014 Author Share Posted November 6, 2014 (edited) 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 November 6, 2014 by unplugged_web Link to comment Share on other sites More sharing options...
justsomeguy Posted November 6, 2014 Share Posted November 6, 2014 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 More sharing options...
unplugged_web Posted November 7, 2014 Author Share Posted November 7, 2014 Thank you Link to comment Share on other sites More sharing options...
unplugged_web Posted November 12, 2014 Author Share Posted November 12, 2014 (edited) 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 November 12, 2014 by unplugged_web Link to comment Share on other sites More sharing options...
justsomeguy Posted November 12, 2014 Share Posted November 12, 2014 You need to URL-encode the base64 value. Link to comment Share on other sites More sharing options...
unplugged_web Posted November 12, 2014 Author Share Posted November 12, 2014 You need to URL-encode the base64 value. I thought that was what I had done and caused the two '=' error? Link to comment Share on other sites More sharing options...
justsomeguy Posted November 12, 2014 Share Posted November 12, 2014 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. Link to comment Share on other sites More sharing options...
unplugged_web Posted November 13, 2014 Author Share Posted November 13, 2014 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 More sharing options...
justsomeguy Posted November 13, 2014 Share Posted November 13, 2014 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now