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

1. مقدمة

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

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

الجمهور

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

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

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

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

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

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

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

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

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

  1. افتح التطبيق النموذجي في Google Play Console، وانتقِل إلى تحقيق الربح المادي باستخدام Google 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 Billing Library التابع إلى التطبيق النموذجي.
    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 باستخدام مختبِري الترخيص وPlay Billing Lab.

للتعرّف على كيفية اختبار خيارات الشراء باستخدام Play Billing Lab، يمكنك الاطّلاع على برنامج Unlock new markets with regional product pricing التعليمي.

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

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

7. تهانينا!

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

استطلاع

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