function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
AKumAKum 

Can we integrate Salesforce and Amazon market place Seller Account ?

Hi Guys ,
Can we consume Amazon Marketplace Web Service from salesforce and create listings and fetch orders .
Best Answer chosen by AKum
Grainne RyanGrainne Ryan
Hi Akum

Since you asked about product feeds in the other thread https://developer.salesforce.com/forums/ForumsMain?id=9060G000000XcNxQAK, this explains how to send a product feed to Amazon.  You should be able to covert this to send any feed to Amazon. 

In order to send feeds to Amazon you need to include an XML body and ContentMD5Value in the Amazon request.   This first function prepares the XML body, it assumes you are looping through all the products you have in Salesforce that you want to create or update in Amazon.  You need to pass it your seller id and a list of the products you want to send to Amazon.  And update it with your own values.
 
//Prepare the feed 
private String prepare_body(List<Products__c> products, String sellerId){
        
       String xmlBody = '<?xml version="1.0"?>' + 
                     '<AmazonEnvelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-
                     instance xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">'+
	               '<Header>' +
            		'<DocumentVersion>1.01</DocumentVersion>' +
            		'<MerchantIdentifier>' + sellerId + '</MerchantIdentifier>' +
            	      '</Header>' +
            	      '<MessageType>OrderAdjustment</MessageType>' +
            	      '<Message>' +
            		  '<MessageID>1</MessageID>' +
                       '<OperationType>Update</OperationType>' ;
     
        // replace all the values here with your own
        For(Product__c product : products){
    	xmlBody  += '<Product>' +
      			'<SKU>product.SKU__c</SKU>' +
      			'<StandardProductID>' +
        			'<Type>ASIN</Type>' +
        			'<Value>product.ASIN__c</Value>' +
      			'</StandardProductID>' +
      			'<ProductTaxCode>product.TAXCODE__c</ProductTaxCode>' +
      			'<DescriptionData>' +
        			'<Title>product.TITLE__c</Title>' +
        			'<Brand>product.BRAND__c</Brand>' +
        			'<Description>product.DESCRIPTION__c</Description>' +
        			'<BulletPoint>product.BULLETPOINT1__c</BulletPoint>' +
        			'<BulletPoint>product.BULLETPOINT2__c</BulletPoint>' +
        			'<MSRP currency="USD"> product.MSRP__c</MSRP>' +
                    '<Manufacturer>product.MANUFACTURER__c</Manufacturer>' +
        				'<ItemType>example-item-type</ItemType>' +
      			'</DescriptionData>' +
      			'<ProductData>' +
        			'<Health>' +
          		          '<ProductType>' +
            				'<HealthMisc>' +										 
                               '<Ingredients>product.INGREDIENTS__c</Ingredients>' +
              					'<Directions>product.DIRECTIONS__c</Directions>' +
            				'</HealthMisc>' +
          		           '</ProductType>' +
        			  '</Health>' +
     			 '</ProductData>' +
    		'</Product>';
            }
            xmlBody += '</Message>' +
                                 '</AmazonEnvelope>' ;

            return xmlBody;
    }

Then use this XML Body to get the ContentMD5Value: 
 
private String get_contentmd5(String xmlBody){
        	Blob targetBlob = Blob.valueOf(xmlBody);
        	Blob hash = Crypto.generateDigest('MD5', targetBlob);    
        	String contentMD5 = EncodingUtil.base64Encode(hash);
        	contentMD5 =  EncodingUtil.URLENCODE(contentMD5,'UTF-8');
        
        	return contentMD5;
    }

