کتابخانه صورت‌حساب Google Play را در برنامه خود ادغام کنید

این مبحث نحوه ادغام کتابخانه صورت‌حساب Google Play را در برنامه خود برای شروع فروش محصولات توضیح می‌دهد.

عمر یک خرید

در اینجا یک جریان خرید معمولی برای خرید یک بار یا اشتراک وجود دارد.

  1. به کاربر نشان دهید چه چیزی می تواند بخرد.
  2. جریان خرید را راه اندازی کنید تا کاربر خرید را بپذیرد.
  3. خرید را در سرور خود تأیید کنید.
  4. به کاربر محتوا بدهید.
  5. تحویل محتوا را تایید کنید. برای محصولات مصرفی، خرید را مصرف کنید تا کاربر بتواند دوباره کالا را خریداری کند.

اشتراک ها به طور خودکار تمدید می شوند تا زمانی که لغو شوند. یک اشتراک می تواند در حالات زیر باشد:

  • فعال : کاربر در وضعیت خوبی قرار دارد و به اشتراک دسترسی دارد.
  • لغو شده : کاربر لغو کرده است اما هنوز تا انقضا دسترسی دارد.
  • در دوره مهلت : کاربر با مشکل پرداخت مواجه شد اما همچنان دسترسی دارد در حالی که Google روش پرداخت را دوباره امتحان می‌کند.
  • در انتظار : کاربر با مشکل پرداخت مواجه شد و زمانی که Google روش پرداخت را دوباره امتحان می‌کند، دیگر دسترسی ندارد.
  • Paused : کاربر دسترسی خود را متوقف کرده و تا زمانی که از سر گرفته نشود، دسترسی ندارد.
  • منقضی شده : کاربر اشتراک را لغو کرده و دسترسی خود را از دست داده است. کاربر در زمان انقضا خراشیده در نظر گرفته می شود.

اتصال به Google Play را راه اندازی کنید

اولین قدم برای ادغام با سیستم صورت‌حساب Google Play این است که کتابخانه صورت‌حساب Google Play را به برنامه خود اضافه کنید و اتصال را راه‌اندازی کنید.

وابستگی کتابخانه صورت‌حساب Google Play را اضافه کنید

مطابق شکل، وابستگی کتابخانه صورت‌حساب Google Play را به فایل build.gradle برنامه خود اضافه کنید:

Groovy

dependencies {
    def billing_version = "7.1.1"

    implementation "com.android.billingclient:billing:$billing_version"
}

Kotlin

dependencies {
    val billing_version = "7.1.1"

    implementation("com.android.billingclient:billing:$billing_version")
}

اگر از Kotlin استفاده می‌کنید، ماژول Google Play Billing Library KTX حاوی برنامه‌های افزودنی و برنامه‌های مشترک Kotlin است که به شما امکان می‌دهد هنگام استفاده از کتابخانه صورت‌حساب Google Play، Kotlin اصطلاحی بنویسید. برای گنجاندن این پسوندها در پروژه خود، مطابق شکل، وابستگی زیر را به فایل build.gradle برنامه خود اضافه کنید:

Groovy

dependencies {
    def billing_version = "7.1.1"

    implementation "com.android.billingclient:billing-ktx:$billing_version"
}

Kotlin

dependencies {
    val billing_version = "7.1.1"

    implementation("com.android.billingclient:billing-ktx:$billing_version")
}

یک BillingClient را راه اندازی کنید

هنگامی که یک وابستگی به کتابخانه صورت‌حساب Google Play اضافه کردید، باید یک نمونه BillingClient مقداردهی اولیه کنید. BillingClient رابط اصلی برای ارتباط بین Google Play Billing Library و بقیه برنامه شما است. BillingClient برای بسیاری از عملیات رایج صورت‌حساب، روش‌های راحت، هم همزمان و هم ناهمزمان را فراهم می‌کند. به موارد زیر توجه داشته باشید:

  • توصیه می‌شود برای جلوگیری از تماس‌های متعدد PurchasesUpdatedListener برای یک رویداد، یک اتصال فعال BillingClient در یک زمان باز داشته باشید.
  • توصیه می شود هنگامی که برنامه شما راه اندازی می شود یا در پیش زمینه قرار می گیرد، اتصال را برای BillingClient آغاز کنید تا مطمئن شوید برنامه شما خریدها را به موقع پردازش می کند. این را می‌توان با استفاده از ActivityLifecycleCallbacks ثبت‌شده توسط registerActivityLifecycleCallbacks و گوش دادن به onActivityResumed برای راه‌اندازی اتصال زمانی که برای اولین بار تشخیص دادید که یک فعالیت از سر گرفته می‌شود، انجام شود. برای جزئیات بیشتر در مورد اینکه چرا این بهترین روش باید دنبال شود، به بخش پردازش خریدها مراجعه کنید. همچنین به یاد داشته باشید که وقتی برنامه شما بسته است، اتصال را قطع کنید.

