إضافة عروض الطلب المُسبَق للمنتجات التي يتم تحصيل سعرها مرة واحدة

1. مقدمة

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

ملاحظة: قبل البدء في هذا الدرس التطبيقي حول الترميز، عليك طلب الوصول إلى ميزة "الطلب المُسبَق" من خلال ملء نموذج إبداء الاهتمام ببرنامج استخدام المنتج قبل إطلاقه (EAP) للمنتجات التي يتم تحصيل سعرها مرة واحدة.

الجمهور

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

المتطلّبات الأساسية

إذا كنت جديدًا على المنتجات التي يتم تحصيل سعرها مرة واحدة، ننصحك بإكمال درس Unlock new markets with regional product pricing تطبيقي حول الترميز.

ما ستتعلمه...

  • كيفية استخدام Google Play Console لإنشاء عروض الطلب المُسبَق لمنتجاتك التي تُباع لمرة واحدة
  • كيفية استخدام واجهات برمجة التطبيقات في مكتبة الفوترة في Play للاستعلام عن المنتجات التي يتم تحصيل سعرها مرة واحدة وتفاصيل عرض الطلب المُسبق المقابل

المتطلبات...

2. إنشاء نموذج التطبيق

يستخدم هذا الدرس التطبيقي حول الترميز نموذجًا لتطبيق Android لتعليمك كيفية إدارة المنتجات التي يتم شراؤها لمرة واحدة. تم تصميم نموذج التطبيق ليكون تطبيق Android يعمل بكامل وظائفه ويتضمّن الرمز المصدر الكامل الذي يعرض الجوانب التالية:

  • دمج التطبيق مع PBL
  • استرداد المنتجات التي يتم تحصيل سعرها مرة واحدة وعروض الطلب المُسبق ذات الصلة
  • تنفيذ عمليات الشراء بالأسعار المحدّدة على مستوى منطقة معيّنة

يوضّح الفيديو التجريبي التالي كيف سيبدو نموذج التطبيق وكيف سيتصرف بعد نشره وتشغيله.

إذا كنت على دراية بالمنتجات التي يتم تحصيل سعرها مرة واحدة وواجهة برمجة التطبيقات Play Billing Library (PBL)، يمكنك تنزيل التطبيق النموذجي واستخدامه.

المتطلّبات الأساسية

قبل إنشاء نموذج التطبيق ونشره، عليك تنفيذ ما يلي:

إنشاء

الهدف من خطوة الإنشاء هذه هو إنشاء ملف حزمة تطبيق Android مُوقَّع للتطبيق النموذجي.

لإنشاء حِزمة تطبيق Android، اتّبِع الخطوات التالية:

  1. نزِّل نموذج التطبيق من GitHub.
  2. إنشاء نموذج التطبيق: قبل الإنشاء، غيِّر اسم حزمة نموذج التطبيق ثم أنشئه. إذا كانت لديك حِزم لتطبيقات أخرى في Play Console، تأكَّد من أنّ اسم الحزمة الذي تقدّمه لنموذج التطبيق فريد.

    ملاحظة: يؤدي إنشاء نموذج التطبيق إلى إنشاء ملف APK فقط يمكنك استخدامه للاختبار المحلي. ومع ذلك، لا يؤدي تشغيل التطبيق إلى جلب المنتجات والأسعار لأنّه لم يتم إعداد المنتجات في Play Console.
  3. أنشِئ حزمة تطبيقات Android موقَّعة.
    1. إنشاء مفتاح تحميل وملف تخزين مفاتيح
    2. توقيع تطبيقك باستخدام مفتاح التحميل
    3. ضبط ميزة "توقيع التطبيق" من Play

الخطوة التالية هي تحميل حِزمة تطبيق Android إلى Google Play Console.

3- إنشاء كلمة مرور صالحة لمرة واحدة (OTP) مع الطلب المُسبَق في Play Console

لإنشاء منتجات يتم تحصيل سعرها مرة واحدة في Google Play Console، يجب أن يكون لديك تطبيق في Play Console. أنشئ تطبيقًا في Play Console، ثم حمِّل حزمة التطبيق الموقَّعة التي تم إنشاؤها سابقًا.

إنشاء تطبيق

لإنشاء تطبيق، اتّبِع الخطوات التالية:

  1. سجِّل الدخول إلى Google Play Console باستخدام حساب المطوِّر.
  2. انقر على إنشاء تطبيق. سيؤدي ذلك إلى فتح صفحة إنشاء تطبيق.
  3. أدخِل اسم التطبيق واختَر اللغة التلقائية وتفاصيل أخرى ذات صلة بالتطبيق.
  4. انقر على إنشاء تطبيق، ما يؤدي إلى إنشاء تطبيق في Google Play Console.

