Kiếm tiền từ trò chơi bằng cách bán sản phẩm kỹ thuật số thông qua Play Billing. SDK này cung cấp các API để hiển thị những sản phẩm có thể mua, bắt đầu quy trình mua và xử lý giao dịch mua. Các lệnh gọi đến những API thanh toán này được thực hiện bằng Tài khoản Google đã khởi chạy trò chơi trong ứng dụng Google Play Games và không yêu cầu thêm bước đăng nhập nào.
Nếu bạn đã tích hợp với Thư viện Play Billing trên Android, thì bạn sẽ thấy quen thuộc với các API Play Billing này. Các tựa game trên máy tính có thể sử dụng lại mọi hoạt động tích hợp phía máy chủ với Play Billing vì chúng giống nhau trên cả Android và máy tính.
Điều kiện tiên quyết
Hoàn tất thiết lập SDK.
Đọc thông tin tổng quan về hệ thống thanh toán của Google Play.
Hoàn tất thiết lập Play Billing.
Bước 1: Truy vấn các giao dịch mua trước đây và giao dịch mua đã hoàn tất bên ngoài ứng dụng của bạn
Khi ứng dụng của bạn khởi động hoặc khi ứng dụng quay lại nền trước, hãy truy vấn các giao dịch mua. Điều này là cần thiết để phát hiện những giao dịch mua diễn ra bên ngoài trò chơi của bạn hoặc để mở khoá quyền truy cập vào những giao dịch mua mà người dùng đã thực hiện trước đó.
Truy vấn về giao dịch mua bằng
BillingClient::QueryPurchases.Tiếp tục bằng cách xử lý các giao dịch mua.
// Query for purchases when:
// - Application starts up
// - Application window re-enters the foreground
auto promise = std::make_shared<std::promise<QueryPurchasesResult>>();
billing_client.QueryPurchases([promise](QueryPurchasesResult result) {
promise->set_value(std::move(result));
});
auto query_purchases_result = promise->get_future().get();
if (query_purchases_result.ok()) {
auto purchases = query_purchases_result.value().product_purchase_details;
// Process the purchases
} else {
// Handle the error
}
Bước 2: Hiển thị các sản phẩm có thể mua
Bạn có thể truy vấn các sản phẩm mà mình hiện có và cho người dùng thấy các sản phẩm đó. Truy vấn thông tin chi tiết về sản phẩm là một bước quan trọng trước khi hiển thị sản phẩm cho người dùng vì việc truy vấn này sẽ trả về thông tin sản phẩm đã bản địa hoá.
Trước khi chào bán một sản phẩm, hãy kiểm tra để đảm bảo rằng người dùng chưa sở hữu sản phẩm đó. Nếu người dùng có một sản phẩm tiêu dùng vẫn còn trong nhật ký mua hàng, thì bạn phải tiêu thụ sản phẩm đó trước khi họ có thể mua lại.
- Truy vấn thông tin chi tiết về sản phẩm bằng cách sử dụng
BillingClient::QueryProductDetails. Truyền mã sản phẩm mà bạn đã đăng ký trong Google Play Console. - Kết xuất
ProductDetailsbao gồm tên theo ngôn ngữ địa phương và giá ưu đãi của sản phẩm. - Duy trì một giá trị tham chiếu đến
offer_tokencủa sản phẩm. Phương thức này dùng để bắt đầu quy trình mua ưu đãi.
QueryProductDetailsParams params;
params.product_ids.push_back({"example_costmetic_1", ProductType::kTypeInApp});
params.product_ids.push_back({"example_costmetic_1", ProductType::kTypeInApp});
params.product_ids.push_back({"example_battle_pass", ProductType::kTypeInApp});
auto promise = std::make_shared<std::promise<QueryProductDetailsResult>>();
billing_client.QueryProductDetails(params, [promise](QueryProductDetailsResult result) {
promise->set_value(std::move(result));
});
auto query_product_details_result = promise->get_future().get();
if (query_product_details_result.ok()) {
auto product_details = query_product_details_result.value().product_details;
// Display the available products and their offers to the user
} else {
// Handle the error
}
Bước 3: Bắt đầu quy trình mua
Khi người dùng thể hiện ý định mua một sản phẩm mà bạn đã cho họ xem, bạn đã sẵn sàng bắt đầu quy trình mua hàng.
- Bắt đầu bằng cách gọi
BillingClient::LaunchPurchaseFlow(). Truyền vàooffer_tokenthu được khi truy vấn thông tin chi tiết về sản phẩm. - Sau khi giao dịch mua hoàn tất, hàm tiếp tục sẽ được gọi cùng với kết quả.
- Nếu thành công, phần tiếp tục sẽ chứa một
ProductPurchaseDetails. Tiếp tục bằng cách xử lý giao dịch mua.
LaunchPurchaseFlowParams params { product_offer.offer_token };
auto promise = std::make_shared<std::promise<LaunchPurchaseFlowResult>>();
billing_client.LaunchPurchaseFlow(params, [promise](LaunchPurchaseFlowResult result) {
promise->set_value(std::move(result));
});
// The purchase flow has started and is now in progress.
auto launch_purchase_flow_result = promise->get_future().get();
// The purchase flow has now completed.
if (launch_purchase_flow_result.ok()) {
auto purchase = launch_purchase_flow_result.value().product_purchase_details;
// Process the purchase
} else if (launch_purchase_flow_result.code() == BillingError::kUserCanceled) {
// Handle an error caused by the user canceling the purchase flow
} else {
// Handle any other error codes
}
Bước 4: Xử lý giao dịch mua
Xử lý bằng máy chủ phụ trợ
Đối với những trò chơi có máy chủ phụ trợ, hãy hoàn tất quy trình xử lý bằng cách gửi purchase_token đến máy chủ phụ trợ của bạn. Hoàn tất phần còn lại của quy trình xử lý bằng API Play Billing phía máy chủ. Quy trình tích hợp phía máy chủ này giống như quy trình tích hợp cho một trò chơi trên Android đã tích hợp với Play Billing.
void ProcessPurchasesWithServer(std::vector<ProductPurchaseDetails> purchases) {
std::vector<std::string> purchase_tokens;
for (const auto& purchase : purchases) {
purchase_tokens.push_back(purchase.purchase_token);
}
// Send purchase tokens to backend server for processing
}
Xử lý mà không cần máy chủ phụ trợ
Đảm bảo rằng khoản thanh toán của người dùng không ở trạng thái đang chờ xử lý bằng cách kiểm tra
ProductPurchaseDetails::purchase_statecó phải làPurchaseState::kPurchaseStatePurchasedhay không. Nếu trạng thái mua hàng là đang chờ xử lý, hãy thông báo cho người dùng rằng họ cần hoàn tất các bước bổ sung thì mới có thể nhận được sản phẩm đã mua.Cấp cho người dùng quyền truy cập vào sản phẩm đã mua và cập nhật bộ nhớ quyền của trò chơi.
Đối với các giao dịch mua sản phẩm không phải hàng tiêu dùng (sản phẩm chỉ có thể mua một lần), hãy kiểm tra xem giao dịch mua đã được xác nhận hay chưa bằng cách sử dụng
ProductPurchaseDetails::is_acknowledged.- Nếu giao dịch mua chưa được xác nhận, hãy thông báo cho Google rằng người dùng đang được cấp quyền sử dụng sản phẩm bằng cách gọi
BillingClient::AcknowledgePurchase.
- Nếu giao dịch mua chưa được xác nhận, hãy thông báo cho Google rằng người dùng đang được cấp quyền sử dụng sản phẩm bằng cách gọi
Đối với giao dịch mua sản phẩm tiêu dùng (sản phẩm có thể mua nhiều lần), hãy thông báo cho Google rằng người dùng đang được cấp quyền sử dụng sản phẩm bằng cách gọi
BillingClient::ConsumePurchase.
void ProcessPurchasesWithoutServer(std::vector<ProductPurchaseDetails> purchases) {
std::vector<std::string> entitled_product_ids;
for (const auto& purchase : purchases) {
auto was_successful = ProcessPurchasePurchaseWithoutServer(purchase);
if (was_successful) {
entitled_product_ids.push_back(purchase.product_id);
}
}
// Note that non-consumable products that were previously purchased may have
// been refunded. These purchases will stop being returned by
// `QueryPurchases()`. If your game has given a user access to one of these
// products storage they should be revoked.
//
// ...
}
bool ProcessPurchasePurchaseWithoutServer(ProductPurchaseDetails purchase) {
auto is_purchase_completed =
purchase.purchase_state == PurchaseState::kPurchaseStatePurchased;
if (!is_purchase_completed) {
// Notify the user that they need to take additional steps to complete
// this purchase.
return false;
}
// Determine if the product ID is associated with a consumable product.
auto is_consumable = IsConsumableProductId(purchase.product_id);
if (is_consumable) {
// Grant an entitlement to the product to the user.
// ...
// Then, notify Google by consuming the purchase.
ConsumePurchaseParams params { purchase.purchase_token };
auto promise = std::make_shared<std::promise<ConsumePurchaseResult>>();
billing_client.ConsumePurchase(params, [promise](ConsumePurchaseResult result) {
promise->set_value(std::move(result));
});
auto consume_purchase_result = promise->get_future().get();
if (!consume_purchase_result.ok()) {
// Examine the failure code & message for more details & notify user
// of failure.
// ...
return false;
}
return true;
}
// Otherwise the product is assumed to be a non-consumable.
// Grant an entitlement to the product to the user.
// ...
// Then, notify Google by acknowledging the purchase (if not already done).
if (purchase.is_acknowledged) {
return true;
}
AcknowledgePurchaseParams params { purchase.purchase_token };
auto promise = std::make_shared<std::promise<AcknowledgePurchaseResult>>();
billing_client.AcknowledgePurchase(params, [promise](AcknowledgePurchaseResult result) {
promise->set_value(std::move(result));
});
auto acknowledge_purchase_result = promise->get_future().get();
if (!acknowledge_purchase_result.ok()) {
// Examine the failure code & message for more details & notify user
// of failure.
// ...
return false;
}
return true;
}
Bước 5: Kiểm thử quy trình tích hợp
Giờ thì bạn đã sẵn sàng kiểm thử quá trình tích hợp với Play Billing. Để kiểm thử trong giai đoạn phát triển, bạn nên tận dụng tính năng nhân viên kiểm thử được cấp phép. Nhân viên kiểm thử được cấp phép có quyền truy cập vào các khoản thanh toán dùng cho mục đích kiểm thử để tránh việc bị tính phí như trong các giao dịch mua thực tế.
Để biết hướng dẫn về cách thiết lập nhân viên kiểm thử được cấp phép và một bộ kiểm thử thủ công mà bạn nên thực hiện, hãy xem tài liệu về cách kiểm thử quá trình tích hợp Thư viện Google Play Billing.