نقل البيانات إلى الإصدار 6 من Google Play Billing Library من الإصدار 4 أو 5

يوضّح هذا الموضوع كيفية نقل البيانات من الإصدار 4 أو 5 من Google Play Billing Library إلى الإصدار 6 من Google Play Billing Library وكيفية استخدام إمكانات الاشتراك الجديدة

للحصول على قائمة كاملة بالتغييرات في الإصدار 6.0.0، يمكنك الرجوع إلى الإصدار الملاحظات.

نظرة عامة

تعتمد Google Play Billing Library 6 على ميزات الاشتراك الجديدة التي تم تقديمها في الإصدار 5 وإضافة المزيد من التحسينات. تتيح لك هذه الميزات بيع والاشتراكات بطرق أكثر، ما يقلّل من التكاليف التشغيلية من خلال التخلّص من الحاجة لإنشاء وإدارة عدد يتزايد باستمرار من رموز التخزين التعريفية.

لمزيد من المعلومات حول الميزات الجديدة المقدَّمة في "مكتبة الفوترة في Play" 5، يمكنك الاطّلاع على التغييرات الأخيرة على الاشتراكات في Play. Console.

ترقية متوافقة مع الإصدارات القديمة من Play Billing Library

تم تلقائيًا تحويل جميع المنتجات المتوفّرة عند الاشتراك إلى هذه الحزمة الجديدة. كجزء من الإصدار 5 من Play Billing Library الذي تم طرحه في أيار (مايو) 2022 للاشتراكات. وهذا يعني أنّك لست مضطرًا لإجراء أي اشتراك. تغييرات إعدادات المنتج للحصول على كتالوج متوافق مع إصدارات Play Billing Library. لمزيد من المعلومات حول كيفية الاستفادة من مزايا الاشتراك تم تحويل رموز التخزين التعريفية إلى اشتراكات متوافقة مع الأنظمة القديمة. راجِع القسم قيد العمل مع الاشتراكات القديمة في قسم مساعدة Play Console .

لا تزال الإصدارات القديمة من تطبيقك تعمل

في حال كان لديك كتالوج اشتراكات متوافق مع الإصدارات القديمة، ستظهر جميع الإصدارات الحالية يجب أن يعمل تطبيقك على النحو المنشود لتلك المنتجات. منتج يتم تحصيل سعره مرة واحدة عمليات الشراء أن تستمر في العمل دون مشكلات في الإصدارات القديمة.

إصدارات تطبيقك التي تستخدم طرقًا متوقّفة نهائيًا (مثل querySkuDetailsAsync()) لن يتمكّنوا من بيع أي خطط أساسية أو عروض غير متأخرة متوافقة. يمكنك الاطّلاع على العروض المتوافقة مع الأنظمة القديمة في دليل Play مركز مساعدة Console المقالة.

الترقية إلى الإصدار 5 أو 6 من Play Billing Library

الإصداران 5 و6 من Play Billing Library يتضمّنان الطرق المتوقّفة نهائيًا querySkuDetailsAsync وBillingFlowParams.Builder.setSkuDetails الذي يأخذ SkuDetails على أنّه فوترة مَعلمة التدفق. يعني ذلك أنّه يمكنك الانتقال تدريجيًا إلى الإصدار 6 من Play Billing Library. من خلال التخطيط لمراحل مختلفة من الترحيل.

كخطوة أولى لنقل البيانات، يمكنك تحديث المكتبة الإصدار، واترك الكتالوج والخلفية كما هي واختبِر تطبيقك مع استمراره في استخدام الطرق المتوقّفة. في حال عدم استخدام queryPurchases أو launchPriceChangeFlow أو setVrPurchaseFlow، من المفترض أن لا يزال يعمل على النحو المنشود. وبعد ذلك، يمكنك التكرار للاستفادة بشكل كامل من طريقة التي تم إطلاقها في أيار (مايو) 2022.