يمكنك الآن تحميل حِزمة نموذج تطبيق العيّنة الموقَّعة.

تحميل حِزمة التطبيق الموقَّعة

  1. حمِّل حِزمة التطبيق الموقَّعة إلى مسار الاختبار الداخلي في Google Play Console. بعد التحميل فقط، يمكنك ضبط الميزات ذات الصلة بتحقيق الربح في Play Console.
    1. انقر على الاختبار والإصدار > الاختبار > الإصدار الداخلي > إنشاء إصدار جديد.
    2. أدخِل اسم إصدار وحمِّل ملف APK الموقَّع.
    3. انقر على التالي، ثمّ انقر على حفظ ونشر.

يمكنك الآن إنشاء المنتجات التي يتم تحصيل رسومها لمرة واحدة.

إنشاء منتج يتم تحصيل سعره مرة واحدة

الآن، أنشِئ المنتج الذي يتم تحصيل سعره مرة واحدة والذي تريد أن يشتريه المستخدمون.

  1. افتح التطبيق النموذجي في Google Play Console، وانتقِل إلى تحقيق الربح من خلال Play > المنتجات > المنتجات التي يتم تحصيل سعرها مرة واحدة.
  2. انقر على إنشاء منتج يتم تحصيل سعره مرة واحدة.
  3. أدخِل تفاصيل المنتج التالية:
    • معرّف المنتج: أدخِل معرّفًا فريدًا. مثلاً: upcoming_movie_1
    • (اختياري) العلامات: أضِف علامات ذات صلة.
    • الاسم: أدخِل اسم منتج. مثلاً: Product Movie
    • الوصف: أدخِل وصفًا للمنتج. مثلاً: Product Description
    • (اختياري) إضافة صورة رمز: حمِّل رمزًا يمثّل منتجك.
    ملاحظة: لأغراض هذا الدرس العملي، يمكنك تخطّي ضبط قسم الضريبة والامتثال والبرامج.
  4. انقر على التالي.
  5. أضِف خيار شراء واضبط إتاحته على مستوى منطقة معيّنة. يتطلّب المنتج الذي يتم تحصيل سعره مرة واحدة خيار شراء واحدًا على الأقل يحدّد طريقة توفير المنتج وسعره ومدى توفّره على مستوى منطقة معيّنة. في هذا الدرس التطبيقي حول الترميز، سنضيف خيار شراء العادي للمنتج.في قسم خيار الشراء، أدخِل التفاصيل التالية:
    • معرّف خيار الشراء: أدخِل معرّفًا فريدًا. مثلاً: buy-movie
    • نوع عملية الشراء: اختَر شراء.
    • (اختياري) العلامات: أضِف علامات خاصة بخيار الشراء هذا.
    • (اختياري) انقر على خيارات متقدّمة لضبط الخيارات المتقدّمة. لأغراض هذا الدرس التطبيقي حول الترميز، يمكنك تخطّي إعداد الخيارات المتقدّمة.
  6. بعد ذلك، عليك ضبط مدى التوفّر والسعر على مستوى منطقة معيّنة لخيار الشراء. في قسم "التوفّر على مستوى مناطق معيّنة"، عليك تحديد المناطق التي يتوفّر فيها منتجك، بما في ذلك تلك التي لم يُنشر تطبيقك فيها حتى الآن. سيتوفّر خيار الشراء تلقائيًا في جميع المناطق.في قسم التوفّر والأسعار، انقر على تعديل مدى التوفّر وإمكانية الوصول.
    1. انقر على ضبط على "غير متوفر".
    يُرجى العِلم أنّه يتم تلقائيًا اختيار جميع المناطق وضبطها على متاحة.
    1. أزِل العلامة من المربّع بجانب United States فقط، ثم انقر على ضبط الحالة على "غير متوفّر". سيتوفّر المنتج الذي يتم تحصيل سعره مرة واحدة الآن في United States فقط.
    2. في القائمة المنسدلة جميع المناطق، اختَر البلدان والمناطق المتاحة. من المفترض أن يظهر لك United States فقط.
    3. انقر على رمز السعر. يؤدي ذلك إلى عرض مربّع حوار لتحديد السعر.
    4. أدخِل 10 دولار أمريكي، ثم انقر على حفظ.
  7. انقر على الحفظ كمسودة.

