Hướng dẫn tích hợp hệ thống thanh toán thay thế do người dùng chọn trong ứng dụng

Hướng dẫn này mô tả cách tích hợp các API để cung cấp hệ thống thanh toán thay thế do người dùng chọn trong ứng dụng của bạn.

Thiết lập Thư viện Play Billing

Thêm phần phụ thuộc Thư viện Play Billing vào ứng dụng Android của bạn. Để sử dụng các API hệ thống thanh toán thay thế, bạn cần sử dụng phiên bản 5.2 trở lên. Nếu bạn cần di chuyển từ phiên bản cũ sang, hãy làm theo hướng dẫn di chuyển này trước khi triển khai hệ thống thanh toán thay thế.

Kết nối với Google Play

Các bước đầu tiên trong quy trình tích hợp cũng giống như các bước tương ứng mà Hướng dẫn tích hợp Google Play Billing mô tả, chỉ có một vài điểm sửa đổi khi khởi động BillingClient:

  • Để cho biết rằng bạn muốn cho người dùng lựa chọn hệ thống thanh toán, bạn cần gọi một phương thức mới là: enableUserChoiceBilling.
  • Bạn cần đăng ký UserChoiceBillingListener để xử lý trường hợp người dùng chọn hệ thống thanh toán thay thế.

Ví dụ sau minh hoạ việc khởi động BillingClient với một số điểm sửa đổi:

Kotlin

val purchasesUpdatedListener =
   PurchasesUpdatedListener { billingResult, purchases ->
       // Handle new Google Play purchase.
   }

val userChoiceBillingListener =
   UserChoiceBillingListener { userChoiceDetails ->
       // Handle alternative billing choice.
   }

var billingClient = BillingClient.newBuilder(context)
   .setListener(purchasesUpdatedListener)
   .enablePendingPurchases()
   .enableUserChoiceBilling(userChoiceBillingListener)
   .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // Handle new Google Play purchase.
    }
};

