Create a order tracking signal

Merchant API code sample to create a 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 = "online~en~us~sku123";
    String productId2 = "online~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 = 'online~en~us~sku123';
        $productId2 = 'online~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 = "online~en~US~sku123"
  product_id2 = "online~en~US~sku1234"
  product_ids_list = [product_id1, product_id2]
  create_order_tracking_signal(product_ids_list)