Jump to content
steve faleiro

Delphi 10.2 / IPWorks - Calculating Amazon MWS signature

Recommended Posts

Using: 
+ Delphi 10.2.3 Tokyo
+ IPWorks SSL and IPWorks Encrypt components

 

I am trying to use the Amazon MWS API from Delphi to get a list of orders, but am unsuccessful in making the request to Amazon MWS. Its mandatory that I use IPWorks components, as required by my client. The response from the API says that the signature is not correct:

Quote

<Error>
 <Type>Sender</Type>
 <Code>SignatureDoesNotMatch</Code>
 <Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing
 method. Consult the service documentation for details.</Message>
</Error>

 

Obviously the issue has something to do with calculating the signature, encoding it to Base64, or something wrong with the request itself. I think its the encoding to Base64 that is not working for me. Maybe something to do with Delphi Unicode and UTF-8 encoding.

I've spent a whole day trying to figure this out and am stuck, so am posting it here. I hope someone can help. Below is my code: 


On the form I have 2 components:  TipwHTTP and TipcHash

    object HTTPS: TipwHTTP
      FollowRedirects = frAlways
      SSLCertStore = 'MY'
      OnTransfer = HTTPSTransfer
    end
    
    object HashMaker: TipcHash
      Algorithm = haHMACSHA256
      EncodeHash = True
    end


    function GetISO8601DateTime_URLEncodedStr(const ADateTime: TDateTime): String;
    var
      d: String;
      l: Integer;
    begin
      d := DateToISO8601(TTimeZone.Local.ToUniversalTime(ADateTime), True);
      l := Length(d);
      d := Copy(d, 1, l - 5) + 'Z'; // remove the milliseconds part
    
      Result := TNetEncoding.URL.Encode(d);
    end;

    const
      DOMAIN_NAME = 'https://mws.amazonservices.com/Orders/2013-09-01';
    var
      sl: TStringList;
      param, signature, aurl: String;
    begin
      sl := TStringList.Create;
      try
        sl.Add('AWSAccessKeyId=' + edtAwsAccessKey.Text); { Index: 0 }
        sl.Add('&Action=ListOrders'); { Index: 1 }
        sl.Add('&CreatedAfter=' + GetISO8601DateTime_URLEncodedStr(dtpOrdersCreatedFrom.Date)); { Index: 2 }
        sl.Add('&MWSAuthToken=' + edtMarketplaceID.Text); { Index: 3 }
        sl.Add('&MarketplaceId.Id.1=' + edtMarketplaceID.Text); { Index: 4 }
        sl.Add('&SellerId=' + edtSellerID.Text); { Index: 5 }
        sl.Add('&SignatureMethod=HmacSHA256'); { Index: 6 }   // <---- Insert Signature here
        sl.Add('&SignatureVersion=2'); { Index: 7 }
        sl.Add('&Timestamp=' + GetISO8601DateTime_URLEncodedStr(Now)); { Index: 8 }
        sl.Add('&Version=2013-09-01'); { Index: 9 }
    
        param := StringReplace(sl.Text, #13#10, '', [rfReplaceAll]);
    
        HashMaker.Key := edtSecretKey.Text;
        HashMaker.Algorithm := haHMACSHA256;
        HashMaker.InputMessage := 'POST\n' + 'mws.amazonservices.com\n' + '/Orders/2013-09-01\n' + param;
        HashMaker.ComputeHash;
        signature := HashMaker.HashValue;
    
        SetStatus('Signature1: ' + signature);
    
        // signature := TNetEncoding.Base64.Encode(TEncoding.UTF8.GetString(BytesOf(signature)));
    
        // SetStatus('Signature2: ' + signature);
    
        sl.Insert(6, '&Signature=' + signature);
        param := StringReplace(sl.Text, #13#10, '', [rfReplaceAll]);
    
        SetStatus('param: ' + param);
    
      finally
        sl.Free;
      end;
    
      with HTTPS do
      begin
        ContentType := 'application/x-www-form-urlencoded; charset=UTF-8';
        Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8';
        Timeout := 0;
    
        aurl := DOMAIN_NAME + '?' + param;
        Post(aurl);
      end;
    
    end;


I would really appreciate if someone can help me solve this.

-Steve


 

Edited by steve faleiro

Share this post


Link to post

Those components come with free support (unprioritized, albeit), [i may be wrong]. Did you contact /n software about this specific problem?

Share this post


Link to post
50 minutes ago, Dany Marmur said:

Those components come with free support (unprioritized, albeit), [i may be wrong]. Did you contact /n software about this specific problem?

Its nothing to do with the components. There is an error in the code in building the HTTP request. Something to do with character encoding (Unicode vs UTF8). 

Share this post


Link to post

I've still not found the answer. I've now posted 2 questions on StackOverflow. If anyone has experience in this area or has solved this problem before, please reply there (or here). 

 

https://stackoverflow.com/questions/69768072/delphi-calculating-amazon-mws-signature

 

https://stackoverflow.com/questions/69781720/delphi-amazon-mws-api-how-do-derive-the-base64-hmac-from-the-sha-256-hmac
 

TIA!

Share this post


Link to post

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

×