এক্সটার্নাল অফার প্রোগ্রামের জন্য ইন-অ্যাপ ইন্টিগ্রেশন সংক্রান্ত নির্দেশিকা

উপযুক্ত অ্যাপ ও অঞ্চলে এক্সটার্নাল অফার কাজ করে এমন API-এর সাথে কীভাবে ইন্টিগ্রেট করতে হয় তা এই নির্দেশিকায় বর্ণনা করা হয়েছে। উপযুক্ততার প্রয়োজনীয়তা ও ভৌগোলিক পরিধি সহ এক্সটার্নাল অফার প্রোগ্রাম সম্পর্কে আরও জানতে প্রোগ্রামের প্রয়োজনীয়তা দেখুন।

Play Billing Library সেট-আপ

এক্সটার্নাল অফার API ব্যবহার করতে, আপনার Android অ্যাপে Play Billing লাইব্রেরি ডিপেন্ডেন্সির 8.2.1 বা তার পরের যেকোনও ভার্সন যোগ করুন । আগের কোনও ভার্সন থেকে মাইগ্রেট করতে হলে, এক্সটার্নাল অফার ইমপ্লিমেন্ট করার চেষ্টা করার আগে মাইগ্রেশন গাইডে দেওয়া নির্দেশাবলী অনুসরণ করুন।

Google Play-তে কানেক্ট করা

ইন্টিগ্রেশন প্রসেসের প্রথম ধাপগুলি বিলিং ইন্টিগ্রেশন গাইডে বর্ণিত ধাপগুলির মতোই, তবে আপনাকে enableBillingProgram কল করে জানাতে হবে যে আপনি এক্সটার্নাল অফার ব্যবহার করতে চান আপনার BillingClient শুরু করার সময়:

নিচের উদাহরণে এইসব পরিবর্তন সহ BillingClient শুরু করার পদ্ধতি দেখানো হয়েছে:

Kotlin

val billingClient = BillingClient.newBuilder(context)
    .enableBillingProgram(
        EnableBillingProgramParams.newBuilder()
            .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
            .build()
    )
    .build()

জাভা

private BillingClient billingClient = BillingClient.newBuilder(context)
    .enableBillingProgram(BillingProgram.EXTERNAL_OFFER)
    .build();

BillingClient চালু করার পরে, ইন্টিগ্রেশন গাইডে যেভাবে বর্ণনা করা হয়েছে সেই অনুযায়ী আপনাকে Google Play-এর সাথে কানেকশন স্থাপন করতে হবে।

উপলভ্যতা যাচাই করুন

বর্তমান ব্যবহারকারীর জন্য এক্সটার্নাল অফার উপলভ্য আছে কিনা তা কনফার্ম করতে, isBillingProgramAvailableAsync কল করুন।

এক্সটার্নাল অফার উপলভ্য থাকলে, এই API BillingResponseCode.OK রিটার্ন করে। আপনার অ্যাপ কীভাবে অন্যান্য রেসপন্স কোডের উত্তর দেবে সেই সম্পর্কে বিস্তারিত জানতে উত্তর হ্যান্ডেল করা দেখুন।

Kotlin

billingClient.isBillingProgramAvailableAsync(
    BillingProgram.EXTERNAL_OFFER,
    object : BillingProgramAvailabilityListener {
        override fun onBillingProgramAvailabilityResponse(
            billingResult: BillingResult,
            billingProgramAvailabilityDetails: BillingProgramAvailabilityDetails
        ) {
            if (billingResult.responseCode != BillingResponseCode.OK) {
                // Handle failures such as retrying due to network errors,
                // handling external offers unavailable, etc.
                return
            }

            // External offers are available. Continue with steps in the
            // guide.
        }
    }
)

জাভা


billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_OFFER,
  new BillingProgramAvailabilityListener() {
    @Override
    public void onBillingProgramAvailabilityResponse(
      BillingResult billingResult,
      BillingProgramAvailabilityDetails billingProgramAvailabilityDetails) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external offers being unavailable, etc.
            return;
        }
        // External offers are available. Continue with steps in the
        // guide.
      }
  });

এক্সটার্নাল ট্রানজ্যাকশন টোকেন প্রস্তুত করা

