इन-ऐप बिलिंग कार्यान्वयन गाइड

इन-ऐप बिलिंग कार्यान्वयन गाइड

नमस्ते। मैं zm soft हूँ, जिसने पिछले साल (2023 के अंत में) डेवलपर के रूप में पंजीकरण किया और ऐप रिलीज़ करना शुरू किया। हम डेवलपर्स के बीच सहयोग से क्लोज्ड टेस्ट पार करने के लिए डेवलपर्स के लिए एक ऐप लॉन्च करने की योजना भी बना रहे हैं, इसलिए चाहें तो ज़रूर देखें।

क्या आप सब इन-ऐप बिलिंग लागू कर रहे हैं? एक ऐप डेवलपर के रूप में, उपयोगकर्ता को संतुष्ट करना और उसके बदले में मुआवज़ा पाना सबसे बड़ी बात है, और यही वह क्षण है जब डेवलपमेंट की मेहनत रंग लाती है। इस बार मैं इसे हासिल करने के तरीके के बारे में लिखना चाहता हूँ।

इन-ऐप बिलिंग क्या है

जैसा आप जानते हैं, इन-ऐप बिलिंग को दो प्रकारों में वर्गीकृत किया जाता है:

  • उपभोग्य आइटम
  • आवधिक सदस्यता आइटम

दोनों Google Play Billing Library के माध्यम से Play Store में पहले से सेट किए गए आइटम तक पहुँचते हैं, और अर्जित राजस्व का एक हिस्सा Google को शुल्क के रूप में भुगतान किया जाता है। कार्यान्वयन के दृष्टिकोण से, दोनों समान हैं, लेकिन आवधिक सदस्यता आइटम की अपनी विशेष सावधानियाँ हैं। सावधानियों को मैं अपने व्यक्तिगत अनुभव के आधार पर समझाऊँगा।

Play Store सेटअप

आइटम पंजीकरण

सबसे पहले, आइटम पंजीकृत करें क्योंकि बिना पंजीकरण के उन्हें प्रदर्शित नहीं किया जा सकता। उस आइटम का वास्तव में उपयोग करना है या नहीं, इसके साथ-साथ कीमत, नाम आदि बाद में बदले जा सकते हैं, इसलिए अस्थायी जानकारी भी ठीक है। हालांकि, केवल ID बदली नहीं जा सकती, इसलिए यदि आप परीक्षण के लिए बनाए गए आइटम को उत्पादन वातावरण में उपयोग करने की सोच रहे हैं, तो [product_1,2,3...] या [sub_1,2,3...] जैसे पुनः उपयोग योग्य ID के साथ पंजीकृत करना उचित होगा। पंजीकरण [Monetize] से किया जा सकता है, जहाँ [In-app products] और [Subscriptions] क्रमशः उपभोग्य और आवधिक सदस्यता आइटम हैं। प्रत्येक आइटम को [Create xx] बटन से पंजीकृत किया जा सकता है।

Play Console の Monetize メニューにあるアプリ内商品・定期購入セクション

मूल रूप से, इनपुट स्क्रीन का अनुसरण करके सेटअप किया जा सकता है, लेकिन जो भ्रामक था वह आवधिक सदस्यता आइटम की कीमत सेटिंग थी। शुरुआत में मुझे नहीं पता था कि एक साथ सभी क्षेत्रों की कीमतें कैसे सेट करें। मुझे लगा प्रत्येक क्षेत्र को अलग-अलग दर्ज करना होगा, लेकिन इसे इस क्रम में किया जा सकता है: [Set prices] - [Country / region] - [Set price]।

Play Console の定期購入価格入力フォーム

बटन दबाने पर नीचे दिखाया गया डायलॉग आता है जो एक साथ सेट करने की अनुमति देता है।

全地域一括価格設定ダイアログ(Play Console)

परीक्षण खाता पंजीकरण

इसके बाद, परीक्षण खाता पंजीकृत करें। बिना पंजीकरण किए परीक्षण में खरीदारी करने पर वास्तविक भुगतान हो जाएगा, इसलिए सावधान रहें। परीक्षण खाते का पंजीकरण मेलिंग सूची पंजीकृत करके किया जाता है। पंजीकरण Play Console में लॉगिन करने के बाद पहली स्क्रीन (डेवलपर स्क्रीन) पर [Settings] - [License testing] से किया जा सकता है।

