Monetisasi game Anda dengan menjual produk digital menggunakan Layanan Penagihan Play. SDK menawarkan API untuk menampilkan produk yang tersedia untuk dibeli, meluncurkan alur pembelian, dan memproses pembelian. Panggilan ke API penagihan ini dilakukan menggunakan Akun Google yang meluncurkan game di dalam klien Google Play Game dan tidak memerlukan langkah login tambahan.
Jika Anda telah berintegrasi dengan library Layanan Penagihan Android Play, API Layanan Penagihan ini akan terlihat familier. Setiap integrasi sisi server dengan Layanan Penagihan Play dapat digunakan kembali oleh judul PC karena sama di Android & PC.
Prasyarat
Selesaikan penyiapan SDK.
Baca ringkasan sistem penagihan Google Play.
Selesaikan Penyiapan Layanan Penagihan Play.
Langkah 1: Buat kueri untuk pembelian sebelumnya & pembelian yang diselesaikan di luar aplikasi Anda
Saat aplikasi dimulai atau saat kembali ke latar depan, buat kueri untuk pembelian. Hal ini diperlukan untuk mendeteksi pembelian yang terjadi di luar game Anda atau untuk membuka akses ke pembelian yang sebelumnya dilakukan oleh pengguna.
Buat kueri pembelian menggunakan
BillingClient::QueryPurchases
.Lanjutkan dengan memproses pembelian.
// 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
}
Langkah 2: Tampilkan produk yang tersedia untuk dibeli
Anda siap membuat kueri untuk produk yang tersedia dan menampilkannya kepada pengguna. Kueri untuk detail produk merupakan langkah penting sebelum menampilkan produk kepada pengguna, karena proses ini akan menampilkan informasi produk yang dilokalkan.
Sebelum menawarkan produk untuk dijual, pastikan pengguna belum memiliki produk tersebut. Jika pengguna memiliki item habis pakai yang masih ada dalam histori pembelian, Anda harus menggunakan produk tersebut sebelum mereka dapat membelinya lagi.
- Buat kueri detail produk menggunakan
BillingClient::QueryProductDetails
. Teruskan ID produk yang Anda daftarkan di dalam Konsol Google Play. - Render
ProductDetails
yang menyertakan nama lokal & harga penawaran produk. - Simpan referensi ke
offer_token
produk. Ini digunakan untuk meluncurkan alur pembelian penawaran.
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
}
Langkah 3: Meluncurkan alur pembelian
Saat pengguna menunjukkan niat untuk membeli produk yang telah Anda tunjukkan, Anda siap meluncurkan alur pembelian.
- Mulai dengan memanggil
BillingClient::LaunchPurchaseFlow()
. Teruskanoffer_token
yang diperoleh saat membuat kueri detail produk. - Setelah pembelian selesai, fungsi kelanjutan akan dipanggil dengan hasilnya.
- Jika berhasil, kelanjutan akan berisi
ProductPurchaseDetails
. Lanjutkan dengan memproses pembelian.
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
}
Langkah 4: Memproses pembelian
Memproses dengan server backend
Untuk game dengan server backend, selesaikan pemrosesan dengan mengirim
purchase_token
ke server backend Anda. Selesaikan
sisa pemrosesan menggunakan
API Layanan Penagihan Play sisi server. Integrasi sisi server ini
sama seperti yang dilakukan untuk game Android yang telah terintegrasi dengan Penagihan Play.
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
}
Memproses tanpa server backend
Pastikan pembayaran pengguna tidak tertunda dengan memeriksa
ProductPurchaseDetails::purchase_state
adalahPurchaseState::kPurchaseStatePurchased
. Jika status pembelian tertunda, beri tahu pengguna bahwa mereka perlu menyelesaikan langkah-langkah tambahan sebelum dapat menerima produk yang dibeli.Berikan akses kepada pengguna ke produk yang dibeli & perbarui penyimpanan hak game Anda.
Untuk pembelian produk tidak habis pakai (produk yang mungkin hanya dapat dibeli satu kali), periksa apakah pembelian telah dikonfirmasi menggunakan
ProductPurchaseDetails::is_acknowledged
.- Jika pembelian belum dikonfirmasi, beri tahu Google bahwa pengguna
diberi hak atas produk dengan memanggil
BillingClient::AcknowledgePurchase
.
- Jika pembelian belum dikonfirmasi, beri tahu Google bahwa pengguna
diberi hak atas produk dengan memanggil
Untuk pembelian habis pakai (produk yang dapat dibeli lebih dari sekali), beri tahu Google bahwa pengguna diberi hak atas produk dengan memanggil
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;
}
Langkah 5: Uji integrasi Anda
Sekarang Anda siap menguji integrasi dengan Layanan Penagihan Play. Untuk melakukan pengujian selama fase pengembangan, sebaiknya manfaatkan penguji lisensi. Penguji lisensi memiliki akses ke pembayaran pengujian sehingga penguji tidak akan dikenai biaya ketika melakukan pembelian.
Untuk petunjuk cara menyiapkan penguji lisensi dan serangkaian pengujian manual, sebaiknya lihat dokumentasi tentang cara menguji integrasi Library Layanan Penagihan Google Play.