Google Play-তে কোনও এক্সটার্নাল ট্রানজ্যাকশনের ব্যাপারে অভিযোগ জানাতে, আপনার কাছে অবশ্যই Play Billing Library থেকে জেনারেট করা এক্সটার্নাল ট্রানজ্যাকশন টোকেন থাকতে হবে। createBillingProgramReportingDetailsAsync API কল করে আপনি এই টোকেন পেতে পারেন। প্রতিটি এক্সটার্নাল অফারের জন্য ব্যবহারকারীকে অ্যাপের বাইরে ডাইরেক্ট করার ঠিক আগে একটি নতুন টোকেন জেনারেট করতে হবে। টোকেনগুলি ট্রানজ্যাকশন জুড়ে ক্যাশে করা যাবে না।

Kotlin

val params =
    BillingProgramReportingDetailsParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
        .build()

billingClient.createBillingProgramReportingDetailsAsync(
    params,
    object : BillingProgramReportingDetailsListener {
        override fun onCreateBillingProgramReportingDetailsResponse(
            billingResult: BillingResult,
            billingProgramReportingDetails: BillingProgramReportingDetails?
        ) {
            if (billingResult.responseCode != BillingResponseCode.OK) {
                // Handle failures such as retrying due to network errors.
                return
            }
            val externalTransactionToken =
                billingProgramReportingDetails?.externalTransactionToken
            // Persist the transaction token in your backend. You may pass it
            // to the external website when calling the launchExternalLink API.
        }
    }
)

জাভা

BillingProgramReportingDetailsParams params =
  BillingProgramReportingDetailsParams.newBuilder()
    .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
    .build();

billingClient.createBillingProgramReportingDetailsAsync(
  params,
  new BillingProgramReportingDetailsListener() {
    @Override
    public void onCreateBillingProgramReportingDetailsResponse(
      BillingResult billingResult,
      @Nullable BillingProgramReportingDetails
        billingProgramReportingDetails) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors.
            return;
        }

        String transactionToken =
          billingProgramReportingDetails.getExternalTransactionToken();
        // Persist the transaction token in your backend. You may pass it
        // to the external website when calling the launchExternalLink API.
      }
});

অথবা, আপনি Kotlin এক্সটেনশন সহ সাসপেন্ড ফাংশন createBillingProgramReportingDetailsAsync কোয়েরি করতে পারেন, যাতে আপনাকে কোনও লিসনার ডিফাইন করতে না হয়:

val createBillingProgramReportingDetailsResult =
    withContext(coroutineContext) {
        billingClient
            .createBillingProgramReportingDetails(params)
    }
// Process the result

এক্সটার্নাল অফার ফ্লো লঞ্চ করা

এক্সটার্নাল অফার ফ্লো শুরু করতে, আপনার উপযুক্ত অ্যাপকে অবশ্যই অ্যাপের মূল থ্রেড থেকে launchExternalLink() API কল করতে হবে। এই API একটি LaunchExternalLinkParams অবজেক্টের ইনপুট নেয়। কোনও LaunchExternalLinkParams অবজেক্ট তৈরি করতে, LaunchExternalLinkParams.Builder ক্লাস ব্যবহার করুন। এই ক্লাসে নিম্নলিখিত প্যারামিটার রয়েছে:

  • linkUri - এক্সটার্নাল ওয়েবসাইটের লিঙ্ক যেখানে ডিজিটাল কন্টেন্ট বা অ্যাপ ডাউনলোড অফার করা হয়। অ্যাপ ডাউনলোডের জন্য, এই লিঙ্কটি Play Developer Console-এ রেজিস্টার ও অনুমোদিত হতে হবে।
  • linkType - ব্যবহারকারীকে অফার করা কন্টেন্টের ধরন।
  • launchMode - লিঙ্কটি কীভাবে লঞ্চ করা হবে তা নির্দিষ্ট করে। অ্যাপ ডাউনলোডের জন্য, আপনাকে এটি LAUNCH_IN_EXTERNAL_BROWSER_OR_APP হিসেবে সেট করতে হবে।
  • billingProgram - এটি BillingProgram.EXTERNAL_OFFER হিসেবে সেট করুন।