برای ایجاد BillingClient ، از newBuilder استفاده کنید. شما می توانید هر زمینه ای را به newBuilder() منتقل کنید و BillingClient از آن برای دریافت یک زمینه برنامه استفاده می کند. این بدان معناست که لازم نیست نگران نشت حافظه باشید. برای دریافت به‌روزرسانی‌های خرید، باید با setListener تماس بگیرید و یک مرجع به PurchasesUpdatedListener ارسال کنید. این شنونده برای همه خریدها در برنامه شما به‌روزرسانی‌ها را دریافت می‌کند.

کاتلین

private val purchasesUpdatedListener =
   PurchasesUpdatedListener { billingResult, purchases ->
       // To be implemented in a later section.
   }

private var billingClient = BillingClient.newBuilder(context)
   .setListener(purchasesUpdatedListener)
   // Configure other settings.
   .build()

جاوا

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // To be implemented in a later section.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    // Configure other settings.
    .build();

به Google Play متصل شوید

پس از ایجاد BillingClient ، باید با Google Play ارتباط برقرار کنید.

برای اتصال به Google Play، با startConnection تماس بگیرید. فرآیند اتصال ناهمزمان است، و شما باید یک BillingClientStateListener پیاده سازی کنید تا پس از تکمیل راه اندازی مشتری و آماده شدن برای درخواست های بیشتر، یک تماس پاسخ دریافت کنید.

همچنین باید منطق تلاش مجدد را برای مدیریت اتصالات از دست رفته به Google Play پیاده سازی کنید. برای پیاده‌سازی منطق امتحان مجدد، روش برگشت تماس onBillingServiceDisconnected() را لغو کنید و مطمئن شوید که BillingClient قبل از درخواست‌های بیشتر، متد startConnection() را برای اتصال مجدد به Google Play فراخوانی می‌کند.

مثال زیر نحوه شروع اتصال و آزمایش آماده استفاده از آن را نشان می دهد:

کاتلین

billingClient.startConnection(object : BillingClientStateListener {
    override fun onBillingSetupFinished(billingResult: BillingResult) {
        if (billingResult.responseCode ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    override fun onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
})

جاوا

billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});

نمایش محصولات موجود برای خرید

پس از برقراری ارتباط با Google Play، آماده پرس و جو برای محصولات موجود خود و نمایش آنها به کاربران خود هستید.

پرس و جو برای جزئیات محصول یک مرحله مهم قبل از نمایش محصولات شما به کاربران است، زیرا اطلاعات محلی محصول را برمی گرداند. برای اشتراک‌ها، مطمئن شوید نمایش محصول شما از همه خط‌مشی‌های Play پیروی می‌کند .

برای درخواست جزئیات محصول درون برنامه‌ای، با queryProductDetailsAsync تماس بگیرید.

برای رسیدگی به نتیجه عملیات ناهمزمان، باید شنونده ای را نیز مشخص کنید که رابط ProductDetailsResponseListener را پیاده سازی کند. سپس می‌توانید روی onProductDetailsResponse را نادیده بگیرید، که پس از اتمام پرس و جو به شنونده اطلاع می‌دهد، همانطور که در مثال زیر نشان داده شده است:

کاتلین

val queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build()

billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
    billingResult,
    productDetailsList ->
      // check billingResult
      // process returned productDetailsList
}

جاوا

QueryProductDetailsParams queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build();

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
        public void onProductDetailsResponse(BillingResult billingResult,
                List<ProductDetails> productDetailsList) {
            // check billingResult
            // process returned productDetailsList
        }
    }
)

هنگام درخواست جزئیات محصول، نمونه‌ای از QueryProductDetailsParams را ارسال کنید که فهرستی از رشته‌های شناسه محصول ایجاد شده در کنسول Google Play را به همراه یک ProductType مشخص می‌کند. ProductType می تواند ProductType.INAPP برای محصولات یک بار مصرف یا ProductType.SUBS برای اشتراک باشد.

پرس و جو با پسوندهای Kotlin

اگر از برنامه‌های افزودنی Kotlin استفاده می‌کنید، می‌توانید با فراخوانی تابع افزونه queryProductDetails() جزئیات محصول درون‌برنامه را جستجو کنید.

queryProductDetails() از کوروتین های Kotlin استفاده می کند تا نیازی به تعریف شنونده جداگانه نداشته باشید. در عوض، تابع تا زمانی که پرس و جو کامل شود، به حالت تعلیق در می آید، پس از آن می توانید نتیجه را پردازش کنید:

suspend fun processPurchases() {
    val productList = listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("product_id_example")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )
    val params = QueryProductDetailsParams.newBuilder()
    params.setProductList(productList)

    // leverage queryProductDetails Kotlin extension function
    val productDetailsResult = withContext(Dispatchers.IO) {
        billingClient.queryProductDetails(params.build())
    }

    // Process the result.
}

به ندرت، برخی از دستگاه‌ها نمی‌توانند از ProductDetails و queryProductDetailsAsync() پشتیبانی کنند، معمولاً به دلیل نسخه‌های قدیمی سرویس‌های Google Play . برای اطمینان از پشتیبانی مناسب از این سناریو، نحوه استفاده از ویژگی‌های سازگاری رو به عقب را در راهنمای انتقال Play Billing Library 5 بیاموزید.