private UserChoiceBillingListener userChoiceBillingListener = new UserChoiceBillingListener() {
    @Override
    public void userSelectedAlternativeBilling(
        UserChoiceDetails userChoiceDetails) {
        // Handle new Google Play purchase.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .enableUserChoiceBilling(userChoiceBillingListener)
    .build();

Sau khi khởi động BillingClient, bạn cần thiết lập kết nối với Google Play theo mô tả trong hướng dẫn tích hợp.

Hiển thị các sản phẩm hiện có

Bạn có thể cho người dùng thấy các sản phẩm hiện có theo cách tương tự như khi tích hợp hệ thống Google Play Billing. Khi người dùng thấy sản phẩm còn hàng và chọn mua một sản phẩm, hãy bắt đầu quy trình thanh toán qua phương thức do người dùng chọn theo mô tả trong phần sau đây.

Bắt đầu quy trình thanh toán theo phương thức do người dùng chọn

Gọi launchBillingFlow() để bắt đầu quy trình thanh toán theo phương thức do người dùng chọn Việc này giống như việc bắt đầu quy trình mua bằng hệ thống thanh toán tích hợp của Google Play: cung cấp một thực thể ProductDetailsofferToken tương ứng với sản phẩm và ưu đãi mà người dùng muốn nhận được. Nếu người dùng chọn hệ thống thanh toán của Google Play, thông tin này sẽ được dùng để tiếp tục quy trình mua.

Khi nhà phát triển gọi launchBillingFlow(), hệ thống thanh toán của Google Play sẽ thực hiện bước kiểm tra sau đây:

  • Hệ thống sẽ kiểm tra xem quốc gia trên Google Play của người dùng có phải là quốc gia có hỗ trợ hệ thống thanh toán thay thế do người dùng lựa chọn (tức là một quốc gia được hỗ trợ) hay không. Nếu quốc gia của người dùng trên Google Play là quốc gia được hỗ trợ, thì Google Play sẽ dựa trên cấu hình của BillingClient để kiểm tra xem liệu hệ thống thanh toán thay thế đã được bật hay chưa.
    • Nếu hệ thống thanh toán thay thế do người dùng chọn đã bật, thì quy trình mua sẽ cho thấy trải nghiệm người dùng do người dùng lựa chọn.
    • Nếu hệ thống thanh toán thay thế do người dùng chọn chưa bật, thì quy trình mua sẽ cho thấy trải nghiệm người dùng tiêu chuẩn của hệ thống thanh toán của Google Play mà không cần người dùng chọn.
  • Nếu quốc gia của người dùng trên Google Play không phải là quốc gia được hỗ trợ, thì quy trình mua sẽ cho thấy trải nghiệm người dùng tiêu chuẩn của hệ thống thanh toán của Google Play mà không cần người dùng chọn.

Quốc gia trên Play của người dùng là quốc gia được hỗ trợ

Quốc gia trên Play của người dùng không phải là quốc gia được hỗ trợ

enableUserChoiceBilling sẽ được gọi trong quá trình thiết lập BillingClient

Người dùng thấy trải nghiệm người dùng do người dùng lựa chọn

Người dùng thấy trải nghiệm người dùng tiêu chuẩn của hệ thống thanh toán của Google Play

EnableUserChoiceBilling không được gọi trong quá trình thiết lập BillingClient

Người dùng thấy trải nghiệm người dùng tiêu chuẩn của hệ thống thanh toán của Google Play

Người dùng thấy trải nghiệm người dùng tiêu chuẩn của hệ thống thanh toán của Google Play

Xử lý lựa chọn của người dùng

Tuỳ thuộc vào việc người dùng chọn hệ thống thanh toán của Google Play hay hệ thống thanh toán thay thế mà bạn sẽ xử lý phần còn lại của quy trình mua theo cách phù hợp.

Khi người dùng chọn một hệ thống thanh toán thay thế

Nếu người dùng chọn hệ thống thanh toán thay thế, thì Google Play sẽ gọi UserChoiceBillingListener để thông báo cho ứng dụng rằng cần khởi động quy trình mua trong hệ thống thanh toán thay thế. Cụ thể, phương thức userSelectedAlternativeBilling() sẽ được gọi.

Mã thông báo giao dịch bên ngoài (do đối tượng UserChoiceDetails cung cấp) đại diện cho chữ ký xác nhận rằng người dùng lựa chọn chuyển đến quy trình thanh toán thay thế. Hãy dùng mã thông báo này để báo cáo mọi giao dịch phát sinh từ lựa chọn này (như giải thích trong hướng dẫn tích hợp phần phụ trợ).

UserChoiceBillingListener sẽ thực hiện những thao tác sau:

  • Nhận dữ liệu về (các) sản phẩm đang được người dùng chọn mua để sản phẩm đó xuất hiện trong quy trình mua trên hệ thống thanh toán thay thế.
  • Thu thập chuỗi nhận được dưới dạng mã thông báo giao dịch bên ngoài rồi gửi tới phần phụ trợ để duy trì chuỗi đó. Sau đó, mã này sẽ được dùng để báo cáo giao dịch bên ngoài cho Google Play nếu người dùng hoàn tất giao dịch mua này.
  • Bắt đầu quy trình mua qua hệ thống thanh toán thay thế của nhà phát triển.

Khi người dùng hoàn tất giao dịch mua hàng bằng hệ thống thanh toán thay thế, thì bạn phải báo cáo giao dịch đó cho Google Play bằng cách gọi API Nhà phát triển Google Play qua phần phụ trợ trong vòng 24 giờ, cung cấp externalTransactionToken và các thông tin cụ thể khác về giao dịch. Vui lòng xem hướng dẫn tích hợp phần phụ trợ để biết thêm thông tin.

Ví dụ sau đây minh hoạ cách triển khai UserChoiceBillingListener:

Kotlin

private val userChoiceBillingListener =
    UserChoiceBillingListener { userChoiceDetails ->
        // Get the products being purchased by the user.
        val products = userChoiceDetails.products

        // Send external transaction token to developer backend server
        // this devBackend object is for demonstration purposes,
        // developers can implement this step however best fits their
        // app to backend communication.
        devBackend.sendExternalTransactionStarted(
            userChoiceDetails.externalTransactionToken,
            user
        )

        // Launch alternative billing
        // ...
        // The developer backend handles reporting the transaction
        // to Google Play's backend once the alternative billing
        // purchase is completed.
    }

Java

private userChoiceBillingListener userChoiceBillingListener = new UserChoiceBillingListener() {
    @Override
    public void userSelectedAlternativeBilling(
           UserChoiceDetails userChoiceDetails) {
       // Get the products being purchased by the user.
       List<Product> products =
              userChoiceDetails.getProducts();

       // Send external transaction token to developer backend server
       // this devBackend object is for demonstration purposes,
       // developers can implement this step however best fits their
       // app to backend communication.
       devBackend.sendExternalTransactionStarted(
              userChoiceDetails.getExternalTransactionToken(),
              user
       );

       // Launch alternative billing
       // ...
       // The developer backend handles reporting the transaction
       // to Google Play's backend once the alternative billing
       // purchase is completed.
    }
};

Khi người dùng chọn hệ thống thanh toán của Google Play

Nếu người dùng chọn hệ thống thanh toán của Google Play, họ sẽ thực hiện tiếp giao dịch mua hàng qua Google Play.

  • Xem phần Xử lý giao dịch mua trong hướng dẫn tích hợp thư viện để biết thêm thông tin về cách xử lý các giao dịch mua mới trong ứng dụng thông qua hệ thống thanh toán của Google Play.
  • Xem phần Gói thuê bao mới trong hướng dẫn quản lý gói thuê bao để được hướng dẫn thêm về giao dịch mua gói thuê bao.

Xử lý các thay đổi trong gói thuê bao

Đối với nhà phát triển sử dụng hệ thống thanh toán thay thế do người dùng chọn, tuỳ vào lựa chọn của người dùng mà giao dịch mua sẽ cần được xử lý thông qua hệ thống thanh toán của Google Play hoặc được báo cáo bằng externalTransactionId. Các thay đổi đối với gói thuê bao hiện tại từng được thực hiện thông qua quy trình theo lựa chọn của người dùng sẽ được tiếp tục thực hiện qua chính hệ thống thanh toán đó cho đến khi hết hạn.

Phần này mô tả cách xử lý một số tình huống thường gặp về việc thay đổi gói thuê bao.

Quy trình nâng cấp và hạ cấp

Các thay đổi đối với gói thuê bao, bao gồm cả quy trình nâng cấp và hạ cấp gói thuê bao được xử lý khác nhau, tuỳ thuộc vào việc gói thuê bao có được mua ban đầu hay không thông qua hệ thống thanh toán của Google Play hoặc một hệ thống thanh toán thay thế.

Các tiện ích bổ sung phụ thuộc vào một gói thuê bao hiện có, có cùng phương thức thanh toán, và điều chỉnh khoản phí định kỳ sẽ được xử lý dưới dạng bản nâng cấp. Đối với các tiện ích bổ sung khác, người dùng có thể chọn hệ thống thanh toán họ muốn sử dụng. Bắt đầu một chiến dịch mới trải nghiệm mua hàng bằng cách sử dụng launchBillingFlow(), như mô tả trong phần Khởi chạy quy trình thanh toán do người dùng chọn.

Gói thuê bao mua qua hệ thống thanh toán thay thế

Đối với gói thuê bao ban đầu được người dùng chọn mua qua hệ thống thanh toán thay thế của nhà phát triển, yêu cầu nâng cấp hoặc hạ cấp của người dùng sẽ được xử lý thông qua hệ thống thanh toán thay thế của nhà phát triển mà người dùng không cần chọn lần nữa.

Để thực hiện việc này, hãy gọi launchBillingFlow() khi người dùng yêu cầu nâng cấp hoặc hạ cấp. Thay vì chỉ định đối tượng SubscriptionUpdateParams trong các tham số, hãy sử dụng setOriginalExternalTransactionId, cung cấp mã giao dịch bên ngoài đối với giao dịch mua ban đầu. Thao tác này sẽ không cho thấy màn hình lựa chọn của người dùng, vì lựa chọn của người dùng cho giao dịch mua ban đầu được giữ nguyên cho việc nâng cấp và hạ cấp. Trong trường hợp này, lệnh gọi đến launchBillingFlow() sẽ tạo ra mã giao dịch bên ngoài mới đối với giao dịch mà bạn truy xuất được qua lệnh gọi lại.

Kotlin

// The external transaction ID from the current
// alternative billing subscription.
val externalTransactionId = //... ;

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        listOf(
            BillingFlowParams.ProductDetailsParams.newBuilder()
                // Fetched via queryProductDetailsAsync.
                .setProductDetails(productDetailsNewPlan)
                // offerIdToken can be found in
                // ProductDetails=>SubscriptionOfferDetails.
                .setOfferToken(offerTokenNewPlan)
                .build()
        )
    )
    .setSubscriptionUpdateParams(
        BillingFlowParams.SubscriptionUpdateParams.newBuilder()
            .setOriginalExternalTransactionId(externalTransactionId)
            .build()

val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

// When the user selects the alternative billing flow,
// the UserChoiceBillingListener is triggered.

Java

// The external transaction ID from the current
// alternative billing subscription.
String externalTransactionId = //... ;

BillingFlowParams billingFlowParams =
        BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(
                ImmutableList.of(
                    ProductDetailsParams.newBuilder()
                        // Fetched via queryProductDetailsAsync.
                        .setProductDetails(productDetailsNewPlan)
                        // offerIdToken can be found in
                        // ProductDetails=>SubscriptionOfferDetails
                        .setOfferToken(offerTokenNewPlan)
                    .build()
                )
            )
            .setSubscriptionUpdateParams(
                SubscriptionUpdateParams.newBuilder()
                    .setOriginalExternalTransactionId(externalTransactionId)
                    .build()
            )
            .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

// When the user selects the alternative billing flow,
// the UserChoiceBillingListener is triggered.

Khi hoàn tất quy trình nâng cấp hoặc hạ cấp gói thuê bao trong hệ thống thanh toán thay thế, bạn cần báo cáo giao dịch mới bằng mã thông báo giao dịch bên ngoài nhận được thông qua lệnh gọi trước đó đối với giao dịch mua gói thuê bao mới.

Gói thuê bao mua qua hệ thống thanh toán của Google Play

Tương tự như vậy, đối với người dùng mua gói thuê bao hiện tại qua hệ thống thanh toán của Google Play sau khi đưa ra lựa chọn, họ sẽ thấy quy trình nâng cấp hoặc hạ cấp gói thuê bao đó trong hệ thống thanh toán của Google Play. Hướng dẫn sau đây mô tả cách bắt đầu quy trình mua để nâng cấp hoặc hạ cấp gói thuê bao thông qua hệ thống thanh toán của Google Play:

  1. Xác định offerToken của ưu đãi đã chọn đối với gói mới:

val offerTokenNewPlan = productDetailsNewPlan
             .getSubscriptionOfferDetails(selectedOfferIndex)
             .getOfferToken()

String offerTokenNewPlan = productDetailsNewPlan
                     .getSubscriptionOfferDetails(selectedOfferIndex)
                     .getOfferToken();
  1. Gửi thông tin chính xác đến hệ thống thanh toán của Google Play để xử lý giao dịch mua mới, bao gồm cả mã thông báo giao dịch mua cho gói thuê bao hiện có:

val billingFlowParams =
    BillingFlowParams.newBuilder().setProductDetailsParamsList(
        listOf(
            BillingFlowParams.ProductDetailsParams.newBuilder()
                .setProductDetails(productDetailsNewPlan)
                .setOfferToken(offerTokenNewPlan)
                .build()
        )
    )
    .setSubscriptionUpdateParams(
        BillingFlowParams.SubscriptionUpdateParams.newBuilder()
            .setOldPurchaseToken(oldToken)
            .setReplaceProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
            .build()
        )
        .build()

BillingClient.launchBillingFlow(activity, billingFlowParams)

BillingFlowParams billingFlowParams =
        BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(
                ImmutableList.of(
                    ProductDetailsParams.newBuilder()
                        // Fetched via queryProductDetailsAsync
                        .setProductDetails(productDetailsNewPlan)
                        // offerIdToken can be found in
                        // ProductDetails=>SubscriptionOfferDetails.
                        .setOfferToken(offerTokenNewPlan)
                        .build()
                )
            )
            .setSubscriptionUpdateParams(
                SubscriptionUpdateParams.newBuilder()
                    // purchaseToken can be found in
                    // Purchase#getPurchaseToken
                    .setOldPurchaseToken("old_purchase_token")
                    .setReplaceProrationMode(ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
                    .build()
            )
            .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

Giao dịch mua này sẽ được xử lý trong hệ thống thanh toán của Google Play. Đồng thời, ứng dụng của bạn sẽ nhận được lệnh gọi PurchasesUpdatedListener.onPurchaseUpdated kèm theo kết quả của giao dịch mua. Nếu giao dịch mua thành công, phương thức onPurchaseUpdated() cũng nhận được thông tin về giao dịch mua mới, đồng thời phần phụ trợ sẽ nhận được Thông báo theo thời gian thực dành cho nhà phát triển SUBSCRIPTION_PURCHASED. Khi lấy trạng thái cho giao dịch mua mới, thuộc tính linkedPurchaseToken sẽ liên kết với giao dịch mua gói thuê bao cũ để bạn có thể gỡ bỏ thông tin đó theo đề xuất.

Huỷ và khôi phục gói thuê bao

Người dùng có thể huỷ gói thuê bao của họ bất cứ lúc nào. Khi người dùng huỷ một gói thuê bao, quá trình chấm dứt hoạt động của gói thuê bao này có thể bị trì hoãn cho đến khi kỳ thanh toán kết thúc. Ví dụ: nếu người dùng huỷ gói thuê bao hằng tháng vào giữa tháng, thì họ vẫn có thể tiếp tục sử dụng dịch vụ đó trong khoảng 2 tuần còn lại cho đến khi bị xoá quyền truy cập. Trong thời gian này, về mặt kỹ thuật thì gói thuê bao vẫn đang hoạt động, nên người dùng vẫn sử dụng được dịch vụ.

Không có gì lạ khi người dùng đổi ý không huỷ gói thuê bao nữa trong thời gian gói thuê bao này còn hoạt động. Trong hướng dẫn này, việc này được gọi là khôi phục. Các phần sau đây mô tả cách xử lý các tình huống khôi phục gói thuê bao khi bạn tích hợp API hệ thống thanh toán thay thế.

Gói thuê bao mua qua hệ thống thanh toán thay thế

Nếu có mã giao dịch bên ngoài cho một gói thuê bao đã huỷ, thì bạn không cần gọi launchBillingFlow() để khôi phục gói thuê bao đó. Vì vậy, bạn không nên sử dụng mã này cho loại quy trình kích hoạt này. Nếu người dùng khôi phục gói thuê bao đã huỷ trong khi thời gian hoạt động của gói thuê bao đó vẫn còn, thì sẽ không có giao dịch nào xảy ra tại thời điểm đó cả. Có thể bạn chỉ cần tiếp tục báo cáo về việc gia hạn khi kết thúc chu kỳ sử dụng hiện tại và bắt đầu đợt gia hạn tiếp theo. Trong đó có cả trường hợp người dùng nhận được một khoản tín dụng hoặc giá gia hạn đặc biệt trong quá trình khôi phục gói thuê bao (ví dụ: chương trình khuyến mãi để khuyến khích người dùng tiếp tục sử dụng gói thuê bao).

Gói thuê bao mua qua hệ thống thanh toán của Google Play

Nhìn chung, người dùng có thể khôi phục gói thuê bao trên hệ thống thanh toán của Google Play. Đối với những gói thuê bao ban đầu được mua trên hệ thống thanh toán của Google Play nhưng sau đó bị huỷ, nếu gói thuê bao đó vẫn còn trong thời gian hoạt động, thì người dùng có thể chọn không huỷ nữa thông qua tính năng Đăng ký lại của Google Play. Trong trường hợp đó, bạn sẽ nhận được Thông báo theo thời gian thực dành cho nhà phát triển SUBSCRIPTION_RESTARTED trong phần phụ trợ, đồng thời sẽ không phát hành mã thông báo giao dịch mua mới. Mã thông báo gốc sẽ được dùng để tiếp tục gói thuê bao. Để tìm hiểu cách quản lý tính năng khôi phục trong hệ thống thanh toán của Google Play, hãy xem phần Khôi phục trong hướng dẫn quản lý gói thuê bao.

Trên ứng dụng, bạn cũng có thể gọi launchBillingFlow() để kích hoạt quy trình khôi phục gói thuê bao trong hệ thống thanh toán của Google Play. Vui lòng xem phần Trước khi gói thuê bao hết hạn – trong ứng dụng để được giải thích về cách thực hiện việc này. Trong trường hợp người dùng đã trải qua quy trình lựa chọn đối với giao dịch mua ban đầu (đã bị huỷ nhưng vẫn còn hoạt động), hệ thống sẽ tự động phát hiện lựa chọn của họ và cho thấy giao diện người dùng để khôi phục giao dịch mua này. Họ sẽ được yêu cầu xác nhận việc mua lại gói thuê bao thông qua Google Play, nhưng không cần thực hiện lại quy trình lựa chọn của người dùng. Trong trường hợp này, hệ thống sẽ phát hành mã thông báo giao dịch mua mới cho người dùng. Phần phụ trợ của bạn sẽ nhận được một Thông báo theo thời gian thực dành cho nhà phát triển SUBSCRIPTION_PURCHASED và giá trị linkedPurchaseToken của trạng thái giao dịch mua mới được thiết lập như trong trường hợp nâng cấp hoặc hạ cấp gói thuê bao, với mã thông báo của giao dịch mua cũ cho gói thuê bao đã bị huỷ.

Đăng ký lại

Nếu một gói thuê bao hết hạn hoàn toàn, cho dù là do gói thuê bao đó bị huỷ hay không khôi phục được do bị từ chối thanh toán (tạm ngưng tài khoản), thì người dùng phải đăng ký lại nếu muốn bắt đầu sử dụng lại.

Bạn cũng có thể cho phép đăng ký lại thông qua ứng dụng (quy trình đăng ký lại sẽ được xử lý tương tự như quy trình đăng ký chuẩn). Người dùng phải chọn được hệ thống thanh toán họ muốn sử dụng. launchBillingFlow() có thể được gọi trong trường hợp này, như mô tả trong phần Bắt đầu quy trình thanh toán theo phương thức do người dùng chọn.

Kiểm thử hệ thống thanh toán thay thế

Bạn nên sử dụng nhân viên kiểm thử được cấp phép để kiểm thử việc tích hợp hệ thống thanh toán thay thế. Bạn sẽ không được lập hoá đơn cho các giao dịch do người kiểm thử được cấp phép tài khoản. Xem bài viết Thử nghiệm tính năng thanh toán trong ứng dụng bằng quy trình cấp phép ứng dụng để biết thêm thông tin thông tin về cách định cấu hình nhân viên kiểm thử được cấp phép.

Các bước tiếp theo

Sau khi hoàn tất quy trình tích hợp trong ứng dụng, bạn đã sẵn sàng tích hợp phần phụ trợ.