{"id":29572707,"url":"https://github.com/accelbyte/accelbyte-unity-sdk-google-play","last_synced_at":"2025-07-19T05:10:59.116Z","repository":{"id":253884890,"uuid":"833412698","full_name":"AccelByte/accelbyte-unity-sdk-google-play","owner":"AccelByte","description":null,"archived":false,"fork":false,"pushed_at":"2024-08-14T00:26:45.000Z","size":524,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-08-20T06:38:59.015Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AccelByte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-25T02:18:56.000Z","updated_at":"2024-08-20T06:39:04.097Z","dependencies_parsed_at":"2024-08-20T06:54:11.098Z","dependency_job_id":null,"html_url":"https://github.com/AccelByte/accelbyte-unity-sdk-google-play","commit_stats":null,"previous_names":["accelbyte/accelbyte-unity-sdk-google-play"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/AccelByte/accelbyte-unity-sdk-google-play","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccelByte%2Faccelbyte-unity-sdk-google-play","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccelByte%2Faccelbyte-unity-sdk-google-play/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccelByte%2Faccelbyte-unity-sdk-google-play/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccelByte%2Faccelbyte-unity-sdk-google-play/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AccelByte","download_url":"https://codeload.github.com/AccelByte/accelbyte-unity-sdk-google-play/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccelByte%2Faccelbyte-unity-sdk-google-play/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265892519,"owners_count":23845035,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-19T05:10:58.329Z","updated_at":"2025-07-19T05:10:59.106Z","avatar_url":"https://github.com/AccelByte.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AccelByte Unity SDK Google Play Games\n\nCopyright (c) 2024 AccelByte Inc. All Rights Reserved.\nThis is licensed software from AccelByte Inc, for limitations\nand restrictions contact your company contract manager.\n\n# Overview\nUnity SDK Google Play Games is extension package to enable Accelbyte SDK support for Android Google Play Games.\n\u003e In present state, our service only able to support GooglePlayGamesPlugin-0.10.14 (Play Game Services V1). Support for Play Game Services V2 is under development.\n\n## Prerequisites\nRequire ([AccelByte Unity SDK](https://github.com/AccelByte/accelbyte-unity-sdk)) package. Minimum version: 16.24.0.\n\nFor more information about configuring AccelByte Unity SDK, see [Install and configure the SDK](https://docs.accelbyte.io/gaming-services/getting-started/setup-game-sdk/unity-sdk/#install-and-configure).\n\n## How to Install\n1. In your Unity project, go to `Window \u003e Package Manager`.\n2. Click the + icon on the Package Manager window and click `Add package from git URL...`\n3. Paste the following link into the URL field and click Add: `https://github.com/AccelByte/accelbyte-unity-sdk-google-play.git`\n4. Install `GooglePlayGamesPlugin-0.10.14-AccelByte.unitypackage` inside `_Install` directory. These package is a fork build based on ([Play Games For Unity v10.14](https://github.com/playgameservices/play-games-plugin-for-unity/blob/v10.14)). Play Games For Unity v11.01 is unable to support external parties integration\n5. Add assembly reference of `Assets/AccelByteExtensions/GooglePlayGames/com.AccelByte.GooglePlayGamesExtension` to your project.\n\n# Features Usage\n\n## Sign In with Google Play Games\n\nWe provide easier way to let player perfrom Sign in With Google Play Games platform. Therefore player doesn't need to register a new account to AGS to utilize the AGS features.\n\n### Code Implementation\n\n1. Header Initialization\n```csharp\nusing AccelByte.Core;\nusing AccelByte.Models;\n```\n\n2. Get Google Play Games Id Token\n```csharp\nprivate string googlePlayGamesIdToken = \"\";\n\nvoid Start()\n{\n    AccelByte.ThirdParties.GooglePlayGames.GooglePlayGamesExtension.Initialize();\n}\n\nprivate void GetGooglePlayGamesIdToken()\n{\n    AccelByte.ThirdParties.GooglePlayGames.GooglePlayGamesExtension.SignIn()\n    .OnSuccess((authCode) =\u003e\n    {\n        googlePlayGamesIdToken = AccelByte.ThirdParties.GooglePlayGames.GooglePlayGamesExtension.GetIdToken();\n        UnityEngine.Debug.Log(\"Obtain Google Play Games Id Token Success\");\n    })\n    .OnFailed((error) =\u003e\n    {\n        UnityEngine.Debug.LogWarning($\"Obtain Google Play Games Id Token Failed: {error.Message}\");\n    });\n}\n```\n\n3. Login to AGS\n```csharp\nprivate void AGSLogin()\n{\n    if (!string.IsNullOrEmpty(googlePlayGamesIdToken))\n    {\n        AccelByteSDK.GetClientRegistry().GetApi().GetUser().LoginWithOtherPlatformV4(\n            AccelByte.Models.PlatformType.GooglePlayGames\n            , googlePlayGamesIdToken\n            , result =\u003e\n        {\n            if (result.IsError)\n            {\n                UnityEngine.Debug.LogError($\"Failed to Login with Google Play Games Platfrom [{result.Error.error}]: {result.Error.error_description}\");\n                return;\n            }\n            UnityEngine.Debug.Log(\"Login with AccelByte IAM success\");\n        });\n    }\n}\n```\n\n## In-App Purchasing\n\n### Configure Your Game\n\n\u003e Please contact AccelByte support for guideline document\n\n### Prerequisites\n\n1. Import package [Unity In App Purchasing (IAP)](https://docs.unity3d.com/Packages/com.unity.purchasing@4.11/manual/index.html) library to the project. We recommend you to use IAP v4.11. In present state, The SDK has compatibility issue with IAP v4.12 and newer.\n2. Please refers to official [Unity documentation](https://docs.unity3d.com/Manual/UnityIAPSettingUp.html) on how to install it.\n\n### Code Implementation\n\n1. Sign in With Google Play Games, please refer to [previous part](https://github.com/AccelByte/accelbyte-unity-sdk-google-play?tab=readme-ov-file#sign-in-with-google-play-games)\n\n2. Please create `MonoBehavior` class implementing `IDetailedStoreListener`. Unity IAP will handle the purchase and trigger callbacks using this interface. Then prepare the following variables\n```csharp\npublic Button buyButton;\n    \nIStoreController storeController;\nprivate string productId = \"item_gold\"; // assume that the registered product id is named Item_gold\nprivate ProductType productType = ProductType.Consumable; // assume that \"item_gold\" is a Consumables\nProduct purchasedProduct;\n```\n\n3. Prepare a [Button](https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/script-Button.html) to trigger the purchasing event. Using Unity Editor's inspector, attach this button into `public Button buyButton;`\n\n4. Prepare a function that will be trigger the purchasing event\n```csharp\nprivate void BuyGold()\n{\n    storeController.InitiatePurchase(productId);\n}\n```\n\n5. Initialize Purchasing\n```csharp\nvoid Start()\n{\n    InitializePurchasing();\n}\n\nvoid InitializePurchasing()\n{\n    var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());\n\n    builder.AddProduct(productId, productType);\n    UnityPurchasing.Initialize(this, builder);\n\n    buyButton.onClick.AddListener(BuyGold);\n}\n\npublic void OnInitialized(IStoreController controller, IExtensionProvider extensions)\n{\n    Debug.Log(\"In-App Purchasing successfully initialized\");\n    storeController = controller;\n}\n\npublic void OnInitializeFailed(InitializationFailureReason error, string message)\n{\n    var errorMessage = $\"Purchasing failed to initialize. Reason: {error}.\";\n\n    if (message != null)\n    {\n        errorMessage += $\" More details: {message}\";\n    }\n\n    UnityEngine.Debug.Log(errorMessage);\n}\n```\n\n6. Handle Process Purchase. Please note that it **must** return `PurchaseProcessingResult.Pending` because purchased item will be synchronized with AccelByte's Backend. [reference](https://docs.unity3d.com/2021.3/Documentation/Manual/UnityIAPProcessingPurchases.html). If client successfully purchase item from Google Play Store, `ProcessPurchase` will be triggered, else `OnPurchaseFailed` will be triggered\n```csharp\npublic PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)\n{\n    //Retrieve the purchased product\n    purchasedProduct = args.purchasedProduct;\n    UnityEngine.Debug.Log($\"Purchase Complete - Product: {purchasedProduct.definition.id}\");\n    string receiptPayload = JObject.Parse(purchasedProduct.receipt)[\"Payload\"].ToString();\n    var receiptJson = JObject.Parse(receiptPayload)[\"json\"].ToString();\n    receiptObject = JObject.Parse(receiptJson);\n    var orderId = ((string)receiptObject[\"orderId\"]);\n    var packageName = ((string)receiptObject[\"packageName\"]);\n    var productId = ((string)receiptObject[\"productId\"]);\n    var purchaseTime = ((long)receiptObject[\"purchaseTime\"]);\n    var purchaseToken = ((string)receiptObject[\"purchaseToken\"]);\n    var autoAck = false; // set autoAck as true if it is durable product or item\n    AGSEntitlementSync(orderId, packageName, productId, purchaseTime, purchaseToken, autoAck);\n    // mark the process as pending, confirm the pending purchase after sync with AGS\n    return PurchaseProcessingResult.Pending;\n}\n\npublic void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)\n{\n    UnityEngine.Debug.Log($\"Purchase failed - Product: '{product.definition.id}',\" +\n        $\" Purchase failure reason: {failureDescription.reason},\" +\n        $\" Purchase failure details: {failureDescription.message}\");\n}\n```\n\n7. Sync Purchased Product with AGS\n```csharp\nprivate void AGSEntitlementSync(string orderId\n        , string packageName\n        , string productId\n        , long purchaseTime\n        , string purchaseToken\n        , bool autoAck)\n    {\n        // Please note that Sync will work after the player is logged in using AB service\n        // Please refer to https://github.com/AccelByte/accelbyte-unity-sdk-google-play?tab=readme-ov-file#sign-in-with-google-play-games for implementation\n        try\n        {\n            AccelByteSDK.GetClientRegistry().GetApi().GetEntitlement()\n            .SyncMobilePlatformPurchaseGoogle(\n                orderId\n                , packageName\n                , productId\n                , purchaseTime\n                , purchaseToken\n                , autoAck\n                , syncResult =\u003e\n                {\n                    if (syncResult.IsError)\n                    {\n                        AccelByteDebug.Log(syncResult.Error.Message);\n                        return;\n                    }\n\n                    if (syncResult.Value.NeedConsume)\n                    {\n                        FinalizePurchase(purchasedProduct);\n                    }\n                });\n        }\n        catch (Exception e)\n        {\n            Debug.LogError($\"Failed to sync with AB {e.Message}\");\n        }\n    }\n\n```\n\n8. Finalize Pending Purchase\n```csharp\nprivate void FinalizePurchase(Product purchasedProduct)\n{\n    Debug.Log($\"Confirm Pending Purchase for: {purchasedProduct.definition.id}\");\n    storeController.ConfirmPendingPurchase(purchasedProduct);\n}\n```\n\nThis is the complete script:\n```csharp\nusing UnityEngine;\nusing UnityEngine.Purchasing;\nusing UnityEngine.Purchasing.Extension;\nusing AccelByte.Core;\nusing Newtonsoft.Json.Linq;\nusing UnityEngine.UI;\nusing System;\n\npublic class NewBehaviourScript : MonoBehaviour, IDetailedStoreListener\n{\n    public Button buyButton;\n    IStoreController storeController; // The Unity Purchasing system.\n    private string productId = \"your_product_id\";\n    private ProductType productType = ProductType.Consumable;\n    Product purchasedProduct;\n    JObject receiptObject;\n\n    void Start()\n    {\n        InitializePurchasing();\n    }\n\n    /// \u003csummary\u003e\n    /// Trigger purchasing initialization\n    /// \u003c/summary\u003e\n    void InitializePurchasing()\n    {\n        var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());\n\n        builder.AddProduct(productId, productType);\n        UnityPurchasing.Initialize(this, builder);\n\n        buyButton.onClick.AddListener(BuyGold);\n    }\n\n    /// \u003csummary\u003e\n    /// A callback that will be triggered when the Initialization step is done\n    /// Its part of IDetailedStoreListener\n    /// No need to attach it anywhere\n    /// \u003c/summary\u003e\n    public void OnInitialized(IStoreController controller, IExtensionProvider extensions)\n    {\n        Debug.Log(\"In-App Purchasing successfully initialized\");\n        storeController = controller;\n    }\n\n    public void OnInitializeFailed(InitializationFailureReason error) { }\n\n    /// \u003csummary\u003e\n    /// A callback will be triggered when the Initialization step is failed, with detailed message\n    /// Its part of IDetailedStoreListener\n    /// No need to attach it anywhere\n    /// \u003c/summary\u003e\n    public void OnInitializeFailed(InitializationFailureReason error, string message)\n    {\n        var errorMessage = $\"Purchasing failed to initialize. Reason: {error}.\";\n\n        if (message != null)\n        {\n            errorMessage += $\" More details: {message}\";\n        }\n\n        UnityEngine.Debug.Log(errorMessage);\n    }\n\n    /// \u003csummary\u003e\n    /// Confirm the pending purchase after sync with AB is done\n    /// It is required because there is a synchronization step\n    /// \u003c/summary\u003e\n    private void FinalizePurchase(Product purchasedProduct)\n    {\n        Debug.Log($\"Confirm Pending Purchase for: {purchasedProduct.definition.id}\");\n        storeController.ConfirmPendingPurchase(purchasedProduct);\n    }\n\n    /// \u003csummary\u003e\n    /// This function will trigger the purchasing event\n    /// \u003c/summary\u003e\n    private void BuyGold()\n    {\n        storeController.InitiatePurchase(productId);\n    }\n\n    /// \u003csummary\u003e\n    /// A callback will be triggered when the purchasing is success\n    /// Its part of IDetailedStoreListener\n    /// No need to attach it anywhere\n    /// \u003c/summary\u003e\n    public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)\n    {\n        UnityEngine.Debug.Log($\"Purchase failed - Product: '{product.definition.id}',\" +\n            $\" Purchase failure reason: {failureDescription.reason},\" +\n            $\" Purchase failure details: {failureDescription.message}\");\n    }\n\n    public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) { }\n\n    /// \u003csummary\u003e\n    /// A callback will be triggered when the purchasing is success\n    /// Its part of IDetailedStoreListener\n    /// No need to attach it anywhere\n    /// \u003c/summary\u003e\n    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)\n    {\n        //Retrieve the purchased product\n        purchasedProduct = args.purchasedProduct;\n\n        UnityEngine.Debug.Log($\"Purchase Complete - Product: {purchasedProduct.definition.id}\");\n\n        string receiptPayload = JObject.Parse(purchasedProduct.receipt)[\"Payload\"].ToString();\n        var receiptJson = JObject.Parse(receiptPayload)[\"json\"].ToString();\n        var receiptObject = JObject.Parse(receiptJson);\n\n        var orderId = ((string)receiptObject[\"orderId\"]);\n        var packageName = ((string)receiptObject[\"packageName\"]);\n        var productId = ((string)receiptObject[\"productId\"]);\n        var purchaseTime = ((long)receiptObject[\"purchaseTime\"]);\n        var purchaseToken = ((string)receiptObject[\"purchaseToken\"]);\n        var autoAck = false; // set autoAck as true if it is durable product or item\n\n        AGSEntitlementSync(orderId, packageName, productId, purchaseTime, purchaseToken, autoAck);\n\n        // mark the process as pending, confirm the pending purchase after sync with AGS\n        return PurchaseProcessingResult.Pending;\n    }\n\n    /// \u003csummary\u003e\n    /// Synchronize the purchased product with AccelByte's server using AccelByte's SDK\n    /// \u003c/summary\u003e\n    private void AGSEntitlementSync(string orderId\n        , string packageName\n        , string productId\n        , long purchaseTime\n        , string purchaseToken\n        , bool autoAck)\n    {\n        // Please note that Sync will work after the player is logged in using AB service\n        // Please refer to https://github.com/AccelByte/accelbyte-unity-sdk-google-play?tab=readme-ov-file#sign-in-with-google-play-games for implementation\n        try\n        {\n            AccelByteSDK.GetClientRegistry().GetApi().GetEntitlement()\n            .SyncMobilePlatformPurchaseGoogle(\n                orderId\n                , packageName\n                , productId\n                , purchaseTime\n                , purchaseToken\n                , autoAck\n                , syncResult =\u003e\n                {\n                    if (syncResult.IsError)\n                    {\n                        AccelByteDebug.Log(syncResult.Error.Message);\n                        return;\n                    }\n\n                    if (syncResult.Value.NeedConsume)\n                    {\n                        FinalizePurchase(purchasedProduct);\n                    }\n                });\n        }\n        catch (Exception e)\n        {\n            Debug.LogError($\"Failed to sync with AB {e.Message}\");\n        }\n    }\n}\n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccelbyte%2Faccelbyte-unity-sdk-google-play","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faccelbyte%2Faccelbyte-unity-sdk-google-play","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccelbyte%2Faccelbyte-unity-sdk-google-play/lists"}