نتیجه را پردازش کنید

کتابخانه صورت‌حساب Google Play نتایج جستجو را در List از اشیاء ProductDetails ذخیره می‌کند. سپس می‌توانید روش‌های مختلفی را روی هر شیء ProductDetails در فهرست فراخوانی کنید تا اطلاعات مربوط به محصول درون‌برنامه‌ای مانند قیمت یا توضیحات آن را مشاهده کنید. برای مشاهده اطلاعات جزئیات محصول موجود، به لیست روش ها در کلاس ProductDetails مراجعه کنید.

قبل از ارائه یک کالا برای فروش، بررسی کنید که کاربر قبلاً آن کالا را ندارد. اگر کاربر یک ماده مصرفی دارد که هنوز در کتابخانه اقلام او موجود است، قبل از اینکه بتواند دوباره آن را بخرد باید آن را مصرف کند.

قبل از ارائه اشتراک، بررسی کنید که کاربر قبلاً مشترک نشده باشد. همچنین به موارد زیر توجه کنید:

  • queryProductDetailsAsync() جزئیات محصول اشتراک و حداکثر 50 پیشنهاد در هر اشتراک را برمی گرداند.
  • queryProductDetailsAsync() فقط پیشنهادهایی را برمی‌گرداند که کاربر واجد شرایط آنها باشد. اگر کاربر بخواهد پیشنهادی را بخرد که برای آن واجد شرایط نیست (به عنوان مثال، اگر برنامه فهرست قدیمی از پیشنهادات واجد شرایط را نشان می‌دهد)، Play به کاربر اطلاع می‌دهد که واجد شرایط نیست، و کاربر می‌تواند طرح پایه را خریداری کند. در عوض

جریان خرید را راه اندازی کنید

برای شروع درخواست خرید از برنامه خود، متد launchBillingFlow() را از رشته اصلی برنامه خود فراخوانی کنید. این روش به یک شی BillingFlowParams اشاره می‌کند که حاوی شی ProductDetails مربوطه است که از فراخوانی queryProductDetailsAsync به دست می‌آید. برای ایجاد یک شی BillingFlowParams ، از کلاس BillingFlowParams.Builder استفاده کنید.

کاتلین

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;

val productDetailsParamsList = listOf(
    BillingFlowParams.ProductDetailsParams.newBuilder()
        // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
        .setProductDetails(productDetails)
        // For One-time products, "setOfferToken" method shouldn't be called.
        // For subscriptions, to get an offer token, call ProductDetails.subscriptionOfferDetails()
        // for a list of offers that are available to the user
        .setOfferToken(selectedOfferToken)
        .build()
)

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build()

// Launch the billing flow
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

جاوا

// An activity reference from which the billing flow will be launched.
Activity activity = ...;

ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
             // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // For one-time products, "setOfferToken" method shouldn't be called.
            // For subscriptions, to get an offer token, call
            // ProductDetails.subscriptionOfferDetails() for a list of offers
            // that are available to the user.
            .setOfferToken(selectedOfferToken)
            .build()
    );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

متد launchBillingFlow() یکی از چندین کد پاسخ فهرست شده در BillingClient.BillingResponseCode را برمی گرداند. حتماً این نتیجه را بررسی کنید تا مطمئن شوید هیچ خطایی در راه‌اندازی جریان خرید وجود ندارد. یک BillingResponseCode OK نشان دهنده راه اندازی موفقیت آمیز است.

در یک تماس موفقیت آمیز برای launchBillingFlow() ، سیستم صفحه خرید Google Play را نمایش می دهد. شکل 1 یک صفحه خرید برای اشتراک را نشان می دهد:

صفحه خرید google play اشتراکی را نشان می دهد که هست             برای خرید موجود است
شکل 1. صفحه خرید Google Play اشتراکی را نشان می دهد که برای خرید در دسترس است.

Google Play onPurchasesUpdated() را فرا می خواند تا نتیجه عملیات خرید را به شنونده ای که رابط PurchasesUpdatedListener پیاده سازی می کند، ارائه دهد. شنونده با استفاده از متد setListener() زمانی که مشتری خود را مقداردهی اولیه می کنید مشخص می شود.

شما باید onPurchasesUpdated() را برای مدیریت کدهای پاسخ احتمالی پیاده سازی کنید. مثال زیر نحوه نادیده گرفتن onPurchasesUpdated() را نشان می دهد:

کاتلین

override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
   if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) {
       for (purchase in purchases) {
           // Process the purchase as described in the next section.
       }
   } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) {
       // Handle an error caused by a user canceling the purchase flow.
   } else {
       // Handle any other error codes.
   }
}

جاوا

@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
    if (billingResult.getResponseCode() == BillingResponseCode.OK
        && purchases != null) {
        for (Purchase purchase : purchases) {
            // Process the purchase as described in the next section.
        }
    } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
        // Handle an error caused by a user canceling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

یک خرید موفق، صفحه موفقیت خرید Google Play مشابه شکل 2 ایجاد می کند.

صفحه موفقیت خرید گوگل پلی
شکل 2. صفحه موفقیت خرید Google Play.

