225 lines
7.3 KiB
C#
225 lines
7.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Purchasing;
|
|
using UnityEngine.Purchasing.Extension;
|
|
using UnityEngine.Purchasing.Security;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Samples.Purchasing.Core.LocalReceiptValidation
|
|
{
|
|
public class LocalReceiptValidation : MonoBehaviour, IStoreListener
|
|
{
|
|
IStoreController m_StoreController;
|
|
|
|
CrossPlatformValidator m_Validator = null;
|
|
|
|
//Your products IDs. They should match the ids of your products in your store.
|
|
public string goldProductId = "com.mycompany.mygame.gold1";
|
|
public ProductType productType = ProductType.Consumable;
|
|
|
|
public Text GoldCountText;
|
|
|
|
public UserWarning userWarning;
|
|
|
|
public Toggle appleCertificateToggle;
|
|
|
|
int m_GoldCount;
|
|
bool m_UseAppleStoreKitTestCertificate;
|
|
|
|
void Start()
|
|
{
|
|
userWarning.Clear();
|
|
appleCertificateToggle.onValueChanged.AddListener(OnAppleStoreKitTestCertificateChanged);
|
|
m_UseAppleStoreKitTestCertificate = appleCertificateToggle.isOn;
|
|
InitializePurchasing();
|
|
UpdateUI();
|
|
}
|
|
|
|
static bool IsCurrentStoreSupportedByValidator()
|
|
{
|
|
//The CrossPlatform validator only supports the GooglePlayStore and Apple's App Stores.
|
|
return IsGooglePlayStoreSelected() || IsAppleAppStoreSelected();
|
|
}
|
|
|
|
static bool IsGooglePlayStoreSelected()
|
|
{
|
|
var currentAppStore = StandardPurchasingModule.Instance().appStore;
|
|
return currentAppStore == AppStore.GooglePlay;
|
|
}
|
|
|
|
static bool IsAppleAppStoreSelected()
|
|
{
|
|
var currentAppStore = StandardPurchasingModule.Instance().appStore;
|
|
return currentAppStore == AppStore.AppleAppStore ||
|
|
currentAppStore == AppStore.MacAppStore;
|
|
}
|
|
|
|
void InitializePurchasing()
|
|
{
|
|
var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
|
|
|
|
builder.AddProduct(goldProductId, productType);
|
|
|
|
UnityPurchasing.Initialize(this, builder);
|
|
}
|
|
|
|
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
|
|
{
|
|
Debug.Log("In-App Purchasing successfully initialized");
|
|
m_StoreController = controller;
|
|
InitializeValidator();
|
|
}
|
|
|
|
void InitializeValidator()
|
|
{
|
|
if (IsCurrentStoreSupportedByValidator())
|
|
{
|
|
#if !UNITY_EDITOR
|
|
var appleTangleData = m_UseAppleStoreKitTestCertificate ? AppleStoreKitTestTangle.Data() : AppleTangle.Data();
|
|
m_Validator = new CrossPlatformValidator(GooglePlayTangle.Data(), appleTangleData, Application.identifier);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
userWarning.WarnInvalidStore(StandardPurchasingModule.Instance().appStore);
|
|
}
|
|
}
|
|
|
|
public void OnInitializeFailed(InitializationFailureReason error)
|
|
{
|
|
OnInitializeFailed(error, null);
|
|
}
|
|
|
|
public void OnInitializeFailed(InitializationFailureReason error, string message)
|
|
{
|
|
var errorMessage = $"Purchasing failed to initialize. Reason: {error}.";
|
|
|
|
if (message != null)
|
|
{
|
|
errorMessage += $" More details: {message}";
|
|
}
|
|
|
|
Debug.Log(errorMessage);
|
|
}
|
|
|
|
public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
|
|
{
|
|
Debug.Log($"Purchase failed - Product: '{product.definition.id}', PurchaseFailureReason: {failureReason}");
|
|
}
|
|
|
|
public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)
|
|
{
|
|
Debug.Log($"Purchase failed - Product: '{product.definition.id}'," +
|
|
$" Purchase failure reason: {failureDescription.reason}," +
|
|
$" Purchase failure details: {failureDescription.message}");
|
|
}
|
|
|
|
public void BuyGold()
|
|
{
|
|
m_StoreController.InitiatePurchase(goldProductId);
|
|
}
|
|
|
|
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
|
|
{
|
|
//Retrieve the purchased product
|
|
var product = args.purchasedProduct;
|
|
|
|
var isPurchaseValid = IsPurchaseValid(product);
|
|
|
|
if (isPurchaseValid)
|
|
{
|
|
//Add the purchased product to the players inventory
|
|
UnlockContent(product);
|
|
Debug.Log("Valid receipt, unlocking content.");
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Invalid receipt, not unlocking content.");
|
|
}
|
|
|
|
//We return Complete, informing Unity IAP that the processing on our side is done and the transaction can be closed.
|
|
return PurchaseProcessingResult.Complete;
|
|
}
|
|
|
|
bool IsPurchaseValid(Product product)
|
|
{
|
|
//If we the validator doesn't support the current store, we assume the purchase is valid
|
|
if (IsCurrentStoreSupportedByValidator())
|
|
{
|
|
try
|
|
{
|
|
var result = m_Validator.Validate(product.receipt);
|
|
|
|
//The validator returns parsed receipts.
|
|
LogReceipts(result);
|
|
}
|
|
|
|
//If the purchase is deemed invalid, the validator throws an IAPSecurityException.
|
|
catch (IAPSecurityException reason)
|
|
{
|
|
Debug.Log($"Invalid receipt: {reason}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void UnlockContent(Product product)
|
|
{
|
|
if (product.definition.id == goldProductId)
|
|
{
|
|
AddGold();
|
|
}
|
|
}
|
|
|
|
void AddGold()
|
|
{
|
|
m_GoldCount++;
|
|
UpdateUI();
|
|
}
|
|
|
|
void UpdateUI()
|
|
{
|
|
GoldCountText.text = $"Your Gold: {m_GoldCount}";
|
|
}
|
|
|
|
static void LogReceipts(IEnumerable<IPurchaseReceipt> receipts)
|
|
{
|
|
Debug.Log("Receipt is valid. Contents:");
|
|
foreach (var receipt in receipts)
|
|
{
|
|
LogReceipt(receipt);
|
|
}
|
|
}
|
|
|
|
static void LogReceipt(IPurchaseReceipt receipt)
|
|
{
|
|
Debug.Log($"Product ID: {receipt.productID}\n" +
|
|
$"Purchase Date: {receipt.purchaseDate}\n" +
|
|
$"Transaction ID: {receipt.transactionID}");
|
|
|
|
if (receipt is GooglePlayReceipt googleReceipt)
|
|
{
|
|
Debug.Log($"Purchase State: {googleReceipt.purchaseState}\n" +
|
|
$"Purchase Token: {googleReceipt.purchaseToken}");
|
|
}
|
|
|
|
if (receipt is AppleInAppPurchaseReceipt appleReceipt)
|
|
{
|
|
Debug.Log($"Original Transaction ID: {appleReceipt.originalTransactionIdentifier}\n" +
|
|
$"Subscription Expiration Date: {appleReceipt.subscriptionExpirationDate}\n" +
|
|
$"Cancellation Date: {appleReceipt.cancellationDate}\n" +
|
|
$"Quantity: {appleReceipt.quantity}");
|
|
}
|
|
}
|
|
|
|
void OnAppleStoreKitTestCertificateChanged(bool value)
|
|
{
|
|
m_UseAppleStoreKitTestCertificate = value;
|
|
InitializeValidator();
|
|
}
|
|
}
|
|
}
|