public virtual async Task ChangeSubscription(IEnterprisesBillingManagerService entBillingMgr, ISecurityDataTokenService secMgr, IIdentityAccessService idMgr, string entLookup,
                                                     string username, string customerName, string plan)
        {
            //cancel existing subscription
            var cancelResp = await entBillingMgr.CancelSubscriptionByUser(username, entLookup);

            var planOption = this.State.Plans.First(p => p.Lookup == plan);

            var licenseType = planOption.Metadata["LicenseType"].ToString();

            //Remove license access
            await idMgr.RevokeLicense(entLookup, username, licenseType);

            // create new subscription
            var completeResp = await entBillingMgr.CompleteStripeSubscription(
                new CompleteStripeSubscriptionRequest()
            {
                CustomerName    = State.CustomerName,
                Plan            = plan,
                Username        = username,
                TrialPeriodDays = 0
            }, entLookup, licenseType);

            State.PaymentStatus = completeResp.Status;

            if (State.PaymentStatus)
            {
                State.PurchasedPlanLookup = plan;

                var tosResp = await secMgr.SetDataToken(new DataToken()
                {
                    Lookup      = "LCU-USER-BILLING.TermsOfService",
                    Name        = "LCU-USER-BILLING.TermsOfService",
                    Description = "Billing Terms of Service",
                    Value       = DateTimeOffset.UtcNow.ToString(),
                });

                var eaResp = await secMgr.SetDataToken(new DataToken()
                {
                    Lookup      = "LCU-USER-BILLING.EnterpriseAgreement",
                    Name        = "LCU-USER-BILLING.EnterpriseAgreement",
                    Description = "Billing Enterprise Agreement",
                    Value       = DateTimeOffset.UtcNow.ToString(),
                });

                //issue new license access
                // var setLicenseAccessResp = await idMgr.IssueLicenseAccess(new LicenseAccessToken()
                // {
                //     AccessStartDate = System.DateTime.Now,
                //     Details = planOption.JSONConvert<MetadataModel>(),
                //     EnterpriseLookup = entLookup,
                //     Lookup = licenseType,
                //     TrialPeriodDays = 0,
                //     Username = username
                // }, entLookup);

                // var setLicenseAccessResp = await idMgr.IssueLicense(new License()
                // {
                //     Details = planOption.JSONConvert<string>(),
                //     Lookup = licenseType,
                //     Type = licenseType,
                // }, entLookup);

                // State.PaymentStatus = setLicenseAccessResp.Status;

                State.SubscriptionID = completeResp.SubscriptionID;

                State.SuccessRedirect = planOption.Metadata["SuccessRedirect"].ToString();
            }

            await ListLicenses(idMgr, entLookup, username, licenseType);

            State.Loading = false;
        }
        public virtual async Task CompletePayment(IEnterprisesBillingManagerService entBillingMgr, ISecurityDataTokenService secMgr, IIdentityAccessService idMgr, string entLookup,
                                                  string username, string methodId, string customerName, string plan, int trialPeriodDays, string projectId)
        {
            State.CustomerName = customerName;

            State.PaymentMethodID = methodId;

            var planOption = this.State.Plans.First(p => p.Lookup == plan);

            var licenseTypeCore = planOption.Metadata["LicenseType"].ToString();

            var licenseTypes = planOption.Metadata.ContainsKey("LicenseTypeOverrides") ?
                               planOption.Metadata["LicenseTypeOverrides"].ToString().Split('|', StringSplitOptions.RemoveEmptyEntries) :
                               new[] { licenseTypeCore };

            var completeResp = await entBillingMgr.CompleteStripeSubscription(
                new CompleteStripeSubscriptionRequest()
            {
                CustomerName    = State.CustomerName,
                PaymentMethodID = methodId,
                Plan            = plan,
                TrialPeriodDays = trialPeriodDays,
                Username        = username
            }, entLookup, licenseTypeCore);

            State.PaymentStatus = completeResp.Status;

            if (State.PaymentStatus.Code == 0)
            {
                State.PurchasedPlanLookup = plan;

                var tosResp = await secMgr.SetDataToken(new DataToken()
                {
                    Lookup      = "LCU-USER-BILLING.TermsOfService",
                    Name        = "LCU-USER-BILLING.TermsOfService",
                    Description = "Billing Terms of Service",
                    Value       = DateTimeOffset.UtcNow.ToString(),
                }, entLookup, email : username, projectId : Guid.Parse(projectId));

                var eaResp = await secMgr.SetDataToken(new DataToken()
                {
                    Lookup      = "LCU-USER-BILLING.EnterpriseAgreement",
                    Name        = "LCU-USER-BILLING.EnterpriseAgreement",
                    Description = "Billing Enterprise Agreement",
                    Value       = DateTimeOffset.UtcNow.ToString(),
                }, entLookup, email : username, projectId : Guid.Parse(projectId));

                var licenseResponse = await idMgr.IssueLicense(new License()
                {
                    Details        = JsonConvert.SerializeObject(planOption.Metadata),
                    ExpirationDate = DateTimeOffset.Now.AddYears(50),
                    IsLocked       = false
                }, entLookup, username, projectId, plan, licenseTypeCore);

                State.PaymentStatus = licenseResponse.Status;

                State.SubscriptionID = completeResp.SubscriptionID;

                State.SuccessRedirect = planOption.Metadata["SuccessRedirect"].ToString();
            }

            else
            {
                //TODO handle when payment fails but subscription is assigned
            }
        }