تلقّي الدفعات من خلال خدمة "الفوترة في Google Play" باستخدام Digital Goods API وPayment Request API

إذا كان تطبيقك موزّعًا من خلال Google Play وأردت بيع سلع رقمية أو إتاحة اشتراكات، عليك استخدام الفوترة في Google Play. توفّر خدمة "الفوترة في Google Play" أدوات لإدارة قائمة منتجاتك وأسعارها واشتراكاتها، وتقارير مفيدة، ومسار دفع يستند إلى "متجر Google Play" ويعرفه المستخدمون.

بالنسبة إلى التطبيقات التي تم إنشاؤها باستخدام أنشطة ويب موثوق بها ويتم تقديمها من خلال "متجر Google Play"، يمكنك الآن استخدام Payment Request API وDigital Goods API للدمج مع خدمة "الفوترة في Google Play". وتتوفّر الميزة على الإصدار 101 من Chrome والإصدارات الأحدث لنظامَي التشغيل Android وChromeOS.

في هذا الدليل، ستتعرّف على كيفية إضافة ميزة "الفوترة في Google Play" إلى تطبيقك المتوافق مع الأجهزة الجوّالة على الويب وحزمه لتوزيعه على "متجر Google Play" لكلٍّ من ChromeOS و"متجر Play".

ستستخدم واجهتَي برمجة تطبيقات لنظامَين أساسيَّين على الويب لإضافة خدمات الفوترة في Play إلى تطبيق الويب التقدّمي (PWA). يتم استخدام واجهة برمجة التطبيقات Digital Goods API لجمع معلومات رموز التخزين التعريفية والتحقق من عمليات الشراء والامتيازات من "متجر Play". تُستخدَم واجهة برمجة التطبيقات Payment Request API لضبط "متجر Google Play" كأحد طرق الدفع وإكمال عملية الشراء.

كيفية تحقيق الربح من التطبيقات على "متجر Play"

هناك طريقتان يمكن من خلالهما تحقيق الربح من تطبيقك باستخدام "الفوترة في Google Play" على "متجر Play":

  • تتيح عمليات الشراء داخل التطبيق بيع السلع الافتراضية الدائمة والمستهلكة، مثل ميزات إضافية أو إزالة الإعلانات.
  • الاشتراكات: تتيح للمستخدمين الوصول بشكل مستمر إلى محتوى أو خدمات مقابل رسوم متكررة، مثل الاشتراكات في خدمة الأخبار أو العضويات.

المتطلبات

لإعداد خدمة "الفوترة في Google Play"، ستحتاج إلى ما يلي:

تعديل مشروع Bubblewrap

إذا لم يكن تطبيق Bubblewrap مثبّتًا، عليك تثبيته. يمكنك الاطّلاع على دليل البدء السريع للحصول على تفاصيل حول كيفية البدء. إذا كان لديك Bubblewrap، احرص على التحديث إلى الإصدار 1.8.2 أو إصدار أحدث.

تتوفّر هذه الميزة أيضًا في Bubblewrap. ولتفعيله، عليك تعديل إعدادات المشروع في twa-manifest.json، الموجودة في جذر المشروع وتفعيل ميزة alphaDependencies وميزة playBilling معًا:

  ...,
  "enableNotifications": true,
  "features": {
    "playBilling": {
      "enabled": true
    }
  },
  "alphaDependencies": {
    "enabled": true
  },
  ...

بعد تعديل ملف الإعدادات، يمكنك تشغيل bubblewrap update لتطبيق الإعدادات على المشروع، ثم تشغيل bubblewrap build لإنشاء حزمة Android جديدة وتحميل هذه الحزمة إلى "متجر Play".

ميزة رصد مدى توفّر واجهة برمجة التطبيقات Digital Goods API و"الفوترة في Google Play"

لا يتيح Chrome حاليًا استخدام Digital Goods API إلا عند تنفيذ تطبيق الويب التقدّمي داخل نشاط ويب موثوق به، ومن الممكن معرفة ما إذا كانت واجهة برمجة التطبيقات متاحة من خلال البحث عن getDigitalGoodsService في عنصر window:

if ('getDigitalGoodsService' in window) {
 // Digital Goods API is supported!
}

