2025-11-15 14:52:01 +01:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Windows.Services.Store;
|
|
|
|
|
using Wino.Core.Domain.Interfaces;
|
2026-04-02 15:07:05 +02:00
|
|
|
using WinRT.Interop;
|
2026-03-19 01:50:14 +01:00
|
|
|
using WinoAddOnProductType = Wino.Core.Domain.Enums.WinoAddOnProductType;
|
2026-04-02 15:07:05 +02:00
|
|
|
using WinoStorePurchaseResult = Wino.Core.Domain.Enums.StorePurchaseResult;
|
2025-11-15 14:52:01 +01:00
|
|
|
|
|
|
|
|
namespace Wino.Mail.WinUI.Services;
|
|
|
|
|
|
|
|
|
|
public class StoreManagementService : IStoreManagementService
|
|
|
|
|
{
|
|
|
|
|
private StoreContext CurrentContext { get; }
|
|
|
|
|
|
2026-03-19 01:50:14 +01:00
|
|
|
private readonly Dictionary<WinoAddOnProductType, string> productIds = new Dictionary<WinoAddOnProductType, string>()
|
2025-11-15 14:52:01 +01:00
|
|
|
{
|
2026-04-02 15:07:05 +02:00
|
|
|
{ WinoAddOnProductType.UNLIMITED_ACCOUNTS, "UnlimitedAccounts" },
|
|
|
|
|
{ WinoAddOnProductType.AI_PACK, "AI_PACK" },
|
2025-11-15 14:52:01 +01:00
|
|
|
};
|
|
|
|
|
|
2026-03-19 01:50:14 +01:00
|
|
|
private readonly Dictionary<WinoAddOnProductType, string> skuIds = new Dictionary<WinoAddOnProductType, string>()
|
2025-11-15 14:52:01 +01:00
|
|
|
{
|
2026-04-02 15:07:05 +02:00
|
|
|
{ WinoAddOnProductType.AI_PACK, "9N2FH734RBVS" },
|
2026-03-19 01:50:14 +01:00
|
|
|
{ WinoAddOnProductType.UNLIMITED_ACCOUNTS, "9P02MXZ42GSM" }
|
2025-11-15 14:52:01 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public StoreManagementService()
|
|
|
|
|
{
|
|
|
|
|
CurrentContext = StoreContext.GetDefault();
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-19 01:50:14 +01:00
|
|
|
public async Task<bool> HasProductAsync(WinoAddOnProductType productType)
|
2025-11-15 14:52:01 +01:00
|
|
|
{
|
2026-03-19 01:50:14 +01:00
|
|
|
if (!productIds.TryGetValue(productType, out var productKey))
|
|
|
|
|
return false;
|
|
|
|
|
|
2025-11-15 14:52:01 +01:00
|
|
|
var appLicense = await CurrentContext.GetAppLicenseAsync();
|
|
|
|
|
|
|
|
|
|
if (appLicense == null)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// Access the valid licenses for durable add-ons for this app.
|
|
|
|
|
foreach (KeyValuePair<string, StoreLicense> item in appLicense.AddOnLicenses)
|
|
|
|
|
{
|
|
|
|
|
StoreLicense addOnLicense = item.Value;
|
|
|
|
|
|
|
|
|
|
if (addOnLicense.InAppOfferToken == productKey)
|
|
|
|
|
{
|
|
|
|
|
return addOnLicense.IsActive;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-19 01:50:14 +01:00
|
|
|
public async Task<WinoStorePurchaseResult> PurchaseAsync(WinoAddOnProductType productType)
|
2025-11-15 14:52:01 +01:00
|
|
|
{
|
2026-03-19 01:50:14 +01:00
|
|
|
if (!skuIds.TryGetValue(productType, out var productKey))
|
|
|
|
|
return WinoStorePurchaseResult.NotPurchased;
|
|
|
|
|
|
2025-11-15 14:52:01 +01:00
|
|
|
if (await HasProductAsync(productType))
|
|
|
|
|
return WinoStorePurchaseResult.AlreadyPurchased;
|
|
|
|
|
else
|
|
|
|
|
{
|
2026-04-02 15:07:05 +02:00
|
|
|
InitializeStoreContextWithWindow();
|
2025-11-15 14:52:01 +01:00
|
|
|
var result = await CurrentContext.RequestPurchaseAsync(productKey);
|
|
|
|
|
|
|
|
|
|
switch (result.Status)
|
|
|
|
|
{
|
|
|
|
|
case StorePurchaseStatus.Succeeded:
|
|
|
|
|
return WinoStorePurchaseResult.Succeeded;
|
|
|
|
|
case StorePurchaseStatus.AlreadyPurchased:
|
|
|
|
|
return WinoStorePurchaseResult.AlreadyPurchased;
|
|
|
|
|
default:
|
|
|
|
|
return WinoStorePurchaseResult.NotPurchased;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-02 15:07:05 +02:00
|
|
|
|
|
|
|
|
public async Task<string?> GetCustomerCollectionsIdAsync(string serviceTicket, string publisherUserId)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(serviceTicket) || string.IsNullOrWhiteSpace(publisherUserId))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InitializeStoreContextWithWindow();
|
|
|
|
|
var collectionsId = await CurrentContext.GetCustomerCollectionsIdAsync(serviceTicket, publisherUserId);
|
|
|
|
|
return string.IsNullOrWhiteSpace(collectionsId) ? null : collectionsId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<string?> GetCustomerPurchaseIdAsync(string serviceTicket, string publisherUserId)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(serviceTicket) || string.IsNullOrWhiteSpace(publisherUserId))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InitializeStoreContextWithWindow();
|
|
|
|
|
var purchaseId = await CurrentContext.GetCustomerPurchaseIdAsync(serviceTicket, publisherUserId);
|
|
|
|
|
return string.IsNullOrWhiteSpace(purchaseId) ? null : purchaseId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void InitializeStoreContextWithWindow()
|
|
|
|
|
{
|
|
|
|
|
var mainWindow = WinoApplication.MainWindow;
|
|
|
|
|
if (mainWindow == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InitializeWithWindow.Initialize(CurrentContext, WindowNative.GetWindowHandle(mainWindow));
|
|
|
|
|
}
|
2025-11-15 14:52:01 +01:00
|
|
|
}
|