android_in_app_purchases.rst 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. .. _doc_android_in_app_purchases:
  2. Android in-app purchases
  3. ========================
  4. Godot offers a first-party ``GodotGooglePlayBilling`` Android plugin since Godot 3.2.2.
  5. The new plugin uses the `Google Play Billing library <https://developer.android.com/google/play/billing>`__
  6. instead of the now deprecated AIDL IAP implementation.
  7. If you learn better by looking at an example, you can find the demo project
  8. `here <https://github.com/godotengine/godot-demo-projects/tree/master/mobile/android_iap>`__.
  9. Migrating from Godot 3.2.1 and lower (GodotPaymentsV3)
  10. ------------------------------------------------------
  11. The new ``GodotGooglePlayBilling`` API is not compatible with its predecessor ``GodotPaymentsV3``.
  12. Changes
  13. *******
  14. - You need to enable the Custom Build option in your Android export settings and install
  15. the ``GodotGooglePlayBilling`` plugin manually (see below for details)
  16. - All purchases have to be acknowledged by your app. This is a
  17. `requirement from Google <https://developer.android.com/google/play/billing/integrate#process>`__.
  18. Purchases that are not acknowledged by your app will be refunded.
  19. - Support for subscriptions
  20. - Signals (no polling or callback objects)
  21. Usage
  22. -----
  23. Getting started
  24. ***************
  25. If not already done, make sure you have enabled and successfully set up :ref:`Android Custom Builds <doc_android_custom_build>`.
  26. Grab the``GodotGooglePlayBilling`` plugin binary and config from the `releases page <https://github.com/godotengine/godot-google-play-billing/releases>`__
  27. and put both into `res://android/plugins`.
  28. The plugin should now show up in the Android export settings, where you can enable it.
  29. Getting started
  30. ***************
  31. To use the ``GodotGooglePlayBilling`` API you first have to get the ``GodotGooglePlayBilling``
  32. singleton and start the connection:
  33. ::
  34. var payment
  35. func _ready():
  36. if Engine.has_singleton("GodotGooglePlayBilling"):
  37. payment = Engine.get_singleton("GodotGooglePlayBilling")
  38. # These are all signals supported by the API
  39. # You can drop some of these based on your needs
  40. payment.connect("connected", self, "_on_connected") # No params
  41. payment.connect("disconnected", self, "_on_disconnected") # No params
  42. payment.connect("connect_error", self, "_on_connect_error") # Response ID (int), Debug message (string)
  43. payment.connect("purchases_updated", self, "_on_purchases_updated") # Purchases (Dictionary[])
  44. payment.connect("purchase_error", self, "_on_purchase_error") # Response ID (int), Debug message (string)
  45. payment.connect("sku_details_query_completed", self, "_on_sku_details_query_completed") # SKUs (Dictionary[])
  46. payment.connect("sku_details_query_error", self, "_on_sku_details_query_error") # Response ID (int), Debug message (string), Queried SKUs (string[])
  47. payment.connect("purchase_acknowledged", self, "_on_purchase_acknowledged") # Purchase token (string)
  48. payment.connect("purchase_acknowledgement_error", self, "_on_purchase_acknowledgement_error") # Response ID (int), Debug message (string), Purchase token (string)
  49. payment.connect("purchase_consumed", self, "_on_purchase_consumed") # Purchase token (string)
  50. payment.connect("purchase_consumption_error", self, "_on_purchase_consumption_error") # Response ID (int), Debug message (string), Purchase token (string)
  51. payment.startConnection()
  52. else:
  53. print("Android IAP support is not enabled. Make sure you have enabled 'Custom Build' and the GodotGooglePlayBilling plugin in your Android export settings! IAP will not work.")
  54. All API methods only work if the API is connected. You can use ``payment.isReady()`` to check the connection status.
  55. Querying available items
  56. ************************
  57. As soon as the API is connected, you can query SKUs using ``querySkuDetails``.
  58. Full example:
  59. ::
  60. func _on_connected():
  61. payment.querySkuDetails(["my_iap_item"], "inapp") # "subs" for subscriptions
  62. func _on_sku_details_query_completed(sku_details):
  63. for available_sku in sku_details:
  64. print(available_sku)
  65. Purchase an item
  66. ****************
  67. To initiate the purchase flow for an item, call ``purchase``.
  68. You **must** query the SKU details for an item before you can
  69. initiate the purchase flow for it.
  70. ::
  71. payment.purchase("my_iap_item")
  72. Then, wait for the ``_on_purchases_updated`` callback and handle the purchase result:
  73. ::
  74. func _on_purchases_updated(purchases):
  75. for purchase in purchases:
  76. if purchase.purchase_state == 1: # 1 means "purchased", see https://developer.android.com/reference/com/android/billingclient/api/Purchase.PurchaseState#constants_1
  77. # enable_premium(purchase.sku) # unlock paid content, add coins, save token on server, etc. (you have to implement enable_premium yourself)
  78. if not purchase.is_acknowledged:
  79. payment.acknowledgePurchase(purchase.purchase_token) # call if non-consumable product
  80. if purchase.sku in list_of_consumable_products:
  81. payment.consumePurchase(purchase.purchase_token) # call if consumable product
  82. Check if the user purchased an item
  83. ***********************************
  84. To get all purchases, call ``queryPurchases``. Unlike most of the other functions, ``queryPurchases`` is
  85. a synchronous operation and returns a :ref:`Dictionary <class_Dictionary>` with a status code
  86. and either an array of purchases or an error message. Only active subscriptions and non-consumed one-time purchases are returned.
  87. Full example:
  88. ::
  89. var query = payment.queryPurchases("inapp") # Or "subs" for subscriptions
  90. if query.status == OK:
  91. for purchase in query.purchases:
  92. if purchase.sku == "my_iap_item" and purchase.purchase_state == 1:
  93. # enable_premium(purchase.sku) # unlock paid content, save token on server, etc.
  94. if !purchase.is_acknowledged:
  95. payment.acknowledgePurchase(purchase.purchase_token)
  96. # Or wait for the _on_purchase_acknowledged callback before giving the user what they bought
  97. Consumables
  98. ***********
  99. If your in-app item is not a one-time purchase but a consumable item (e.g. coins) which can be purchased
  100. multiple times, you can consume an item by calling ``consumePurchase`` with a purchase token.
  101. Call ``queryPurchases`` to get the purchase token. Calling ``consumePurchase`` automatically
  102. acknowledges a purchase.
  103. Consuming a product allows the user to purchase it again, and removes it from appearing in subsequent ``queryPurchases`` calls.
  104. ::
  105. var query = payment.queryPurchases("inapp") # Or "subs" for subscriptions
  106. if query.status == OK:
  107. for purchase in query.purchases:
  108. if purchase.sku == "my_consumable_iap_item" and purchase.purchase_state == 1:
  109. # enable_premium(purchase.sku) # add coins, save token on server, etc.
  110. payment.consumePurchase(purchase.purchase_token)
  111. # Or wait for the _on_purchase_consumed callback before giving the user what they bought
  112. Subscriptions
  113. *************
  114. Subscriptions don't work much different from regular in-app items. Just use ``"subs"`` as second
  115. argument to ``querySkuDetails`` to get subscription details.
  116. Check ``is_auto_renewing`` in the results of ``queryPurchases()`` to see if a
  117. user has cancelled an auto-renewing subscription