یک خرید موفق همچنین یک رمز خرید ایجاد می کند، که یک شناسه منحصر به فرد است که نشان دهنده کاربر و شناسه محصول برای محصول درون برنامه ای است که خریداری کرده است. برنامه‌های شما می‌توانند رمز خرید را به صورت محلی ذخیره کنند، اگرچه ما قویاً توصیه می‌کنیم رمز را به سرور باطن امن خود منتقل کنید تا بتوانید خرید را تأیید کرده و در برابر تقلب محافظت کنید. این فرآیند بیشتر در شناسایی و پردازش خریدها توضیح داده شده است.

همچنین رسید تراکنش حاوی شناسه سفارش یا شناسه منحصر به فرد تراکنش به کاربر ایمیل می شود. کاربران برای هر خرید یک بار محصول، و همچنین برای خرید اشتراک اولیه و تمدید خودکار مکرر بعدی، ایمیلی با شناسه سفارش منحصر به فرد دریافت می کنند. می‌توانید از شناسه سفارش برای مدیریت بازپرداخت در کنسول Google Play استفاده کنید.

قیمت شخصی را مشخص کنید

اگر برنامه شما می‌تواند بین کاربران اتحادیه اروپا توزیع شود، هنگام فراخوانی launchBillingFlow از روش setIsOfferPersonalized() استفاده کنید تا به کاربران فاش کنید که قیمت یک مورد با استفاده از تصمیم‌گیری خودکار شخصی‌سازی شده است.

صفحه خرید Google Play نشان می دهد که قیمت برای کاربر سفارشی شده است.
شکل 3. صفحه خرید Google Play که نشان می دهد قیمت برای کاربر سفارشی شده است.

شما باید با هنر مشورت کنید. 6 (1) (ea) CRD دستورالعمل حقوق مصرف کننده 2011/83/EU برای تعیین اینکه آیا قیمتی که به کاربران ارائه می دهید شخصی است یا خیر.

setIsOfferPersonalized() یک ورودی بولی می گیرد. وقتی true ، رابط کاربری Play شامل افشا می شود. وقتی false ، UI افشاء را حذف می کند. مقدار پیش فرض false است.

برای اطلاعات بیشتر به مرکز راهنمایی مصرف کننده مراجعه کنید.

شناسه های کاربر را ضمیمه کنید

هنگامی که جریان خرید را راه‌اندازی می‌کنید، برنامه شما می‌تواند هر شناسه کاربری را که برای کاربری که با استفاده از obfuscatedAccountId یا obfuscatedProfileId خرید می‌کند، ضمیمه کند. یک شناسه نمونه می تواند یک نسخه مبهم از ورود کاربر در سیستم شما باشد. تنظیم این پارامترها می تواند به Google کمک کند کلاهبرداری را شناسایی کند . علاوه بر این، می‌تواند به شما کمک کند تا اطمینان حاصل کنید که خریدها به کاربر مناسب نسبت داده می‌شوند، همانطور که در اعطای حقوق به کاربران بحث شد.

خریدها را شناسایی و پردازش کنید

شناسایی و پردازش خرید توضیح داده شده در این بخش برای همه انواع خریدها از جمله خریدهای خارج از برنامه مانند بازخریدهای تبلیغاتی قابل اعمال است.

برنامه شما خریدهای جدید و خریدهای در انتظار تکمیل شده را به یکی از روش های زیر شناسایی می کند:

  1. هنگامی که onPurchasesUpdated در نتیجه تماس برنامه شما با launchBillingFlow فراخوانی می شود (همانطور که در بخش قبل توضیح داده شد) یا اگر برنامه شما با اتصال کتابخانه صورتحساب فعال اجرا می شود، زمانی که خریدی خارج از برنامه شما انجام شده است یا خرید معلقی انجام شده است. به عنوان مثال، یکی از اعضای خانواده خرید معلقی را در دستگاه دیگری تأیید می کند.
  2. وقتی برنامه شما با queryPurchasesAsync تماس می گیرد تا خریدهای کاربر را پرس و جو کند.

برای شماره 1 onPurchasesUpdated تا زمانی که برنامه شما در حال اجرا است و اتصال کتابخانه صورت‌حساب Google Play فعال دارد، به‌طور خودکار برای خریدهای جدید یا تکمیل‌شده فراخوانی می‌شود. اگر برنامه شما اجرا نمی شود یا برنامه شما اتصال کتابخانه صورتحساب Google Play فعال ندارد، onPurchasesUpdated فراخوانی نمی شود. به یاد داشته باشید، برای اطمینان از اینکه برنامه شما به‌روزرسانی‌های خرید را به‌موقع دریافت می‌کند، به برنامه‌تان توصیه می‌شود تا زمانی که برنامه‌تان در پیش‌زمینه است، یک اتصال فعال را حفظ کند.