Then send the request to Amazon, you will need to prepare a signature to do this.
private void send_feed_to_amazon(String xmlBody, String ContentMD5){

         String timestamp = datetime.now().formatGMT('yyyy-MM-
           dd\'T\'HH:mm:ss.SSS\'Z\'');
        
        //Construct a query string with the query information
        String queryString = 'AWSAccessKeyId=' + accessKey + 
            '&Action=SubmitFeed'+
            '&FeedType=_POST_PRODUCT_DATA_'+
            '&MarketplaceId.Id.1=' + MarketplaceId  +
            '&SellerId=' + SellerId +
            '&SignatureMethod=' + SignatureMethod  +
            '&SignatureVersion=' + SignatureVersion  +
            '&Timestamp=' + timestamp  +
            '&Version=' + version;

        String stringtoSign = 'POST' + '\n' +
            'mws.amazonservices.co.uk' + '\n' +
            '/Orders/2013-09-01' + '\n' +
            queryString;
        
        //Covert query string to signature using Amazon secret key as key
        Blob mac = Crypto.generateMac('HMacSHA256', 
        blob.valueof(stringtoSign),blob.valueof(amazonSecretKey));

        String signature = EncodingUtil.base64Encode(mac);
        signature = EncodingUtil.urlEncode(signature,'UTF-8');


      //Create a new request
       HttpRequest request = new HttpRequest();    
        
       request.setEndpoint(endpoint +'?AWSAccessKeyId=' + accessKey +
            '&Action=SubmitFeed'+
            '&FeedType=_POST_PRODUCT_DATA_'+
            '&ContentMD5Value=ContentMD5'+
            '&SellerId=' + sellerId +
            '&SignatureVersion=2' +
            '&Timestamp=' + timestamp +
            '&Version=' + version +
            '&Signature=' + signature +
            '&SignatureMethod='+ signatureMethod +
            '&MarketplaceIdList.Id.1=' + marketplaceId);
        
        request.setMethod('POST');
        request.setBody(xmlBody);
        
        Http http = new Http();
        try {
            HttpResponse response = http.send(request);
            System.debug(response.getStatus());
            System.debug(response.getStatusCode());
            System.debug(response.getBody());
        } 
        catch(System.CalloutException e) {
            System.debug(e);
        }
}

This should return your FeedSubmissionId and you can use that to check the status and confirm that the feed was accepted.
See http://docs.developer.amazonservices.com/en_UK/feeds/Feeds_GetFeedSubmissionResult.html

I hope this helps.
Gráinne


 

All Answers

Rahul KumarRahul Kumar (Salesforce Developers) 
Hi Akum,

Integration with Amazon Market place Seller May I suggest you please check the below link. Hope it will be helpful.

Best Regards
Rahul Kumar
 
Grainne RyanGrainne Ryan
Hi Akum

Since you asked about product feeds in the other thread https://developer.salesforce.com/forums/ForumsMain?id=9060G000000XcNxQAK, this explains how to send a product feed to Amazon.  You should be able to covert this to send any feed to Amazon. 

In order to send feeds to Amazon you need to include an XML body and ContentMD5Value in the Amazon request.   This first function prepares the XML body, it assumes you are looping through all the products you have in Salesforce that you want to create or update in Amazon.  You need to pass it your seller id and a list of the products you want to send to Amazon.  And update it with your own values.
 