إذا سبق لك استخدام هذه الميزات مع Google Play Billing Library 5، يمكنك المتابعة مباشرةً إلى الأقسام المسماة تحديث Google Play Billing Library وتغيير اشتراك المستخدم عمليات الشراء. إذا كنت تبدأ من إصدار سابق أو لم تستخدم الميزات الجديدة بالكامل بعد، يمكنك الاطلاع على نقل البيانات بالكامل الخطوات التالية لمعرفة كيفية تطبيقها.

خطوات نقل البيانات الكاملة

إنشاء اشتراكات جديدة في كتالوج منتجات الخلفية

باستخدام Play Console أو واجهة برمجة التطبيقات Play Developer API، يمكنك الآن إعداد اشتراك واحد يتضمّن عدة خطط أساسية، لكلّ منها عدة خطط على مستوى خدمات Google. تشمل عروض الاشتراك نماذج أسعار مرنة وخيارات أهلية. يمكنك إنشاء عروض على مدار فترة الاشتراك باستخدام مجموعة متنوعة من للتجديد التلقائي وخطط الدفع المسبق.

نوصي بإنشاء منتجات جديدة وفقًا لبنية الكيان في الإصدار الجديد منصة للاشتراكات لدمج واجهة برمجة التطبيقات Play Billing Library 6 قبل نقل تطبيقك. يمكنك دمج المنتجات المتكرّرة في الكتالوج القديم. تمثّل مزايا الاستخدام نفسها ضمن اشتراك واحد والاستخدام إعدادات الخطة الأساسية والعروض الترويجية لتمثيل جميع الخيارات المطلوبة لتقديمها. لمزيد من المعلومات عن هذا الاقتراح، يمكنك الاطّلاع على مقالة العمل مع الاشتراكات القديمة في قسم مساعدة Play Console .

ننصح بعدم تعديل المنتجات المتوفّرة من خلال الاشتراك المحوَّلة بعد إصدار مايو 2022: فيجب أن تتركها كما هي تُباع مع نُسخ تطبيقك باستخدام طرق متوقّفة نهائيًا (مثل querySkuDetailsAsync()) بدون إدخال تغييرات أن تؤثر على هذه الإصدارات القديمة.

أدّت عملية التحويل إلى إنشاء المنتجات المتوفّرة عند الاشتراك في الكتالوج الخاص بك. قبل أيار (مايو) 2022 للقراءة فقط لتجنُّب التغييرات غير المقصودة التي قد تؤدي إلى مشاكل متعلقة بعملية الدمج الحالية. إنّ إجراء تغييرات على هذه الاشتراكات ولكن قد تكون هناك آثار قد تؤثر على واجهتك الأمامية عمليات الدمج في الخلفية:

  • في الواجهة الأمامية، تحتاج إصدارات التطبيق التي تستخدم querySkuDetailsAsync() إلى يمكن فقط بيع تفاصيل المنتجات المتوفّرة عند الاشتراك للخطط الأساسية المتوافقة مع الإصدارات القديمة. والعروض، ولا يمكن أن يكون هناك سوى خطة أساسية واحدة وعرض واحد لذلك إذا أضفت خططًا أو عروضًا جديدة إلى الاشتراكات المحوَّلة لن تتمكّن من بيع الخطط الأساسية أو العروض الأساسية الإضافية الجديدة في هذه من تطبيقك.

  • في الخلفية، إذا عدّلت اشتراكاتك المحوَّلة في واجهة مستخدم Play Console، لن تتمكّن من إدارتها باستخدام inappproducts نقطة نهاية، إذا كنت تستدعي نقطة النهاية لهذا الغرض. يجب عليك أيضًا نقل البيانات إلى نقطة النهاية الجديدة لحالة شراء الاشتراك (purchases.subscriptionsv2.get) لإدارة عمليات الشراء لهذه الاشتراكات، لأنّ نقطة النهاية القديمة لحالة الشراء (purchases.subscriptions.get) لا تعرض سوى البيانات اللازمة للتعامل مع الخطط الأساسية والعروض المتوافقة مع الأنظمة القديمة عمليات الشراء. الاطّلاع على مقالة إدارة حالة شراء الاشتراك للحصول على المزيد من المعلومات.

