Merchant API code sample to create an order tracking signal.

### Java

    // Copyright 2025 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.

    package shopping.merchant.samples.ordertracking.v1;

    import com.google.api.gax.core.FixedCredentialsProvider;
    import com.google.auth.oauth2.GoogleCredentials;
    import com.google.shopping.merchant.ordertracking.v1.CreateOrderTrackingSignalRequest;
    import com.google.shopping.merchant.ordertracking.v1.OrderTrackingSignal;
    import com.google.shopping.merchant.ordertracking.v1.OrderTrackingSignal.LineItemDetails;
    import com.google.shopping.merchant.ordertracking.v1.OrderTrackingSignal.ShipmentLineItemMapping;
    import com.google.shopping.merchant.ordertracking.v1.OrderTrackingSignal.ShippingInfo;
    import com.google.shopping.merchant.ordertracking.v1.OrderTrackingSignal.ShippingInfo.ShippingState;
    import com.google.shopping.merchant.ordertracking.v1.OrderTrackingSignalsServiceClient;
    import com.google.shopping.merchant.ordertracking.v1.OrderTrackingSignalsServiceSettings;
    import com.google.shopping.type.Price;
    import com.google.type.DateTime;
    import com.google.type.TimeZone;
    import java.util.Arrays;
    import java.util.List;
    import shopping.merchant.samples.utils.Authenticator;
    import shopping.merchant.samples.utils.Config;

    /** This class demonstrates how to create an order tracking signal. */
    public class CreateOrderTrackingSignalSample {
      private static String getParent(String accountId) {
        return String.format("accounts/%s", accountId);
      }

      private static void createOrderTrackingSignal(Config config, List<String> productIds)
          throws Exception {
        GoogleCredentials credentials = new Authenticator().authenticate();
        OrderTrackingSignalsServiceSettings orderTrackingSignalsServiceSettings =
            OrderTrackingSignalsServiceSettings.newBuilder()
                .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
                .build();

        String parent = getParent(config.getAccountId().toString());

        String firstProductId = productIds.get(0);
        String secondProductId = productIds.get(1);

        DateTime orderCreatedTime =
            DateTime.newBuilder()
                .setYear(2025)
                .setMonth(3)
                .setDay(24)
                .setHours(12)
                .setMinutes(2)
                .setSeconds(22)
                .setTimeZone(TimeZone.newBuilder().setId("America/Los_Angeles"))
                .build();
        DateTime shippedTime1 =
            DateTime.newBuilder()
                .setYear(2025)
                .setMonth(3)
                .setDay(25)
                .setHours(16)
                .setMinutes(22)
                .setTimeZone(TimeZone.newBuilder().setId("America/Los_Angeles"))
                .build();
        DateTime shippedTime2 =
            DateTime.newBuilder()
                .setYear(2025)
                .setMonth(3)
                .setDay(26)
                .setHours(16)
                .setMinutes(22)
                .setTimeZone(TimeZone.newBuilder().setId("America/Los_Angeles"))
                .build();
        DateTime earliestDeliveryPromiseTime =
            DateTime.newBuilder()
                .setYear(2025)
                .setMonth(3)
                .setDay(27)
                .setTimeZone(TimeZone.newBuilder().setId("America/Los_Angeles"))
                .build();
        DateTime latestDeliveryPromiseTime =
            DateTime.newBuilder()
                .setYear(2025)
                .setMonth(3)
                .setDay(30)
                .setTimeZone(TimeZone.newBuilder().setId("America/Los_Angeles"))
                .build();
        DateTime actualDeliveryTime =
            DateTime.newBuilder()
                .setYear(2025)
                .setMonth(3)
                .setDay(29)
                .setHours(16)
                .setMinutes(22)
                .setTimeZone(TimeZone.newBuilder().setId("America/Los_Angeles"))
                .build();

        ShippingInfo shippingInfo1 =
            ShippingInfo.newBuilder()
                .setShipmentId("shipment_id1")
                .setCarrier("UPS")
                .setCarrierService("Ground")
                .setTrackingId("1Z23456789")
                .setShippedTime(shippedTime1)
                .setEarliestDeliveryPromiseTime(earliestDeliveryPromiseTime)
                .setLatestDeliveryPromiseTime(latestDeliveryPromiseTime)
                .setActualDeliveryTime(actualDeliveryTime)
                .setShippingStatus(ShippingState.DELIVERED)
                .setOriginPostalCode("94043")
                .setOriginRegionCode("US")
                .build();
        ShippingInfo shippingInfo2 =
            ShippingInfo.newBuilder()
                .setShipmentId("shipment_id2")
                .setCarrier("USPS")
                .setCarrierService("Ground Advantage")
                .setTrackingId("987654321")
                .setShippedTime(shippedTime2)
                .setShippingStatus(ShippingState.SHIPPED)
                .setOriginPostalCode("94043")
                .setOriginRegionCode("US")
                .build();

        try (OrderTrackingSignalsServiceClient orderTrackingSignalsServiceClient =
            OrderTrackingSignalsServiceClient.create(orderTrackingSignalsServiceSettings)) {
          CreateOrderTrackingSignalRequest request =
              CreateOrderTrackingSignalRequest.newBuilder()
                  .setParent(parent)
                  .setOrderTrackingSignal(
                      OrderTrackingSignal.newBuilder()
                          // Unique order ID across all merchants orders.
                          .setOrderId("unique_order_id443455")
                          // If sending signal on behalf of another merchant use setMerchantId to
                          // indicate the merchant.
                          // .setMerchantId(123L)
                          .setOrderCreatedTime(orderCreatedTime)
                          .addShippingInfo(shippingInfo1)
                          .addShippingInfo(shippingInfo2)
                          // Details of the line items in the order including quantity and fields
                          // identifying the product.
                          .addLineItems(
                              LineItemDetails.newBuilder()
                                  .setQuantity(2)
                                  .setProductId(firstProductId)
                                  .setLineItemId("item1"))
                          .addLineItems(
                              LineItemDetails.newBuilder()
                                  .setQuantity(1)
                                  .setProductId(secondProductId)
                                  .setLineItemId("item2")
                                  // Optional fields used to identify the product when product ID is not
                                  // sufficient.
                                  .setMpn("00638HAY")
                                  .setProductTitle("Tshirt-small-blue")
                                  .setBrand("Brand1")
                                  // Any GTIN associated with the product.
                                  .addGtins("001234567890"))
                          // Mapping of line items to shipments.
                          .addShipmentLineItemMapping(
                              ShipmentLineItemMapping.newBuilder()
                                  .setShipmentId("shipment_id1")
                                  .setLineItemId("item2")
                                  .setQuantity(1))
                          .addShipmentLineItemMapping(
                              ShipmentLineItemMapping.newBuilder()
                                  .setShipmentId("shipment_id2")
                                  .setLineItemId("item1")
                                  .setQuantity(1))
                          .addShipmentLineItemMapping(
                              ShipmentLineItemMapping.newBuilder()
                                  .setShipmentId("shipment_id1")
                                  .setLineItemId("item1")
                                  .setQuantity(1))
                          // The price represented as a number in micros (1 million micros is an
                          // equivalent to one's currency standard unit, for example, 1 USD = 1000000
                          // micros).
                          .setCustomerShippingFee(
                              Price.newBuilder()
                                  // Equivalent to 5 USD.
                                  .setAmountMicros(5000000)
                                  .setCurrencyCode("USD"))
                          .setDeliveryPostalCode("10011"))
                  .build();
          System.out.println("Sending Create OrderTrackingSignal request.");
          OrderTrackingSignal response =
              orderTrackingSignalsServiceClient.createOrderTrackingSignal(request);
          System.out.println("Created OrderTrackingSignal below.");
          System.out.println(response);

        } catch (Exception e) {
          System.out.println(e);
        }
      }

      public static void main(String[] args) throws Exception {
        Config config = Config.load();
        // All products in the order. Replace with actual products in the order. Be sure to include all
        // products in the order.
        String productId1 = "en~us~sku123";
        String productId2 = "en~us~skuabc";
        List<String> productIds = Arrays.asList(productId1, productId2);
        createOrderTrackingSignal(config, productIds);
      }
    }

