Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
покупки через програму Android
Godot пропонує плагін для Android GodotGooglePlayBilling, сумісний з Godot 4.2+, який використовує бібліотеку Google Play Billing <https://developer.android.com/google/play/billing>`_.
Використання
Перші кроки
Переконайтеся, що ви ввімкнули та успішно налаштували Android Gradle Builds. Дотримуйтесь інструкцій з встановлення на сторінці GodotGooglePlayBilling github.
Ініціалізуйте плагін
Щоб скористатися API GodotGooglePlayBilling:
Доступ до
BillingClient.Підключіться до його сигналів, щоб отримувати результати виставлення рахунків.
Викликає
start_connection.
Приклад ініціалізації:
var billing_client: BillingClient
func _ready():
billing_client = BillingClient.new()
billing_client.connected.connect(_on_connected) # No params
billing_client.disconnected.connect(_on_disconnected) # No params
billing_client.connect_error.connect(_on_connect_error) # response_code: int, debug_message: String
billing_client.query_product_details_response.connect(_on_query_product_details_response) # response: Dictionary
billing_client.query_purchases_response.connect(_on_query_purchases_response) # response: Dictionary
billing_client.on_purchase_updated.connect(_on_purchase_updated) # response: Dictionary
billing_client.consume_purchase_response.connect(_on_consume_purchase_response) # response: Dictionary
billing_client.acknowledge_purchase_response.connect(_on_acknowledge_purchase_response) # response: Dictionary
billing_client.start_connection()
Перед використанням API повинен бути у підключеному стані. Сигнал connected надсилається, коли процес підключення завершується успішно. Ви також можете використовувати is_ready(), щоб визначити, чи готовий плагін до використання. Функція get_connection_state() повертає поточний стан підключення плагіна.
Повернуті значення для get_connection_state():
# Matches BillingClient.ConnectionState in the Play Billing Library.
# Access in your script as: BillingClient.ConnectionState.CONNECTED
enum ConnectionState {
DISCONNECTED, # This client was not yet connected to billing service or was already closed.
CONNECTING, # This client is currently in process of connecting to billing service.
CONNECTED, # This client is currently connected to billing service.
CLOSED, # This client was already closed and shouldn't be used again.
}
Отримати наявні товари
Після підключення API запитуйте ідентифікатори продуктів за допомогою query_product_details(). Ви повинні успішно виконати запит деталей продукту перед викликом функцій purchase(), purchase_subscription() або update_subscription(), інакше вони повернуть помилку. query_product_details() приймає два параметри: масив рядків ідентифікатора продукту та тип продукту, що запитується. Тип продукту має бути BillingClient.ProductType.INAPP для звичайних покупок у додатку або BillingClient.ProductType.SUBS для підписок. Рядки ідентифікатора в масиві повинні відповідати ідентифікаторам продуктів, визначеним у записі Google Play Console для вашого додатка.
Приклад використання query_product_details():
func _on_connected():
billing_client.query_product_details(["my_iap_item"], BillingClient.ProductType.INAPP) # BillingClient.ProductType.SUBS for subscriptions.
func _on_query_product_details_response(query_result: Dictionary):
if query_result.response_code == BillingClient.BillingResponseCode.OK:
print("Product details query success")
for available_product in query_result.product_details:
print(available_product)
else:
print("Product details query failed")
print("response_code: ", query_result.response_code, "debug_message: ", query_result.debug_message)
Запит на покупки користувачів і
Щоб отримати дані про покупки користувача, викличте функцію query_purchases(), передаючи тип продукту запиту. Тип продукту має бути BillingClient.ProductType.INAPP для звичайних покупок у додатку або BillingClient.ProductType.SUBS для підписок. Сигнал query_purchases_response надсилається з результатом. Сигнал має один параметр: Dictionary з кодом відповіді та масивом покупок або повідомленням налагодження. У масив покупок включено лише активні підписки та невикористані одноразові покупки.
Приклад використання query_purchases():
func _query_purchases():
billing_client.query_purchases(BillingClient.ProductType.INAPP) # Or BillingClient.ProductType.SUBS for subscriptions.
func _on_query_purchases_response(query_result: Dictionary):
if query_result.response_code == BillingClient.BillingResponseCode.OK:
print("Purchase query success")
for purchase in query_result.purchases:
_process_purchase(purchase)
else:
print("Purchase query failed")
print("response_code: ", query_result.response_code, "debug_message: ", query_result.debug_message)
Придбайте товар
Щоб запустити процес виставлення рахунків для товару: використовуйте purchase() для продуктів у додатку, передаючи рядок ідентифікатора продукту. Використовуйте purchase_subscription() для підписок, передаючи ідентифікатор продукту та ідентифікатор базового плану. Ви також можете за бажанням вказати ідентифікатор пропозиції.
Для обох функцій purchase() та purchase_subscription() ви можете за бажанням передати логічне значення, щоб вказати, чи є пропозиції персоналізованими
Нагадування: ви повинні запитати деталі товару, перш ніж передати їх до purchase(). Цей метод повертає словник, який вказує, чи успішно запущено процес виставлення рахунків. Він містить код відповіді та масив покупок або повідомлення про налагодження.
Приклад використання purchase():
var result = billing_client.purchase("my_iap_item")
if result.response_code == BillingClient.BillingResponseCode.OK:
print("Billing flow launch success")
else:
print("Billing flow launch failed")
print("response_code: ", result.response_code, "debug_message: ", result.debug_message)
Результат покупки буде надіслано через сигнал on_purchases_updated.
func _on_purchases_updated(result: Dictionary):
if result.response_code == BillingClient.BillingResponseCode.OK:
print("Purchase update received")
for purchase in result.purchases:
_process_purchase(purchase)
else:
print("Purchase update error")
print("response_code: ", result.response_code, "debug_message: ", result.debug_message)
Обробка покупки товару
Сигнали query_purchases_response та on_purchases_updated надають масив покупок у форматі Dictionary. Словник покупок містить ключі, що відповідають значенням класу Purchase у Google Play Billing.
Поля покупки:
order_id: String
purchase_token: String
package_name: String
purchase_state: int
purchase_time: int (milliseconds since the epoch (Jan 1, 1970))
original_json: String
is_acknowledged: bool
is_auto_renewing: bool
quantity: int
signature: String
product_ids: PackedStringArray
Перевірити стан покупки
Перевірте значення purchase_state покупки, щоб визначити, чи була покупка завершена чи все ще очікує на розгляд.
Значення PurchaseState:
# Matches Purchase.PurchaseState in the Play Billing Library
# Access in your script as: BillingClient.PurchaseState.PURCHASED
enum PurchaseState {
UNSPECIFIED,
PURCHASED,
PENDING,
}
Якщо покупка перебуває в стані ОЧІКУВАННЯ, вам не слід присуджувати вміст покупки або виконувати будь-яку подальшу обробку покупки, доки вона не досягне стану ПРИДБАНО. Якщо у вас є інтерфейс магазину, ви можете відобразити інформацію про незавершені покупки, які потрібно завершити в магазині Google Play. Додаткову інформацію про незавершені покупки див. у розділі «Обробка незавершених транзакцій <https://developer.android.com/google/play/billing/integrate#pending>`_ у документації бібліотеки платежів Google Play.
Витратні матеріали
Якщо ваш елемент у додатку не є одноразовою покупкою, а споживчим предметом (наприклад, монетами), який можна придбати кілька разів, ви можете використати елемент, викликавши consume_purchase(), передаючи значення purchase_token зі словника покупок. Виклик consume_purchase() автоматично підтверджує покупку. Споживання продукту дозволяє користувачеві придбати його знову, він більше не відображатиметься в наступних викликах query_purchases(), якщо його не буде придбано повторно.
Приклад використання consume_purchase():
func _process_purchase(purchase):
if "my_consumable_iap_item" in purchase.product_ids and purchase.purchase_state == BillingClient.PurchaseState.PURCHASED:
# Add code to store payment so we can reconcile the purchase token
# in the completion callback against the original purchase
billing_client.consume_purchase(purchase.purchase_token)
func _on_consume_purchase_response(result: Dictionary):
if result.response_code == BillingClient.BillingResponseCode.OK:
print("Consume purchase success")
_handle_purchase_token(result.token, true)
else:
print("Consume purchase failed")
print("response_code: ", result.response_code, "debug_message: ", result.debug_message, "purchase_token: ", result.token)
# Find the product associated with the purchase token and award the
# product if successful
func _handle_purchase_token(purchase_token, purchase_successful):
# check/award logic, remove purchase from tracking list
Підтвердження покупок
Якщо ваш продукт у додатку є одноразовою покупкою, ви повинні підтвердити покупку, викликавши функцію acknowledge_purchase(), передавши значення purchase_token зі словника покупок. Якщо ви не підтвердите покупку протягом трьох днів, користувач автоматично отримає відшкодування, а Google Play скасовує покупку. Якщо ви викликаєте comsume_purchase(), покупка автоматично підтверджується, і вам не потрібно викликати acknowledge_purchase().
Приклад використання acknowledge_purchase():
func _process_purchase(purchase):
if "my_one_time_iap_item" in purchase.product_ids and \
purchase.purchase_state == BillingClient.PurchaseState.PURCHASED and \
not purchase.is_acknowledged:
# Add code to store payment so we can reconcile the purchase token
# in the completion callback against the original purchase
billing_client.acknowledge_purchase(purchase.purchase_token)
func _on_acknowledge_purchase_response(result: Dictionary):
if result.response_code == BillingClient.BillingResponseCode.OK:
print("Acknowledge purchase success")
_handle_purchase_token(result.token, true)
else:
print("Acknowledge purchase failed")
print("response_code: ", result.response_code, "debug_message: ", result.debug_message, "purchase_token: ", result.token)
# Find the product associated with the purchase token and award the
# product if successful
func _handle_purchase_token(purchase_token, purchase_successful):
# check/award logic, remove purchase from tracking list
Підписки
Підписки працюють здебільшого як звичайні елементи в додатку. Використовуйте BillingClient.ProductType.SUBS як другий аргумент query_product_details(), щоб отримати деталі підписки. Передайте BillingClient.ProductType.SUBS до query_purchases(), щоб отримати деталі придбання підписки.
Ви можете перевірити is_auto_renewing у запиті на придбання підписки, повернутому query_purchases(), щоб дізнатися, чи скасував користувач підписку з автоматичним поновленням.
Вам потрібно підтверджувати придбання нових підписок, але не автоматичне поновлення підписки.
Якщо ви підтримуєте оновлення або зниження рівня підписки між різними рівнями, вам слід використовувати update_subscription() для використання процесу оновлення підписки для зміни активної підписки. Як і purchase(), результати повертаються сигналом on_purchases_updated. Ось параметри update_subscription():
old_purchase_token: Токен покупки поточної активної підписки
replacement_mode: Режим заміни, який слід застосувати до підписки
product_id: Ідентифікатор продукту нової підписки для переходу
base_plan_id: Ідентифікатор базового плану цільової підписки
offer_id: Ідентифікатор пропозиції за базовим планом (необов'язково)
is_offer_personalized: Чи вмикати персоналізоване ціноутворення (необов'язково)
Значення режимів заміщення визначаються як:
# Access in your script as: BillingClient.ReplacementMode.WITH_TIME_PRORATION
enum ReplacementMode {
# Unknown...
UNKNOWN_REPLACEMENT_MODE = 0,
# The new plan takes effect immediately, and the remaining time will be prorated and credited to the user.
# Note: This is the default behavior.
WITH_TIME_PRORATION = 1,
# The new plan takes effect immediately, and the billing cycle remains the same.
CHARGE_PRORATED_PRICE = 2,
# The new plan takes effect immediately, and the new price will be charged on next recurrence time.
WITHOUT_PRORATION = 3,
# Replacement takes effect immediately, and the user is charged full price of new plan and
# is given a full billing cycle of subscription, plus remaining prorated time from the old plan.
CHARGE_FULL_PRICE = 5,
# The new purchase takes effect immediately, the new plan will take effect when the old item expires.
DEFERRED = 6,
}
Поведінка за замовчуванням — WITH_TIME_PRORATION.
Приклад використання update_subscription:
billing_client.update_subscription(_active_subscription_purchase.purchase_token, \
BillingClient.ReplacementMode.WITH_TIME_PRORATION, "new_sub_product_id", "base_plan_id")