نقل البيانات من Content API for Shopping إلى Merchant API

يوضّح هذا الدليل عملية نقل البيانات من Content API for Shopping إلى Merchant API لإدارة بيانات النشاط التجاري.

يمكنك استخدام هذا الدليل لنقل عملية التنفيذ الحالية Content API for Shopping إلى Merchant API. لمزيد من المعلومات حول تفاصيل Merchant API وواجهات برمجة التطبيقات الفرعية، يُرجى الاطّلاع على تصميم Merchant API.

البدء

لبدء استخدام Merchant API، غيِّر تنسيق عناوين URL لطلباتك إلى التنسيق التالي:

https://merchantapi.googleapis.com/{SUB_API}/{VERSION}/{RESOURCE_NAME}:{METHOD}

لاستخدام Merchant API، يجب ربط حسابك على Merchant Center بمشروعك على Google Cloud باستخدام طريقة تسجيل المطوّرين، وذلك باتّباع الخطوات التالية:

POST https://merchantapi.googleapis.com/accounts/v1/accounts/{ACCOUNT_ID}/developerRegistration:registerGcp

{
  developer_email:"example-email@example.com"
}

لمزيد من المعلومات، يُرجى الاطّلاع على دليل البدء السريع ومرجع Merchant API.

التحسينات مقارنةً بواجهة Content API for Shopping

تتيح لك Merchant API إمكانية إعداد سير العمل في Merchant Center وأتمتته وتبسيطه، كما توفّر إمكانات محسّنة مقارنةً بواجهة Content API for Shopping.

حالات الاستخدام الرئيسية:

  • إدارة الحسابات آليًا
  • إدارة المنتجات آليًا
  • إدارة المستودع الآلية
  • إعداد التقارير المخصّصة

مجالات التحسين الرئيسية:

التغييرات التي تم إجراؤها:

  • تمت زيادة الحد الأقصى pageSize من 250 إلى 1,000 صف لكل طلب بيانات من واجهة برمجة التطبيقات.
  • تم إصلاح مشكلة التأخير التي كانت تحدث عند إدراج المنتجات والعروض الترويجية ومراجعات المنتجات ومراجعات التجّار بعد إنشاء DataSources.

الميزات القادمة:

  • إطلاق تعريف معدَّل لـ clickPotentialRank في جدول productView ضمن واجهة برمجة التطبيقات الفرعية لإعداد التقارير: * يتم تعديل ترتيب المنتجات استنادًا إلى clickPotential ليصبح بين 1 و1000.
    • تظل المنتجات التي تتضمّن قيمة clickPotentialRank منخفضة هي المنتجات التي لديها أكبر إمكانية لجذب النقرات بين منتجات التاجر التي تستوفي شروط طلب البحث. هذا التغيير غير مهم وقد يتم إطلاقه في 1 يوليو 2025.
  • تتيح AccountIdAlias في مرجع AccountRelationship إدارة بنى الحسابات المعقّدة بشكل أفضل. على سبيل المثال، تستخدم الأسواق اسمًا مستعارًا يحدّده المستخدم بدلاً من المعرّف الداخلي للتاجر، مثل معرّف الحساب.

توافق gRPC

تتيح Merchant API استخدام gRPC وREST. يمكنك استخدام gRPC لواجهة Merchant API وREST لواجهة Content API for Shopping في الوقت نفسه.

تتطلّب مكتبات برامج Merchant API استخدام gRPC.

لمزيد من المعلومات، يُرجى الاطّلاع على نظرة عامة حول gRPC.

التوافق

يوضّح هذا الدليل التغييرات العامة التي تنطبق على Merchant API بالكامل.

تم تصميم Merchant API لتعمل جنبًا إلى جنب مع ميزات Content API for Shopping الحالية.

على سبيل المثال، يمكنك استخدام Merchant Inventories API مع عملية التنفيذ الحالية للإصدار 2.1 من Content API for Shopping products. يمكنك استخدام Content API for Shopping لتحميل منتج محلي جديد (تبيعه في متجر محلي)، ثم استخدام مورد Merchant Inventories API LocalInventory لإدارة المعلومات المتعلّقة بهذا المنتج في المتجر.

التحسينات مقارنةً بواجهة Content API

تتفوّق Merchant API على Content API في المجالات التالية:

دعونا نلقي نظرة على هذه التغييرات بمزيد من التفصيل.

إصدارات واجهات برمجة التطبيقات الفرعية

تقدّم Merchant API مفهومَي تحديد الإصدارات وواجهات برمجة التطبيقات الفرعية. يحسّن التصميم المعياري سهولة الاستخدام، إذ يتيح لك التركيز على واجهات برمجة التطبيقات الفرعية التي تحتاج إليها، كما يسهّل عمليات نقل البيانات المستقبلية إلى الإصدارات الأحدث. سيتم تطبيق تحديد الإصدار مع عناوين URL للطلبات، والاستراتيجية مشابهة لتجربة Google Ads API.