//Prepare the feed 
private String prepare_body(List<Products__c> products, String sellerId){
        
       String xmlBody = '<?xml version="1.0"?>' + 
                     '<AmazonEnvelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-
                     instance xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">'+
	               '<Header>' +
            		'<DocumentVersion>1.01</DocumentVersion>' +
            		'<MerchantIdentifier>' + sellerId + '</MerchantIdentifier>' +
            	      '</Header>' +
            	      '<MessageType>OrderAdjustment</MessageType>' +
            	      '<Message>' +
            		  '<MessageID>1</MessageID>' +
                       '<OperationType>Update</OperationType>' ;
     
        // replace all the values here with your own
        For(Product__c product : products){
    	xmlBody  += '<Product>' +
      			'<SKU>product.SKU__c</SKU>' +
      			'<StandardProductID>' +
        			'<Type>ASIN</Type>' +
        			'<Value>product.ASIN__c</Value>' +
      			'</StandardProductID>' +
      			'<ProductTaxCode>product.TAXCODE__c</ProductTaxCode>' +
      			'<DescriptionData>' +
        			'<Title>product.TITLE__c</Title>' +
        			'<Brand>product.BRAND__c</Brand>' +
        			'<Description>product.DESCRIPTION__c</Description>' +
        			'<BulletPoint>product.BULLETPOINT1__c</BulletPoint>' +
        			'<BulletPoint>product.BULLETPOINT2__c</BulletPoint>' +
        			'<MSRP currency="USD"> product.MSRP__c</MSRP>' +
                    '<Manufacturer>product.MANUFACTURER__c</Manufacturer>' +
        				'<ItemType>example-item-type</ItemType>' +
      			'</DescriptionData>' +
      			'<ProductData>' +
        			'<Health>' +
          		          '<ProductType>' +
            				'<HealthMisc>' +										 
                               '<Ingredients>product.INGREDIENTS__c</Ingredients>' +
              					'<Directions>product.DIRECTIONS__c</Directions>' +
            				'</HealthMisc>' +
          		           '</ProductType>' +
        			  '</Health>' +
     			 '</ProductData>' +
    		'</Product>';
            }
            xmlBody += '</Message>' +
                                 '</AmazonEnvelope>' ;

            return xmlBody;
    }

Then use this XML Body to get the ContentMD5Value: 
 
private String get_contentmd5(String xmlBody){
        	Blob targetBlob = Blob.valueOf(xmlBody);
        	Blob hash = Crypto.generateDigest('MD5', targetBlob);    
        	String contentMD5 = EncodingUtil.base64Encode(hash);
        	contentMD5 =  EncodingUtil.URLENCODE(contentMD5,'UTF-8');
        
        	return contentMD5;
    }

Then send the request to Amazon, you will need to prepare a signature to do this.
private void send_feed_to_amazon(String xmlBody, String ContentMD5){

         String timestamp = datetime.now().formatGMT('yyyy-MM-
           dd\'T\'HH:mm:ss.SSS\'Z\'');
        
        //Construct a query string with the query information
        String queryString = 'AWSAccessKeyId=' + accessKey + 
            '&Action=SubmitFeed'+
            '&FeedType=_POST_PRODUCT_DATA_'+
            '&MarketplaceId.Id.1=' + MarketplaceId  +
            '&SellerId=' + SellerId +
            '&SignatureMethod=' + SignatureMethod  +
            '&SignatureVersion=' + SignatureVersion  +
            '&Timestamp=' + timestamp  +
            '&Version=' + version;

        String stringtoSign = 'POST' + '\n' +
            'mws.amazonservices.co.uk' + '\n' +
            '/Orders/2013-09-01' + '\n' +
            queryString;
        
        //Covert query string to signature using Amazon secret key as key
        Blob mac = Crypto.generateMac('HMacSHA256', 
        blob.valueof(stringtoSign),blob.valueof(amazonSecretKey));

        String signature = EncodingUtil.base64Encode(mac);
        signature = EncodingUtil.urlEncode(signature,'UTF-8');


      //Create a new request
       HttpRequest request = new HttpRequest();    
        
       request.setEndpoint(endpoint +'?AWSAccessKeyId=' + accessKey +
            '&Action=SubmitFeed'+
            '&FeedType=_POST_PRODUCT_DATA_'+
            '&ContentMD5Value=ContentMD5'+
            '&SellerId=' + sellerId +
            '&SignatureVersion=2' +
            '&Timestamp=' + timestamp +
            '&Version=' + version +
            '&Signature=' + signature +
            '&SignatureMethod='+ signatureMethod +
            '&MarketplaceIdList.Id.1=' + marketplaceId);
        
        request.setMethod('POST');
        request.setBody(xmlBody);
        
        Http http = new Http();
        try {
            HttpResponse response = http.send(request);
            System.debug(response.getStatus());
            System.debug(response.getStatusCode());
            System.debug(response.getBody());
        } 
        catch(System.CalloutException e) {
            System.debug(e);
        }
}

