Tích hợp Thư viện Google Play Billing vào ứng dụng | Hệ thống thanh toán của Google Play | Android Developers
Chủ đề này diễn đạt cách tích hợp Thư viện Google Play Billing vào ứng dụng để khởi đầu bán loại sản phẩm .
Chủ đề này bao gồm các mã ví dụ dựa trên ứng dụng mẫu
chính thức trên GitHub. Bạn có thể xem
các tài nguyên khác
để biết danh sách đầy đủ ứng dụng mẫu và tài nguyên khác mà bạn có thể sử dụng
trong khi tích hợp.Bạn đang đọc: Tích hợp Thư viện Google Play Billing vào ứng dụng | Hệ thống thanh toán của Google Play | Android Developers
Mục Chính
- Vòng đời của một giao dịch mua hàng
- Khởi tạo kết nối với Google Play
- Hiển thị các sản phẩm có sẵn để mua
- Bắt đầu quy trình mua
- Báo giá dành riêng cho bạn
- Xử lý giao dịch mua hàng
- Tìm nạp các giao dịch mua hàng
- Xử lý giao dịch mua hàng được thực hiện bên ngoài ứng dụng
- Xử lý các giao dịch đang chờ
- Xử lý giao dịch mua số lượng nhiều
Vòng đời của một giao dịch mua hàng
Dưới đây là tiến trình mua nổi bật cho thanh toán giao dịch mua hàng một lần hoặc một gói thuê bao .
- Hiển thị cho người dùng những sản phẩm mà họ có thể mua.
- Khởi chạy quy trình mua để người dùng chấp nhận giao dịch mua hàng.
- Xác minh giao dịch mua hàng trên máy chủ.
- Cung cấp nội dung cho người dùng.
- Xác nhận việc phân phối nội dung. Đối với các sản phẩm tiêu dùng, hãy tiến hành
giao dịch mua để người dùng có thể mua lại mặt hàng đó.Các gói thuê bao sẽ tự động hóa gia hạn cho đến khi bị hủy. Gói thuê bao hoàn toàn có thể trải qua những trạng thái sau :
- Đang hoạt động: Người dùng hiện ở trạng thái tốt và có quyền truy cập vào gói thuê bao.
- Đã huỷ: Người dùng đã huỷ nhưng vẫn có quyền truy cập vào gói thuê bao cho đến khi hết hạn.
- Trong thời gian gia hạn: Người dùng gặp phải vấn đề thanh toán nhưng vẫn có quyền truy cập trong khi Google đang thử lại phương thức thanh toán.
- Tạm ngưng: Người dùng gặp phải vấn đề thanh toán và không còn quyền truy cập trong khi Google đang thử lại phương thức thanh toán.
- Bị tạm dừng: Người dùng đã tạm dừng quyền truy cập và không có quyền truy cập cho đến khi họ tiếp tục.
- Đã hết hạn: Người dùng đã huỷ và mất quyền truy cập vào gói thuê bao.
Người dùng được coi là rời bỏ ứng dụng khi gói thuê bao hết hạn.Khởi tạo kết nối với Google Play
Bước tiên phong để tích hợp với mạng lưới hệ thống giao dịch thanh toán của Google Play là thêm Thư viện Google Play Billing vào ứng dụng của bạn và khởi đầu liên kết .
Thêm phần phụ thuộc Thư viện Google Play Billing
Lưu ý:Nếu đã làm theo hướng dẫn Giai đoạn chuẩn bị sẵn sàng thì bạn đã thêm những phần phụ thuộc thiết yếu và hoàn toàn có thể chuyển sang phần tiếp theo .
Thêm phần phụ thuộc Thư viện Google Play Billing vào tệp
build.gradle
của ứng dụng như dưới đây:Groovy
dependencies { def billing_version = "6.0.0" implementation "com.android.billingclient:billing:$billing_version" }Kotlin
dependencies { val billing_version = "6.0.0" implementation("com.android.billingclient:billing:$billing_version") }Nếu bạn đang sử dụng Kotlin, mô-đun KTX của Thư viện Google Play Billing chứa các tiện ích và coroutine của Kotlin, cho phép bạn viết mã
Kotlin tương thích khi sử dụng Thư viện Google Play Billing. Để đưa
các tiện ích này vào dự án, hãy thêm phần phụ thuộc sau vào
tệpbuild.gradle
của ứng dụng như dưới đây:Groovy
dependencies { def billing_version = "6.0.0" implementation "com.android.billingclient:billing-ktx:$billing_version" }Kotlin
dependencies { val billing_version = "6.0.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }Khởi chạy BillingClient
Sau khi thêm một phần phụ thuộc vào Thư viện Google Play Billing, bạn cần
khởi chạy một bản sao củaBillingClient
.BillingClient
là giao diện chính để giao tiếp giữa
Thư viện Google Play Billing và các phần còn lại của ứng dụng.BillingClient
cung cấp các phương thức thuận tiện (cả đồng bộ và không đồng bộ) cho
nhiều hoạt động thanh toán phổ biến. Chúng tôi đặc biệt khuyến nghị bạn chỉ nên có một
kết nốiBillingClient
hiện hoạt tại một thời điểm để tránh tạo ra nhiều lệnh gọi lạiPurchasesUpdatedListener
cho một sự kiện duy nhất.Để tạo
BillingClient
, hãy sử dụng
newBuilder()
.
Bạn có thể chuyển bất kỳ ngữ cảnh nào đến hàmnewBuilder()
, đồng thờiBillingClient
sử dụng hàm này để
nhận ngữ cảnh của ứng dụng. Điều đó có nghĩa là bạn không cần lo lắng về việc rò rỉ bộ nhớ. Để nhận thông tin cập nhật về giao dịch mua, bạn cũng phải gọi hàm
setListener()
bằng cách truyền tham chiếu đến một
PurchasesUpdatedListener
.
Trình nghe này nhận nội dung cập nhật cho tất cả giao dịch mua trong ứng dụng.Kotlin
private val purchasesUpdatedListener = PurchasesUpdatedListener { billingResult, purchases -> // To be implemented in a later section. } private var billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .build()Java
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() { @Override public void onPurchasesUpdated(BillingResult billingResult, Listpurchases) { // To be implemented in a later section. } }; private BillingClient billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .build(); Lưu ý:
BillingResult
chứaBillingResult
còn chứaThư viện Google Play Billing sẽ trả về lỗi dưới dạng
BillingResult
chứaBillingResponseCode
, giúp phân loại các lỗi liên quan đến việc thanh toán mà ứng dụng của bạn có thể gặp phải. Ví dụ: nếu bạn nhận được mã lỗiSERVICE_DISCONNECTED
, ứng dụng phải khởi động lại kết nối với Google Play. Ngoài ra,còn chứa thông báo gỡ lỗi. Đây là một thông báo hữu ích trong quá trình phát triển để chẩn đoán lỗi.Kết nối với Google Play
Sau khi đã tạo một
BillingClient
, bạn cần thiết lập kết nối với Google Play.Để kết nối với Google Play, hãy gọi hàm
startConnection()
.
Quá trình kết nối không đồng bộ, và bạn phải triển khai
BillingClientStateListener
để nhận một lệnh gọi lại sau khi ứng dụng được thiết lập và sẵn sàng
tạo thêm yêu cầu.Bạn cũng phải triển khai logic thử lại để xử lý việc mất kết nối với
Google Play. Để triển khai logic thử lại, hãy ghi đè phương pháp gọi lại
onBillingServiceDisconnected()
và đảm bảo rằngBillingClient
gọi phương thức
startConnection()
để kết nối lại với Google Play trước khi tạo yêu cầu tiếp theo.Ví dụ sau đây minh họa cách khởi đầu một liên kết và kiểm tra xem liên kết đã chuẩn bị sẵn sàng để sử dụng chưa :
Kotlin
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. } })Java
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. } });Lưu ý:
BillingClient
khi
thực thi bất kỳ phương thức nào.Bạn nên triển khai logic kết nối lại của riêng mình và ghi đè phương thức
onBillingServiceDisconnected()
. Hãy đảm bảo bạn duy trì kết nốikhi thực thi bất kỳ phương thức nào.Hiển thị các sản phẩm có sẵn để mua
Sau khi thiết lập liên kết với Google Play, bạn hoàn toàn có thể truy vấn những mẫu sản phẩm mà mình hiện có và cho người dùng thấy những mẫu sản phẩm đó .
Truy vấn thông tin cụ thể về loại sản phẩm là một bước quan trọng trước khi hiển thị mẫu sản phẩm cho người dùng vì việc truy vấn này sẽ trả về thông tin loại sản phẩm đã bản địa hóa. Đối với gói thuê bao, hãy bảo vệ loại sản phẩm hiển thị tuân thủ toàn bộ chủ trương của Play .Để truy vấn thông tin chi tiết về sản phẩm trong ứng dụng, hãy gọi
queryProductDetailsAsync()
.Để xử lý kết quả của hoạt động không đồng bộ, bạn cũng phải chỉ định một trình nghe có chức năng triển khai giao diện
ProductDetailsResponseListener
. Sau đó, bạn có thể ghi đè
onProductDetailsResponse()
để thông báo cho trình nghe khi truy vấn kết thúc, như minh hoạ trong ví dụ sau:Kotlin
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 } )Java
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, ListproductDetailsList) { // check billingResult // process returned productDetailsList } } ) Khi truy vấn thông tin chi tiết về sản phẩm, hãy chuyển một bản sao của
QueryProductDetailsParams
để chỉ định danh sách các chuỗi mã sản phẩm được tạo trong Google Play Console cùng vớiProductType
.ProductType
có thể làProductType.INAPP
đối với các sản phẩm tính phí một lần hoặcProductType.SUBS
đối với các gói thuê bao.Truy vấn bằng tiện ích Kotlin
Nếu đang sử dụng phần mở rộng Kotlin, bạn có thể truy vấn thông tin chi tiết về sản phẩm trong ứng dụng bằng cách gọi hàm mở rộng
queryProductDetails()
.
queryProductDetails()
tận dụng coroutine của Kotlin để bạn không cần xác định một trình nghe riêng biệt. Thay vào đó, hàm này sẽ tạm ngưng cho đến khi truy vấn hoàn tất, sau đó bạn có thể xử lý kết quả:suspend fun processPurchases() { val productList = ArrayList
() productList.add( 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. } Trong một số ít trường hợp, một số thiết bị không hỗ trợ
ProductDetails
vàqueryProductDetailsAsync()
, thường là do các phiên bản Dịch vụ Google Play đã lỗi thời. Để đảm bảo nhận được sự hỗ trợ phù hợp cho trường hợp này, hãy tìm hiểu cách sử dụng tính năng tương thích ngược trong hướng dẫn di chuyển Thư viện Play Billing 5.Xử lý kết quả
Thư viện Google Play Billing lưu trữ các kết quả truy vấn trong một
List
các đối tượngProductDetails
. Sau đó, bạn có thể gọi nhiều phương thức cho mỗi đối tượngProductDetails
trong danh sách để xem thông tin liên quan về một sản phẩm trong ứng dụng, chẳng hạn như giá hoặc phần mô tả. Để xem thông tin chi tiết về sản phẩm có sẵn, hãy xem danh sách các phương thức trong lớpProductDetails
.Trước khi chào bán một mẫu sản phẩm, hãy kiểm tra để bảo vệ rằng người dùng chưa chiếm hữu loại sản phẩm đó. Nếu người dùng có một loại sản phẩm tiêu dùng vẫn còn trong thư viện mẫu sản phẩm, thì họ phải tiêu thụ trước khi hoàn toàn có thể mua lại mẫu sản phẩm đó .
Trước khi đưa ra khuyễn mãi thêm một gói thuê bao, hãy xác định rằng người dùng chưa ĐK. Ngoài ra, hãy quan tâm những điều sau :
queryProductDetailsAsync()
trả về thông tin chi tiết của sản phẩm đăng ký và tối đa 50 ưu đãi cho mỗi gói thuê bao.queryProductDetailsAsync()
chỉ trả về những ưu đãi người dùng đủ điều kiện. Nếu người dùng cố gắng mua một ưu đãi mà họ không đủ điều kiện (ví dụ: nếu ứng dụng đang đưa ra danh sách ưu đãi đủ điều kiện nhưng đã hết hạn), thì Play sẽ thông báo cho người dùng việc họ không đủ điều kiện, và họ có thể chuyển sang mua gói cơ bản.Lưu ý:
Một số thiết bị Android có thể có phiên bản ứng dụng cũ của Cửa hàng Google Play và không hỗ trợ một số loại sản phẩm, chẳng hạn như các gói thuê bao. Trước khi ứng dụng bước vào quy trình thanh toán, bạn có thể gọi hàm
isFeatureSupported()
để xác định xem thiết bị có hỗ trợ các sản phẩm bạn muốn bán hay không. Để biết danh sách các loại sản phẩm có thể được hỗ trợ, hãy xemBillingClient.FeatureType
Bắt đầu quy trình mua
Để bắt đầu yêu cầu mua hàng từ ứng dụng của bạn, hãy gọi phương thức
launchBillingFlow()
từ luồng chính của ứng dụng. Phương thức này tham chiếu đến đối tượngBillingFlowParams
chứa đối tượngProductDetails
liên quan đã nhận được từ việc gọiqueryProductDetailsAsync()
.
Để tạo một đối tượngBillingFlowParams
, hãy dùng lớpBillingFlowParams.Builder
.Kotlin
// 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) // 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)Java
// An activity reference from which the billing flow will be launched. Activity activity = ...; ImmutableList productDetailsParamsList = ImmutableList.of( ProductDetailsParams.newBuilder() // retrieve a value for "productDetails" by calling queryProductDetailsAsync() .setProductDetails(productDetails) // to get an offer token, call ProductDetails.getSubscriptionOfferDetails() // 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);Phương thức
launchBillingFlow()
trả về một trong nhiều mã phản hồi
được liệt kê trong
BillingClient.BillingResponseCode
.
Hãy kiểm tra kết quả này để đảm bảo không có lỗi khi khởi chạy
quy trình mua.BillingResponseCode
OK
cho biết đã khởi chạy thành công.Khi bạn gọi hàm
launchBillingFlow()
thành công, hệ thống sẽ hiển thị màn hình mua hàng trên Google Play. Hình 1 hiển thị màn hình mua cho một
gói thuê bao:
Hình 1. Màn hình mua hàng trên Google Play hiển thị một
gói thuê bao mà bạn có thể mua.Google Play gọi hàm
onPurchasesUpdated()
để cung cấp kết quả
của thao tác mua hàng cho một trình nghe có nhiệm vụ triển khai giao diện
PurchasesUpdatedListener
. Trình nghe này được chỉ định bằng phương thức
setListener()
khi bạn khởi chạy ứng dụng của mình.Bạn phải thực thi
onPurchasesUpdated()
để xử lý các mã phản hồi khả thi.
Ví dụ sau đây trình bày cách ghi đèonPurchasesUpdated()
:Kotlin
override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List?) { if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) { for (purchase in purchases) { handlePurchase(purchase) } } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user cancelling the purchase flow. } else { // Handle any other error codes. } } Java
@Override void onPurchasesUpdated(BillingResult billingResult, Listpurchases) { if (billingResult.getResponseCode() == BillingResponseCode.OK && purchases != null) { for (Purchase purchase : purchases) { handlePurchase(purchase); } } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user cancelling the purchase flow. } else { // Handle any other error codes. } } Giao dịch mua thành công xuất sắc sẽ tạo ra một màn hình hiển thị mua hàng thành công xuất sắc trên Google Play, tựa như như hình 2 .
Hình 2. Màn hình giao dịch mua thành công của
Google Play.Một lượt mua hàng thành công xuất sắc cũng tạo ra một mã mua hàng. Mã này là giá trị nhận dạng duy nhất, đại diện thay mặt cho người dùng và mã mẫu sản phẩm của mẫu sản phẩm trong ứng dụng mà họ đã mua. Ứng dụng hoàn toàn có thể tàng trữ cục bộ mã thông tin thanh toán giao dịch mua, nhưng bạn nên truyền mã thông tin này tới sever phụ trợ bảo mật thông tin của bạn. Tại sever đó, bạn hoàn toàn có thể xác định và bảo vệ thanh toán giao dịch mua khỏi hành vi gian lận. Quy trình này được miêu tả kỹ hơn trong phần tiếp theo .
Người dùng cũng sẽ nhận được biên nhận thanh toán giao dịch chứa Mã đơn hàng hoặc một mã nhận dạng duy nhất của thanh toán giao dịch qua email. Người dùng sẽ nhận được một email kèm Mã đơn hàng duy nhất cho mỗi lần mua mẫu sản phẩm tính phí một lần, cũng như thanh toán giao dịch mua gói thuê bao lần đầu và những lần gia hạn tự động hóa định kỳ tiếp theo. Bạn hoàn toàn có thể sử dụng Mã đơn hàng để quản trị tiền hoàn trả trong Google Play Console .Báo giá dành riêng cho bạn
Nếu bạn có thể phân phối ứng dụng cho người dùng ở Liên minh Châu Âu, hãy sử dụng phương thức
setIsOfferPersonalized()
để cho người dùng biết rằng giá của mặt hàng đã được cá nhân hoá bằng tính năng ra quyết định tự động.
Hình 3. Màn hình mua hàng trên Google Play cho biết giá này được điều chỉnh cho phù hợp với người dùng.Bạn phải tìm hiểu thêm qua Art. 6 ( 1 ) ( ea ) CRD của Chỉ thị về quyền của người tiêu dùng ( 2011 / 83 / EU ) để xác lập xem giá bạn cung ứng cho người dùng có được cá thể hóa hay không .
setIsOfferPersonalized()
nhận giá trị nhập boolean. Khitrue
, giao diện người dùng Play có bao gồm thông tin công bố. Khifalse
, giao diện người dùng bỏ qua thông tin công bố. Giá trị mặc định làfalse
.Hãy truy cập vào Trung tâm trợ giúp người tiêu dùng để biết thêm thông tin.
Xử lý giao dịch mua hàng
Sau khi người dùng hoàn tất giao dịch mua, ứng dụng cần xử lý
giao dịch mua đó. Trong hầu hết các trường hợp, ứng dụng sẽ nhận được thông báo về giao dịch mua hàng thông quaPurchasesUpdatedListener
.
Tuy nhiên, trong một số trường hợp, ứng dụng sẽ ghi nhận giao dịch mua hàng bằng cách gọiBillingClient.queryPurchasesAsync()
như mô tả trong phần Tìm nạp các giao dịch mua hàng.Ngoài ra, nếu có ứng dụng Thông báo theo thời gian thực dành cho nhà phát triển trong phần phụ trợ bảo mật, bạn có thể đăng ký giao dịch mua hàng mới bằng cách nhận
subscriptionNotification
hoặconeTimeProductNotification
(chỉ dành cho các giao dịch mua hàng đang chờ xử lý) thông báo cho bạn về giao dịch mua hàng mới. Sau khi nhận được những thông báo này, hãy gọi API Nhà phát triển Google Play để nhận trạng thái đầy đủ và cập nhật trạng thái phụ trợ của riêng bạn.Ứng dụng nên giải quyết và xử lý thanh toán giao dịch mua hàng theo cách sau :
- Xác minh giao dịch mua hàng.
- Cung cấp nội dung cho người dùng và xác nhận việc phân phối nội dung.
Đánh dấu mặt hàng là đã tiêu thụ để người dùng có thể mua lại (không bắt buộc).Để xác minh một giao dịch mua hàng, trước tiên hãy kiểm tra xem
trạng thái mua hàng
có phải làPURCHASED
hay không.
Nếu giao dịch mua làPENDING
, thì bạn nên xử lý giao dịch mua như được mô tả trong phần Xử lý các giao dịch đang chờ. Đối với các giao dịch mua nhận được qua
onPurchasesUpdated()
hoặcqueryPurchasesAsync()
,
bạn nên xác minh thêm để đảm bảo tính hợp pháp của giao dịch mua trước khi
cấp quyền cho ứng dụng. Để tìm hiểu cách xác minh giao dịch mua một cách chính xác, hãy xem phần
Xác minh giao dịch mua trước khi cấp quyền.Sau khi xác minh giao dịch mua hàng, ứng dụng sẽ sẵn sàng cấp quyền cho người dùng. Tài khoản người dùng liên kết với giao dịch mua hàng có thể được xác định bằng
ProductPurchase.obfuscatedExternalAccountId
doPurchases.products:get
trả về trong các giao dịch mua sản phẩm trong ứng dụng vàSubscriptionPurchase.obfuscatedExternalAccountId
doPurchases.subscriptions:get
trả về đối với các gói thuê bao ở phía máy chủ hoặcobfuscatedAccountId
từPurchase.getAccountIdentifiers()
ở phía máy khách, nếu được đặt vớisetObfuscatedAccountId
khi giao dịch mua hàng được thực hiện.Sau khi cấp quyền, ứng dụng phải xác nhận thanh toán giao dịch mua hàng. Việc xác nhận này cho Google Play biết rằng bạn đã cấp quyền cho thanh toán giao dịch mua hàng .
Lưu ý:Nếu bạn không xác nhận thanh toán giao dịch mua hàng trong vòng 3 ngày, người dùng sẽ tự động hóa được hoàn tiền và Google Play sẽ tịch thu thanh toán giao dịch mua hàng đó .
Quy trình cấp quyền và xác nhận thanh toán giao dịch mua hàng nhờ vào vào việc mẫu sản phẩm được mua là loại sản phẩm tiêu dùng, mẫu sản phẩm không phải hàng tiêu dùng hay gói thuê bao .Sản phẩm tiêu dùng
Đối với sản phẩm tiêu dùng, nếu ứng dụng có phần phụ trợ bảo mật, bạn nên dùng
Purchases.products:consume
để sử dụng sản phẩm được mua một cách đáng tin cậy. Đảm bảo sản phẩm được mua chưa được sử dụng bằng cách kiểm traconsumptionState
trong kết quả của lệnh gọiPurchases.products:get
.
Nếu ứng dụng của bạn chỉ dành cho máy khách không có phần phụ trợ, hãy sử dụngconsumeAsync()
từ Thư viện Google Play Billing. Cả hai phương thức đều đáp ứng yêu cầu xác nhận và cho biết rằng ứng dụng đã cấp quyền cho người dùng. Các phương thức này cũng cho phép ứng dụng tạo sản phẩm tính phí một lần tương ứng với mã thông báo giao dịch mua hàng đầu vào để mua lại. VớiconsumeAsync()
, bạn cũng phải truyền một đối tượng sẽ triển khai giao diệnConsumeResponseListener
. Đối tượng này xử lý kết quả của hoạt động tiêu thụ. Bạn có thể ghi đè phương thứconConsumeResponse()
mà Thư viện Google Play Billing này sẽ dùng khi hoạt động hoàn tất.Ví dụ sau minh họa việc tiêu thụ một mẫu sản phẩm bằng Thư viện Google Play Billing bằng mã mua hàng được link :
Kotlin
suspend fun handlePurchase(purchase: Purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener. val purchase : Purchase = ...; // Verify the purchase. // Ensure entitlement was not already granted for this purchaseToken. // Grant entitlement to the user. val consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build() val consumeResult = withContext(Dispatchers.IO) { client.consumePurchase(consumeParams) } }Java
void handlePurchase(Purchase purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener. Purchase purchase = ...; // Verify the purchase. // Ensure entitlement was not already granted for this purchaseToken. // Grant entitlement to the user. 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); }Lưu ý:Đôi khi, nhu yếu tiêu thụ hoàn toàn có thể không thành công xuất sắc, do đó bạn phải kiểm tra sever phụ trợ bảo mật thông tin để bảo vệ rằng mọi mã thông tin thanh toán giao dịch mua hàng đều chưa được sử dụng và ngăn ứng dụng cấp quyền nhiều lần cho cùng một thanh toán giao dịch mua hàng. Hoặc ứng dụng hoàn toàn có thể chờ cho đến khi bạn nhận được phản hồi tiêu thụ thành công xuất sắc từ Google Play trước khi cấp quyền. Nếu chọn giữ lại những thanh toán giao dịch mua hàng của người dùng cho đến khi Google Play gửi phản hồi tiêu thụ thành công xuất sắc, bạn phải rất là cẩn trọng để không mất dấu những thanh toán giao dịch mua hàng mà bạn đã gửi nhu yếu tiêu thụ .
Sản phẩm không phải hàng tiêu dùng
Để xác nhận giao dịch mua sản phẩm không phải hàng tiêu dùng, nếu ứng dụng có phần phụ trợ bảo mật, bạn nên sử dụng
Purchases.products:acknowledge
để xác nhận giao dịch mua hàng một cách đáng tin cậy.
Đảm bảo giao dịch mua hàng chưa được xác nhận trước đó bằng cách kiểm traacknowledgementState
trong kết quả của lệnh gọiPurchases.products:get
.Nếu ứng dụng của bạn chỉ dành cho máy khách, hãy dùng
BillingClient.acknowledgePurchase()
từ Thư viện Google Play Billing trong ứng dụng của bạn. Trước khi xác nhận giao dịch mua hàng, ứng dụng của bạn phải kiểm tra xem giao dịch đã được xác nhận hay chưa bằng cách dùng phương thứcisAcknowledged()
trong Thư viện Google Play Billing.Ví dụ sau cho biết cách xác nhận thanh toán giao dịch mua hàng bằng cách sử dụng Thư viện Google Play Billing :
Kotlin
val client: BillingClient = ... val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ... suspend fun handlePurchase() { if (purchase.purchaseState === PurchaseState.PURCHASED) { if (!purchase.isAcknowledged) { val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) val ackPurchaseResult = withContext(Dispatchers.IO) { client.acknowledgePurchase(acknowledgePurchaseParams.build()) } } } }Java
BillingClient client = ... AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ... void handlePurchase(Purchase purchase) { if (purchase.getPurchaseState() == PurchaseState.PURCHASED) { if (!purchase.isAcknowledged()) { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener); } } }Gói thuê bao
Gói thuê bao được xử lý tương tự như sản phẩm không phải hàng tiêu dùng. Nếu có thể, hãy sử dụng
Purchases.subscriptions.acknowledge
từ API Nhà phát triển Google Play để xác nhận một cách đáng tin cậy giao dịch mua hàng từ phần phụ trợ bảo mật của bạn. Xác minh rằng giao dịch mua hàng chưa được xác nhận trước đó bằng cách kiểm traacknowledgementState
trong tài nguyên giao dịch mua hàng từPurchases.subscriptions:get
.
Nếu không, bạn có thể xác nhận gói thuê bao bằng cách sử dụngBillingClient.acknowledgePurchase()
từ Thư viện Google Play Billing sau khi kiểm traisAcknowledged()
.
Bạn cần xác nhận tất cả các giao dịch mua gói thuê bao ban đầu. Bạn không cần xác nhận việc gia hạn gói thuê bao.
Để biết thêm thông tin về thời điểm cần xác nhận gói thuê bao, hãy xem chủ đề Bán gói thuê bao.Tìm nạp các giao dịch mua hàng
Theo dõi thông tin cập nhật về giao dịch mua bằng cách sử dụng
PurchasesUpdatedListener
là không đủ để đảm bảo rằng ứng dụng sẽ xử lý tất cả giao dịch mua. Có thể
ứng dụng không biết tất cả giao dịch mua mà người dùng đã thực hiện. Dưới đây là một số trường hợp ứng dụng có thể bị mất dấu hoặc không biết về giao dịch mua:
- Các vấn đề về mạng trong khi mua hàng: Người dùng mua hàng thành công và nhận được xác nhận của Google, nhưng thiết bị của họ bị mất
kết nối mạng trước khi nhận được thông báo
về giao dịch mua thông quaPurchasesUpdatedListener
.- Nhiều thiết bị: Người dùng mua một mặt hàng trên một thiết bị và kỳ vọng thấy mặt hàng đó khi chuyển đổi thiết bị.
- Xử lý giao dịch mua thực hiện bên ngoài ứng dụng: Người dùng có thể thực hiện một số giao dịch mua (như sử dụng các mã khuyến mãi) bên ngoài ứng dụng của bạn.
Để xử lý những trường hợp này, hãy đảm bảo ứng dụng gọi hàm
BillingClient.queryPurchasesAsync()
trong phương thứconResume()
để đảm bảo rằng tất cả giao dịch mua đều được xử lý thành công như mô tả trong phần xử lý giao dịch mua.Ví dụ sau đây cho thấy cách tìm nạp giao dịch mua gói thuê bao của người dùng.
Lưu ýqueryPurchasesAsync()
chỉ trả về thuê bao đang hoạt động và không truy vấn được các giao dịch mua hàng một lần.Kotlin
val params = QueryPurchasesParams.newBuilder() .setProductType(ProductType.SUBS) // uses queryPurchasesAsync Kotlin extension function val purchasesResult = billingClient.queryPurchasesAsync(params.build()) // check purchasesResult.billingResult // process returned purchasesResult.purchasesList, e.g. display the plans user ownsJava
billingClient.queryPurchasesAsync( QueryPurchasesParams.newBuilder() .setProductType(ProductType.SUBS) .build(), new PurchasesResponseListener() { public void onQueryPurchasesResponse(BillingResult billingResult, List purchases) { // check billingResult // process returned purchase list, e.g. display the plans user owns } } );Tìm nạp nhật ký mua
queryPurchaseHistoryAsync()
trả về giao dịch mua gần đây nhất của người dùng đối với từng sản phẩm, ngay cả khi giao dịch mua đó đã hết hạn, bị huỷ hoặc đã hoàn tất.Nếu đang sử dụng tiện ích Kotlin, bạn có thể dùng hàm mở rộng
queryPurchaseHistory()
.Kotlin
val params = QueryPurchaseHistoryParams.newBuilder() .setProductType(ProductType.SUBS) // uses queryPurchaseHistory Kotlin extension function val purchaseHistoryResult = billingClient.queryPurchaseHistory(params.build()) // check purchaseHistoryResult.billingResult // process returned purchaseHistoryResult.purchaseHistoryRecordList, e.g. display purchaseJava
billingClient.queryPurchaseHistoryAsync( QueryPurchaseHistoryParams.newBuilder() .setProductType(ProductType.SUBS) .build(), new PurchaseHistoryResponseListener() { public void onPurchaseHistoryResponse( BillingResult billingResult, List purchasesHistoryList) { // check billingResult // process returned purchase history list, e.g. display purchase history } } );Xử lý giao dịch mua hàng được thực hiện bên ngoài ứng dụng
Một số thanh toán giao dịch mua như sử dụng những mã tặng thêm hoàn toàn có thể diễn ra bên ngoài ứng dụng của bạn. Khi người dùng mua hàng bên ngoài ứng dụng, họ muốn ứng dụng đưa ra thông tin trong ứng dụng hoặc sử dụng 1 số ít chính sách thông tin để người dùng biết rằng ứng dụng đã nhận và giải quyết và xử lý thanh toán giao dịch mua một cách đúng mực. Một số chính sách được đồng ý là :
- Hiển thị một cửa sổ bật lên trong ứng dụng.
- Chuyển thông báo tới hộp thông báo trong ứng dụng và nêu rõ rằng có một tin nhắn mới trong hộp thông báo trong ứng dụng.
- Sử dụng một nội dung thông báo trên hệ điều hành.
Xin chú ý quan tâm rằng ứng dụng hoàn toàn có thể ở bất kể trạng thái nào khi phát hiện thanh toán giao dịch mua. Thậm chí ứng dụng hoàn toàn có thể không được thiết lập khi thanh toán giao dịch mua hàng được thực thi. Người dùng mong ước nhận thông tin về thanh toán giao dịch mua khi liên tục sử dụng ứng dụng, bất kể ứng dụng đó đang trong trạng thái sử dụng nào .
Bạn phải phát hiện những thanh toán giao dịch mua hàng bất kể ứng dụng đang trong trạng thái nào tại thời gian người dùng mua hàng. Tuy nhiên, đôi lúc cũng có những ngoại lệ hoàn toàn có thể gật đầu về việc không thông tin ngay lập tức cho người dùng rằng họ đã nhận được mẫu sản phẩm. Ví dụ :
- Khi họ đang tham gia vào phần hành động của một trò chơi, thông báo hiển thị có thể khiến người dùng mất tập trung. Trong trường hợp này, bạn phải thông báo cho người dùng sau khi phần hành động này kết thúc.
- Khi đoạn phim cắt cảnh đang chạy, việc hiển thị thông báo có thể khiến người dùng bị phân tâm. Trong trường hợp này, bạn phải thông báo cho người dùng sau khi đoạn phim cắt cảnh chạy hết.
- Trong quá trình hướng dẫn ban đầu và thiết lập người dùng của trò chơi. Bạn nên
thông báo cho người dùng mới về phần thưởng ngay sau khi họ mở trò chơi hoặc trong
quá trình thiết lập người dùng ban đầu. Tuy nhiên, bạn có thể đợi cho đến khi cảnh chính trong trò chơi
xuất hiện để thông báo cho người dùng.Hãy luôn nghĩ tới trải nghiệm của người dùng khi quyết định thời điểm và cách thông báo cho họ về
giao dịch mua được thực hiện bên ngoài ứng dụng. Bất cứ khi nào người dùng không nhận được
thông báo ngay lập tức, họ có thể cảm thấy hoang mang, từ đó ngừng sử dụng ứng dụng, liên hệ với bộ phận hỗ trợ người dùng hoặc than phiền về việc đó trên mạng xã hội.
Lưu ý:PurchasesUpdatedListener
đăng ký ngữ cảnh cho ứng dụng của bạn để xử lý thông tin cập nhật về giao dịch mua, bao gồm cả giao dịch mua thực hiện bên ngoài ứng dụng của bạn. Tức là nếu quy trình đăng ký của bạn không tồn tại,PurchasesUpdatedListener
sẽ không được thông báo. Đây là lý do ứng dụng của bạn nên gọiBillingClient.queryPurchasesAsync()
trong phương thứconResume()
như đã đề cập trong Tìm nạp giao dịch.Xử lý các giao dịch đang chờ
Lưu ý:
Bạn phải xử lý các Giao dịch đang chờ xử lý trong Thư viện Google Play Billing phiên bản 2.0 trở lên. Bạn nên xử lý các giao dịch đang chờ xử lý một cách rõ ràng.
Lưu ý:Bạn không hề sử dụng phương pháp giao dịch thanh toán bổ trợ cho những thanh toán giao dịch mua gói thuê bao .
Google Play tương hỗ thanh toán giao dịch đang chờ giải quyết và xử lý hoặc thanh toán giao dịch nhu yếu một hoặc nhiều bước bổ trợ giữa thời gian người dùng triển khai thanh toán giao dịch mua và khi phương pháp giao dịch thanh toán cho thanh toán giao dịch mua được giải quyết và xử lý. Ứng dụng không được cấp quyền cho những thanh toán giao dịch mua này cho đến khi Google thông tin cho bạn rằng đã tính phí thành công xuất sắc phương pháp giao dịch thanh toán của người dùng .Ví dụ: người dùng có thể tạo một giao dịch mua mặt hàng
PENDING
trong ứng dụng bằng cách
chọn phương thức thanh toán là tiền mặt. Sau đó, người dùng có thể chọn một cửa hàng
thực tế để hoàn tất giao dịch và nhận mã thông qua cả
thông báo và email. Khi đến cửa hàng thực tế, người dùng
có thể sử dụng mã này và thanh toán cho thu ngân bằng tiền mặt. Sau đó, Google sẽ thông báo cho
cả bạn và người dùng rằng đã nhận được tiền mặt. Sau đó, ứng dụng có thể cấp quyền cho người dùng.Ứng dụng phải hỗ trợ các giao dịch đang chờ xử lý bằng cách gọi hàm
enablePendingPurchases()
trong khi khởi chạy ứng dụng.Khi ứng dụng nhận được một giao dịch mua mới, thông qua
PurchasesUpdatedListener
hoặc từ việc gọi hàmqueryPurchasesAsync()
, hãy sử dụng phương thứcgetPurchaseState()
để xác định trạng thái mua hàng làPURCHASED
hayPENDING
.Lưu ý:
Bạn chỉ nên cấp quyền khi trạng thái là
PURCHASED
. Hãy sử dụng hàm
getPurchaseState()
thay vì hàmgetOriginaljson()
và đảm bảo
xử lý giao dịchPENDING
một cách phù hợp.Nếu ứng dụng đang chạy khi người dùng hoàn tất giao dịch mua,
PurchasesUpdatedListener
sẽ được gọi lại vàPurchaseState
hiện làPURCHASED
. Tại thời điểm này,
ứng dụng có thể xử lý giao dịch mua hàng bằng cách sử dụng phương thức tiêu chuẩn để
xử lý giao dịch mua hàng một lần. Ứng dụng cũng nên gọi hàm
queryPurchasesAsync()
trong phương thứconResume()
của ứng dụng để
xử lý những giao dịch mua đã chuyển sang trạng tháiPURCHASED
trong khi
ứng dụng không chạy.Lưu ý:
Bạn chỉ nên xác nhận giao dịch mua hàng khi trạng thái là
PURCHASED
, tức là không xác nhận giao dịch mua hàng ở trạng tháiPENDING
. Thời hạn xác nhận
ba ngày chỉ bắt đầu khi trạng thái mua hàng chuyển đổi từ
“PENDING” (ĐANG CHỜ XỬ LÝ) thành “PURCHASED” (ĐÃ MUA).Ứng dụng cũng có thể sử dụng
Thông báo theo thời gian thực dành cho nhà phát triển
cho các giao dịch mua đang chờ xử lý bằng cách lắng nghe
OneTimeProductNotifications
. Khi giao dịch mua chuyển từ trạng tháiPENDING
sangPURCHASED
, ứng dụng sẽ nhận được
thông báoONE_TIME_PRODUCT_PURCHASED
. Nếu giao dịch mua bị huỷ,
ứng dụng sẽ nhận được thông báoONE_TIME_PRODUCT_CANCELED
. Điều này có thể xảy ra nếu khách hàng không hoàn tất việc thanh toán trong khung thời gian yêu cầu.
Khi nhận được những thông báo này, bạn có thể sử dụng API Nhà phát triển Google Play, bao gồm trạng tháiPENDING
cho
Purchases.products
.Lưu ý:Bạn hoàn toàn có thể kiểm tra những thanh toán giao dịch đang chờ giải quyết và xử lý bằng cách sử dụng trình kiểm thử giấy phép. Ngoài hai thẻ tín dụng thanh toán kiểm thử, trình kiểm thử được cấp phép có quyền truy vấn vào hai công cụ kiểm thử cho những phương pháp thanh toán giao dịch bị trì hoãn do khoản thanh toán giao dịch tự động hóa triển khai xong hoặc hủy sau vài phút. Trong quy trình kiểm thử ứng dụng, bạn nên xác định rằng ứng dụng không cấp quyền hoặc xác nhận thanh toán giao dịch mua ngay sau khi mua bằng một trong hai công cụ này. Khi mua hàng bằng công cụ kiểm thử tự động hóa hoàn tất, bạn nên xác định rằng ứng dụng cấp quyền và xác nhận thanh toán giao dịch mua hàng sau khi hoàn tất .
Bạn hoàn toàn có thể tìm thấy những bước chi tiết cụ thể về cách kiểm thử trường hợp này trong phần Kiểm thử thanh toán giao dịch mua hàng đang chờ giải quyết và xử lý .Xử lý giao dịch mua số lượng nhiều
Được tương hỗ trong phiên bản 4.0 trở lên của Thư viện Google Play Billing, Google Play được cho phép người mua mua nhiều lần cùng một mẫu sản phẩm trong ứng dụng trong một thanh toán giao dịch bằng cách chỉ định số lượng trong giỏ hàng. Ứng dụng cần giải quyết và xử lý những thanh toán giao dịch mua hàng số lượng nhiều và cấp quyền dựa trên số lượng mẫu sản phẩm đã chỉ định .
Lưu ý:Số lượng nhiều dành cho các sản phẩm tiêu dùng trong ứng dụng, tức là các mặt hàng
có thể mua, tiêu dùng và mua lại. Không bật tính năng này cho
những sản phẩm chỉ mua một lần.Để xử lý các giao dịch mua với số lượng nhiều, logic cấp phép của ứng dụng cần
kiểm tra số lượng mặt hàng. Bạn có thể truy cập trườngquantity
qua một trong
các API sau:
getQuantity()
trong Thư viện Google Play Billing.Purchases.products.quantity
từ API Nhà phát triển Google Play.Sau khi thêm logic để giải quyết và xử lý thanh toán giao dịch mua số lượng nhiều, bạn cần bật tính năng số lượng lớn cho mẫu sản phẩm tương ứng trên trang quản trị loại sản phẩm trong ứng dụng trong Google Play Console .
Lưu ý:Hãy bảo vệ rằng ứng dụng của bạn được cho phép thực thi thanh toán giao dịch mua với số lượng nhiều trước khi bật tính năng này trong bảng điều khiển và tinh chỉnh. Có thể bạn buộc phải update lên phiên bản ứng dụng tương hỗ tính năng này trước khi hoàn toàn có thể bật tính năng trên mẫu sản phẩm .
Source: https://thomaygiat.com
Category : Ứng Dụng
15+ app hack game đỉnh cao giúp bạn làm chủ mọi cuộc chơi
Cùng với sự tăng trưởng của ngành công nghiệp game, những app hack game không tính tiền cũng tăng trưởng theo để giúp người chơi…
Hướng dẫn khắc phục nhanh lỗi vào ứng dụng Android bị văng ra liên tục
Thế giới Android rất phong phú khi nói đến phần cứng. Mặc dù điều đó mang lại những tùy chọn phong phú cho người dùng…
Top app giả lập pc trên điện thoại android
Bạn muốn giả lập pc trên điện thoại cảm ứng android nhưng chưa biết phải làm bằng cách nào ? Hãy cùng Hoàng Long PC…
Tổng hợp game Gameloft mod hay nhất cho Android
Mục ChínhTổng hợp game Gameloft mod hay nhất cho AndroidTổng hợp game Gameloft hack mod hay nhất cho Android1. Asphalt 8 mod cho Android – Thể…
Android 11 – Hệ điều hành Android 11 mới nhất – https://thomaygiat.com
Hệ điều hành Android 11 đã chính thức ra mắt, cung cấp cho bạn khả năng điều khiển thiết bị mạnh mẽ, những cách dễ…
Mẹo nghe nhạc Youtube khi tắt màn hình trên Android (100% thành công)
Làm thế nào để nghe nhạc Youtube khi tắt màn hình trên Android ? Chắc hẳn câu hỏi này đã có rất nhiều bạn đặt…