إدارة قائمة الاشتراكات في الخلفية باستخدام واجهة برمجة التطبيقات الجديدة

إذا كنت تدير كتالوج المنتجات المتوفّرة عند الاشتراك تلقائيًا من خلال واجهة Google Play Developer API، وعليك استخدام المنتج الجديد المتوفّر عند الاشتراك لنقاط النهاية للتعريف لإنشاء الاشتراكات والخطط الأساسية والعروض وإدارتها. اطّلِع على ميزات الاشتراك في أيار (مايو) 2022 الدليل للاطّلاع على مزيد من المعلومات حول التغييرات في واجهة برمجة التطبيقات لكتالوج المنتجات في هذا الإصدار.

لنقل وحدة إدارة كتالوج المنتجات تلقائيًا اشتراكات "الفوترة في Google Play"، بدلاً من inappproducts واجهة برمجة تطبيقات مع واجهة برمجة التطبيقات Subscription Publishing API الجديدة وإدارتها ونشرها قائمة الاشتراكات الخاصة بك هناك ثلاث نقاط نهاية جديدة:

وتتمتع نقاط النهاية الجديدة هذه بجميع الوظائف اللازمة للاستفادة من جميع إمكانات جديدة في قائمتك، مثل علامات الخطة الأساسية والعروض، والاستهداف الإقليمي، وخطط الدفع المسبق والمزيد.

لا يزال يتعين عليك استخدام inappproducts واجهة برمجة تطبيقات لإدارة كتالوج المنتجات داخل التطبيق للمنتجات التي يتم شراؤها لمرة واحدة

لن تتمكّن إصدارات تطبيقك التي تستخدم طُرقًا متوقفة نهائيًا (مثل querySkuDetailsAsync()) من بيع أي خطط أساسية أو عروض غير متوافقة مع الإصدارات القديمة. يمكنك الاطّلاع على العروض المتوافقة مع الأنظمة القديمة هنا.

تعديل Google Play Billing Library

بعد إنشاء كتالوج جديد للمنتجات المتوفّرة عند الاشتراك يمكنك نقل تطبيقك إلى الإصدار 5 من Google Billing Library استبدال القائمة الحالية يمكن الاعتماد على Play Billing Library مع الإصدار المحدَّث من ملف build.gradle لتطبيقك.

dependencies {
    def billingVersion = "6.0.0"

    implementation "com.android.billingclient:billing:$billingVersion"
}

يجب أن يتم إنشاء مشروعك على الفور، حتى إذا لم تكن قد عدّلت أي مكالمات الطرق: يتوافق الإصدار 6 من Play Billing Library مع الإصدارات القديمة. يعد مفهوم رمز التخزين التعريفي تُعد متوقّفة نهائيًا، ولكنها لا تزال موجودة لجعل نقل التطبيقات أكثر بساطة عملية متزايدة.

إعداد عميل الفوترة والاتصال بـ Google Play

تظل الخطوات الأولى لإطلاق عمليات الشراء من تطبيق Android كما هي:

عرض المنتجات المتوفّرة للشراء

للاستفادة من جميع العروض التي يكون المستخدم مؤهَّلاً لشرائها، يُرجى اتّباع الخطوات التالية:

  • استبدال SkuDetailsParams بـ QueryProductDetailsParams
  • تبديل مكالمة "BillingClient.querySkuDetailsAsync()" لاستخدام BillingClient.queryProductDetailsAsync()

يُرجى العلم أنّ نتائج طلب البحث أصبحت الآن ProductDetails بدلاً من SkuDetails. تحتوي كل سلعة ProductDetails على معلومات عن المنتج (المعرّف والعنوان والنوع وما إلى ذلك). بالنسبة إلى المنتجات المتوفّرة عند الاشتراك، ProductDetails يحتوي على List<ProductDetails.SubscriptionOfferDetails>، وهو قائمة بتفاصيل عرض الاشتراك. بالنسبة إلى المنتجات التي يتم شراؤها لمرة واحدة، يحتوي ProductDetails على ProductDetails.OneTimePurchaseOfferDetails. هذه لتحديد العروض التي ستُعرض للمستخدمين

