diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs
index eb49914eb..dc3d103eb 100644
--- a/MediaBrowser.Api/PluginService.cs
+++ b/MediaBrowser.Api/PluginService.cs
@@ -118,6 +118,30 @@ namespace MediaBrowser.Api
public string Name { get; set; }
}
+ [Route("/Appstore/Register", "POST", Summary = "Registers an appstore sale")]
+ [Authenticated]
+ public class RegisterAppstoreSale
+ {
+ [ApiMember(Name = "Store", Description = "Store Name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string Store { get; set; }
+ [ApiMember(Name = "Application", Description = "Application id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string Application { get; set; }
+ [ApiMember(Name = "Product", Description = "Product id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string Product { get; set; }
+ [ApiMember(Name = "Type", Description = "Type of product (Product or Subscription)", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string Type { get; set; }
+ [ApiMember(Name = "StoreId", Description = "Store User Id (if needed)", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string StoreId { get; set; }
+ [ApiMember(Name = "StoreToken", Description = "Unique ID for this purchase in the store", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string StoreToken { get; set; }
+ [ApiMember(Name = "Feature", Description = "Emby Feature Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string Feature { get; set; }
+ [ApiMember(Name = "Email", Description = "Email address for purchase", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string Email { get; set; }
+ [ApiMember(Name = "Amount", Description = "String representation of price (can have currency sign)", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string Amount { get; set; }
+ }
+
///
/// Class PluginsService
///
@@ -265,6 +289,16 @@ namespace MediaBrowser.Api
return ToOptimizedSerializedResultUsingCache(result);
}
+ ///
+ /// Post app store sale
+ ///
+ ///
+ ///
+ public async Task Post(RegisterAppstoreSale request)
+ {
+ await _securityManager.RegisterAppStoreSale(request.Store, request.Application, request.Product, request.Feature, request.Type, request.StoreId, request.StoreToken, request.Email, request.Amount);
+ }
+
///
/// Posts the specified request.
///
diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
index c2725e9bf..facaaeff9 100644
--- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
+++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
@@ -18,6 +18,7 @@ namespace MediaBrowser.Common.Implementations.Security
public class PluginSecurityManager : ISecurityManager
{
private const string MBValidateUrl = MbAdmin.HttpsUrl + "service/registration/validate";
+ private const string AppstoreRegUrl = /*MbAdmin.HttpsUrl*/ "http://mb3admin.com/test/admin/" + "service/appstore/register";
///
/// The _is MB supporter
@@ -185,6 +186,63 @@ namespace MediaBrowser.Common.Implementations.Security
}
}
+ ///
+ /// Register an app store sale with our back-end. It will validate the transaction with the store
+ /// and then register the proper feature and then fill in the supporter key on success.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task RegisterAppStoreSale(string store, string application, string product, string feature,
+ string type, string storeId, string storeToken, string email, string amt)
+ {
+ var data = new Dictionary()
+ {
+ {"store", store},
+ {"application", application},
+ {"product", product},
+ {"feature", feature},
+ {"type", type},
+ {"storeId", storeId},
+ {"token", storeToken},
+ {"email", email},
+ {"amt", amt}
+ };
+
+ var options = new HttpRequestOptions()
+ {
+ Url = AppstoreRegUrl,
+ CancellationToken = CancellationToken.None
+ };
+ options.RequestHeaders.Add("X-Emby-Token", /*_appHost.SystemId*/ "08606E86D043");
+
+ try
+ {
+ using (var json = await _httpClient.Post(options, data).ConfigureAwait(false))
+ {
+ var reg = _jsonSerializer.DeserializeFromStream(json);
+ if (!String.IsNullOrEmpty(reg.key))
+ {
+ SupporterKey = reg.key;
+ }
+ }
+
+ }
+ catch (Exception e)
+ {
+ _logger.ErrorException("Error registering appstore purchase {0}", e, _jsonSerializer.SerializeToString(data));
+ //TODO - really need to write this to a file so we can re-try it automatically
+ throw new ApplicationException("Error registering store sale");
+ }
+
+ }
+
private async Task GetRegistrationStatusInternal(string feature,
string mb2Equivalent = null,
string version = null)
diff --git a/MediaBrowser.Common.Implementations/Security/RegRecord.cs b/MediaBrowser.Common.Implementations/Security/RegRecord.cs
index f4e4337bf..ece70b772 100644
--- a/MediaBrowser.Common.Implementations/Security/RegRecord.cs
+++ b/MediaBrowser.Common.Implementations/Security/RegRecord.cs
@@ -7,5 +7,6 @@ namespace MediaBrowser.Common.Implementations.Security
public string featId { get; set; }
public bool registered { get; set; }
public DateTime expDate { get; set; }
+ public string key { get; set; }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Common/Security/ISecurityManager.cs b/MediaBrowser.Common/Security/ISecurityManager.cs
index 935454353..1b2e22a78 100644
--- a/MediaBrowser.Common/Security/ISecurityManager.cs
+++ b/MediaBrowser.Common/Security/ISecurityManager.cs
@@ -1,3 +1,4 @@
+using System;
using MediaBrowser.Model.Entities;
using System.Threading.Tasks;
@@ -45,5 +46,20 @@ namespace MediaBrowser.Common.Security
///
/// Task<SupporterInfo>.
Task GetSupporterInfo();
+
+ ///
+ /// Register and app store sale with our back-end
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task RegisterAppStoreSale(string store, string application, string product, string feature,
+ string type, string storeId, string storeToken, string email, string amt);
}
}
\ No newline at end of file