Zarabiaj na 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 przy użyciu konta Google, z którego uruchomiono grę w aplikacji Gry Play Google, i nie wymagają żadnych dodatkowych kroków logowania.
Jeśli masz zintegrowaną bibliotekę Płatności w Google Play na Androidzie, te interfejsy API Płatności w Google Play powinny być Ci znane. Wszystkie integracje po stronie serwera z Płatnościami w Google Play mogą być ponownie wykorzystywane w przypadku gier na PC, ponieważ są takie same na Androidzie i PC.
Wymagania wstępne
Dokończ konfigurowanie pakietu SDK.
Przeczytaj omówienie systemu rozliczeniowego Google Play.
Krok 1. Wyślij zapytanie o wcześniejsze zakupy i zakupy dokonane poza aplikacją
Gdy aplikacja się uruchamia lub wraca na pierwszy plan, wysyłaj zapytania o zakupy. Jest to konieczne do wykrywania zakupów dokonanych poza grą lub do odblokowywania dostępu do zakupów dokonanych wcześniej przez użytkownika.
Wysyłanie zapytań o zakupy za pomocą
BillingClient::QueryPurchases.Kontynuuj, przetwarzając zakupy.
// 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. Wyświetl 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 produktu to ważny krok przed wyświetleniem produktów użytkownikom, ponieważ zwraca on zlokalizowane informacje o produkcie.
Zanim zaoferujesz produkt na sprzedaż, sprawdź, czy użytkownik nie jest już jego właścicielem. Jeśli użytkownik ma produkt jednorazowy, który nadal znajduje się w jego historii zakupów, musisz go wykorzystać, zanim będzie mógł go ponownie kupić.
- Zapytanie o szczegóły produktu za pomocą funkcji
BillingClient::QueryProductDetails. Przekaż identyfikatory produktów zarejestrowane w Konsoli Google Play. - Wyświetl
ProductDetails, który zawiera zlokalizowaną nazwę produktu i cenę oferty. - Zachowaj odniesienie do
offer_tokenproduktu. Służy to do uruchamiania 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 pod numer
BillingClient::LaunchPurchaseFlow(). Przekażoffer_tokenuzyskany podczas wysyłania zapytania o szczegóły produktu. - Po sfinalizowaniu zakupu zostanie wywołana funkcja kontynuacji z wynikiem.
- Jeśli operacja się uda, kontynuacja będzie 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. Przetwarzanie zakupu
Proces z serwerem backendu
W przypadku gier z serwerem backendu dokończ przetwarzanie, wysyłając purchase_token na serwer backendu. Dokończ przetwarzanie za pomocą interfejsów API Płatności w Google Play po stronie serwera. Ta integracja po stronie serwera jest taka sama jak w przypadku gry na Androida zintegrowanej z płatnościami w Google 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 backendu
Sprawdź, czy płatność użytkownika nie jest w stanie oczekiwania, sprawdzając, czy
ProductPurchaseDetails::purchase_statema wartośćPurchaseState::kPurchaseStatePurchased. Jeśli stan zakupu to „oczekujący”, powiadom użytkownika, że musi wykonać dodatkowe czynności, zanim otrzyma zakupiony produkt.Przyznaj użytkownikowi dostęp do kupionego produktu i zaktualizuj pamięć uprawnień w grze.
W przypadku zakupów produktów niekonsumpcyjnych (produktów, które można kupić tylko raz) sprawdź, czy zakup został już potwierdzony za pomocą funkcji
ProductPurchaseDetails::is_acknowledged.- Jeśli zakup nie został potwierdzony, powiadom Google, że użytkownikowi przyznano uprawnienia do produktu, wywołując funkcję
BillingClient::AcknowledgePurchase.
- Jeśli zakup nie został potwierdzony, powiadom Google, że użytkownikowi przyznano uprawnienia do produktu, wywołując funkcję
W przypadku zakupów produktów konsumpcyjnych (produktów, które można kupić więcej niż raz) powiadom Google, że użytkownik otrzymuje uprawnienie do produktu, wywołując funkcję
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 rozliczeniami w Google Play. Aby przeprowadzić testy w fazie rozwoju, zalecamy skorzystanie z testerów licencji. Testerzy licencji mają dostęp do płatności testowych, które pozwalają uniknąć obciążania prawdziwymi pieniędzmi za zakupy.
Instrukcje konfigurowania testerów licencji i zestaw testów ręcznych, które zalecamy przeprowadzić, znajdziesz w dokumentacji dotyczącej testowania integracji Biblioteki płatności w Google Play.