يوضح المثال التالي الشكل الذي قد يبدو عليه تطبيقك قبل وبعد إجراء هذه التغييرات:

قبل

Kotlin

val skuList = ArrayList<String>()

skuList.add("up_basic_sub")

val params = SkuDetailsParams.newBuilder()

params.setSkusList(skuList).setType(BillingClient.SkuType.SUBS).build()

billingClient.querySkuDetailsAsync(params) {
    billingResult,
    skuDetailsList ->
    // Process the result
}

Java

List<String> skuList = new ArrayList<>();

skuList.add("up_basic_sub");

SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();

params.setSkusList(skuList).setType(SkuType.SUBS).build();

billingClient.querySkuDetailsAsync(params,
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(BillingResult billingResult,
                List<SkuDetails> skuDetailsList) {
            // Process the result.
        }
    }
);

بعد

Kotlin

val productList =
    listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("up_basic_sub")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )

val params = QueryProductDetailsParams.newBuilder().setProductList(productList).build()

billingClient.queryProductDetailsAsync(params) {
    billingResult,
    productDetailsList ->
    // Process the result
}

Java

ImmutableList<Product> productList = ImmutableList.of(Product.newBuilder()
                                            .setProductId("up_basic_sub")
                                            .setProductType(ProductType.SUBS)
                                            .build());

QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
    .setProductList(productList)
    .build();

billingClient.queryProductDetailsAsync(
        params,
        new ProductDetailsResponseListener() {
                public void onProductDetailsResponse(BillingResult billingResult, List<ProductDetails> productDetailsList) {
                    // Process the result
                }
        }
);

يعرض استدعاء queryProductDetailsAsync دالة List<ProductDetails>. تحتوي كل سلعة ProductDetails على معلومات عن المنتج (المعرّف والعنوان والنوع وما إلى ذلك). الفرق الرئيسي هو أنّ الاشتراك تحتوي المنتجات الآن أيضًا على List<ProductDetails.SubscriptionOfferDetails> يتضمّن جميع العروض المتوفّرة للمستخدم

بما أنّ الإصدارات السابقة من Play Billing Library لا تتوافق مع الإصدار الجديد (الاشتراكات والخطط الأساسية والعروض وما إلى ذلك)، سيوفر النظام الجديد تحوِّل كل رمز تخزين تعريفي للاشتراك إلى رمز تخزين تعريفي واحد متوافق مع الأنظمة القديمة الخطة الأساسية والعرض. المنتجات المتاحة التي يتم شراؤها لمرة واحدة هي أيضًا تم النقل إلى عنصر ProductDetails. تفاصيل العرض لمرة واحدة شراء منتج يمكن الوصول إليه من خلال طريقة getOneTimePurchaseOfferDetails().

في حالات نادرة، لا تتوافق بعض الأجهزة مع ProductDetails وqueryProductDetailsAsync()، وهذا عادة بسبب إصدارات قديمة من خدمات Google Play: للتأكد الدعم المناسب لهذا السيناريو، اتصل isFeatureSupported() لـ PRODUCT_DETAILS قبل الاتصال بـ queryProductDetailsAsync. إذا كان الرد OK، إذا كان الجهاز متوافقًا مع هذه الميزة، يمكنك مواصلة الاتصال بالرقم queryProductDetailsAsync(). إذا كان الردّ FEATURE_NOT_SUPPORTED، يمكنك بدلاً من ذلك طلب قائمة المنتجات المتاحة المتوافقة مع الأنظمة القديمة querySkuDetailsAsync() مزيد من المعلومات حول كيفية استخدام التوافق مع الأنظمة القديمة يُرجى مراجعة دليل ميزات الاشتراك لشهر أيار (مايو) 2022.

بدء مسار شراء العرض

يشبه بدء تدفق شراء للعرض إلى حد كبير إطلاق تدفق لرمز التخزين التعريفي. لبدء طلب شراء باستخدام الإصدار 6، يُرجى اتّباع الخطوات التالية:

  • بدلاً من استخدام السمة SkuDetails لـ BillingFlowParams، استخدام ProductDetailsParams.
  • يمكن الحصول على تفاصيل العروض، مثل معرّف العرض ومعرّف الخطة الأساسية وغيرها، باستخدام "SubscriptionOfferDetails". الخاص بك.