### PHP

    <?php
    /**
     * Copyright 2025 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.
     */

    require_once __DIR__ . '/../../../vendor/autoload.php';
    require_once __DIR__ . '/../../Authentication/Authentication.php';
    require_once __DIR__ . '/../../Authentication/Config.php';
    use Google\ApiCore\ApiException;
    use Google\Shopping\Merchant\OrderTracking\V1\Client\OrderTrackingSignalsServiceClient;
    use Google\Shopping\Merchant\OrderTracking\V1\CreateOrderTrackingSignalRequest;
    use Google\Shopping\Merchant\OrderTracking\V1\OrderTrackingSignal;
    use Google\Shopping\Merchant\OrderTracking\V1\OrderTrackingSignal\LineItemDetails;
    use Google\Shopping\Merchant\OrderTracking\V1\OrderTrackingSignal\ShipmentLineItemMapping;
    use Google\Shopping\Merchant\OrderTracking\V1\OrderTrackingSignal\ShippingInfo;
    use Google\Shopping\Merchant\OrderTracking\V1\OrderTrackingSignal\ShippingInfo\ShippingState;
    use Google\Shopping\Type\Price;
    use Google\Type\DateTime;
    use Google\Type\TimeZone;

    /** This class demonstrates how to create an order tracking signal. */
    class CreateOrderTrackingSignalSample
    {
        /**
         * A helper function to create the parent string.
         *
         * @param string $accountId The account that owns the product.
         *
         * @return string The parent has the format: `accounts/{account_id}`
         */
        private static function getParent(string $accountId): string
        {
            return sprintf('accounts/%s', $accountId);
        }

        /**
         * Creates an order tracking signal.
         *
         * @param array $config The configuration data used for authentication and
         *     getting the account ID.
         * @param array $productIds The product IDs for all items in the order.
         *
         * @return void
         */
        public static function createOrderTrackingSignalSample(
            array $config,
            array $productIds
        ): void {
            // Gets the OAuth credentials to make the request.
            $credentials = Authentication::useServiceAccountOrTokenFile();

            // Creates a client.
            $orderTrackingSignalsServiceClient = new OrderTrackingSignalsServiceClient(
                ['credentials' => $credentials]
            );

            // Creates parent to identify where to insert the product.
            $parent = self::getParent($config['accountId']);

            $firstProductId = $productIds[0];
            $secondProductId = $productIds[1];

            // The timezone for all DateTime objects.
            $timeZone = new TimeZone(['id' => 'America/Los_Angeles']);

            // The time the order was created.
            $orderCreatedTime = new DateTime(
                [
                    'year' => 2025,
                    'month' => 3,
                    'day' => 24,
                    'hours' => 12,
                    'minutes' => 2,
                    'seconds' => 22,
                    'time_zone' => $timeZone
                ]
            );

            // The time the first shipment was shipped.
            $shippedTime1 = new DateTime(
                [
                    'year' => 2025,
                    'month' => 3,
                    'day' => 25,
                    'hours' => 16,
                    'minutes' => 22,
                    'time_zone' => $timeZone
                ]
            );

            // The time the second shipment was shipped.
            $shippedTime2 = new DateTime(
                [
                    'year' => 2025,
                    'month' => 3,
                    'day' => 26,
                    'hours' => 16,
                    'minutes' => 22,
                    'time_zone' => $timeZone
                ]
            );

            // The earliest promised delivery time.
            $earliestDeliveryPromiseTime = new DateTime(
                [
                    'year' => 2025,
                    'month' => 3,
                    'day' => 27,
                    'time_zone' => $timeZone
                ]
            );

            // The latest promised delivery time.
            $latestDeliveryPromiseTime = new DateTime(
                [
                    'year' => 2025,
                    'month' => 3,
                    'day' => 30,
                    'time_zone' => $timeZone
                ]
            );

            // The actual delivery time.
            $actualDeliveryTime = new DateTime(
                [
                    'year' => 2025,
                    'month' => 3,
                    'day' => 29,
                    'hours' => 16,
                    'minutes' => 22,
                    'time_zone' => $timeZone
                ]
            );

            // Shipping information for the first shipment.
            $shippingInfo1 = new ShippingInfo(
                [
                    'shipment_id' => 'shipment_id1',
                    'carrier' => 'UPS',
                    'carrier_service' => 'Ground',
                    'tracking_id' => '1Z23456789',
                    'shipped_time' => $shippedTime1,
                    'earliest_delivery_promise_time' => $earliestDeliveryPromiseTime,
                    'latest_delivery_promise_time' => $latestDeliveryPromiseTime,
                    'actual_delivery_time' => $actualDeliveryTime,
                    'shipping_status' => ShippingState::DELIVERED,
                    'origin_postal_code' => '94043',
                    'origin_region_code' => 'US'
                ]
            );

            // Shipping information for the second shipment.
            $shippingInfo2 = new ShippingInfo(
                [
                    'shipment_id' => 'shipment_id2',
                    'carrier' => 'USPS',
                    'carrier_service' => 'Ground Advantage',
                    'tracking_id' => '987654321',
                    'shipped_time' => $shippedTime2,
                    'shipping_status' => ShippingState::SHIPPED,
                    'origin_postal_code' => '94043',
                    'origin_region_code' => 'US'
                ]
            );

            // Calls the API and catches and prints any network failures/errors.
            try {
                // The price represented as a number in micros (1 million micros is an
                // equivalent to one's currency standard unit, for example, 1 USD = 1000000
                // micros).
                $customerShippingFee = new Price(
                    [
                        // Equivalent to 5 USD.
                        'amount_micros' => 5000000,
                        'currency_code' => 'USD'
                    ]
                );

                // Details of the line items in the order including quantity and fields
                // identifying the product.
                $lineItems = [
                    new LineItemDetails(
                        [
                            'quantity' => 2,
                            'product_id' => $firstProductId,
                            'line_item_id' => 'item1'
                        ]
                    ),
                    new LineItemDetails(
                        [
                            'quantity' => 1,
                            'product_id' => $secondProductId,
                            'line_item_id' => 'item2',
                            // Optional fields used to identify the product when product ID is not
                            // sufficient.
                            'mpn' => '00638HAY',
                            'product_title' => 'Tshirt-small-blue',
                            'brand' => 'Brand1',
                            // Any GTINs associated with the product.
                            'gtins' => ['001234567890']
                        ]
                    )
                ];

                // Mapping of line items to shipments.
                $shipmentLineItemMapping = [
                    new ShipmentLineItemMapping(
                        [
                            'shipment_id' => 'shipment_id1',
                            'line_item_id' => 'item2',
                            'quantity' => 1
                        ]
                    ),
                    new ShipmentLineItemMapping(
                        [
                            'shipment_id' => 'shipment_id2',
                            'line_item_id' => 'item1',
                            'quantity' => 1
                        ]
                    ),
                    new ShipmentLineItemMapping(
                        [
                            'shipment_id' => 'shipment_id1',
                            'line_item_id' => 'item1',
                            'quantity' => 1
                        ]
                    )
                ];

                // Constructs the OrderTrackingSignal.
                $orderTrackingSignal = new OrderTrackingSignal(
                    [
                        // Unique order ID across all merchants orders.
                        'order_id' => 'unique_order_id443455',
                        // If sending signal on behalf of another merchant use setMerchantId to
                        // indicate the merchant.
                        // 'merchant_id' => 123,
                        'order_created_time' => $orderCreatedTime,
                        'shipping_info' => [$shippingInfo1, $shippingInfo2],
                        'line_items' => $lineItems,
                        'shipment_line_item_mapping' => $shipmentLineItemMapping,
                        'customer_shipping_fee' => $customerShippingFee,
                        'delivery_postal_code' => '10011'
                    ]
                );

                // Prepares the request message.
                $request = new CreateOrderTrackingSignalRequest(
                    [
                        'parent' => $parent,
                        'order_tracking_signal' => $orderTrackingSignal
                    ]
                );

                print "Sending Create OrderTrackingSignal request.\n";
                $response = $orderTrackingSignalsServiceClient->createOrderTrackingSignal(
                    $request
                );
                print "Created OrderTrackingSignal below.\n";
                // Pretty-prints the Protobuf JSON response.
                print $response->serializeToJsonString(true) . "\n";
            } catch (ApiException $e) {
                printf("Call failed with message: %s\n", $e->getMessage());
            }
        }

        /**
         * Helper to execute the sample.
         *
         * @return void
         */
        public function callSample(): void
        {
            $config = Config::generateConfig();
            // All products in the order. Replace with actual products in the order. Be sure to include all
            // products in the order.
            $productId1 = 'en~us~sku123';
            $productId2 = 'en~us~skuabc';
            $productIds = [$productId1, $productId2];
            self::createOrderTrackingSignalSample($config, $productIds);
        }
    }

    // Runs the script.
    $sample = new CreateOrderTrackingSignalSample();
    $sample->callSample();

