Achats intégrés à l’application Android

Depuis la version 3.2.2, Godot propose un plugin Android GodotGooglePlayBilling. Le nouveau plugin utilise la bibliothèque Google Play Billing library au lieu de l'implémentation AIDL IAP qui est maintenant obsolète.

If you learn better by looking at an example, you can find the demo project here.

Migrer à partir de Godot 3.2.1 et moins (GodotPaymentsV3)

La nouvelle API GodotGooglePlayBilling n'est pas compatible avec son prédécesseur GodotPaymentsV3.

Modifications

  • Vous devez activer l'option Custom Build dans vos paramètres d'exportation Android et installer le plugin GodotGooglePlayBilling manuellement (voir ci-dessous pour plus de détails)
  • Tous les achats doivent être confirmés par votre application. C'est une exigence de Google. Les achats qui ne sont pas reconnus par votre application seront remboursés.
  • Prise en charge des abonnements
  • Signaux (pas polling ou callback d'objets)

Utilisation

Prise en main

Si ce n'est pas déjà fait, assurez-vous que vous avez activé et configuré avec succès Android Custom Builds. Prenez le binaire et la configuration du plugin GodotGooglePlayBilling sur la page des versions et mettez les deux dans res://android/plugins. Le plugin devrait maintenant apparaître dans les paramètres d'exportation d'Android, où vous pouvez l'activer.

Prise en main

Pour utiliser l'API GodotGooglePlayBilling, vous devez d'abord obtenir le singleton GodotGooglePlayBilling et démarrer la connexion :

var payment

func _ready():
    if Engine.has_singleton("GodotGooglePlayBilling"):
        payment = Engine.get_singleton("GodotGooglePlayBilling")

        # These are all signals supported by the API
        # You can drop some of these based on your needs
        payment.connect("connected", self, "_on_connected") # No params
        payment.connect("disconnected", self, "_on_disconnected") # No params
        payment.connect("connect_error", self, "_on_connect_error") # Response ID (int), Debug message (string)
        payment.connect("purchases_updated", self, "_on_purchases_updated") # Purchases (Dictionary[])
        payment.connect("purchase_error", self, "_on_purchase_error") # Response ID (int), Debug message (string)
        payment.connect("sku_details_query_completed", self, "_on_sku_details_query_completed") # SKUs (Dictionary[])
        payment.connect("sku_details_query_error", self, "_on_sku_details_query_error") # Response ID (int), Debug message (string), Queried SKUs (string[])
        payment.connect("purchase_acknowledged", self, "_on_purchase_acknowledged") # Purchase token (string)
        payment.connect("purchase_acknowledgement_error", self, "_on_purchase_acknowledgement_error") # Response ID (int), Debug message (string), Purchase token (string)
        payment.connect("purchase_consumed", self, "_on_purchase_consumed") # Purchase token (string)
        payment.connect("purchase_consumption_error", self, "_on_purchase_consumption_error") # Response ID (int), Debug message (string), Purchase token (string)

        payment.startConnection()
    else:
        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.")

Toutes les méthodes API ne fonctionnent que si l'API est connectée. Vous pouvez utiliser payment.isReady() pour vérifier l'état de la connexion.

Recherche d'articles disponibles

Dès que l'API est connectée, vous pouvez interroger les SKU en utilisant querySkuDetails.

Exemple complet :

func _on_connected():
  payment.querySkuDetails(["my_iap_item"], "inapp") # "subs" for subscriptions

func _on_sku_details_query_completed(sku_details):
  for available_sku in sku_details:
    print(available_sku)

Acheter un article

Pour lancer le flux d'achat d'un article, appelez purchase. Vous devez demander les détails du SKU d'un article avant de pouvoir lancer le processus d'achat.

payment.purchase("my_iap_item")

Vérifier si l'utilisateur a acheté un article

Pour obtenir tous les achats, appelez le service queryPurchases. Contrairement à la plupart des autres fonctions, queryPurchases est une opération synchrone et retourne un Dictionary avec un code de statut et soit un tableau d'achats soit un message d'erreur.

Exemple complet :

var query = payment.queryPurchases("inapp") # Or "subs" for subscriptions
if query.status == OK:
    for purchase in query.purchases:
        if purchase.sku == "my_iap_item":
            premium = true # Entitle the user to the content they bought
            if !purchase.is_acknowledged:
                payment.acknowledgePurchase(purchase.purchase_token)

Consommables

Si votre article intégré à l'application n'est pas un achat unique mais un article consommable (par exemple des pièces de monnaie) qui peut être acheté plusieurs fois, vous pouvez consommer un article en appelant consumePurchase avec un jeton d'achat. Appelez queryPurchases pour obtenir le jeton d'achat. Le fait d'appeler consumePurchase confirme automatiquement l'achat.

var query = payment.queryPurchases("inapp") # Or "subs" for subscriptions
if query.status == OK:
    for purchase in query.purchases:
        if purchase.sku == "my_consumable_iap_item":
            if !purchase.is_acknowledged:
                payment.consumePurchase(purchase.purchase_token)
                # Check the _on_purchase_consumed callback and give the user what they bought

Abonnements

Les abonnements ne sont pas très différents des articles intégrés à l'application. Il suffit d'utiliser "subs" comme deuxième argument à querySkuDetails pour obtenir les détails de l'abonnement. Vérifiez is_auto_renewing dans les résultats de queryPurchases() pour voir si un utilisateur a annulé un abonnement à renouvellement automatique