لشراء منتج باستخدام العرض الذي اختاره المستخدم، يجب الحصول على offerToken للعرض المحدد وتمريره إلى العنصر ProductDetailsParams.

بعد إنشاء عنصر "BillingFlowParams"، سيتم بدء مسار الفوترة. لن تتغيّر قيمة بطاقة BillingClient.

يوضح المثال التالي الشكل الذي قد يبدو عليه تطبيقك قبل وبعد إجراء هذه التغييرات:

قبل

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...
// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
val billingFlowParams = BillingFlowParams.newBuilder()
                            .setSkuDetails(skuDetails)
                            .build()

val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

Java

// An activity reference from which the billing flow will be launched.
Activity activity = ...;
// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)
        .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

بعد

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;

val productDetailsParamsList = listOf(
    BillingFlowParams.ProductDetailsParams.newBuilder()
        // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
        .setProductDetails(productDetails)
        // For One-time product, "setOfferToken" method shouldn't be called.
        // For subscriptions, to get the offer token corresponding to the selected
        // offer call productDetails.subscriptionOfferDetails?.get(selectedOfferIndex)?.offerToken
        .setOfferToken(selectedOfferToken)
        .build()
)

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build()

// Launch the billing flow
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

Java

// An activity reference from which the billing flow will be launched.
Activity activity = ...;

ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
             // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // For one-time products, "setOfferToken" method shouldn't be called.
            // For subscriptions, to get the offer token corresponding to the selected
            // offer call productDetails.getSubscriptionOfferDetails().get(selectedOfferIndex).getOfferToken()
            .setOfferToken(selectedOfferToken)
            .build()
    );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

معالجة عمليات الشراء

جارٍ معالجة عمليات الشراء باستخدام الإصدار 6 من Google Play Billing Library إلى الإصدارات السابقة.

سحب جميع عمليات الشراء النشطة التي يملكها المستخدم وطلب منتجات جديدة عمليات الشراء، قم بما يلي:

  • بدلاً من تمرير قيمة BillingClient.SkuType إلى queryPurchasesAsync()، تمرير كائن QueryPurchasesParams الذي يحتوي على القيمة BillingClient.ProductType.

يوضح المثال التالي كيف قد يبدو تطبيقك من قبل بعد إجراء هذه التغييرات:

قبل

Kotlin

billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS) {
    billingResult,
    purchaseList -> {
        // Process the result
    }
}

Java

billingClient.queryPurchasesAsync(
    BillingClient.SkuType.SUBS,
    new PurchasesResponseListener() {
        public void onQueryPurchasesResponse(
                BillingResult billingResult,
                ListP<urchase >purchases) {
            // process the result
        }
    }
);

بعد

Kotlin

billingClient.queryPurchasesAsync(
    QueryPurchasesParams.newBuilder()
        .setProductType(BillingClient.ProductType.SUBS)
        .build()
) { billingResult, purchaseList ->
    // Process the result
}

Java

billingClient.queryPurchasesAsync(
    QueryPurchasesParams.newBuilder().setProductType(ProductType.SUBS).build(),
    new PurchasesResponseListener() {
        public void onQueryPurchasesResponse(
                BillingResult billingResult,
                List<Purchase> purchases) {
            // Process the result
        }
    }
);

خطوات إدارة عمليات الشراء خارج التطبيق والمعاملات المعلّقة لم تتغير.

إدارة حالة شراء الاشتراك باستخدام واجهة برمجة التطبيقات الجديدة في الخلفية

