unity內購-Google支付(unity In-App Purchasing)
阿新 • • 發佈:2018-11-28
unity In-App Purchasing 支付
支援二次驗證,json解析完之後,把解析出來的引數發給伺服器,因為是unity封裝的sdk,code引數需要在購買成功之後的回撥裡給伺服器發個int型別的引數,賦值為零。伺服器要接Google源生的;
如果有不明白的加QQ群:636926481
1.開啟unity
2.如果沒有出現這個介面說明你沒有登入unity,有賬號的就登陸就可以,沒有的自己申請
3.操作完之後點選import
5.全選,然後Cancel
6.新增第一個按鈕,然後配置
8.選擇商品按鈕
9.開啟IAPButten
10.程式碼複製進去,全部替換,
#if UNITY_PURCHASING using UnityEngine.Events; using UnityEngine.UI; using System.IO; using System.Collections.Generic; namespace UnityEngine.Purchasing { [RequireComponent(typeof(Button))] [AddComponentMenu("Unity IAP/IAP Button")] [HelpURL("https://docs.unity3d.com/Manual/UnityIAP.html")] public class IAPButton : MonoBehaviour { public enum ButtonType { Purchase, Restore } [System.Serializable] public class OnPurchaseCompletedEvent : UnityEvent<Product> { }; [System.Serializable] public class OnPurchaseFailedEvent : UnityEvent<Product, PurchaseFailureReason> { }; [HideInInspector] public string productId; [Tooltip("The type of this button, can be either a purchase or a restore button")] public ButtonType buttonType = ButtonType.Purchase; [Tooltip("Consume the product immediately after a successful purchase")] public bool consumePurchase = true; [Tooltip("Event fired after a successful purchase of this product")] public OnPurchaseCompletedEvent onPurchaseComplete; [Tooltip("Event fired after a failed purchase of this product")] public OnPurchaseFailedEvent onPurchaseFailed; [Tooltip("[Optional] Displays the localized title from the app store")] public Text titleText; [Tooltip("[Optional] Displays the localized description from the app store")] public Text descriptionText; [Tooltip("[Optional] Displays the localized price from the app store")] public Text priceText; //用於驗證是否可購買 private bool ISGoogle = true; void Start() { Button button = GetComponent<Button>(); if (buttonType == ButtonType.Purchase) { if (button) { button.onClick.AddListener(PurchaseProduct); } if (string.IsNullOrEmpty(productId)) { Debug.LogError("IAPButton productId is empty"); } if (!CodelessIAPStoreListener.Instance.HasProductInCatalog(productId)) { Debug.LogWarning("The product catalog has no product with the ID \"" + productId + "\""); } } else if (buttonType == ButtonType.Restore) { if (button) { button.onClick.AddListener(Restore); } } } void OnEnable() { if (buttonType == ButtonType.Purchase) { CodelessIAPStoreListener.Instance.AddButton(this); if (CodelessIAPStoreListener.initializationComplete) { UpdateText(); } } } void OnDisable() { if (buttonType == ButtonType.Purchase) { CodelessIAPStoreListener.Instance.RemoveButton(this); } } void PurchaseProduct() { if (buttonType == ButtonType.Purchase && ISGoogle == true ) { Debug.Log("IAPButton.PurchaseProduct() with product ID: " + productId); Product product = CodelessIAPStoreListener.Instance.GetProduct(productId); ISGoogle = false; if (product != null) { Debug.LogFormat("product recipt:{0}", product.receipt); Debug.LogFormat("Purchasing product asychronously productyType is:{0}", product.definition.type.ToString()); CodelessIAPStoreListener.Instance.InitiatePurchase(productId); } } } void Restore() { if (buttonType == ButtonType.Restore) { if (Application.platform == RuntimePlatform.WSAPlayerX86 || Application.platform == RuntimePlatform.WSAPlayerX64 || Application.platform == RuntimePlatform.WSAPlayerARM) { CodelessIAPStoreListener.Instance.ExtensionProvider.GetExtension<IMicrosoftExtensions>() .RestoreTransactions(); } else if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.tvOS) { CodelessIAPStoreListener.Instance.ExtensionProvider.GetExtension<IAppleExtensions>() .RestoreTransactions(OnTransactionsRestored); } else if (Application.platform == RuntimePlatform.Android && StandardPurchasingModule.Instance().appStore == AppStore.SamsungApps) { CodelessIAPStoreListener.Instance.ExtensionProvider.GetExtension<ISamsungAppsExtensions>() .RestoreTransactions(OnTransactionsRestored); } else if (Application.platform == RuntimePlatform.Android && StandardPurchasingModule.Instance().appStore == AppStore.CloudMoolah) { CodelessIAPStoreListener.Instance.ExtensionProvider.GetExtension<IMoolahExtension>() .RestoreTransactionID((restoreTransactionIDState) => { OnTransactionsRestored( restoreTransactionIDState != RestoreTransactionIDState.RestoreFailed && restoreTransactionIDState != RestoreTransactionIDState.NotKnown); }); } else { Debug.LogWarning(Application.platform.ToString() + " is not a supported platform for the Codeless IAP restore button"); } } } void OnTransactionsRestored(bool success) { Debug.Log("Transactions restored: " + success); } /** * Invoked to process a purchase of the product associated with this button */ public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) { Debug.Log(string.Format("IAPButton.ProcessPurchase(PurchaseEventArgs {0} - {1})", e, e.purchasedProduct.definition.id)); ISGoogle = true; onPurchaseComplete.Invoke(e.purchasedProduct); //json解析 var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(purchasedProduct.receipt); var store = (string)wrapper["Store"]; var payload = (string)wrapper["Payload"]; var gpDetails = (Dictionary<string, object>)MiniJson.JsonDecode(payload); var gpJson = (string)gpDetails["json"]; var gpSig = (string)gpDetails["signature"]; return (consumePurchase) ? PurchaseProcessingResult.Complete : PurchaseProcessingResult.Pending; } /** * Invoked on a failed purchase of the product associated with this button */ public void OnPurchaseFailed(Product product, PurchaseFailureReason reason) { Debug.Log(string.Format("IAPButton.OnPurchaseFailed(Product {0}, PurchaseFailureReason {1})", product, reason)); onPurchaseFailed.Invoke(product, reason); ISGoogle = true; } internal void UpdateText() { var product = CodelessIAPStoreListener.Instance.GetProduct(productId); if (product != null) { if (titleText != null) { titleText.text = product.metadata.localizedTitle; } if (descriptionText != null) { descriptionText.text = product.metadata.localizedDescription; } if (priceText != null) { priceText.text = product.metadata.localizedPriceString; } } } } } #endif
對於後期會涉及到更新,需要程式碼控制商品的遊戲,建議使用
需要把第七步填寫的引數全部去掉,把客戶端商品上的APIButten去掉,程式碼放在商城介面上
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Purchasing; using UnityEngine.Purchasing.Security; public class Purchaser : MonoBehaviour, IStoreListener { private IStoreController mStoreController; private IExtensionProvider mExtensionProvider; ConfigurationBuilder builder; public static string kProductIDConsumable = "consumable"; //消耗商品 public static string kProductIDNonConsumable = "nonconsumable"; //非消耗商品 public static string kProductIDSubscription = "subscription"; //訂閱產品 //商品 private const string product_1 = "buy_gold_001"; private const string product_2 = "buy_gold_002"; private const string product_3 = "buy_gold_003"; private const string product_4 = "buy_gold_004"; private bool ISGoogle = true; void Start() { if (mStoreController == null) { InitPurchasing(); } } //初始化 public void InitPurchasing() { if (IsInitialized()) { return; } // Create a builder, first passing in a suite of Unity provided stores. var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); //新增商品ID和型別 對應定義的商品ID builder.AddProduct(product_1, ProductType.Consumable, new IDs { {product_1, GooglePlay.Name } }); builder.AddProduct(product_2, ProductType.Consumable, new IDs { {product_2, GooglePlay.Name } }); builder.AddProduct(product_3, ProductType.Consumable, new IDs { {product_3, GooglePlay.Name } }); builder.AddProduct(product_4, ProductType.Consumable, new IDs { {product_4, GooglePlay.Name } }); UnityPurchasing.Initialize(this, builder); } //購買 public void BuyProduct(string productID) { ISGoogle = false; if (IsInitialized() && ISGoogle == true) { Product produdt = mStoreController.products.WithID(productID); if (produdt != null && produdt.availableToPurchase) { mStoreController.InitiatePurchase(produdt); Debug.Log(produdt.metadata.localizedPrice); } else { Debug.Log("fail"); } } else { Debug.Log("BuyProductID FAIL. Not initialized."); } } //恢復購買 public void ReSotre() { if (!IsInitialized()) { return; } if (mExtensionProvider != null&& (Application.platform == RuntimePlatform.IPhonePlayer|| Application.platform == RuntimePlatform.OSXPlayer)) { var apple = mExtensionProvider.GetExtension<IAppleExtensions>(); apple.RestoreTransactions((result) => { // Restore purchases initiated. See ProcessPurchase for any restored transacitons. Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore."); }); } } private bool IsInitialized() { return mStoreController != null && mExtensionProvider != null; } public void BuyConsumable1() { BuyProduct(product_1); } public void BuyConsumable2() { BuyProduct(product_2); } public void BuyConsumable3() { BuyProduct(product_3); } public void BuyConsumable4() { BuyProduct(product_4); } //---------------IStoreListener的四個介面的實現----------- //初始化成功 public void OnInitialized(IStoreController controller, IExtensionProvider extensions) { mStoreController = controller; mExtensionProvider = extensions; Debug.Log("----------------初始化成功---------------------"); } //初始化失敗 public void OnInitializeFailed(InitializationFailureReason error) { Debug.Log("----------------初始化失敗-------------------- -:" + error); } //購買失敗 public void OnPurchaseFailed(Product e, PurchaseFailureReason p) { var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(e.receipt); var store = (string)wrapper["Store"]; var payload = (string)wrapper["Payload"]; ISGoogle = true; var gpDetails = (Dictionary<string, object>)MiniJson.JsonDecode(payload); var gpJson = (string)gpDetails["json"]; var gpSig = (string)gpDetails["signature"]; NetworkManager.SendCustom(CLIENT_CUSTOM_MESSAGE_ENUM.CLIENT_CUSTOMMSG_GOOGLE_DELIVERY, (int)p, gpJson, gpSig); Debug.Log( "購買失敗--------------------"); } //購買成功和恢復成功的回撥,可以根據id的不同進行不同的操作 public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) { var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(e.purchasedProduct.receipt); var store = (string)wrapper["Store"]; ISGoogle = true; var payload = (string)wrapper["Payload"]; var gpDetails = (Dictionary<string, object>)MiniJson.JsonDecode(payload); var gpJson = (string)gpDetails["json"]; var gpSig = (string)gpDetails["signature"]; NetworkManager.SendCustom(CLIENT_CUSTOM_MESSAGE_ENUM.CLIENT_CUSTOMMSG_GOOGLE_DELIVERY, 0, gpJson, gpSig); return PurchaseProcessingResult.Complete; } }
出現支付頁面證明sdk接入成功
注意:如果有報錯-1002,就是測試機的問題,在設定裡面把Google商店和谷歌的所有產品的 允許應用彈出視窗 的許可權開啟,在測試就會出來支付視窗了
注意:如果內購無法購買並且報錯沒有初始化,但是初始化邏輯能走通,可能是測試機的google賬號的問題,把測試機上的google賬號全部移除,在重新登入就好了,就可以了