طلبات أكثر فعالية

تتطلّب طلبات عناوين URL من Merchant API المزيد من المَعلمات لاستدعاء Merchant API. ويشمل ذلك المورد والإصدار والاسم (المعرّفات) والطريقة (الطرق غير العادية). لمزيد من المعلومات حول هذا الموضوع، يُرجى الاطّلاع على معرّفات الحسابات والمنتجات والأمثلة.

مبادئ AIP للمعرفات

في حين أنّ Content API for Shopping تستخدم المعرّفات لتحديد الموارد (على سبيل المثال، merchantId، productId)، تستخدم Merchant API معرّفًا name للتوافق مع AIP (اطّلِع على مبادئ تحسين واجهة برمجة التطبيقات).

يتضمّن المعرّف {name} معرّف المورد والعنصر الرئيسي (أو ربما عدة عناصر رئيسية)، بحيث يكون {name} مساويًا accounts/{account}/products/{product}

تعرض جميع طلبات القراءة والكتابة الحقل name كمعرّف للمورد.

يتضمّن {name} أيضًا معرّفَي المجموعة accounts/ وproducts/.

تستخدِم Merchant API {account} للإشارة إلى معرّف Merchant Center و{product} للإشارة إلى معرّفات المنتجات.

على سبيل المثال، نفِّذ طريقة getName() لاسترداد name من أحد الموارد، وخزِّن الناتج كمتغيّر بدلاً من إنشاء name بنفسك من أرقام تعريف التاجر والمورد.

في ما يلي مثال على كيفية استخدام الحقل name في مكالماتك:

   POST https://merchantapi.googleapis.com/inventories/v1/{PARENT}/regionalInventories:insert

يوضّح الجدول كيف يتغيّر طلب products.get في Content API for Shopping:

واجهة برمجة تطبيقات المحتوى في Shopping Merchant API
GET https://shoppingcontent.googleapis.com/content/v2.1/{merchantId}/products/{productId} GET https://merchantapi.googleapis.com/products/v1/{name}

لمزيد من التفاصيل، يُرجى مراجعة تغييرات المعرّف.

كمثال آخر، سيبدو استرداد منتج بالمعرّف en~US~1234 من معرّف Merchant Center 4321 باستخدام Merchant API على النحو التالي:

    GET
    https://merchantapi.googleapis.com/products/v1/accounts/4321/products/online~en~US~1234

حيث {name} يساوي accounts/4321/products/en~US~1234. يتم عرض حقل الاسم الجديد هذا كمعرّف المورد لجميع طلبات القراءة والكتابة في Merchant API.

في Content API for Shopping، تشير النقطتان الرأسيتان (:) إلى فاصل في اسم المنتج، بينما تؤدي علامة التلدة (~) هذه الوظيفة في Merchant API. لا يتضمّن معرّف Merchant API الجزء channel.

على سبيل المثال، معرّف المنتج في Content API for Shopping:

channel:contentLanguage:feedLabel:offerId.

في Merchant API، يصبح ما يلي:

contentLanguage~feedLabel~offerId.

الحقول الرئيسية لموارد الأطفال

في Merchant API، تحتوي جميع الموارد الفرعية على الحقل parent. يمكنك استخدام الحقل parent لتحديد {name} المورد الذي سيتم إدراج المورد الفرعي فيه، بدلاً من تمرير المورد الرئيسي بأكمله. يمكنك أيضًا استخدام حقل parent مع list.

على سبيل المثال، لإدراج مستودعات المنتجات المحلية لمنتج معيّن، حدِّد name الخاص بالمنتج في الحقل parent للطريقة list. في هذه الحالة، يكون product هو parent لموارد LocalInventory التي تم عرضها.

    GET
    https://merchantapi.googleapis.com/inventories/v1/{parent}/localInventories

لاسترداد جميع المستودعات المحلية للمنتج en~US~1234' والحساب 4321، سيكون الطلب على النحو التالي:

    GET
    https://merchantapi.googleapis.com/inventories/v1/accounts/4321/products/online~en~US~1234/localInventories</code>

الوالد هو accounts/{account}/products/{product}. يُرجى العِلم أنّه في هذه الحالة، يتضمّن المرجع localInventories مرجعَين رئيسيَّين مضمّنَين في معرّف الاسم (accounts/ وproducts/)، لأنّ الحساب هو المرجع الرئيسي لمورد المنتج.

تعدادات مشتركة

يوفّر استخدام التعدادات الشائعة المزيد من الاتساق.

يحدّد الحقل Destination.DestinationEnum مساحات العرض التي سيتم عرض المراجع عليها. تعرض DestinationEnum جميع القيم المتاحة لاستهداف الوجهات، وهي موحّدة في جميع واجهات برمجة التطبيقات الفرعية، مثل سمات العروض الترويجية.

