Achats Intégrés Unity
Espace de noms : UnityEngine.Purchasing | Sécurité : UnityEngine.Purchasing.Security
Paquet : com.unity.purchasing
Unity IAP a son propre chemin d'initialisation via UnityIAPServices.StoreController() → store.Connect(). Il ne nécessite pas UnityServices.InitializeAsync(), mais les deux peuvent coexister si votre projet utilise d'autres services UGS. Si Analytics est présent et que InitializeAsync() est appelée, IAP enverra automatiquement des événements de transaction.
Avant de commencer
Lisez toujours references/pre-check.md en premier. Ce fichier analyse le projet à la recherche de packages IAP tiers, de Google Billing natif et de versions existantes d'Unity IAP, puis achemine vers le bon chemin. Ne lisez aucun autre fichier de référence et n'apportez aucune modification tant que le routage n'est pas résolu.
Références détaillées
- Analyse du projet et routage des chemins (à lire en premier) : Voir references/pre-check.md
- Signatures d'API et exemples de code : Voir references/api-notes.md
- Extensions de plateforme (Apple, Google) : Voir references/platform-notes.md
- Édition de
IAPProductCatalog.json(schéma, sérialisation décimale, actualisation) : Voir references/codeless-catalog.md - Migration v4 → v5 : Voir references/migration-v4-to-v5.md
- Conversion de Google BillingClient natif vers Unity IAP 5 : Voir references/path-convert-native-google-billing.md
- Conversion du plugin iOS StoreKit natif vers Unity IAP 5 : Voir references/path-convert-native-storekit.md
- Conversion de la facturation Essential Kit vers Unity IAP 5 : Voir references/convert-essentialkit.md
- UniPay (FLOBUK) — évaluation et conseils : Voir references/convert-unipay.md
- RevenueCat — évaluation et conseils de conversion : Voir references/convert-revenuecat.md
- Adapty — évaluation et conseils de conversion : Voir references/convert-adapty.md
- Ajout d'Unity IAP 5 à un projet sans IAP existant : Voir references/path-add-iap-to-new-project.md
- Implémentation des capacités IAP D2C (fournisseur de paiement tiers — Stripe/Coda, nécessite v5.4+) : Voir references/path-implement-iap-d2c.md
Lisez les fichiers de référence à la demande — seulement lorsque vous avez besoin de signatures d'API spécifiques, de détails d'extensions de plateforme ou de correspondances de migration.
Flux d'initialisation
- Obtenez
StoreControllerviaUnityIAPServices.StoreController()(ou des services individuels viaDefaultStore(),DefaultProduct(),DefaultPurchase()) - Abonnez-vous à tous les événements requis (voir Abonnements aux événements requis ci-dessous) avant d'appeler
Connect() await store.Connect()pour vous connecter au magasin de la plateforme- Sur
OnStoreConnected, appelezstore.FetchProducts(List<ProductDefinition>)pour charger le catalogue - Sur
OnProductsFetched, les produits sont prêts pour l'affichage et l'achat
Utilisez Awake() pour l'initialisation — garantit qu'IAP est prêt avant les autres méthodes Start().
Types de produits : ProductType.Consumable, ProductType.NonConsumable, ProductType.Subscription.
Récupération des produits
Définissez les produits comme List<ProductDefinition> et passez-les à store.FetchProducts(). Utilisez StoreSpecificIds lorsque les identifiants de produits diffèrent entre les magasins Apple/Google. Pour les catalogues complexes, utilisez CatalogProvider pour gérer les ensembles de produits et les identifiants spécifiques au magasin.
| Méthode | Comportement |
|---|---|
GetProducts() | Renvoie la liste des produits mise en cache (synchrone, obsolète si FetchProducts n'a pas été appelée) |
FetchProducts() | Interroge le magasin pour obtenir des prix/disponibilités à jour et met à jour le cache |
GetProductById(id) | Renvoie un seul produit mis en cache par son identifiant |
Ces méthodes ne sont PAS interchangeables. Appelez toujours FetchProducts() d'abord avant de vous fier à GetProducts().
Flux d'achat en deux étapes
IAP v5 utilise un flux obligatoire en deux étapes : En attente → Confirmer.
store.PurchaseProduct(product)— lance la boîte de dialogue d'achat de la plateformeOnPurchasePendingse déclenche — vous recevez unePendingOrder- Validez le reçu, accordez le contenu au joueur
store.ConfirmPurchase(pendingOrder)— finalise la transactionOnPurchaseConfirmedse déclenche — reçoit le type de baseOrder; utilisez la correspondance de modèleConfirmedOrder(succès) vsFailedOrder(échec de la confirmation)
Vous DEVEZ appeler ConfirmPurchase(pendingOrder) après avoir accordé le contenu. Les achats non confirmés sont redistribués au prochain lancement de l'application pour éviter les pertes d'achats.
Dé-duplication : OnPurchasePending peut se déclencher plusieurs fois pour le même achat (par exemple, redémarrage de l'application avant confirmation). Vérifiez toujours si le contenu a déjà été accordé.
Consommables : Les achats consommables confirmés ne sont PAS renvoyés par FetchPurchases. Suivez vous-même les octrois de consommables (par exemple, dans Cloud Save ou Economy).
Achats différés : OnPurchaseDeferred se déclenche pour les achats Demander à acheter (iOS) et les achats différés Google Play. N'accordez PAS le contenu — attendez OnPurchasePending une fois approuvé.
Restauration des transactions
store.RestoreTransactions(callback) redistribue les achats non-consommables et les abonnements. Chaque achat restauré déclenche OnPurchasePending.
Requis sur iOS pour la conformité à l'App Store d'Apple — ajoutez un bouton "Restaurer les achats".
Les abonnements non renouvelables Apple ne peuvent pas être restaurés via RestoreTransactions. Suivez-les côté serveur.
Validation du reçu
| Plateforme | Approche |
|---|---|
| Google Play | CrossPlatformValidator avec GooglePlayTangle.Data() — validation locale prise en charge |
| Apple (StoreKit 2) | La validation locale est une opération sans effet. Utilisez order.Info.Apple?.jwsRepresentation pour la validation côté serveur |
Générez les données de tanglement via Services > In-App Purchasing > Receipt Validation Obfuscator dans l'éditeur Unity.
Vérification des droits
Utilisez-la lorsque vous n'avez pas l'Order et que vous souhaitez connaître le statut d'un produit spécifique (remplace product.hasReceipt de v4). Si vous avez déjà l'Order, vérifiez plutôt son type : PendingOrder correspond à EntitledUntilConsumed (consommables) ou EntitledButNotFinished (non-consommables/abonnements), ConfirmedOrder correspond à FullyEntitled.
Appelez store.CheckEntitlement(product) et gérez store.OnCheckEntitlement. Vérifiez entitlement.Status == EntitlementStatus.FullyEntitled.
Valeurs de EntitlementStatus : FullyEntitled, EntitledUntilConsumed, EntitledButNotFinished, NotEntitled, Unknown.
Récupération des achats existants
store.FetchPurchases() récupère tous les achats en cours depuis le magasin. Utile au démarrage de l'application.
| Méthode | Comportement |
|---|---|
GetPurchases() | Renvoie la liste des achats mise en cache |
FetchPurchases() | Interroge le magasin pour les achats en cours et remplace la liste mise en cache |
FetchPurchases() remplace toute la liste mise en cache à chaque appel. Seuls les non-consommables et les abonnements sont retournés.