আপনি launchExternalLink()-এ কল করলে, এটি ব্যবহারকারীর সেটিংসের উপর ভিত্তি করে ব্যবহারকারীকে অতিরিক্ত তথ্য ডায়ালগ দেখাতে পারে। launchMode প্যারামিটারের উপর নির্ভর করে, Play হয় এক্সটার্নাল ব্রাউজারে লিঙ্ক URI লঞ্চ করে অথবা URI লঞ্চ করার জন্য আপনার অ্যাপে ফ্লো রিটার্ন করে। বেশিরভাগ ক্ষেত্রে, আপনি LAUNCH_IN_EXTERNAL_BROWSER_OR_APP মোড ব্যবহার করতে পারবেন যেখানে Play আপনার জন্য URI লঞ্চ করবে। আপনি যদি আরও কাস্টমাইজ করা আচরণ চান, যেমন, কোনও ওয়েবভিউতে URI লঞ্চ করা বা কোনও নির্দিষ্ট ব্রাউজারে URI খোলা, তাহলে আপনি CALLER_WILL_LAUNCH_LINK মোড ব্যবহার করতে পারেন। ব্যবহারকারীর গোপনীয়তা সুরক্ষিত রাখতে, URI-তে কোনও ব্যক্তিগতভাবে শনাক্তকরণযোগ্য তথ্য (PII) পাস করা হচ্ছে না কিনা তা নিশ্চিত করুন।

Kotlin

// An activity reference from which the external offers flow will be launched.
val activity = this.activity

val params =
    LaunchExternalLinkParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
        // You can pass along the external transaction token from
        // BillingProgramReportingDetails as a URL parameter in the URI
        .setLinkUri(yourLinkUri)
        .setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_APP_DOWNLOAD)
        .setLaunchMode(
            LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP
        )
        .build()

val listener: LaunchExternalLinkResponseListener =
    LaunchExternalLinkResponseListener { billingResult ->
        if (billingResult.responseCode == BillingResponseCode.OK) {
            // Proceed with the rest of the external offer flow. If the user
            // purchases an item, be sure to report the transaction to Google Play.
        } else {
            // Handle failures such as retrying due to network errors.
        }
    }

billingClient.launchExternalLink(activity, params, listener)

জাভা


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