يمثّل الحقل ReportingContext.ReportingContextEnum السياق الذي تنطبق عليه المشاكل في حسابك ومنتجاتك. يُستخدَم هذا الحقل في جميع طرق إعداد التقارير (على سبيل المثال، في IssueSeverityPerReportingContext).

التوافق مع الإصدارات السابقة

عند بدء استخدام Merchant API، سيستمر عمل عملية الدمج الحالية مع Content API for Shopping بدون انقطاع. لمزيد من المعلومات، راجِع التوافق.

بعد نقل واجهات برمجة التطبيقات الفرعية إلى Merchant API، ننصحك باستخدام Merchant API فقط لواجهات برمجة التطبيقات الفرعية التي تم نقلها.

مدى توفّر استدعاء الإجراء عن بُعد (gRPC)

gRPC هي الطريقة الجديدة التي ننصح بها لدمج واجهة Merchant API.

تشمل مزاياها ما يلي:

تصبح عملية تجميع الدفعات المخصّصة عملية تجميع دفعات مضمّنة

تعمل عملية تجميع البيانات بكفاءة أكبر عند استخدام طلبات غير متزامنة. مزيد من المعلومات حول استخدام طلبات متوازية لتحقيق التجميع في Merchant API وكيفية إعادة تصميم الرمز البرمجي للطلبات المتزامنة

للمساعدة في تسريع عملية نقل البيانات، ننصحك باستخدام مكتبات البرامج للعملاء.

لا تتوافق Merchant API مع طريقة customBatch المضمّنة في Content API for Shopping. بدلاً من ذلك، يمكنك الاطّلاع على إرسال طلبات متعددة في آن واحد أو تنفيذ عمليات طلب البيانات بشكل غير متزامن.

يوضّح نموذج Java التالي كيفية إدراج إدخال منتج.

   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.v1.Availability;
import com.google.shopping.merchant.products.v1.Condition;
import com.google.shopping.merchant.products.v1.InsertProductInputRequest;
import com.google.shopping.merchant.products.v1.ProductAttributes;
import com.google.shopping.merchant.products.v1.ProductInput;
import com.google.shopping.merchant.products.v1.ProductInputsServiceClient;
import com.google.shopping.merchant.products.v1.ProductInputsServiceSettings;
import com.google.shopping.merchant.products.v1.Shipping;
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();

    ProductAttributes attributes =
        ProductAttributes.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(Availability.IN_STOCK)
            .setCondition(Condition.NEW)
            .setGoogleProductCategory("Media > Books")
            .addGtins("9780007350896")
            .addShipping(shipping)
            .addShipping(shipping2)
            .build();

    return ProductInput.newBuilder()
        .setContentLanguage("en")
        .setFeedLabel("CH")
        .setOfferId(generateRandomString())
        .setProductAttributes(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 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);
  }
}

إذا كنت تستخدم customBatch في Content API، وتحتاج إلى هذه الميزة في Merchant API، يُرجى إخبارنا بالسبب في ملاحظاتك.

الميزات الحصرية

لن تظهر الميزات المستقبلية إلا في Merchant API. (ستكون هناك بعض الاستثناءات، مثل مواصفات خلاصة 2025 السنوية).

تشمل الميزات الحصرية في Merchant API ما يلي:

  • Reviews API استخدِم "المراجعات" لتنفيذ تقييمات المنتجات والمتاجر وإدارتها. لمزيد من المعلومات، اطّلِع على مراجعة البائع ومراجعة المنتج.
  • الإشعارات: يمكنك الاشتراك لتلقّي إشعارات فورية بشأن التغييرات التي تطرأ على بيانات المنتجات في الحساب.

السعر

في ما يلي التغييرات التي أجريناها على Price في حزمة Merchant Common:

واجهة برمجة تطبيقات المحتوى في Shopping Merchant API
حقل المبلغ value:string amountMicros:int64
حقل العملة currency:string currencyCode:string

يتم الآن تسجيل مبلغ Price بوحدات ميكرو، حيث إنّ مليون وحدة ميكرو تعادل الوحدة العادية لعملتك.

في Content API for Shopping، كان Price عبارة عن رقم عشري على شكل سلسلة.

تم تغيير اسم حقل المبلغ من value إلى amountMicros

تم تغيير اسم حقل العملة من currency إلى currencyCode. يبقى التنسيق ISO 4217.

آخر الأخبار والإشعارات

للحصول على تحديثات أكثر تفصيلاً، اطّلِع على ملاحظات الإصدار الخاصة بكل واجهة برمجة تطبيقات فرعية. للاطّلاع على المزيد من التحديثات المجمّعة المنتظمة حول Merchant API، راجِع آخر التحديثات.

للحصول على مزيد من التفاصيل المحدّدة ومعرفة المزيد عن Merchant API، يمكنك الاطّلاع على نظرة عامة على موقع المطوّرين ودليل نقل البيانات بشكل عام.

اطّلِع على تصميم Merchant API للحصول على تفاصيل حول Merchant API وواجهات برمجة التطبيقات الفرعية.