عليك نقل مكوّن إدارة حالة شراء الاشتراكات. في الخلفية حتى يكونوا مستعدين للتعامل مع عمليات شراء المنتجات الجديدة التي تم إنشاؤها في الخطوات السابقة. إدارة حالة شراء اشتراكاتك الحالية على النحو المعتاد مع المنتجات المتوفّرة عند الاشتراك المحوَّلة والتي المحدد قبل إطلاق أيار (مايو) 2022، وينبغي أن تكفي إدارة عمليات الشراء من العروض المتوافقة مع الأنظمة القديمة، غير أنّها لا توفّر أيًا من الوظائف الجديدة

عليك تطبيق Subscription Purchases API الجديدة في وحدة إدارة حالة شراء الاشتراكات التي تتحقق من عملية الشراء حالة وإدارة استحقاقات اشتراك "الفوترة في Play" في الخلفية. لا يعرض الإصدار القديم من واجهة برمجة التطبيقات جميع التفاصيل اللازمة لإدارتها عمليات الشراء في المنصة الجديدة. للحصول على تفاصيل حول التغييرات من الإصدارات السابقة، يُرجى مراجعة دليل ميزات الاشتراك الجديدة لشهر أيار (مايو) 2022.

عليك عادةً استدعاء واجهة برمجة التطبيقات Subscription Purchases API في كل مرة تتلقّى فيها SubscriptionNotification إشعار في الوقت الفعلي خاصة بالمطوّرين لجذب أحدث المعلومات حول حالة الاشتراك. يجب استبدال مكالمات إلى purchases.subscriptions.get باستخدام الإصدار الجديد من Subscription Purchases API purchases.subscriptionsv2.get هناك مورد جديد يسمى SubscriptionPurchaseV2 يوفر ما يكفي معلومات لإدارة إذن الشراء للاشتراكات في النموذج الجديد.

تعرض نقطة النهاية الجديدة هذه حالة جميع المنتجات المتوفّرة عند الاشتراك جميع عمليات الشراء، بغض النظر عن إصدار التطبيق الذي تم بيعها ووقت تعريف المنتج (قبل إصدار مايو 2022 أو بعده) لذا، لن تحتاج سوى إلى هذا الإصدار من اشتراكك بعد النقل وحدة إدارة حالة الشراء

تغيير عمليات شراء اشتراكات المستخدم

في الإصدار 5 من Play Billing Library والإصدارات الأقدم، ProrationMode تم استخدامها لتطبيق تغييرات على عمليات شراء اشتراكات المستخدم، مثل الترقيات أو الرجوع إلى إصدار سابق. تم إيقافها واستبدالها ReplacementMode في الإصدار 6.

التعامل مع التغييرات في أسعار الاشتراكات

لقد تمت إزالة واجهة برمجة تطبيقات launchPriceConfirmationFlow التي سبق أن تم إيقافها نهائيًا في Play Billing Library 6. للحصول على خيارات بديلة، يمكنك الاطّلاع على تغييرات الأسعار. الدليل.

التعامل مع أخطاء Play Billing Library

في الإصدار 6 من Play Billing Library، تمت إضافة رمز NETWORK_ERROR جديد للإشارة إلى: المشكلات في الاتصال بالشبكة بين جهاز المستخدم وحساب Google نظام التشغيل حدثت أيضًا تغييرات على الرموز SERVICE_TIMEOUT SERVICE_UNAVAILABLE لمزيد من المعلومات، يُرجى الاطّلاع على التعامل مع الرد الخاص بـ BillingResult. الرموز البرمجية.

التعامل مع المعاملات غير المكتملة

لن تنشئ Play Billing Library أي طلب بدءًا من الإصدار 6.0.0. رقم تعريف عمليات الشراء المعلّقة بالنسبة إلى عمليات الشراء هذه، تتم تعبئة مُعرّف الطلب بعد يتم نقل عملية الشراء إلى PURCHASED الولاية. تأكَّد من أنّ عملية الدمج لا تتوقّع مُعرّف الطلب إلا بعد اكتملت المعاملة بالكامل. لا يزال بإمكانك استخدام الرمز المميّز للشراء السجلات. لمزيد من المعلومات حول التعامل مع عمليات الشراء المعلَّقة، يُرجى الاطّلاع على صفحة Play. دليل دمج مكتبة الفوترة دليل إدارة مراحل نشاط الشراء