برای شماره 2 باید با BillingClient.queryPurchasesAsync() تماس بگیرید تا مطمئن شوید که برنامه شما همه خریدها را پردازش می کند. توصیه می‌شود زمانی که برنامه شما با موفقیت با کتابخانه صورت‌حساب Google Play ارتباط برقرار کرد، این کار را انجام دهید (که وقتی برنامه شما راه‌اندازی می‌شود یا در پیش‌زمینه قرار می‌گیرد، همانطور که در مقداردهی اولیه BillingClient بحث شد توصیه می‌شود. این را می‌توان با تماس با queryPurchasesAsync هنگام دریافت انجام داد. نتیجه موفقیت آمیز برای onServiceConnected پیروی از این توصیه برای مدیریت رویدادها و موقعیت هایی مانند:

  • مشکلات شبکه در حین خرید : یک کاربر می‌تواند خرید موفقی انجام دهد و از Google تأیید دریافت کند، اما قبل از اینکه دستگاه او اعلان خرید را از طریق PurchasesUpdatedListener دریافت کند، دستگاه او اتصال شبکه را از دست می‌دهد.
  • چند دستگاه : یک کاربر ممکن است یک مورد را در یک دستگاه بخرد و پس از تعویض دستگاه انتظار داشته باشد که آن مورد را ببیند.
  • رسیدگی به خریدهای خارج از برنامه شما : برخی از خریدها، مانند بازخریدهای تبلیغاتی، می توانند خارج از برنامه شما انجام شوند.
  • مدیریت انتقال وضعیت خرید : کاربر ممکن است در حالی که برنامه شما در حال اجرا نیست، پرداخت را برای خرید در حال تعلیق تکمیل کند و انتظار داشته باشد زمانی که برنامه شما را باز می کند، تأییدی را دریافت کند که خرید را انجام داده است.

هنگامی که برنامه شما یک خرید جدید یا تکمیل شده را شناسایی کرد، برنامه شما باید:

  • خرید را تایید کنید
  • برای خریدهای تکمیل شده به کاربر محتوا اعطا کنید.
  • به کاربر اطلاع دهید.
  • به Google اطلاع دهید که برنامه شما خریدهای تکمیل شده را پردازش کرده است.

این مراحل به تفصیل در بخش‌های بعدی مورد بحث قرار می‌گیرند و سپس بخشی برای جمع‌بندی مجدد تمام مراحل ارائه می‌شود.

خرید را تایید کنید

قبل از اعطای مزایا به کاربر، برنامه شما همیشه باید خریدها را تأیید کند تا از قانونی بودن آنها اطمینان حاصل کند. این را می توان با پیروی از دستورالعمل های شرح داده شده در بررسی خریدها قبل از اعطای حق انجام داد. تنها پس از تأیید خرید، برنامه شما باید به پردازش خرید و اعطای حقوق به کاربر ادامه دهد، که در بخش بعدی مورد بحث قرار می‌گیرد.

اعطای حق به کاربر

هنگامی که برنامه شما خریدی را تأیید کرد، می‌تواند به اعطای این حق به کاربر ادامه دهد و به کاربر اطلاع دهد. قبل از اعطای حق، مطمئن شوید که برنامه شما بررسی می‌کند که وضعیت خرید PURCHASED است. اگر خرید در حالت PENDING است، برنامه شما باید به کاربر اطلاع دهد که هنوز باید اقدامات لازم برای تکمیل خرید را قبل از اعطای حق انجام دهد. فقط زمانی این حق را اعطا کنید که خرید از ENDING به SUCCESS تغییر کند. اطلاعات تکمیلی را می‌توانید در «کنترل معاملات معلق» پیدا کنید.

اگر شناسه‌های کاربری را به خرید متصل کرده‌اید، همانطور که در پیوست کردن شناسه‌های کاربر بحث شد، می‌توانید آن‌ها را بازیابی کنید و از آنها برای نسبت دادن به کاربر صحیح در سیستم خود استفاده کنید. این تکنیک هنگام تطبیق خریدهایی که برنامه شما ممکن است زمینه در مورد اینکه خرید برای کدام کاربری است را از دست داده باشد، مفید است. توجه داشته باشید، خریدهایی که خارج از برنامه شما انجام می‌شوند، این شناسه‌ها را ندارند. در این صورت برنامه شما می‌تواند این حق را به کاربر وارد شده اعطا کند یا از کاربر بخواهد یک حساب ترجیحی را انتخاب کند.

به کاربر اطلاع دهید

پس از اعطای حق به کاربر، برنامه شما باید یک اعلان برای تأیید خرید موفق نشان دهد. این تضمین می کند که کاربر در مورد اینکه آیا خرید با موفقیت انجام شده است یا خیر، سردرگم نمی شود، که می تواند منجر به توقف استفاده از برنامه شما، تماس با پشتیبانی کاربر یا شکایت از آن در رسانه های اجتماعی شود. توجه داشته باشید که برنامه شما ممکن است در هر زمانی در طول چرخه عمر برنامه شما به روز رسانی های خرید را شناسایی کند. برای مثال، یکی از والدین خرید معلقی را در دستگاه دیگری تأیید می‌کند، در این صورت ممکن است برنامه شما بخواهد اطلاع‌رسانی به کاربر را تا زمان مناسب به تأخیر بیندازد. برخی از نمونه هایی که در آن تاخیر مناسب است عبارتند از:

  • در حین بخش اکشن بازی یا کات سین، نمایش یک پیام ممکن است حواس کاربر را پرت کند. در این صورت باید پس از اتمام قسمت اکشن به کاربر اطلاع دهید.
  • در طول آموزش اولیه و تنظیمات کاربر بخش های بازی. به عنوان مثال، یک کاربر ممکن است قبل از نصب برنامه شما، خریدی را در خارج از آن انجام داده باشد. توصیه می کنیم بلافاصله پس از باز کردن بازی یا در حین راه اندازی اولیه کاربر، پاداش را به کاربران جدید اطلاع دهید. اگر برنامه شما از کاربر می‌خواهد قبل از اعطای حق به کاربر، یک حساب کاربری ایجاد کند یا وارد سیستم شود، توصیه می‌شود به کاربر خود اطلاع دهید که چه مراحلی را برای ادعای خرید خود تکمیل کند. این بسیار مهم است زیرا اگر برنامه شما خرید را پردازش نکرده باشد، خریدها پس از 3 روز بازپرداخت می شوند.

هنگام اطلاع دادن کاربر در مورد خرید، Google Play مکانیسم های زیر را توصیه می کند:

  • نمایش یک گفتگوی درون برنامه.
  • پیام را به یک جعبه پیام درون برنامه تحویل دهید، و به وضوح بیان کنید که یک پیام جدید در جعبه پیام درون برنامه وجود دارد.
  • از پیام اعلان سیستم عامل استفاده کنید.

این اعلان باید کاربر را از مزایایی که دریافت کرده است مطلع کند. به عنوان مثال، "شما 100 سکه طلا خریداری کردید!". به‌علاوه، اگر خرید در نتیجه مزایای برنامه‌ای مانند Play Pass باشد، برنامه شما این موضوع را به کاربر اطلاع می‌دهد. به عنوان مثال "اقلام دریافت شد! شما به تازگی 100 جواهر با Play Pass دریافت کردید. ادامه دهید.". هر برنامه ممکن است راهنمایی در مورد متن توصیه شده برای نمایش به کاربران برای برقراری ارتباط منافع داشته باشد.

به Google اطلاع دهید که خرید پردازش شده است

پس از اینکه برنامه شما به کاربر حق داد و او را در مورد تراکنش موفقیت آمیز مطلع کرد، برنامه شما باید به Google اطلاع دهد که خرید با موفقیت پردازش شده است. این کار با تایید خرید انجام می شود و باید ظرف سه روز انجام شود تا اطمینان حاصل شود که خرید به طور خودکار بازپرداخت نمی شود و حق باطل نمی شود . فرآیند تایید انواع مختلف خرید در بخش های زیر توضیح داده شده است.

محصولات مصرفی

در مورد مواد مصرفی، اگر برنامه شما دارای پشتوانه امنی است، توصیه می‌کنیم از Purchases.products:consume برای مصرف مطمئن خریدها استفاده کنید. اطمینان حاصل کنید که خرید قبلاً مصرف نشده است، با بررسی consumptionState از نتیجه تماس Purchases.products:get . اگر برنامه شما فقط برای کلاینت بدون پشتیبان است، از consumeAsync() از کتابخانه صورت‌حساب Google Play استفاده کنید. هر دو روش الزامات تأیید را برآورده می‌کنند و نشان می‌دهند که برنامه شما به کاربر این حق را داده است. این روش‌ها همچنین به برنامه شما امکان می‌دهند محصول یک‌بار مصرف مربوط به رمز خرید ورودی را برای خرید مجدد در دسترس قرار دهد. با consumeAsync() باید یک شی را نیز ارسال کنید که رابط ConsumeResponseListener را پیاده سازی کند. این شیء نتیجه عملیات مصرف را کنترل می کند. می‌توانید روش onConsumeResponse() را که کتابخانه صورت‌حساب Google Play پس از اتمام عملیات فراخوانی می‌کند، لغو کنید.

مثال زیر مصرف یک محصول با کتابخانه صورت‌حساب Google Play را با استفاده از رمز خرید مرتبط نشان می‌دهد:

کاتلین

    val consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build()
    val consumeResult = withContext(Dispatchers.IO) {
        client.consumePurchase(consumeParams)
    }

جاوا

    ConsumeParams consumeParams =
            ConsumeParams.newBuilder()
                .setPurchaseToken(purchase.getPurchaseToken())
                .build();

    ConsumeResponseListener listener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                // Handle the success of the consume operation.
            }
        }
    };

    billingClient.consumeAsync(consumeParams, listener);