Play Console のライセンステスト設定画面(テストアカウント登録用)

मेलिंग सूची में पंजीकृत उपयोगकर्ता से ऐप खरीदने की प्रक्रिया करने पर, भुगतान जानकारी "टेस्ट कार्ड" के रूप में प्रदर्शित होती है, और वास्तविक भुगतान किए बिना परीक्षण किया जा सकता है।

कार्यान्वयन कार्य

ऐप की तरफ से कार्यान्वयन में निम्नलिखित कार्य आवश्यक हैं:

  • लाइब्रेरी आयात
  • स्टोर से कनेक्शन और आइटम जानकारी प्राप्ति
  • आइटम प्रदर्शन स्क्रीन का कार्यान्वयन
  • खरीद का अनुरोध
  • खरीद पूर्ण होने पर प्रसंस्करण

नीचे प्रत्येक के बारे में विस्तार से लिखूँगा।

लाइब्रेरी आयात

लाइब्रेरी आयात के लिए निम्नलिखित आवश्यक हैं:

  • build.gradle का संशोधन
  • android.manifest का संशोधन

build.gradle संशोधन उदाहरण:

dependencies {
    implementation "com.android.billingclient:6.0.0"
}

manifest संशोधन उदाहरण:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="com.android.vending.BILLING" />

    <application

संस्करण आदि के लिए आधिकारिक दस्तावेज़ देखें।

स्टोर से कनेक्शन और आइटम जानकारी प्राप्ति

BillingClient को इनिशियलाइज़ करके और startConnection चलाकर स्टोर से संचार संभव हो जाता है। queryProductDetailsAsync से प्रत्येक आइटम की जानकारी प्राप्त की जा सकती है। विस्तार के लिए आधिकारिक दस्तावेज़ देखें। मेरे मामले में, किसी कारण से बल्क प्राप्ति ठीक से काम नहीं किया, इसलिए पहले आइटम की सूची प्राप्त करके फिर queryProductDetailAsync से प्रत्येक आइटम के विवरण अलग-अलग प्राप्त किए। प्राप्त आइटम (SKU) उपभोग्य या आवधिक प्रकार का है, इसे उसके प्रकार inapp या subs से पहचाना जा सकता है।

आइटम प्रदर्शन स्क्रीन का कार्यान्वयन

आइटम की जानकारी मिलने के बाद, उसे सूची में प्रदर्शित करें ताकि खरीदारी का चयन किया जा सके। यहाँ आवधिक सदस्यता आइटम को संभालते समय Subscription Policy का अनुपालन आवश्यक है, और मेरे मामले में निम्नलिखित दो कारणों से लगातार ऐप अपडेट अस्वीकृत हो गए:

  • कीमत और शर्तों का अधूरा स्थानीयकरण
  • ऑफर शर्तों का अधूरा विवरण

पहले, कीमत और शर्तों के अधूरे स्थानीयकरण के बारे में: कारण अवधि का प्रदर्शन था (उदाहरण: $10/month)। अनुवाद में असमर्थित भाषा की क्षेत्र सेटिंग से चलाने पर "month" भाग अनुवादित नहीं था। BillingClient का उपयोग करके जानकारी प्राप्त करने पर, कीमत राशि formattedPrice स्ट्रिंग के रूप में मिलती है जिसमें यूनिट जानकारी भी शामिल होती है, इसलिए ऐप में अनुवाद करने की आवश्यकता नहीं। इसके विपरीत, अवधि की जानकारी P1M जैसी ISO 8601 प्रारूप में सूचित होती है, जिसे ऐप में अनुवाद करना होता है। निम्नलिखित प्रकार की प्रत्येक भाषा के लिए रूपांतरण प्रक्रिया जोड़कर इसे संभाला:

fun formatBillingPeriod(billingPeriod: String, languageCode: String): String {
    return when(languageCode) {
        "en" -> {
            when (billingPeriod) {
                "P1W" -> "weekly"
                "P1M" -> "monthly"
                "P3M" -> "every 3 months"
                "P6M" -> "every 6 months"
                "P1Y" -> "annually"
                else -> "unknown"
            }
        }
        "ja" -> {
            when (billingPeriod) {
                "P1W" -> "週間"
                "P1M" -> "月額"
                "P3M" -> "3ヶ月ごと"
                "P6M" -> "6ヶ月ごと"
                "P1Y" -> "年額"
                else -> "不明"
            }
        }
        "fr" -> {
            when (billingPeriod) {
                "P1W" -> "hebdomadaire"
                "P1M" -> "mensuel"
                "P3M" -> "tous les 3 mois"
                "P6M" -> "tous les 6 mois"
                "P1Y" -> "annuel"
                else -> "inconnu"
            }
        }
        "es" -> {
            when (billingPeriod) {
                "P1W" -> "semanal"
                "P1M" -> "mensual"
                "P3M" -> "cada 3 meses"
                "P6M" -> "cada 6 meses"
                "P1Y" -> "anual"
                else -> "desconocido"
            }
        }
        "de" -> {
            when (billingPeriod) {
                "P1W" -> "wöchentlich"
                "P1M" -> "monatlich"
                "P3M" -> "alle 3 Monate"
                "P6M" -> "alle 6 Monate"
                "P1Y" -> "jährlich"
                else -> "unbekannt"
            }
        }
        else -> "unknown"
    }
}

इसके बाद, ऑफर शर्तों के अधूरे विवरण के बारे में:

オファー条件違反のサブスクリプション拒否通知 サブスクリプションポリシー違反の拒否メール抜粋

समस्या समझ में आई, लेकिन समाधान के रूप में विशेष रूप से क्या लिखना है यह नहीं पता था। नीचे उस ईमेल के मूल अंग्रेज़ी पाठ का अंश है जिसमें मुझे अस्वीकृति की सूचना मिली:

Issue found: Violation of Subscriptions policy

Your app does not comply with the Subscriptions policy.

  • Your offer does not clearly and accurately describe the terms of your trial offer or introductory pricing, including when a free trial will convert to a paid subscription, how much the paid subscription will cost, and that a user can cancel if they do not want to convert to a paid subscription.

समाधान के रूप में, अन्य ऐप्स से भाषाई संदर्भ उधार लिया। चूँकि यह ज़्यादातर तय शब्दावली जैसी लगती है, इसलिए सोचने की बजाय सिद्ध उदाहरणों का अनुसरण करना बेहतर समझा।

खरीद का अनुरोध

स्क्रीन से आइटम चुना जा सके तो अंततः आइटम खरीद प्रसंस्करण होता है। प्राप्त आइटम के लिए खरीद फ़्लो निष्पादित करने पर वास्तविक खरीद स्क्रीन बुलाई जा सकती है।

परीक्षण

शुरुआत में तैयार परीक्षण खाते से लॉगिन करके परीक्षण करने पर, वास्तविक शुल्क उत्पन्न किए बिना परीक्षण किया जा सकता है। यहाँ दो सावधानियाँ हैं:

  • खरीद फ़्लो निष्पादन स्टोर में पंजीकृत ऐप से किया जाए
  • आवधिक सदस्यता आइटम की अवधि कस्टम सेट होती है

debug build ऐप होने पर खरीद स्क्रीन में error प्रदर्शित होगी और फ़्लो निष्पादित नहीं होगा।

आवधिक सदस्यता आइटम के बारे में: वास्तविक खरीद स्क्रीन पर जाने पर टेस्ट कार्ड से भुगतान प्रदर्शित होता है। इस समय खरीद स्क्रीन में नवीनीकरण अवधि दिखती है, लेकिन यह प्रदर्शित अवधि आइटम में वास्तव में सेट अवधि से अलग होती है। मेरे मामले में, 5 मिनट प्रदर्शित थे। सदस्यता नवीनीकरण के लिए अत्यधिक छोटी निश्चित अवधि प्रदर्शित करने का विनिर्देश प्रतीत होता है। (मुझे लगा कि कहीं सेटिंग में गलती हुई और कुछ समय तक सेटिंग की समीक्षा करता रहा।)

सारांश

शुरू में कठिन लगता है, लेकिन पूरी तस्वीर समझ लेने के बाद, इन-ऐप बिलिंग आधिकारिक दस्तावेज़ जैसी सार्वजनिक जानकारी देखकर आश्चर्यजनक रूप से आसानी से लागू की जा सकती है। हालांकि, आवधिक सदस्यता के लिए ऐसी भी समस्याएँ होती हैं जो जब तक आज़माएँ नहीं तब तक पता नहीं चलती, इसलिए आशा है कि जो बिंदुओं पर मैं ठोकर खाया वे भविष्य में इसे लागू करने वाले डेवलपर्स के काम आएंगे।