You can use this guide to integrate Merchant API with your existing Content API for Shopping implementation.
The Merchant API lets you automate account-, product-, and inventory-related management workflows on Merchant Center. Merchant API use cases include:
- Automated account management
- Automated product management
- Automated inventory management
- Custom reporting
Improvements over Content API
Merchant API improves over Content API in the following areas:
- Sub-APIs with new features for your unique integration
- New methods for inventory, products data, and other APIs
- The ability to create not only primary data sources, but multiple data sources like:
- Introduces upload of product reviews and merchant reviews
- With Merchant API, you can enable notifications for changes to account data
Get started
See the Merchant API design for details about the Merchant API, and its sub-APIs.
To start using the Merchant API, change your request URLs to the following format:
https://merchantapi.googleapis.com/{SUB_API} /{VERSION} /{RESOURCE_NAME} :{METHOD} …
For more information, see the quickstart guide and the Merchant API reference.
gRPC support
The Merchant API supports gRPC and REST. You can use gRPC for the Merchant API and REST for the Content API for Shopping at the same time.
The Merchant API client libraries require gRPC.
See use gRPC for more information.
Compatibility
This guide describes general changes that apply to the entire Merchant API. See the following guides for changes to specific features:
- Migrate accounts management
- Migrate shipping settings
- Migrate products management
- Migrate data sources management
- Migrate inventories management
- Migrate promotions management
- Migrate reporting management
- Migrate conversion sources management
- Migrate local feeds partnership management
The Merchant API is designed to work alongside existing Content API for Shopping v2.1 features.
For example, you can use the Merchant Inventories API alongside your existing
Content API for Shopping v2.1
products
implementation. You
might use the Content API for Shopping to
upload a new local product
(that you sell in a local store), then use the Merchant Inventories API
LocalInventory
resource to manage in-store information for that product.
Batch requests
The Merchant API doesn't support the customBatch
method featured in the Content API for Shopping. Instead, see
Send multiple requests at once or
execute your calls asynchronously.
The following sample demonstrates how to insert a product input.
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutureCallback;
import com.google.api.core.ApiFutures;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.shopping.merchant.products.v1beta.Attributes;
import com.google.shopping.merchant.products.v1beta.InsertProductInputRequest;
import com.google.shopping.merchant.products.v1beta.ProductInput;
import com.google.shopping.merchant.products.v1beta.ProductInputsServiceClient;
import com.google.shopping.merchant.products.v1beta.ProductInputsServiceSettings;
import com.google.shopping.merchant.products.v1beta.Shipping;
import com.google.shopping.type.Channel.ChannelEnum;
import com.google.shopping.type.Price;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import shopping.merchant.samples.utils.Authenticator;
import shopping.merchant.samples.utils.Config;
/** This class demonstrates how to insert a product input */
public class InsertProductInputAsyncSample {
private static String getParent(String accountId) {
return String.format("accounts/%s", accountId);
}
private static String generateRandomString() {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder(8);
for (int i = 0; i < 8; i++) {
sb.append(characters.charAt(random.nextInt(characters.length())));
}
return sb.toString();
}
private static ProductInput createRandomProduct() {
Price price = Price.newBuilder().setAmountMicros(33_450_000).setCurrencyCode("USD").build();
Shipping shipping =
Shipping.newBuilder().setPrice(price).setCountry("GB").setService("1st class post").build();
Shipping shipping2 =
Shipping.newBuilder().setPrice(price).setCountry("FR").setService("1st class post").build();
Attributes attributes =
Attributes.newBuilder()
.setTitle("A Tale of Two Cities")
.setDescription("A classic novel about the French Revolution")
.setLink("https://exampleWebsite.com/tale-of-two-cities.html")
.setImageLink("https://exampleWebsite.com/tale-of-two-cities.jpg")
.setAvailability("in stock")
.setCondition("new")
.setGoogleProductCategory("Media > Books")
.setGtin(0, "9780007350896")
.addShipping(shipping)
.addShipping(shipping2)
.build();
return ProductInput.newBuilder()
.setChannel(ChannelEnum.ONLINE)
.setContentLanguage("en")
.setFeedLabel("CH")
.setOfferId(generateRandomString())
.setAttributes(attributes)
.build();
}
public static void asyncInsertProductInput(Config config, String dataSource) throws Exception {
// Obtains OAuth token based on the user's configuration.
GoogleCredentials credential = new Authenticator().authenticate();
// Creates service settings using the credentials retrieved above.
ProductInputsServiceSettings productInputsServiceSettings =
ProductInputsServiceSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(credential))
.build();
// Creates parent to identify where to insert the product.
String parent = getParent(config.getAccountId().toString());
// Calls the API and catches and prints any network failures/errors.
try (ProductInputsServiceClient productInputsServiceClient =
ProductInputsServiceClient.create(productInputsServiceSettings)) {
// Creates five insert product input requests with random product IDs.
List<InsertProductInputRequest> requests = new ArrayList<>(5);
for (int i = 0; i < 5; i++) {
InsertProductInputRequest request =
InsertProductInputRequest.newBuilder()
.setParent(parent)
// You can only insert products into datasource types of Input "API" and "FILE", and
// of Type "Primary" or "Supplemental."
// This field takes the `name` field of the datasource.
.setDataSource(dataSource)
// If this product is already owned by another datasource, when re-inserting, the
// new datasource will take ownership of the product.
.setProductInput(createRandomProduct())
.build();
requests.add(request);
}
System.out.println("Sending insert product input requests");
List<ApiFuture<ProductInput>> futures =
requests.stream()
.map(
request ->
productInputsServiceClient.insertProductInputCallable().futureCall(request))
.collect(Collectors.toList());
// Creates callback to handle the responses when all are ready.
ApiFuture<List<ProductInput>> responses = ApiFutures.allAsList(futures);
ApiFutures.addCallback(
responses,
new ApiFutureCallback<List<ProductInput>>() {
@Override
public void onSuccess(List<ProductInput> results) {
System.out.println("Inserted products below");
System.out.println(results);
}
@Override
public void onFailure(Throwable throwable) {
System.out.println(throwable);
}
},
MoreExecutors.directExecutor());
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) throws Exception {
Config config = Config.load();
// Identifies the data source that will own the product input.
String dataSource = "accounts/" + config.getAccountId() + "/dataSources/{datasourceId}";
asyncInsertProductInput(config, dataSource);
}
}
If you use customBatch
in Content API, and need this feature for the Merchant
API, let us know why in your feedback.
Identifiers
To align with Google's API improvement principles, we've made some changes to the identifiers for Merchant API resources.
name replaces Id
All Merchant API resources use the name
field as their unique identifier.
Here's an example of how to use the name
field in your calls:
POST https://merchantapi.googleapis.com/inventories/v1beta/{PARENT} /regionalInventories:insert
This new name
field is returned as the resource identifier for all read and
write calls in the Merchant API.
For example, implement a getName()
method to retrieve the name
from a
resource, and store the output as a variable instead of constructing the name
from the merchant and resource IDs yourself.
parent fields for child resources
In the Merchant API, all child resources have the parent
field. You can use the parent
field to specify the name
of the resource to
insert the child to, instead of passing the entire parent resource.
You can also use the parent
field with list
methods to list the child resources of that parent
.
For example, to list local inventories for a given product, specify the
product's name
in the
parent
field for the
list
method. In this case, the given product
is the parent
of the
LocalInventory
resources returned.
Types
Here are some common types shared across the Merchant API sub-APIs.
Price
Here's what's changed for Price
in the Merchant Common package:
Content API | Merchant API | |
---|---|---|
Amount field | value:string |
amountMicros:int64 |
Currency field | currency:string
|
currencyCode:string |
The Price
amount is now recorded in micros, where 1 million micros is
equivalent to your currency's standard unit.
In the Content API for Shopping, Price
was a decimal number in the form of a
string.
The amount field name has changed from value
to amountMicros
The currency field name has changed from currency
to currencyCode
. The
format remains as ISO 4217.