ملاحظة: لا تفعّل خيار الشراء بعد. سنفعّله بعد إعداد عرض الطلب المُسبَق. يرجع ذلك إلى أنّه لا يمكنك إضافة عرض طلب مُسبَق إلى خيار شراء نشط تم ضبط إتاحته على مستوى منطقة معيّنة.

إضافة عرض للطلب المُسبَق

الآن، ستضيف عرض طلب مُسبَق لخيار الشراء "شراء" الذي أنشأته سابقًا. يتيح عرض الطلب المُسبَق للمستخدمين شراء منتجك قبل إصداره رسميًا. يُرجى العِلم أنّ عروض الطلب المُسبَق تتوفّر لخيار الشراء شراء فقط، ولا يمكن إعدادها إلا للمنتجات الجديدة في منطقة معيّنة.

تتضمّن إضافة عرض طلب مُسبَق الخطوتَين التاليتَين:

  1. جهِّز خيار الشراء شراء لعرض الطلب المُسبَق.
  2. أضِف عرض الطلب المُسبَق لخيار الشراء.

تجهيز خيار الشراء "شراء" لعرض الطلب المُسبَق

  1. افتح التطبيق النموذجي في Google Play Console، وانتقِل إلى تحقيق الربح من خلال Play > المنتجات > المنتجات التي يتم تحصيل سعرها مرة واحدة.
  2. في صفحة المنتجات التي يتم تحصيل سعرها مرة واحدة، انقر على السهم المتّجه لليمين بجانب منتجك (upcoming_movie_1). سيؤدي هذا إلى فتح صفحة تعديل المنتج الذي يتم تحصيل سعره مرة واحدة.
  3. انقر على السهم المتّجه لليسار بجانب خيار الشراء buy-movie الذي أنشأته سابقًا. سيؤدي هذا إلى فتح صفحة تعديل خيار الشراء.
  4. انقر على تعديل مدى التوفّر وإمكانية الوصول، ثم اختَر ضبط الحالة على "متوفّر" والسماح للمستخدمين بالطلب المُسبق.
  5. من القائمة المنسدلة جميع المناطق، اختَر البلدان والمناطق المتاحة. من المفترض أن يعرض هذا القسم United States فقط الذي سبق لك إعداده.
  6. اختَر البلد، ثم انقر على ضبط الحالة على "متوفر" للطلب المُسبَق فقط.
  7. انقر على حفظ.

يُرجى العِلم أنّه لم تتم إضافة عرض طلب مُسبَق إلى خيار الشراء بعد. الخطوة التالية هي إضافة عرض الطلب المُسبَق.

إضافة عرض للطلب المُسبَق

  1. افتح التطبيق النموذجي في Google Play Console، وانتقِل إلى تحقيق الربح من خلال Play > المنتجات > المنتجات التي يتم تحصيل سعرها مرة واحدة.
  2. في صفحة المنتجات التي يتم تحصيل سعرها مرة واحدة، انقر على إضافة عرض > طلب مُسبَق لمنتجك (upcoming_movie_1). سيؤدي ذلك إلى فتح صفحة إضافة طلب مُسبَق.
  3. أدخِل تفاصيل الطلب المُسبَق:
    • معرّف الطلب المُسبَق: أدخِل preorder-offer-1.
    • (اختياري) إضافة خصم: يمكنك اختيار بدون خصم أو خصم بنسبة مئوية أو مبلغ خصم دقيق. لأغراض هذا الدرس التطبيقي، اختَر بدون.
    • (اختياري) العلامات: أضِف علامات ذات صلة.
    • تاريخ البدء ووقته: حدِّد تاريخًا بعد 3 أيام على الأقل.
    • تاريخ الانتهاء ووقته: اضبط تاريخًا بعد 24 ساعة على الأقل من تاريخ البدء.
    • التوفّر بعد الطلب المُسبق: اختَر ما إذا كان المنتج سيتوفّر فورًا بعد انتهاء فترة الطلب المُسبق أو في تاريخ/وقت محدّد لاحقًا.
    • (اختياري) ضمان السعر الأقل: حدِّد هذا الخيار إذا كنت تريد تحصيل السعر الأقل من المستخدمين، وذلك بين سعر الطلب المُسبَق والسعر عند الإصدار. ويمكن أن يشكّل ذلك حافزًا قويًا للمشترين الأوائل.
  4. انقر على حفظ.
  5. افتح صفحة تعديل المنتج الذي يتم تحصيل سعره مرة واحدة لمنتجك (upcoming_movie_1).
  6. انقر على تفعيل لخيار الشراء (buy-movie).
  7. انقر على تفعيل لعرض الطلب المُسبَق (preorder-offer-1) ضمن خيار الشراء. يؤدي ذلك إلى تفعيل عرض الطلب المُسبَق وإطلاقه في التاريخ الذي سبق أن حدّدته في تفاصيل الطلب المُسبَق.