LaunchExternalLinkParams params = LaunchExternalLinkParams.newBuilder()
  .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
  // You can pass along the external transaction token from  
  // BillingProgramReportingDetails as a URL parameter in the URI
  .setLinkUri(yourLinkUri)
  .setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_APP_DOWNLOAD)
  .setLaunchMode(
    LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
  .build();

LaunchExternalLinkResponseListener listener =
  new LaunchExternalLinkResponseListener() {
    @Override
    public void onLaunchExternalLinkResponse(BillingResult billingResult) {
      if (billingResult.responseCode == BillingResponseCode.OK) {
        // Proceed with the rest of the external offer flow. If the user
        // purchases an item, be sure to report the transaction to Google
        // Play.
      } else {
        // Handle failures such as retrying due to network errors.
      }
    }
  }

billingClient.launchExternalLink(activity, params, listener);

আপনি LaunchMode-এর মান CALLER_WILL_LAUNCH_LINK হিসেবে সেট করলে, ব্যবহারকারীকে অ্যাপের বাইরে তখনই ডাইরেক্ট করা উচিত, যদি onLaunchExternalLinkResponse-এ BillingResponseCode.OK থাকে।

Google Play-তে ট্রানজ্যাকশনের বিষয়ে অভিযোগ জানানো

আপনার ব্যাকএন্ড থেকে Google Play Developer API কল করে আপনাকে অবশ্যই Google Play-তে সব এক্সটার্নাল ট্রানজ্যাকশন সম্পর্কে রিপোর্ট করতে হবে। আপনি কোনও ট্রানজ্যাকশনের ব্যাপারে অভিযোগ জানালে, আপনাকে অবশ্যই externalTransactionToken API থেকে পাওয়া createBillingProgramReportingDetailsAsync প্রদান করতে হবে। কোনও ব্যবহারকারী একাধিক বার কিনলে, প্রতিটি কেনাকাটার রিপোর্ট করার জন্য আপনি একই externalTransactionToken ব্যবহার করতে পারবেন। কীভাবে কোনও ট্রানজ্যাকশনের ব্যাপারে অভিযোগ জানাতে হয় তা জানতে, ব্যাকএন্ড ইন্টিগ্রেশন গাইড দেখুন।

উত্তরের ম্যানেজমেন্ট

কোনও সমস্যা হলে, isBillingProgramAvailableAsync(), createBillingProgramReportingDetailsAsync() এবং launchExternalLink() পদ্ধতিগুলি BillingResponseCode.OK ছাড়া অন্য উত্তর দিতে পারে। এইসব রেসপন্স কোড কীভাবে হ্যান্ডেল করবেন তা নিচে দেওয়া হল:

  • ERROR: এটি ইন্টার্নাল সমস্যা। ট্রানজ্যাকশন সম্পূর্ণ করবেন না বা এক্সটার্নাল ওয়েবসাইট খুলবেন না। আপনি যখন ব্যবহারকারীকে অ্যাপের বাইরে ডাইরেক্ট করার চেষ্টা করবেন, তখন ব্যবহারকারীকে তথ্য দেখানোর ডায়ালগ দেখানোর জন্য launchExternalLink() কল করে আবার চেষ্টা করুন।
  • FEATURE_NOT_SUPPORTED: বর্তমান ডিভাইসে Play Store-এ এক্সটার্নাল অফার API কাজ করে না। ট্রানজ্যাকশন সম্পূর্ণ করবেন না বা এক্সটার্নাল ওয়েবসাইট খুলবেন না।
  • USER_CANCELED: এক্সটার্নাল ওয়েবসাইট খোলার প্রসেসটি সম্পূর্ণ করবেন না। আপনি যখন ব্যবহারকারীকে অ্যাপের বাইরে ডাইরেক্ট করার চেষ্টা করবেন, তখন launchExternalLink() আবার কল করে ব্যবহারকারীকে তথ্য ডায়ালগ দেখান।
  • BILLING_UNAVAILABLE: ট্রানজ্যাকশনটি এক্সটার্নাল অফারের জন্য উপযুক্ত নয় এবং তাই এই প্রোগ্রামের অধীনে এটি প্রসেস করা উচিত নয়। এর কারণ হল ব্যবহারকারী এই প্রোগ্রামের জন্য উপযুক্ত দেশে থাকেন না অথবা আপনার অ্যাকাউন্ট প্রোগ্রামে সফলভাবে এনরোল করা হয়নি। যদি দ্বিতীয়টি হয়, তাহলে Play Developer Console-এ আপনার এনরোলমেন্ট স্ট্যাটাস চেক করুন।
  • DEVELOPER_ERROR: অনুরোধে সমস্যা আছে। এগিয়ে যাওয়ার আগে সমস্যা শনাক্ত ও সমাধান করতে ডিবাগ মেসেজ ব্যবহার করুন।
  • NETWORK_ERROR, SERVICE_DISCONNECTED, SERVICE_UNAVAILABLE: এগুলি হল ক্ষণস্থায়ী সমস্যা যা উপযুক্ত আবার চেষ্টা করার নীতি দিয়ে ম্যানেজ করা উচিত। SERVICE_DISCONNECTED-এর ক্ষেত্রে, আবার চেষ্টা করার আগে Google Play-এর সাথে কানেকশন আবার স্থাপন করুন।

এক্সটার্নাল অফার পরীক্ষা করা

আপনার এক্সটার্নাল অফার ইন্টিগ্রেশন পরীক্ষা করার জন্য লাইসেন্স টেস্টার ব্যবহার করা উচিত। লাইসেন্স টেস্টার অ্যাকাউন্ট থেকে শুরু করা ট্রানজ্যাকশনের জন্য আপনাকে ইনভয়েস করা হবে না। লাইসেন্স টেস্টার কনফিগার করা সম্পর্কে আরও তথ্য পেতে, অ্যাপ্লিকেশন লাইসেন্সিং সহ ইন-অ্যাপ বিলিং টেস্ট করা দেখুন।

পরবর্তী ধাপ

ইন-অ্যাপ ইন্টিগ্রেশন সম্পূর্ণ হয়ে গেলে, আপনি ব্যাকএন্ড ইন্টিগ্রেট করার জন্য প্রস্তুত।