محصولات غیر مصرفی

برای تأیید خریدهای غیرقابل مصرف، اگر برنامه شما دارای پشتوانه ایمن است، توصیه می کنیم از Purchases.products:acknowledge برای تأیید مطمئن خریدها استفاده کنید. اطمینان حاصل کنید که خرید قبلا تأیید نشده است، با بررسی acknowledgementState از نتیجه تماس Purchases.products:get .

اگر برنامه شما فقط برای مشتری است، از BillingClient.acknowledgePurchase() از کتابخانه صورت‌حساب Google Play در برنامه خود استفاده کنید. قبل از تأیید خرید، برنامه شما باید با استفاده از روش isAcknowledged() در کتابخانه صورت‌حساب Google Play بررسی کند که آیا قبلاً تأیید شده است یا خیر.

مثال زیر نحوه تأیید خرید با استفاده از کتابخانه صورت‌حساب Google Play را نشان می‌دهد:

کاتلین

val client: BillingClient = ...
val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ...

val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
    .setPurchaseToken(purchase.purchaseToken)
val ackPurchaseResult = withContext(Dispatchers.IO) {
     client.acknowledgePurchase(acknowledgePurchaseParams.build())
}

جاوا

BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...

AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
 client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);

اشتراک ها

اشتراک ها به طور مشابه با موارد غیر مصرفی اداره می شوند. در صورت امکان، از Purchases.subscriptions.acknowledge از Google Play Developer API استفاده کنید تا به طور قابل اعتماد خرید را از قسمت پشتیبان امن خود تأیید کنید. با بررسی وضعیت acknowledgementState در منبع خرید از Purchases.subscriptions:get ، اطمینان حاصل کنید که خرید قبلاً تأیید نشده است. در غیر این صورت، می‌توانید با استفاده از BillingClient.acknowledgePurchase() از کتابخانه صورت‌حساب Google Play پس از بررسی isAcknowledged() اشتراک را تأیید کنید. همه خریدهای اشتراک اولیه باید تایید شوند. تمدید اشتراک نیازی به تایید ندارد. برای کسب اطلاعات بیشتر در مورد اینکه چه زمانی باید اشتراک ها تایید شوند، به مبحث فروش اشتراک ها مراجعه کنید.