فيديو حول إنشاء عرض طلب مُسبَق

يعرض الفيديو التالي خطوات إنشاء عرض الطلب المُسبَق الموضّحة سابقًا.

4. الدمج مع PBL

لدمج تطبيقك مع مكتبة الفوترة في Play (PBL)، اتّبِع الخطوات التالية:

  1. أضِف اعتمادية "مكتبة الفوترة في Play" إلى التطبيق النموذجي.
    dependencies {
    val billing_version = "8.1.0"
    
    implementation("com.android.billingclient:billing-ktx:$billing_version")
    }
    
  2. ابدأ BillingClient. ‫BillingClient هي حزمة تطوير البرامج (SDK) الخاصة بالعميل والموجودة في تطبيقك وتتواصل مع "مكتبة الفوترة في Play". يوضّح مقتطف الرمز البرمجي التالي كيفية تهيئة أداة الفوترة.
    private BillingClient createBillingClient() {
    return BillingClient.newBuilder(activity)
        .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build())
        // For one-time products, add a listener to process and acknowledge the purchases. This will notify
        // Google the purchase was processed.
        // For client-only apps, use billingClient.acknowledgePurchase().
        // If you have a secure backend, you must acknowledge purchases on your server using the
        // server-side API.
        // See https://developer.android.com/google/play/billing/security#acknowledge
        // In this sample snippet purchases aren't processed. You must
        // implement your business logic to process and acknowledge the purchases.
        .setListener((billingResult, purchases) -> {})
        .enableAutoServiceReconnection()
        .build();
     }
    
  3. الربط بخدمة Google Play: يوضّح مقتطف الرمز التالي كيفية الربط بخدمة Google Play.
    /**
    * Starts the billing connection with Google Play. This method should be called exactly once
    * before any other methods in this class.
    *
    * @param productList The list of products to query for after the connection is established.
    */
    public void startBillingConnection(List<Product> productList) {
        billingClient.startConnection(
            new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                Log.d(TAG, "Billing Client Connection Successful");
                queryProductDetails(productList);
                } else {
                Log.e(TAG, "Billing Client Connection Failed: " + billingResult.getDebugMessage());
                listener.onBillingSetupFailed(billingResult); // Propagate the error to the listener to show a message to the user.
                }
            }
    
            @Override
            public void onBillingServiceDisconnected() {
                Log.e(TAG, "Billing Client Connection Lost");
                listener.onBillingError("Billing Connection Lost");
            }
            });
    }
    
  4. استرداد تفاصيل المنتج الذي يتم تحصيل سعره مرة واحدة: بعد دمج تطبيقك مع PBL، عليك استرداد تفاصيل المنتج الذي يتم تحصيل سعره مرة واحدة في تطبيقك. يعرض مقتطف الرمز التالي كيفية استرداد تفاصيل المنتج الذي يتم تحصيل سعره مرة واحدة في تطبيقك.
    private void queryProductDetails(List<Product> productList) {
        QueryProductDetailsParams queryProductDetailsParams =
            QueryProductDetailsParams.newBuilder().setProductList(productList).build();
    
        billingClient.queryProductDetailsAsync(
            queryProductDetailsParams,
            new ProductDetailsResponseListener() {
            @Override
            public void onProductDetailsResponse(
                BillingResult billingResult, QueryProductDetailsResult productDetailsResponse) {
                if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                List<ProductDetails> productDetailsList =
                    productDetailsResponse.getProductDetailsList();
                    listener.onProductDetailsResponse(productDetailsList);
                } else {
                Log.e(TAG, "QueryProductDetailsAsync Failed: " + billingResult.getDebugMessage());
                listener.onBillingError("Query Products Failed: " + billingResult.getResponseCode());
                }
            }
            });
    }
    
    سيؤدي جلب المنتج الذي يتم تحصيل سعره مرة واحدة (upcoming_movie_1 في هذا المثال) في ProductDetails إلى ظهور ردّ مشابه لما يلي:
    {
        "productId": "upcoming_movie_1",
        "type": "inapp",
        "title": "Purrfect Mayhem: The Final Playback (Movies All Day | Play Samples)",
        "name": "Purrfect Mayhem: The Final Playback",
        "description": "Yolo and Thorne must reach the original broadcasting site to initiate the \"Final Playback\" and save the timeline. Follow them through their race against the Clockinators.",
        "skuDetailsToken": "<---skuDetailsToken--->",
        "oneTimePurchaseOfferDetails": {},
        "oneTimePurchaseOfferDetailsList": [
            {
                "priceAmountMicros": 8500000,
                "priceCurrencyCode": "USD",
                "formattedPrice": "$8.50",
                "offerIdToken": "<---offerIdToken--->",
                "offerId": "preorder",
                "purchaseOptionId": "buy-option",
                "offerTags": [],
                "validTimeWindow": {
                    "startTimeMillis": 1756771200000,
                    "endTimeMillis": 1785542400000
                },
                "preorderDetails": {
                    "preorderReleaseTimeMillis": 1785542400000,
                    "preorderPresaleEndTimeMillis": 1785542400000
                }
            }
        ]
    }
    
    يُرجى العِلم أنّ تفاصيل عرض الطلب المُسبَق متاحة في oneTimePurchaseOfferDetailsList. تحتوي هذه القائمة على خيار شراء واحد (buy-option) تم إعداد عرض الطلب المُسبَق له في Play Console. يمكنك تحديد كل خيار شراء بشكلٍ فريد من خلال offerIdToken.
  5. استرجِع رمز العرض الترويجي مع تفاصيل عرض الطلب المُسبَق. تحتاج إلى رمز العرض الترويجي لتشغيل عملية الفوترة في الخطوة 6.
    @Override
    public void onProductDetailsResponse(List<ProductDetails> productDetailsList) {
    
    if (productDetailsList != null && !productDetailsList.isEmpty()) {
    
    // Process productDetailsList returned by QueryProductDetailsResult
    for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) {
      for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails :
          productDetails.getOneTimePurchaseOfferDetailsList()) {
        // Checks if the offer is a preorder offer.
        if (oneTimePurchaseOfferDetails.getPreorderDetails() != null) {
          // Process the returned PreorderDetails
          OneTimePurchaseOfferDetails.PreorderDetails preorderDetails =
              oneTimePurchaseOfferDetails.getPreorderDetails();
          // Get preorder release time in millis.
          long preorderReleaseTimeMillis = preorderDetails.getPreorderReleaseTimeMillis();
          // Get preorder presale end time in millis.
          long preorderPresaleEndTimeMillis = preorderDetails.getPreorderPresaleEndTimeMillis();
          // Get offer ID
            String offerId = oneTimePurchaseOfferDetails.getOfferId();
          // Get the associated purchase option ID
          if (oneTimePurchaseOfferDetails.getPurchaseOptionId() != null) {
            String purchaseOptionId = oneTimePurchaseOfferDetails.getPurchaseOptionId();
          }
        }
      }
      }
      } else {
            Log.e(TAG, "No product details found for " + productId);
        }
    }
    
  6. تشغيل مسار الفوترة
    /**
     * Launches the billing flow for the product with the given offer token.
    *
    * @param activity The activity instance from which the billing flow will be launched.
    * @param productDetails The product details of the product to purchase.
    * @param offerToken The offer token of the product to purchase.
    * @return The result of the billing flow.
    */
    public void launchPurchase(Activity activity, ProductDetails productDetails, String offerToken) {
        ImmutableList<BillingFlowParams.ProductDetailsParams> productDetailsParamsList =
            ImmutableList.of(
                BillingFlowParams.ProductDetailsParams.newBuilder()
                    .setProductDetails(productDetails)
                    .setOfferToken(offerToken)
                    .build());
        BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(productDetailsParamsList)
            .build();
        billingClient.launchBillingFlow(activity, billingFlowParams);
    }
    

5- خيارات الشراء التجريبي

قبل إتاحة المنتجات التي يتم تحصيل سعرها مرة واحدة في تطبيقك المنشور، يمكنك اختبار عملية تكامل Play Billing Library باستخدام مختبِري الترخيص وPlay Billing Lab.

للتعرّف على كيفية اختبار خيارات الشراء باستخدام Play Billing Lab، يمكنك الاطّلاع على درس تطبيقي حول الترميز فتح أسواق جديدة من خلال تسعير المنتجات على مستوى المنطقة.

6. الخطوات التالية

المستندات المرجعية

7. تهانينا!

تهانينا! لقد انتقلت بنجاح إلى Google Play Console لإنشاء عرض طلب مُسبَق لمنتج يتم تحصيل سعره مرة واحدة. أصبح لديك الآن فهم أعمق لكتالوج المنتجات المرن في Google Play الذي يتيح إجراء عمليات شراء لمرة واحدة.

استطلاع

نقدّر ملاحظاتك بشأن هذا الدرس العملي. يُرجى تخصيص بضع دقائق لإكمال الاستطلاع.