This should return your FeedSubmissionId and you can use that to check the status and confirm that the feed was accepted.
See http://docs.developer.amazonservices.com/en_UK/feeds/Feeds_GetFeedSubmissionResult.html

I hope this helps.
Gráinne


 
This was selected as the best answer
Grainne RyanGrainne Ryan
I don't know how to edit replies but Line 36 of the send_feed_amazon function should read:
'&ContentMD5Value=' + ContentMD5 +
 
AKumAKum

Thanks @Grainne

Your solution seems promising and also signifying the possibility of bulk product uploads . Also can we send product images along with same xml body or we have to use the other feedType and a different callout for image upload ?

Grainne RyanGrainne Ryan
Yes you can send images, just give the type and the link,  put this under SKU:
<ImageType>Main</ImageType>
<ImageLocation>URL</ImageLocation></ProductImage>
AKumAKum

Hey @Grainne ,

I think something is missing while I am calling feed api from salesforce . Can you look below sample code which is similar to yours but returning error "Invalid query string provided - Keys may not contain &lt;" .

public with sharing class SendFeedToAmazon {
public static void ListProduct() {
        //Current time in GMT ISO 8601
        String timestamp = datetime.now().formatGMT('yyyy-MM-dd\'T\'HH:mm:ss.SSS\'Z\'');
        timestamp = EncodingUtil.urlEncode(timestamp,'UTF-8');
        
        //Amazon Variables
        String action = 'SubmitFeed';
        String FeedType ='_POST_PRODUCT_DATA_';
        String version = '2009-01-01';
        String signatureVersion = '2';
        String signatureMethod = 'HmacSHA256';
        String marketplaceId= 'Example';
        String sellerId = 'Example';
        String endpoint = 'https://mws.amazonservices.com/Feeds/2009-01-01';
        String accessKey = 'Example';
        String amazonSecretKey = 'Example';
    
        //Construct a query string with the query information
        String queryString = 'AWSAccessKeyId=' + accessKey + 
            '&Action=' + action  +
            '&FeedType=' + FeedType + 
            '&MarketplaceIdList.Id.1=' + MarketplaceId  +
            '&SellerId=' + SellerId +
            '&SignatureMethod=' + SignatureMethod  +
            '&SignatureVersion=' + SignatureVersion  +
            '&Timestamp=' + timestamp  +
            '&Version=' + version ;

        String stringtoSign = 'POST' + '\n' +
            'mws.amazonservices.com' + '\n' +
            '/Feeds/2009-01-01' + '\n' +
            queryString;
        
        //Covert query string to signature using Amazon secret key as key
        Blob mac = Crypto.generateMac('HMacSHA256', blob.valueof(stringtoSign),blob.valueof(amazonSecretKey));
        String signature = EncodingUtil.base64Encode(mac);
        signature = EncodingUtil.urlEncode(signature,'UTF-8');

        System.debug(signature);
     
        HttpRequest req = new HttpRequest(); 
        
        //Below is the MD5Value
        
        String xmlBody = '<?xml version="1.0" encoding="iso-8859-1"?>' +
'<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'+
    'xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">'+
  '<Header>'+
    '<DocumentVersion>1.01</DocumentVersion>'+
    '<MerchantIdentifier>M_EXAMPLE_123456</MerchantIdentifier>'+
  '</Header>'+
  '<MessageType>Product</MessageType>'+
  '<PurgeAndReplace>false</PurgeAndReplace>'+
  '<Message>'+
    '<MessageID>1</MessageID>'+
    '<OperationType>Update</OperationType>'+
    '<Product>'+
      '<SKU>56789</SKU>'+
      '<StandardProductID>'+
        '<Type>ASIN</Type>'+
        '<Value>B0EXAMPLEG</Value>'+
      '</StandardProductID>'+
      '<ProductTaxCode>A_GEN_NOTAX</ProductTaxCode>'+
      '<DescriptionData>'+
        '<Title>Example Product Title</Title>'+
        '<Brand>Example Product Brand</Brand>'+
        '<Description>This is an example product description.</Description>'+
        '<BulletPoint>Example Bullet Point 1</BulletPoint>'+
        '<BulletPoint>Example Bullet Point 2</BulletPoint>'+
        '<MSRP currency="USD">25.19</MSRP>'+
        '<Manufacturer>Example Product Manufacturer</Manufacturer>'+
        '<ItemType>example-item-type</ItemType>'+
      '</DescriptionData>'+
      '<ProductData>'+
        '<Health>'+
          '<ProductType>'+
            '<HealthMisc>'+
              '<Ingredients>Example Ingredients</Ingredients>'+
              '<Directions>Example Directions</Directions>'+
            '</HealthMisc>'+
          '</ProductType>'+
        '</Health>'+
      '</ProductData>'+
    '</Product>'+
  '</Message>'+
'</AmazonEnvelope>';
        
        
        
        Blob targetBlob = Blob.valueOf(xmlBody);
        Blob hash = Crypto.generateDigest('MD5', targetBlob);    
        String contentMD5 = EncodingUtil.base64Encode(hash);
        contentMD5 =  EncodingUtil.URLENCODE(contentMD5,'UTF-8');   
        
        req.setEndpoint(endpoint +'?AWSAccessKeyId=' + accessKey +
            '&Action=' + action +
            '&FeedType=' + FeedType  +
            '&ContentMD5Value=' + ContentMD5+
            '&SellerId=' + sellerId +
            '&SignatureVersion=2' +
            '&Timestamp=' + timestamp +
            '&Version=' + version +
            '&Signature=' + signature +
            '&SignatureMethod='+ signatureMethod +
            '&MarketplaceIdList.Id.1=' + marketplaceId);
        
        req.setMethod('POST');
        req.setBody(xmlBody);
        
        
        Http http = new Http();
        try {
            HttpResponse res = http.send(req);
            System.debug(':::::' + res.getStatus());
            System.debug(':::::' + res.getStatusCode());
            System.debug(':::::' + res.getBody());
            } 
        catch(System.CalloutException e) {
            System.debug(e);
        }
	}
}

