Monetiza tu juego vendiendo productos digitales con la Facturación Play. El SDK ofrece APIs para mostrar productos disponibles para comprar, iniciar el flujo de compra y procesar las compras. Las llamadas a estas APIs de facturación se realizan con la Cuenta de Google que inició el juego dentro del cliente de Google Play Juegos y no requieren pasos de acceso adicionales.
Si realizaste la integración con la biblioteca de Play Billing de Android, estas APIs de Play Billing deberían resultarte familiares. Los títulos para PC pueden volver a usar cualquier integración del servidor con Play Billing, ya que son las mismas para Android y PC.
Requisitos previos
Completa la configuración del SDK.
Lee la descripción general del sistema de facturación de Google Play.
Completa la configuración de Facturación Play.
Paso 1: Consulta las compras anteriores y las compras completadas fuera de tu aplicación
Cuando se inicia tu aplicación o cuando vuelve a entrar en primer plano, consulta las compras. Esto es necesario para detectar las compras que se realizaron fuera de tu juego o para desbloquear el acceso a las compras que el usuario realizó anteriormente.
Consulta las compras con
BillingClient::QueryPurchases
.Continúa con el procesamiento de las compras.
// 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
}
Paso 2: Muestra los productos disponibles para comprar
Ya puedes buscar los productos disponibles y mostrarlos a los usuarios. La consulta de detalles de productos es un paso importante antes de mostrar los productos a los usuarios, ya que devuelve información localizada sobre los productos.
Antes de ofrecer un producto en venta, verifica que el usuario no lo tenga. Si el usuario todavía tiene un producto consumible en su historial de compras, debes consumirlo antes de que pueda volver a comprarlo.
- Consulta los detalles de los productos con
BillingClient::QueryProductDetails
. Pasa los IDs de producto que registraste en Google Play Console. - Renderiza el
ProductDetails
, que incluye el nombre localizado del producto y el precio de la oferta. - Mantén una referencia al
offer_token
del producto. Se usa para iniciar un flujo de compra de la oferta.
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
}
Paso 3: Inicia un flujo de compra
Cuando el usuario muestra la intención de comprar un producto que le mostraste, significa que ya puedes iniciar el flujo de compra.
- Para comenzar, llama a
BillingClient::LaunchPurchaseFlow()
. Pasa eloffer_token
que se obtuvo cuando consultaste los detalles del producto. - Una vez que se complete la compra, se llamará a la función de Continuation con el resultado.
- Si se realiza correctamente, la Continuation contiene un
ProductPurchaseDetails
. Continúa con el procesamiento de la compra.
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
}
Paso 4: Procesa una compra
Procesa con un servidor de backend
En el caso de los juegos con un servidor de backend, completa el procesamiento enviando el objeto purchase_token
a tu servidor de backend. Completa el
resto del procesamiento con las
APIs de Play Billing del servidor. Esta integración del servidor es la misma que se realiza para un juego para Android que se integró con la Facturación 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
}
Procesa sin un servidor de backend
Para asegurarte de que el pago del usuario no esté pendiente, verifica que
ProductPurchaseDetails::purchase_state
seaPurchaseState::kPurchaseStatePurchased
. Si el estado de la compra es pendiente, notifícale al usuario que debe completar pasos adicionales antes de poder recibir el producto que compró.Otorga al usuario acceso al producto comprado y actualiza el almacenamiento de derechos de tu juego.
En el caso de las compras de productos no consumibles (productos que solo se pueden comprar una vez), verifica si la compra ya se confirmó con
ProductPurchaseDetails::is_acknowledged
.- Si no se confirmó la compra, llama a
BillingClient::AcknowledgePurchase
para notificar a Google que se le otorgará un derecho al producto al usuario.
- Si no se confirmó la compra, llama a
En el caso de las compras de productos consumibles (productos que se pueden comprar más de una vez), llama a
BillingClient::ConsumePurchase
para notificar a Google que se le otorga al usuario un derecho al producto.
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;
}
Paso 5: Prueba tu integración
Ya está todo listo para probar tu integración con la Facturación Play. Para realizar las pruebas durante la fase de desarrollo, recomendamos aprovechar los verificadores de licencias. Los verificadores con licencia tienen acceso a pagos de prueba que evitan los cargos reales por las compras.
Si deseas obtener instrucciones para configurar verificadores de licencias y un paquete de pruebas manuales, te recomendamos que consultes la documentación sobre cómo probar la integración de la Biblioteca de Facturación Google Play.