قد تكون Digital Goods API متاحة في أي متصفّح وتتوافق مع متاجر مختلفة. للتحقّق مما إذا كان backend لمتجر معيّن متوافقًا، عليك استدعاء getDigitalGoodsService() مع تمرير معرّف المتجر كمَعلمة. يتم التعرّف على "متجر Google Play" باستخدام السلسلة https://play.google.com/billing:

if ('getDigitalGoodsService' in window) {
  // Digital Goods API is supported!
  try {
    const service =
        await window.getDigitalGoodsService('https://play.google.com/billing');
    // Google Play Billing is supported!

  } catch (error) {
    // Google Play Billing is not available. Use another payment flow.
    return;
  }
}

استرداد تفاصيل رمز التخزين التعريفي

توفّر Digital Goods API getDetails()، ما يسمح باسترداد معلومات مثل عنوان المنتج ووصفه والأهم من ذلك، السعر من الخلفية الخاصة بالدفعات.

ويمكنك بعد ذلك استخدام هذه المعلومات في واجهة المستخدم وتقديم المزيد من التفاصيل للمستخدم:

const skuDetails = await service.getDetails(['shiny_sword', 'gem']);
for (item of skuDetails) {
  // Format the price according to the user locale.
  const localizedPrice = new Intl.NumberFormat(
      navigator.language,
      {style: 'currency', currency: item.price.currency}
    ).format(item.price.value);

  // Render the price to the UI.
  renderProductDetails(
        item.itemId, item.title, localizedPrice, item.description);
}

إنشاء مسار الشراء

تأخذ الدالة الإنشائية لطلب الدفع مَعلمتَين: قائمة بطرق الدفع وقائمة باطلاعات الدفع.

عند الدخول إلى "نشاط موثوق به على الويب"، يجب استخدام طريقة الدفع "الفوترة في Google Play" من خلال ضبط https://play.google.com/billing كمعرّف وإضافة رمز التخزين التعريفي للمنتج كعضو في البيانات:

async function makePurchase(service, sku) {
   // Define the preferred payment method and item ID
   const paymentMethods = [{
       supportedMethods: "https://play.google.com/billing",
       data: {
           sku: sku,
       }
   }];

   ...
}

على الرغم من أنّ تفاصيل الدفع مطلوبة، ستتجاهل خدمة "الفوترة على Play" هذه القيم وستستخدِم القيم التي تم ضبطها عند إنشاء رمز التخزين التعريفي في Play Console، لذا يمكن ملؤها بقيم زائفة:

const paymentDetails = {
    total: {
        label: `Total`,
        amount: {currency: `USD`, value: `0`}
    }
};

const request = new PaymentRequest(paymentMethods, paymentDetails);

عليك طلب "show()" في عنصر طلب الدفع لبدء عملية الدفع. إذا تمكّن الوعد من التقدّم، قد يعني ذلك أنّه تم إتمام عملية الدفع بنجاح. إذا تعذّر إكمال الدفع، من المرجّح أنّ المستخدم أوقف الدفع.

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

...
const request = new PaymentRequest(paymentMethods, paymentDetails);
try {
    const paymentResponse = await request.show();
    const {purchaseToken} = paymentResponse.details;

    // Call backend to validate and acknowledge the purchase.
    if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
        // Optional: tell the PaymentRequest API the validation was
        // successful. The user-agent may show a "payment successful"
        // message to the user.
        const paymentComplete = await paymentResponse.complete('success');
    } else {
        // Optional: tell the PaymentRequest API the validation failed. The
        // user agent may show a message to the user.
        const paymentComplete = await paymentResponse.complete('fail');
    }
} catch(e) {
    // The purchase failed, and we can handle the failure here. AbortError
    // usually means a user cancellation
}
...

اختياريًا، يمكن استدعاء consume() على purchaseToken لوضع علامة على عملية الشراء على أنّها مُستخدَمة والسماح بشرائها مرة أخرى.

عند تجميع كل العناصر معًا، تظهر طريقة الشراء على النحو التالي:

async function makePurchase(service, sku) {
    // Define the preferred payment method and item ID
    const paymentMethods = [{
        supportedMethods: "https://play.google.com/billing",
        data: {
            sku: sku,
        }
    }];

    // The "total" member of the paymentDetails is required by the Payment
    // Request API, but is not used when using Google Play Billing. We can
    // set it up with bogus details.
    const paymentDetails = {
        total: {
            label: `Total`,
            amount: {currency: `USD`, value: `0`}
        }
    };

    const request = new PaymentRequest(paymentMethods, paymentDetails);
    try {
        const paymentResponse = await request.show();
        const {purchaseToken} = paymentResponse.details;

        // Call backend to validate and acknowledge the purchase.
        if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
            // Optional: consume the purchase, allowing the user to purchase
            // the same item again.
            service.consume(purchaseToken);

            // Optional: tell the PaymentRequest API the validation was
            // successful. The user-agent may show a "payment successful"
            // message to the user.
            const paymentComplete =
                    await paymentResponse.complete('success');
        } else {
            // Optional: tell the PaymentRequest API the validation failed.
            // The user agent may show a message to the user.
            const paymentComplete = await paymentResponse.complete('fail');
        }
    } catch(e) {
        // The purchase failed, and we can handle the failure here.
        // AbortError usually means a user cancellation
    }
}

الاطّلاع على حالة عمليات الشراء الحالية

تسمح لك Digital Goods API بالتحقق مما إذا كان لدى المستخدم أي استحقاقات حالية (عمليات شراء داخل التطبيق لم يتم استهلاكها بعد أو اشتراكات مستمرة) من عمليات الشراء السابقة التي أجراها، سواء على جهاز آخر أو من عملية تثبيت سابقة أو حصّل قيمتها من رمز ترويجي أو في آخر مرة فتح فيها التطبيق.


const service =
     await window.getDigitalGoodsService('https://play.google.com/billing');
...
const existingPurchases = await service.listPurchases();
for (const p of existingPurchases) {
    // Update the UI with items the user is already entitled to.
    console.log(`Users has entitlement for ${p.itemId}`);
}

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

const service =
     await window.getDigitalGoodsService("https://play.google.com/billing");
...
const existingPurchases = await service.listPurchases();
for (const p of existingPurchases) {
    await verifyOrAcknowledgePurchaseOnBackend(p.purchaseToken, p.itemId);

    // Update the UI with items the user is already entitled to.
    console.log(`Users has entitlement for ${p.itemId}`);
}

اختبار عملية الدمج

على جهاز Android مخصّص للتطوير

يمكنك تفعيل Digital Goods API على جهاز Android مخصّص للتطوير من أجل الاختبار:

  • تأكَّد من استخدام الإصدار 9 من نظام التشغيل Android أو إصدار أحدث مع تفعيل وضع المطوِّر.
  • ثبِّت الإصدار 101 من Chrome أو إصدارًا أحدث.
  • فعِّل العلامات التالية في Chrome من خلال الانتقال إلى chrome://flags والبحث عن العلامة حسب الاسم:
    • #enable-debug-for-store-billing
  • تأكد من استضافة الموقع باستخدام بروتوكول https. سيؤدي استخدام http إلى تغيير واجهة برمجة التطبيقات إلى undefined.

على جهاز ChromeOS

ستتوفّر واجهة برمجة التطبيقات Digital Goods API على الإصدار الثابت من ChromeOS اعتبارًا من الإصدار 89. في الوقت الحالي، يمكنك اختبار Digital Goods API:

  • ثبِّت تطبيقك من "متجر Play" على الجهاز.
  • تأكَّد من أنّ الموقع الإلكتروني مستضاف باستخدام بروتوكول https. سيؤدي استخدام http إلى أن تكون واجهة برمجة التطبيقات undefined

من خلال مستخدمي الاختبار وفِرق ضمان الجودة

يقدّم "متجر Play" ميزات لتسهيل عملية الاختبار، بما في ذلك حسابات المستخدمين التجريبية ورموز التخزين التعريفية التجريبية. اطّلِع على مستندات اختبار "الفوترة في Google Play" للحصول على مزيد من المعلومات.

ما هي الخطوة التالية؟

كما هو موضّح في هذا المستند، تتضمّن واجهة برمجة التطبيقات Play Billing API مكونات من جهة العميل تديرها واجهة برمجة التطبيقات Digital Goods API ومكونات من جهة الخادم.