خلاصه

قطعه کد زیر خلاصه ای از این مراحل را نشان می دهد.

کاتلین

fun handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify
.
    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

جاوا

void handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify

    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

برای تأیید اینکه برنامه شما این مراحل را به درستی اجرا کرده است، می توانید راهنمای آزمایش را دنبال کنید.

رسیدگی به معاملات معلق

Google Play از تراکنش‌های معلق یا تراکنش‌هایی که نیاز به یک یا چند مرحله اضافی بین زمانی که کاربر خریدی را شروع می‌کند تا زمانی که روش پرداخت برای خرید پردازش می‌شود، پشتیبانی می‌کند. تا زمانی که Google به شما اطلاع ندهد که روش پرداخت کاربر با موفقیت کسر شده است، برنامه شما نباید حق این نوع خریدها را اعطا کند.

به عنوان مثال، یک کاربر می تواند با انتخاب یک فروشگاه فیزیکی که در آن بعداً با پول نقد پرداخت می کند، تراکنش را آغاز کند. کاربر یک کد را از طریق اعلان و ایمیل دریافت می کند. هنگامی که کاربر به فروشگاه فیزیکی می رسد، می تواند کد را نزد صندوقدار بازخرید کند و با پول نقد پرداخت کند. سپس Google به شما و کاربر اطلاع می دهد که پرداخت دریافت شده است. سپس برنامه شما می تواند به کاربر این حق را بدهد.

enablePendingPurchases() به عنوان بخشی از مقداردهی اولیه BillingClient برای فعال کردن تراکنش های معلق برای برنامه خود فراخوانی کنید. برنامه شما باید تراکنش های معلق را برای محصولات یکبار مصرف فعال و پشتیبانی کند. قبل از افزودن پشتیبانی، مطمئن شوید که چرخه عمر خرید تراکنش های معلق را درک کرده اید.

وقتی برنامه شما خرید جدیدی دریافت می‌کند، چه از طریق PurchasesUpdatedListener یا در نتیجه تماس queryPurchasesAsync ، از روش getPurchaseState() برای تعیین اینکه آیا وضعیت خرید PURCHASED یا PENDING است استفاده کنید. شما باید این حق را تنها زمانی اعطا کنید که ایالت PURCHASED باشد.

اگر برنامه شما در حال اجرا است و وقتی کاربر خرید را تکمیل می‌کند، یک اتصال کتابخانه صورت‌حساب Play فعال دارید، PurchasesUpdatedListener شما دوباره فراخوانی می‌شود و PurchaseState اکنون PURCHASED است. در این مرحله، برنامه شما می‌تواند خرید را با استفاده از روش استاندارد شناسایی و پردازش خریدها پردازش کند. برنامه شما همچنین باید queryPurchasesAsync() را در روش onResume() برنامه شما فراخوانی کند تا خریدهایی را انجام دهد که در حالی که برنامه شما در حال اجرا نبود به حالت PURCHASED منتقل شده اند.

هنگامی که خرید از PENDING به PURCHASED تغییر می کند، مشتری real_time_developer_notifications شما یک اعلان ONE_TIME_PRODUCT_PURCHASED یا SUBSCRIPTION_PURCHASED دریافت می کند. اگر خرید لغو شود، یک اعلانی ONE_TIME_PRODUCT_CANCELED یا SUBSCRIPTION_PENDING_PURCHASE_CANCELED دریافت خواهید کرد. این می تواند اتفاق بیفتد اگر مشتری شما پرداخت را در بازه زمانی لازم انجام ندهد. توجه داشته باشید که همیشه می‌توانید از Google Play Developer API برای بررسی وضعیت فعلی خرید استفاده کنید.