The whole code sample is similar to your orderList code https://developer.salesforce.com/forums/ForumsMain?id=9060G000000XcNxQAK and I have changed values wherever needed but its returning error with code 400.
Grainne RyanGrainne Ryan
Hi @Akum

There are just two changes you need
1) Set the request header -  req.setHeader('Content-type', 'text/xml');
2) You should have the ContentM5 value in the query string
String queryString = 'AWSAccessKeyId=' + accessKey + 
            '&Action=' + action  +
            '&ContentMD5Value=' + ContentMD5+
            '&FeedType=' + FeedType + 
            '&MarketplaceIdList.Id.1=' + MarketplaceId  +
            '&SellerId=' + SellerId +
            '&SignatureMethod=' + SignatureMethod  +
            '&SignatureVersion=' + SignatureVersion  +
            '&Timestamp=' + timestamp  +
            '&Version=' + version;

That should work.  

Gráinne
AKumAKum

Thanks @Grainne , That took some time but worked :) but still I am unable to send images along with product xml . I was able to do it with image api but not with product feed while creating a product . It says image tag is not expected here. Do you have any sample xml for doing this ?

Thanks !

josefina markjosefina mark
Hey AKum, yes, you can easily do it as numerous platforms assist the process of integration of Amazon Seller Central to Salesforce, which includes the methods of automation of business and the sharing of data. Most companies as well as every need to integrate vary from one another. The most common is the front-office web property that has a back-office app, like an online storefront linked to an ERP, to pass orders via automatic processing when the order is placed online. Explore a lot more details on this topic through https://sellersonar.com/blog/rma-amazon-what-is-it/ now. By successfully doing so one can deal with the power of technology to customize the agent experience via data.