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

أندريه سيبرياني باندارا
"أندريه سيبرياني باندارا"

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

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

ستتعرّف في هذا الدليل على كيفية إضافة خدمة "الفوترة في Google Play" إلى تطبيق الويب التقدّمي (PWA) وتجميعه للتوزيع على "متجر Google Play" لكل من ChromeOS و"متجر Play".

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

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

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

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

المتطلّبات

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

تعديل مشروع التفاف الفقاعات

إذا لم يكن تطبيق 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"

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

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

قد تكون واجهة برمجة التطبيقات Digital Goods API متاحة في أي متصفّح ويمكن استخدامها في متاجر مختلفة. للتحقّق مما إذا كانت واجهة متجر معيّنة متوافقة، عليك استدعاء 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);
}

بناء تدفق الشراء

تستند طريقة إنشاء PaymentRequest إلى معلمتين: قائمة طرق الدفع وقائمة بتفاصيل الدفع.

عند الدخول إلى "النشاط على الويب الموثوق به"، يجب استخدام طريقة الدفع "الفوترة في 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 قيد التطوير للاختبار:

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

على جهاز ChromeOS

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

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

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

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

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

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