Zarabiaj na swojej grze, sprzedając produkty cyfrowe za pomocą Płatności w Google Play. Pakiet SDK udostępnia interfejsy API do wyświetlania produktów dostępnych do kupienia, uruchamiania procesu zakupu i przetwarzania zakupów. Wywołania tych interfejsów API do rozliczeń są wykonywane za pomocą konta Google, na którym uruchomiono grę w ramach klienta Google Play Games, i nie wymagają żadnych dodatkowych czynności logowania.
Jeśli masz już za sobą integrację z Biblioteką płatności w Google Play, te interfejsy API powinny być Ci znane. Wszelkie integracje z systemem płatności Play Billing można ponownie wykorzystać w tytułach na PC, ponieważ są one takie same na Androida i PC.
Wymagania wstępne
Przeprowadź konfigurację pakietu SDK.
Zapoznaj się z omówieniem systemu rozliczeniowego Google Play.
Krok 1. Zapytanie o wcześniejsze zakupy i zakupy dokonane poza aplikacją
Gdy aplikacja uruchamia się lub wraca na pierwszy plan, wysyła zapytanie o zakupy. Jest to konieczne do wykrywania zakupów dokonanych poza grą lub do odblokowania dostępu do zakupów dokonanych wcześniej przez użytkownika.
Zapytanie o zakupy przy użyciu
BillingClient::QueryPurchases
.Kontynuuj przetwarzanie zakupów.
// 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
}
Krok 2. Pokaż produkty dostępne do kupienia
Możesz już wysyłać zapytania o dostępne produkty i wyświetlać je użytkownikom. Wysyłanie zapytań o szczegóły produktów jest ważnym krokiem przed wyświetleniem produktów użytkownikom, ponieważ zwraca ono zlokalizowane informacje o produktach.
Zanim zaoferujesz produkt do sprzedaży, sprawdź, czy użytkownik nie ma już tego produktu. Jeśli użytkownik ma produkt jednorazowy, który nadal znajduje się w jego historii zakupów, musisz go zużyć, zanim będzie mógł go kupić ponownie.
- Wyszukaj szczegóły produktu za pomocą zapytania
BillingClient::QueryProductDetails
. Przekaż identyfikatory produktów zarejestrowane w Konsoli Google Play. - Wyrenderuj element
ProductDetails
, który zawiera lokalizowaną nazwę produktu i cenę oferty. - Zachowaj odwołanie do
offer_token
produktu. Służy on do uruchomienia procesu zakupu oferty.
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
}
Krok 3. Uruchom proces zakupu
Gdy użytkownik wyrazi chęć zakupu produktu, który mu wyświetliłeś, możesz rozpocząć proces zakupu.
- Zacznij od zadzwonienia na numer
BillingClient::LaunchPurchaseFlow()
. Przekażoffer_token
uzyskany podczas zapytania o szczegóły produktu. - Po zakończeniu zakupu zostanie wywołana funkcja kontynuacji z otrzymanym wynikiem.
- W przypadku powodzenia ciąg dalszy zawiera element
ProductPurchaseDetails
. Kontynuuj, przetwarzając zakup.
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
}
Krok 4. Przeprowadź zakup.
Przetwarzanie na serwerze backend
W przypadku gier z serwerem backendu przetwarzanie można dokończyć, wysyłając purchase_token
na serwer backendu. Dokończ pozostałą część przetwarzania za pomocą interfejsów Play Billing API po stronie serwera. Ta integracja po stronie serwera jest taka sama jak w przypadku gry na Androida zintegrowanej z Płatnościami w 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
}
Przetwarzanie bez serwera backendowego
Upewnij się, że płatność użytkownika nie jest oczekująca, sprawdzając, czy parametr
ProductPurchaseDetails::purchase_state
ma wartośćPurchaseState::kPurchaseStatePurchased
. Jeśli stan zakupu to „Oczekuje”, poinformuj użytkownika, że musi wykonać dodatkowe czynności, zanim otrzyma zakupiony produkt.Przyznasz użytkownikowi dostęp do zakupionego produktu i zaktualizujesz pamięć uprawnień gry.
W przypadku zakupów niekonsumpcyjnych (produktów, które można kupić tylko raz) sprawdź, czy zakup został już potwierdzony za pomocą
ProductPurchaseDetails::is_acknowledged
.- Jeśli zakup nie został potwierdzony, poinformuj Google, że użytkownikowi przyznano uprawnienia do produktu, dzwoniąc pod numer
BillingClient::AcknowledgePurchase
.
- Jeśli zakup nie został potwierdzony, poinformuj Google, że użytkownikowi przyznano uprawnienia do produktu, dzwoniąc pod numer
W przypadku zakupów produktów konsumpcyjnych (produktów, które można kupić więcej niż raz) poinformuj Google, że użytkownikowi przyznano uprawnienia do produktu, dzwoniąc pod numer
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;
}
Krok 5. Sprawdź integrację
Możesz teraz przetestować integrację z płatnościami w Google Play. Aby przetestować aplikację na etapie rozwoju, zalecamy skorzystanie z usługi Tester licencji. Testerzy licencji mają dostęp do testowych form płatności, które umożliwiają uniknięcie pobierania prawdziwych pieniędzy za zakupy.
Instrukcje konfigurowania testerów licencji i pakietu testów ręcznych znajdziesz w dokumentacji Testowanie integracji z Biblioteką płatności w Google Play.