### Python

    # -*- coding: utf-8 -*-
    # Copyright 2025 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
    #
    #     http://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.
    """A module to create OrderTrackingSignals."""

    from examples.authentication import configuration
    from examples.authentication import generate_user_credentials
    from google.shopping.merchant_ordertracking_v1 import CreateOrderTrackingSignalRequest
    from google.shopping.merchant_ordertracking_v1 import OrderTrackingSignalsServiceClient
    from google.shopping.merchant_ordertracking_v1.types import OrderTrackingSignal
    from google.shopping.type import Price
    from google.type import datetime_pb2

    # Read the Merchant Center account ID from the configuration.
    _ACCOUNT_ID = configuration.Configuration().read_merchant_info()
    # Construct the parent resource name for API calls.
    _PARENT = f"accounts/{_ACCOUNT_ID}"


    def create_order_tracking_signal(product_ids: list[str]):
      """Creates an order tracking signal for a given merchant account and product IDs."""

      # Gets OAuth Credentials.
      credentials = generate_user_credentials.main()

      # Creates a client for the Order Tracking Signals API.
      client = OrderTrackingSignalsServiceClient(credentials=credentials)

      first_product_id = product_ids[0]
      second_product_id = product_ids[1]

      # Define the time the order was created.
      order_created_time = datetime_pb2.DateTime(
          year=2025,
          month=3,
          day=24,
          hours=12,
          minutes=2,
          seconds=22,
          time_zone=datetime_pb2.TimeZone(id="America/Los_Angeles"),
      )
      # Define the time the first shipment was made.
      shipped_time1 = datetime_pb2.DateTime(
          year=2025,
          month=3,
          day=25,
          hours=16,
          minutes=22,
          time_zone=datetime_pb2.TimeZone(id="America/Los_Angeles"),
      )
      # Define the time the second shipment was made.
      shipped_time2 = datetime_pb2.DateTime(
          year=2025,
          month=3,
          day=26,
          hours=16,
          minutes=22,
          time_zone=datetime_pb2.TimeZone(id="America/Los_Angeles"),
      )
      # Define the earliest promised delivery time.
      earliest_delivery_promise_time = datetime_pb2.DateTime(
          year=2025,
          month=3,
          day=27,
          time_zone=datetime_pb2.TimeZone(id="America/Los_Angeles"),
      )
      # Define the latest promised delivery time.
      latest_delivery_promise_time = datetime_pb2.DateTime(
          year=2025,
          month=3,
          day=30,
          time_zone=datetime_pb2.TimeZone(id="America/Los_Angeles"),
      )
      # Define the actual delivery time.
      actual_delivery_time = datetime_pb2.DateTime(
          year=2025,
          month=3,
          day=29,
          hours=16,
          minutes=22,
          time_zone=datetime_pb2.TimeZone(id="America/Los_Angeles"),
      )

      # Define shipping information for the first shipment.
      shipping_info1 = OrderTrackingSignal.ShippingInfo(
          shipment_id="shipment_id1",
          carrier="UPS",
          carrier_service="Ground",
          tracking_id="1Z23456789",
          shipped_time=shipped_time1,
          earliest_delivery_promise_time=earliest_delivery_promise_time,
          latest_delivery_promise_time=latest_delivery_promise_time,
          actual_delivery_time=actual_delivery_time,
          shipping_status=OrderTrackingSignal.ShippingInfo.ShippingState.DELIVERED,
          origin_postal_code="94043",
          origin_region_code="US",
      )
      # Define shipping information for the second shipment.
      shipping_info2 = OrderTrackingSignal.ShippingInfo(
          shipment_id="shipment_id2",
          carrier="USPS",
          carrier_service="Ground Advantage",
          tracking_id="987654321",
          shipped_time=shipped_time2,
          shipping_status=OrderTrackingSignal.ShippingInfo.ShippingState.SHIPPED,
          origin_postal_code="94043",
          origin_region_code="US",
      )

      # Construct the OrderTrackingSignal payload.
      order_tracking_signal_payload = OrderTrackingSignal(
          # Unique order ID across all merchants orders.
          order_id="unique_order_id443455",
          # If sending signal on behalf of another merchant use merchant_id to
          # indicate the merchant.
          # merchant_id=123,
          order_created_time=order_created_time,
          shipping_info=[shipping_info1, shipping_info2],
          # Details of the line items in the order including quantity and fields
          # identifying the product.
          line_items=[
              OrderTrackingSignal.LineItemDetails(
                  quantity=2, product_id=first_product_id, line_item_id="item1"
              ),
              OrderTrackingSignal.LineItemDetails(
                  quantity=1,
                  product_id=second_product_id,
                  line_item_id="item2",
                  # Optional fields used to identify the product when product ID is
                  # not sufficient.
                  mpn="00638HAY",
                  product_title="Tshirt-small-blue",
                  brand="Brand1",
                  # Any GTINs associated with the product.
                  gtins=["001234567890"],
              ),
          ],
          # Mapping of line items to shipments.
          shipment_line_item_mapping=[
              OrderTrackingSignal.ShipmentLineItemMapping(
                  shipment_id="shipment_id1", line_item_id="item2", quantity=1
              ),
              OrderTrackingSignal.ShipmentLineItemMapping(
                  shipment_id="shipment_id2", line_item_id="item1", quantity=1
              ),
              OrderTrackingSignal.ShipmentLineItemMapping(
                  shipment_id="shipment_id1", line_item_id="item1", quantity=1
              ),
          ],
          # The price represented as a number in micros (1 million micros is an
          # equivalent to one's currency standard unit, for example, 1 USD = 1000000
          # micros).
          customer_shipping_fee=Price(
              # Equivalent to 5 USD.
              amount_micros=5000000,
              currency_code="USD",
          ),
          delivery_postal_code="10011",
      )

      # Create the request object.
      request = CreateOrderTrackingSignalRequest(
          parent=_PARENT, order_tracking_signal=order_tracking_signal_payload
      )

      # Make the API call to create the order tracking signal.
      try:
        print("Sending Create OrderTrackingSignal request.")
        response = client.create_order_tracking_signal(request=request)
        print("Created OrderTrackingSignal below.")
        print(response)
      except RuntimeError as e:
        print(e)


    if __name__ == "__main__":
      # All products in the order. Replace with actual products in the order.
      # Be sure to include all products in the order.
      product_id1 = "en~US~sku123"
      product_id2 = "en~US~sku1234"
      product_ids_list = [product_id1, product_id2]
      create_order_tracking_signal(product_ids_list)