Stay organized with collections
Save and categorize content based on your preferences.
Merchant API code sample to insert promotions asynchronously.
Java
// Copyright 2023 Google LLC//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// https://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.packageshopping.merchant.samples.promotions.v1;importcom.google.api.core.ApiFuture;importcom.google.api.core.ApiFutureCallback;importcom.google.api.core.ApiFutures;importcom.google.api.gax.core.FixedCredentialsProvider;importcom.google.auth.oauth2.GoogleCredentials;importcom.google.common.util.concurrent.MoreExecutors;importcom.google.protobuf.Timestamp;importcom.google.shopping.merchant.promotions.v1.Attributes;importcom.google.shopping.merchant.promotions.v1.CouponValueType;importcom.google.shopping.merchant.promotions.v1.InsertPromotionRequest;importcom.google.shopping.merchant.promotions.v1.OfferType;importcom.google.shopping.merchant.promotions.v1.ProductApplicability;importcom.google.shopping.merchant.promotions.v1.Promotion;importcom.google.shopping.merchant.promotions.v1.PromotionsServiceClient;importcom.google.shopping.merchant.promotions.v1.PromotionsServiceSettings;importcom.google.shopping.merchant.promotions.v1.RedemptionChannel;importcom.google.shopping.type.CustomAttribute;importcom.google.shopping.type.Destination.DestinationEnum;importcom.google.type.Interval;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;importjava.util.stream.Collectors;importshopping.merchant.samples.utils.Authenticator;importshopping.merchant.samples.utils.Config;/** This class demonstrates how to insert multiple promotions asynchronously. */publicclassInsertPromotionsAsyncSample{privatestaticStringgenerateRandomString(){Stringcharacters="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";Randomrandom=newRandom();StringBuildersb=newStringBuilder(8);for(inti=0;i < 8;i++){sb.append(characters.charAt(random.nextInt(characters.length())));}returnsb.toString();}privatestaticPromotioncreatePromotion(StringaccountId){StringmerchantPromotionId=generateRandomString();Attributesattributes=Attributes.newBuilder().setProductApplicability(ProductApplicability.ALL_PRODUCTS).setOfferType(OfferType.GENERIC_CODE).setGenericRedemptionCode("ABCD1234").setLongTitle("My promotion").setCouponValueType(CouponValueType.PERCENT_OFF).addPromotionDestinations(DestinationEnum.SHOPPING_ADS).setPercentOff(10)// Note that promotions have a 6-month limit.// For more information, read here: https://support.google.com/merchants/answer/2906014// Also note that only promotions valid within the past 365 days are shown in the UI..setPromotionEffectiveTimePeriod(Interval.newBuilder().setStartTime(Timestamp.newBuilder().setSeconds(1726842472)).setEndTime(Timestamp.newBuilder().setSeconds(1726842473)).build()).build();returnPromotion.newBuilder().setName(String.format("accounts/%s/merchantPromotions/%s",accountId,merchantPromotionId)).setPromotionId(merchantPromotionId).setContentLanguage("fr").setTargetCountry("CH").addRedemptionChannel(RedemptionChannel.ONLINE).setAttributes(attributes)// Custom attributes allow you to add additional information which is not available in// Attributes. For example, you might want to pilot experimental functionality..addCustomAttributes(CustomAttribute.newBuilder().setName("another example name").setValue("another example value").build()).build();}publicstaticvoidasyncInsertPromotions(StringaccountId,StringdataSourceId)throwsException{GoogleCredentialscredential=newAuthenticator().authenticate();PromotionsServiceSettingsmerchantPromotionsServiceSettings=PromotionsServiceSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(credential)).build();try(PromotionsServiceClientmerchantPromotionsServiceClient=PromotionsServiceClient.create(merchantPromotionsServiceSettings)){// Arbitrarily creates five merchant promotions with random IDs.List<InsertPromotionRequest>requests=newArrayList<>();for(inti=0;i < 5;i++){InsertPromotionRequestrequest=InsertPromotionRequest.newBuilder().setParent(String.format("accounts/%s",accountId)).setPromotion(createPromotion(accountId)).setDataSource(String.format("accounts/%s/dataSources/%s",accountId,dataSourceId)).build();requests.add(request);}// Inserts the merchant promotions.List<ApiFuture<Promotion>>futures=requests.stream().map(request->
merchantPromotionsServiceClient.insertPromotionCallable().futureCall(request)).collect(Collectors.toList());// Creates callback to handle the responses when all are ready.ApiFuture<List<Promotion>>responses=ApiFutures.allAsList(futures);ApiFutures.addCallback(responses,newApiFutureCallback<List<Promotion>>(){@OverridepublicvoidonSuccess(List<Promotion>results){System.out.println("Inserted merchant promotions below:");System.out.println(results);}@OverridepublicvoidonFailure(Throwablethrowable){System.out.println(throwable);}},MoreExecutors.directExecutor());}catch(Exceptione){System.out.println(e);}}publicstaticvoidmain(String[]args)throwsException{Configconfig=Config.load();asyncInsertPromotions(config.getAccountId().toString(),"<YOUR_DATA_SOURCE_ID>");}}
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-13 UTC."],[[["\u003cp\u003eThis code sample demonstrates how to insert multiple promotions asynchronously using the Merchant API in Java.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eInsertPromotionsAsyncSample\u003c/code\u003e class showcases the process of creating and inserting promotions, including setting attributes like product applicability, offer type, and redemption details.\u003c/p\u003e\n"],["\u003cp\u003eThe code uses \u003ccode\u003eApiFuture\u003c/code\u003e and \u003ccode\u003eApiFutures\u003c/code\u003e to manage asynchronous requests for inserting multiple promotions, improving efficiency.\u003c/p\u003e\n"],["\u003cp\u003eThe sample provides a \u003ccode\u003ecreatePromotion\u003c/code\u003e method to build promotion objects with random IDs and a defined set of attributes, including setting a time limit.\u003c/p\u003e\n"],["\u003cp\u003eA callback function is used to handle the responses for asynchronous actions, providing a way to process the successful insertion of promotions or handle failures.\u003c/p\u003e\n"]]],["The code asynchronously inserts multiple promotions into a merchant account. It generates five `InsertPromotionRequest` objects, each containing promotion details like merchant ID, product applicability, offer type, and redemption code. Each request is sent using `PromotionsServiceClient`, and responses are handled via callbacks. On success, it prints the inserted promotions; on failure, it logs the error. It uses `ApiFutures` to manage multiple requests concurrently.\n"],null,["# Insert promotions asynchronously\n\nMerchant API code sample to insert promotions asynchronously. \n\n### Java\n\n\n // Copyright 2023 Google LLC\n //\n // Licensed under the Apache License, Version 2.0 (the \"License\");\n // you may not use this file except in compliance with the License.\n // You may obtain a copy of the License at\n //\n // https://www.apache.org/licenses/LICENSE-2.0\n //\n // Unless required by applicable law or agreed to in writing, software\n // distributed under the License is distributed on an \"AS IS\" BASIS,\n // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n // See the License for the specific language governing permissions and\n // limitations under the License.\n\n package shopping.merchant.samples.promotions.v1;\n import com.google.api.core.ApiFuture;\n import com.google.api.core.ApiFutureCallback;\n import com.google.api.core.ApiFutures;\n import com.google.api.gax.core.FixedCredentialsProvider;\n import com.google.auth.oauth2.GoogleCredentials;\n import com.google.common.util.concurrent.MoreExecutors;\n import com.google.protobuf.Timestamp;\n import com.google.shopping.merchant.promotions.v1.Attributes;\n import com.google.shopping.merchant.promotions.v1.CouponValueType;\n import com.google.shopping.merchant.promotions.v1.InsertPromotionRequest;\n import com.google.shopping.merchant.promotions.v1.OfferType;\n import com.google.shopping.merchant.promotions.v1.ProductApplicability;\n import com.google.shopping.merchant.promotions.v1.Promotion;\n import com.google.shopping.merchant.promotions.v1.PromotionsServiceClient;\n import com.google.shopping.merchant.promotions.v1.PromotionsServiceSettings;\n import com.google.shopping.merchant.promotions.v1.RedemptionChannel;\n import com.google.shopping.type.CustomAttribute;\n import com.google.shopping.type.Destination.DestinationEnum;\n import com.google.type.Interval;\n import java.util.ArrayList;\n import java.util.List;\n import java.util.Random;\n import java.util.stream.Collectors;\n import shopping.merchant.samples.utils.Authenticator;\n import shopping.merchant.samples.utils.Config;\n\n /** This class demonstrates how to insert multiple promotions asynchronously. */\n public class InsertPromotionsAsyncSample {\n\n private static String generateRandomString() {\n String characters = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n Random random = new Random();\n StringBuilder sb = new StringBuilder(8);\n for (int i = 0; i \u003c 8; i++) {\n sb.append(characters.charAt(random.nextInt(characters.length())));\n }\n return sb.toString();\n }\n\n private static Promotion createPromotion(String accountId) {\n String merchantPromotionId = generateRandomString();\n\n Attributes attributes =\n Attributes.newBuilder()\n .setProductApplicability(ProductApplicability.ALL_PRODUCTS)\n .setOfferType(OfferType.GENERIC_CODE)\n .setGenericRedemptionCode(\"ABCD1234\")\n .setLongTitle(\"My promotion\")\n .setCouponValueType(CouponValueType.PERCENT_OFF)\n .addPromotionDestinations(DestinationEnum.SHOPPING_ADS)\n .setPercentOff(10)\n // Note that promotions have a 6-month limit.\n // For more information, read here: https://support.google.com/merchants/answer/2906014\n // Also note that only promotions valid within the past 365 days are shown in the UI.\n .setPromotionEffectiveTimePeriod(\n Interval.newBuilder()\n .setStartTime(Timestamp.newBuilder().setSeconds(1726842472))\n .setEndTime(Timestamp.newBuilder().setSeconds(1726842473))\n .build())\n .build();\n\n return Promotion.newBuilder()\n .setName(String.format(\"accounts/%s/merchantPromotions/%s\", accountId, merchantPromotionId))\n .setPromotionId(merchantPromotionId)\n .setContentLanguage(\"fr\")\n .setTargetCountry(\"CH\")\n .addRedemptionChannel(RedemptionChannel.ONLINE)\n .setAttributes(attributes)\n // Custom attributes allow you to add additional information which is not available in\n // Attributes. For example, you might want to pilot experimental functionality.\n .addCustomAttributes(\n CustomAttribute.newBuilder()\n .setName(\"another example name\")\n .setValue(\"another example value\")\n .build())\n .build();\n }\n\n public static void asyncInsertPromotions(String accountId, String dataSourceId) throws Exception {\n GoogleCredentials credential = new Authenticator().authenticate();\n\n PromotionsServiceSettings merchantPromotionsServiceSettings =\n PromotionsServiceSettings.newBuilder()\n .setCredentialsProvider(FixedCredentialsProvider.create(credential))\n .build();\n\n try (PromotionsServiceClient merchantPromotionsServiceClient =\n PromotionsServiceClient.create(merchantPromotionsServiceSettings)) {\n\n // Arbitrarily creates five merchant promotions with random IDs.\n List\u003cInsertPromotionRequest\u003e requests = new ArrayList\u003c\u003e();\n for (int i = 0; i \u003c 5; i++) {\n InsertPromotionRequest request =\n InsertPromotionRequest.newBuilder()\n .setParent(String.format(\"accounts/%s\", accountId))\n .setPromotion(createPromotion(accountId))\n .setDataSource(String.format(\"accounts/%s/dataSources/%s\", accountId, dataSourceId))\n .build();\n requests.add(request);\n }\n\n // Inserts the merchant promotions.\n List\u003cApiFuture\u003cPromotion\u003e\u003e futures =\n requests.stream()\n .map(\n request -\u003e\n merchantPromotionsServiceClient.insertPromotionCallable().futureCall(request))\n .collect(Collectors.toList());\n\n // Creates callback to handle the responses when all are ready.\n ApiFuture\u003cList\u003cPromotion\u003e\u003e responses = ApiFutures.allAsList(futures);\n ApiFutures.addCallback(\n responses,\n new ApiFutureCallback\u003cList\u003cPromotion\u003e\u003e() {\n @Override\n public void onSuccess(List\u003cPromotion\u003e results) {\n System.out.println(\"Inserted merchant promotions below:\");\n System.out.println(results);\n }\n\n @Override\n public void onFailure(Throwable throwable) {\n System.out.println(throwable);\n }\n },\n MoreExecutors.directExecutor());\n } catch (Exception e) {\n System.out.println(e);\n }\n }\n\n\n public static void main(String[] args) throws Exception {\n Config config = Config.load();\n asyncInsertPromotions(config.getAccountId().toString(), \"\u003cYOUR_DATA_SOURCE_ID\u003e\");\n }\n } \n https://github.com/google/merchant-api-samples/blob/c6de994268c785ce22af0065932518a9ac5b3c03/java/src/main/java/shopping/merchant/samples/promotions/v1/InsertPromotionsAsyncSample.java"]]