خریدهای چندتایی را انجام دهید

Google Play که در نسخه‌های 4.0 و بالاتر از کتابخانه صورت‌حساب Google Play پشتیبانی می‌شود، به مشتریان امکان می‌دهد با تعیین مقداری از سبد خرید، بیش از یک محصول درون‌برنامه مشابه را در یک تراکنش خریداری کنند. از برنامه شما انتظار می‌رود که خریدهای چندتایی را انجام دهد و بر اساس مقدار خرید مشخص‌شده، حق اعطا کند.

برای احترام به خریدهای چندتایی، منطق تهیه برنامه شما باید مقدار مورد را بررسی کند. می توانید از یکی از API های زیر به فیلد quantity دسترسی داشته باشید:

پس از اینکه منطق را برای انجام خریدهای چندتایی اضافه کردید، سپس باید ویژگی چند مقداری را برای محصول مربوطه در صفحه مدیریت محصول درون برنامه ای در کنسول برنامه نویس Google Play فعال کنید.

پیکربندی صورت‌حساب کاربر را پرس و جو کنید

getBillingConfigAsync() کشوری را که کاربر برای Google Play استفاده می کند ارائه می کند.

می‌توانید پیکربندی صورت‌حساب کاربر را پس از ایجاد BillingClient جستجو کنید. قطعه کد زیر نحوه برقراری تماس با getBillingConfigAsync() را توضیح می دهد. پاسخ را با اجرای BillingConfigResponseListener مدیریت کنید. این شنونده به‌روزرسانی‌هایی را برای تمام درخواست‌های پیکربندی صورت‌حساب که از برنامه شما آغاز شده است، دریافت می‌کند.

اگر BillingResult برگشتی حاوی هیچ خطایی نباشد، می‌توانید قسمت countryCode را در شی BillingConfig بررسی کنید تا Play Country کاربر را بدست آورید.

کاتلین

// Use the default GetBillingConfigParams.
val getBillingConfigParams = GetBillingConfigParams.newBuilder().build()
billingClient.getBillingConfigAsync(getBillingConfigParams,
    object : BillingConfigResponseListener {
        override fun onBillingConfigResponse(
            billingResult: BillingResult,
            billingConfig: BillingConfig?
        ) {
            if (billingResult.responseCode == BillingResponseCode.OK
                && billingConfig != null) {
                val countryCode = billingConfig.countryCode
                ...
            } else {
                // TODO: Handle errors
            }
        }
    })

جاوا

// Use the default GetBillingConfigParams.
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build();
billingClient.getBillingConfigAsync(getBillingConfigParams,
    new BillingConfigResponseListener() {
      public void onBillingConfigResponse(
          BillingResult billingResult, BillingConfig billingConfig) {
        if (billingResult.getResponseCode() == BillingResponseCode.OK
            && billingConfig != null) {
            String countryCode = billingConfig.getCountryCode();
            ...
         } else {
            // TODO: Handle errors
        }
      }
    });

یادآوری‌های رها کردن سبد خرید در صفحه اصلی بازی‌های Google Play (به طور پیش‌فرض فعال است)

برای توسعه‌دهندگان بازی‌هایی که از طریق IAP کسب درآمد می‌کنند، یکی از راه‌هایی که می‌توان واحدهای ذخیره‌سازی سهام (SKU) فعال در کنسول Google Play را خارج از برنامه‌تان فروخت، ویژگی Cart Abandonment Reminder است، که کاربران را وادار می‌کند تا خریدهای قبلی خود را انجام دهند. در حال مرور فروشگاه Google Play این خریدها خارج از برنامه شما، از خانه بازی‌های Google Play در فروشگاه Google Play انجام می‌شود.

این ویژگی به‌طور پیش‌فرض فعال است تا به کاربران کمک کند از جایی که کار را رها کرده‌اند ادامه دهند و به توسعه‌دهندگان کمک کند فروش را به حداکثر برسانند. با این حال، می‌توانید با ارسال فرم انصراف از ویژگی یادآوری سبد خرید، برنامه خود را از این ویژگی خارج کنید. برای بهترین روش‌ها در مدیریت SKUها در کنسول Google Play، به ایجاد محصول درون‌برنامه مراجعه کنید.

تصاویر زیر یادآور ترک سبد خرید را نشان می‌دهند که در فروشگاه Google Play ظاهر می‌شود:

صفحه فروشگاه Google Play یک را نشان می دهد     درخواست خرید برای خریدی که قبلاً رها شده است
شکل 2. صفحه فروشگاه Google Play یک درخواست خرید برای خریدی که قبلاً رها شده را نشان می دهد.

صفحه فروشگاه Google Play یک را نشان می دهد     درخواست خرید برای خریدی که قبلاً رها شده است
شکل 3. صفحه فروشگاه Google Play یک درخواست خرید برای خریدی که قبلاً رها شده است را نشان می دهد.