public static List <Transfer> GetTransferHistory_Next(int itemLimit, string startingAfterTransferId) { var transfers = new List <Transfer>(); #region (Plan A) Check Redis Cache First #endregion #region (Plan B) Call Stripe API, Transform Data & Store in Redis CacheTransfer var stripeManager = new StripeManager(); var stripeTransfers = stripeManager.GetTransfers_Next(itemLimit, startingAfterTransferId); if (stripeTransfers != null) { foreach (var stripeTransfer in stripeTransfers) { transfers.Add(Transformations.TransformStripeTransferToTransfer(stripeTransfer)); } } #endregion return(transfers); }
public static List <Transfer> GetTransferHistory_ByDateRange_Last(int itemLimit, string endingBeforeTransferId, DateTime startDate, DateTime endDate, string accountId = null) { var transfers = new List <Transfer>(); #region (Plan A) Check Redis Cache First #endregion #region (Plan B) Call Stripe API, Transform Data & Store in Redis Cache var stripeManager = new StripeManager(); var stripeTransfers = stripeManager.GetTransfers_ByDateRange_Last(itemLimit, endingBeforeTransferId, startDate, endDate); if (stripeTransfers != null) { foreach (var stripeTransfer in stripeTransfers) { transfers.Add(Transformations.TransformStripeTransferToTransfer(stripeTransfer)); } } #endregion return(transfers); }
public void TestCharge() { StripeToken token = CreateTestToken(); string chargeId = StripeManager.Charge(token.Id, 78.90f, "Test naked charge"); Assert.IsNotNull(chargeId); }
public void TestCustomers() { // SUBSCRIBE // Arrange ICustomerEntity customer = CreateMockCustomer(); // Act StripeManager.CreateCustomer(customer); // Assert Assert.IsNotNull(customer.PaymentSystemId); // RETRIEVE // Act StripeCustomer stripeCustomer = StripeManager.RetrieveCustomer(customer); // Assert Assert.IsNotNull(stripeCustomer); // UPDATE // Arrange customer.Email = "*****@*****.**"; // act StripeCustomer updatedStripeCustomer = StripeManager.UpdateCustomer(customer); // Assert Assert.IsNotNull(updatedStripeCustomer); }
public static Charge GetPayment(string chargeId) { var charge = new Charge(); #region (Plan A) Check Redis Cache First #endregion #region (Plan B) Call Stripe API, Transform Data & Store in Redis Cache var stripeManager = new StripeManager(); //string stripeCustomerId = null; var stripeCharge = stripeManager.GetCharge(chargeId); if (stripeCharge != null) { return(Transformations.TransformStripeChargeToCharge(stripeCharge, false)); } #endregion return(charge); }
public static Transfer GetTransfer(string transferId) { var transfer = new Transfer(); #region (Plan A) Check Redis Cache First #endregion #region (Plan B) Call Stripe API, Transform Data & Store in Redis Cache var stripeManager = new StripeManager(); var stripeTransfer = stripeManager.GetTransfer(transferId); if (stripeTransfer != null) { return(Transformations.TransformStripeTransferToTransfer(stripeTransfer)); } #endregion return(transfer); }
private static void AddSubscriptionPlan(Angjobs.Models.DBContext context) { string paymentSystemId = "Up100PerMo"; if (context.SubscriptionPlans.FirstOrDefault(p => p.PaymentSystemId == paymentSystemId) == null) { var plan = new SubscriptionPlan(); plan.Description = "Up to 100 job applications - monthly plan"; plan.PaymentSystemId = paymentSystemId; plan.Price = 3.99f; plan.Currency = "gbp"; plan.State = SubscriptionPlan.SubscriptionState.Available; plan.Title = "Up to 100 job applications per month"; plan.CreatedDateUtc = DateTime.UtcNow; plan.IsSoftDeleted = false; context.SubscriptionPlans.Add(plan); try { StripeManager.CreatePlan(plan); } catch (Exception ex) { Debug.WriteLine("Error:", ex.Message); } } }
private static void DeleteTestPlanB() { // Arrange var plan = CreateMockPlanB(); // Act StripeManager.DeletePlan(plan); }
public static Balance GetBalance() { var balance = new Balance(); var stripeBalance = new StripeManager().GetBalance(); if (stripeBalance != null) { balance = Transformations.TransformStripeBalanceToBalance(stripeBalance); } return(balance); }
public static DataAccessResponseType ProcessSuccessfulStripeChargeEvent(string stripeCustomerId, string stripeChargeId, string stripeCardId, string StripeInvoiceId, string StripeEventId) { var response = new DataAccessResponseType(); //Get all owners for the account: var accountOwnerEmails = AccountManager.GetAccountOwnerEmails(stripeCustomerId); //Get the account //var account = AccountManager.GetAccountByStripeCustomerID(stripeCustomerID, false); var account = AccountManager.GetAccount(stripeCustomerId); //Get the associated Stripe Invoice: var stripeManager = new StripeManager(); var stripeCharge = stripeManager.GetCharge(stripeChargeId); var stripeCard = stripeManager.GetCard(stripeCustomerId, account.StripeCardID); //<-- in case card is updated we use the latest stripe card ID //Generate dollar amount var chargeTotalAmount = Sahara.Core.Common.Methods.Billing.ConvertStripeAmountToDollars(stripeCharge.Amount.ToString()); //For HTML invoice or charge details string var htmlPaymentDetailsString = string.Empty; if (!String.IsNullOrEmpty(StripeInvoiceId)) { //Charge has in invoice associated var stripeInvoice = stripeManager.GetInvoice(StripeInvoiceId); //Generate HTML invoice htmlPaymentDetailsString = Sahara.Core.Common.Methods.Billing.GenerateStripeHTMLInvoice(stripeInvoice); } else { //Generate HTML charge details (No associated invoice exists) htmlPaymentDetailsString = Sahara.Core.Common.Methods.Billing.GenerateStripeHTMLChargeDetails(stripeCharge); } //email all account owners a copy of the associated charge/invoice details EmailManager.Send( accountOwnerEmails, Settings.Endpoints.Emails.FromBilling, Settings.Copy.EmailMessages.AccountCharged.FromName, String.Format(Settings.Copy.EmailMessages.AccountCharged.Subject), String.Format(Settings.Copy.EmailMessages.AccountCharged.Body, account.AccountName, stripeCard.CardBrand, stripeCard.Last4, chargeTotalAmount, htmlPaymentDetailsString), true); //Clear Billing Issues Marker From Account //????/ response.isSuccess = true; return(response); }
/// <summary> /// Purchase credits while adding a new card to the account /// </summary> /// <param name="accountId"></param> /// <param name="dollarAmount"></param> /// <param name="creditCard"></param> /// <returns></returns> /* * public static DataAccessResponseType BuyCredits(string accountId, int dollarAmount, NewCreditCard creditCard) * { * //Add/Update Card to the account, get back StripeCustomerID * var addUpdateNewCreditCardResponse = AccountManager.AddUpdateCreditCard(); * * if(addUpdateNewCreditCardResponse.isSuccess) * { * //if successful, make the transaction * return ExecuteCreditsTransaction(accountId, dollarAmount); * } * else * { * return addUpdateNewCreditCardResponse; * } * * }*/ #region Shared Private Methods private static DataAccessResponseType ExecuteCreditsTransaction(string accountId, decimal dollarAmount) { //Convert dollarAmount to credits var creditsToAdd = Common.Methods.Commerce.ConvertDollarAmountToCredits(dollarAmount); var dollarAmountStripeInteger = Sahara.Core.Common.Methods.Billing.ConvertDecimalToStripeAmount(dollarAmount); var account = AccountManager.GetAccount(accountId); //Make sure account has a StripeCustomerId if (account.StripeCustomerID == null) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "Accont does not have a customerId for Stripe." }); } //Create invoice and charge the account; var stripeManager = new StripeManager(); var stripeCustomerId = account.StripeCustomerID; var chargeDescription = "Purchase of " + creditsToAdd + " credits"; var chargeAccountResponse = stripeManager.ChargeAccount(account.StripeCustomerID, chargeDescription, dollarAmountStripeInteger); if (!chargeAccountResponse.isSuccess) { //If unsuccesful, return the result: return(chargeAccountResponse); } //If successful store into SQL bool sqlResult = Sql.Statements.UpdateStatements.UpdateAccountCredits(accountId, creditsToAdd); if (!sqlResult) { //Log issue so that credits can be added manually } //Log transaction into Azure Tables for the account //Partitions: PurchasedCredits, SpentCredits //TODO //Refresh cache: RefreshCreditsCache(accountId); return(new DataAccessResponseType { isSuccess = true }); }
public static List <BalanceTransaction> GetBalanceTransaction_AvailableSinceHourssAgo(int sinceHoursAgo, string startingAfterBalanceTransactionId = null) { var balanceTransactions = new List <BalanceTransaction>(); var stripeBalanceTransactions = new StripeManager().GetBalanceTransactions_AvailableSinceHoursAgo(sinceHoursAgo, startingAfterBalanceTransactionId); if (stripeBalanceTransactions != null) { foreach (var stripeBalanceTransaction in stripeBalanceTransactions) { balanceTransactions.Add(Transformations.TransformStripeBalanceTransactionToBalanceTransaction(stripeBalanceTransaction)); } } return(balanceTransactions); }
/// <summary> /// Used to Seed Stripe during platform initialization /// </summary> /// <returns></returns> public static DataAccessResponseType DuplicatePlansToStripe() { var response = new DataAccessResponseType(); var stripeManager = new StripeManager(); //Get Plans & Frequencies to initialize plans on Stripe: var paymentPlans = GetPaymentPlans(true, true, false); var paymentFrequencies = GetPaymentFrequencies(false); foreach (PaymentPlan paymentPlan in paymentPlans) { foreach (PaymentFrequency paymentFrequency in paymentFrequencies) { // We ignore any payment plans that have no cost and or frequencies that are set to 0 // Stripe is only used to manage plans that have a cost associated to it above 0.0 if (paymentPlan.MonthlyRate != 0 && paymentFrequency.PaymentFrequencyMonths != 0) { //Create the new Stripe plan ID var id = Sahara.Core.Common.Methods.Billing.GenerateStripePlanID(paymentPlan.PaymentPlanName, paymentFrequency.IntervalCount, paymentFrequency.Interval); //Check if plan exists in Stripe, delete if it does: if (stripeManager.PlanExists(id).isSuccess) { stripeManager.DeletePlan(id); } //Cretae the rest of the new Stripe plan var name = Sahara.Core.Common.Methods.Billing.GenerateStripePlanName(paymentPlan.PaymentPlanName, paymentFrequency.PaymentFrequencyName); var amount = Sahara.Core.Common.Methods.Billing.GenerateStripePlanAmountInCents(paymentPlan.MonthlyRate, paymentFrequency.PaymentFrequencyMonths, paymentFrequency.PriceBreak); stripeManager.CreatePlan( id, name, amount, paymentFrequency.Interval, paymentFrequency.IntervalCount ); response.isSuccess = true; } } } return(response); }
public static List <Transfer> GetTransferHistory(int limit) { var transfers = new List <Transfer>(); var stripeTransfers = new StripeManager().GetTransfers(limit); if (stripeTransfers != null) { foreach (var stripeTransfer in stripeTransfers) { transfers.Add(Transformations.TransformStripeTransferToTransfer(stripeTransfer)); } } return(transfers); }
public void TestChargeWithCustomer() { // Arrange ICustomerEntity customer = CreateMockCustomer(); IChargeEntity charge = CreateMockCharge(); StripeToken token = CreateTestToken(customer); StripeManager.CreateCustomer(customer, token.Id); // Act - charge customer string chargeId = StripeManager.Charge(customer, charge); Assert.IsNotNull(chargeId); chargeId = StripeManager.Charge(customer, 12.34f, "Test charge with customer"); Assert.IsNotNull(chargeId); }
public static List <Charge> GetPaymentHistory(int itemLimit, string accountId = null) { var charges = new List <Charge>(); #region (Plan A) Check Redis Cache First #endregion #region (Plan B) Call Stripe API, Transform Data & Store in Redis Cache var stripeManager = new StripeManager(); string stripeCustomerId = null; bool addAccountDetails = false; if (!String.IsNullOrEmpty(accountId)) { stripeCustomerId = AccountManager.GetAccount(accountId, true, AccountManager.AccountIdentificationType.AccountID).StripeCustomerID; } else { addAccountDetails = true; } var stripeCharges = stripeManager.GetCharges(itemLimit, stripeCustomerId); if (stripeCharges != null) { foreach (var stripeCharge in stripeCharges) { charges.Add(Transformations.TransformStripeChargeToCharge(stripeCharge, addAccountDetails)); } } #endregion return(charges); }
public void TestSubscriptions() { // Arrange EnsureTestPlansDeleted(); // NOTE: Due to the reliance on the API, we must create these for real IPlanEntity planA = CreateMockPlanA(); StripeManager.CreatePlan(planA); ICustomerEntity customer = CreateMockCustomer(); StripeManager.CreateCustomer(customer); ISubscriptionEntity subscription = CreateMockSubscription(); // CREATE // Subscribe // Act StripeSubscription newSub = StripeManager.Subscribe(customer, subscription, planA); Assert.IsNotNull(newSub); // CHANGE // ChangeSubscriptionPlan IPlanEntity planB = CreateMockPlanB(); StripeManager.CreatePlan(planB); StripeSubscription changedSub = StripeManager.ChangeSubscriptionPlan(customer, subscription, planB); Assert.IsNotNull(changedSub); // DELETE StripeSubscription cancelledSub = StripeManager.Unsubscribe(customer, subscription); Assert.IsNotNull(cancelledSub); Assert.IsTrue(cancelledSub.Status == "canceled"); }
public static Invoice GetInvoice(string stripeInvoiceId) { var invoice = new Invoice(); #region (Plan A) Check Redis Cache First #endregion #region (Plan B) Call Stripe API, Transform Data & Store in Redis Cache if (!String.IsNullOrEmpty(stripeInvoiceId)) { var stripeManager = new StripeManager(); var stripeInvoice = stripeManager.GetInvoice(stripeInvoiceId); invoice = Transformations.TransformStripeInvoiceToInvoice(stripeInvoice); } #endregion return(invoice); }
public void OnCreate(Bundle savedInstanceState, StripeConfig stripeConfig) { _stripeConfig = stripeConfig; PaymentConfiguration.Init(_stripeConfig.ApiKey); var stripeRemoteService = new StripeRemoteService(_stripeConfig, _restHttpClient, _logManager, _jsonSerializer); CustomerSession.InitCustomerSession(new StripeEphemeralKeyProvider(stripeRemoteService)); _paymentSession = new PaymentSession(CrossCurrentActivity.Current.Activity); var config = new PaymentSessionConfig.Builder() .SetShippingInfoRequired(false) .SetShippingMethodsRequired(false) .Build(); _paymentSession.Init(new PaymentSessionListener(), config, savedInstanceState); StripeManager.Initialize(stripeRemoteService, _stripeConfig); }
public static Invoice GetUpcomingInvoice(string accountId) { var invoice = new Invoice(); #region (Plan A) Check Redis Cache First #endregion #region (Plan B) Call Stripe API, Transform Data & Store in Redis Cache var stripeManager = new StripeManager(); string stripeCustomerId = null; bool addAccountDetails = false; if (!String.IsNullOrEmpty(accountId)) { stripeCustomerId = AccountManager.GetAccount(accountId, true, AccountManager.AccountIdentificationType.AccountID).StripeCustomerID; } else { addAccountDetails = true; } //var stripeCustomerId = AccountManager.GetAccount(accountId, false, AccountManager.AccountIdentificationType.AccountID).StripeCustomerID; if (!String.IsNullOrEmpty(stripeCustomerId)) { var stripeInvoice = stripeManager.GetUpcomingInvoice(stripeCustomerId); if (stripeInvoice != null) { invoice = Transformations.TransformStripeInvoiceToInvoice(stripeInvoice, addAccountDetails); } } #endregion return(invoice); }
public static List <Invoice> GetInvoiceHistory_ByDateRange_Next(int itemLimit, string startingAfterInvoiceId, DateTime startDate, DateTime endDate, string accountId = null) { var invoices = new List <Invoice>(); #region (Plan A) Check Redis Cache First #endregion #region (Plan B) Call Stripe API, Transform Data & Store in Redis Cache var stripeManager = new StripeManager(); string stripeCustomerId = null; bool addAccountDetails = false; if (!String.IsNullOrEmpty(accountId)) { stripeCustomerId = AccountManager.GetAccount(accountId, true, AccountManager.AccountIdentificationType.AccountID).StripeCustomerID; } else { addAccountDetails = true; } var stripeInvoices = stripeManager.GetInvoices_ByDateRange_Next(itemLimit, startingAfterInvoiceId, startDate, endDate, stripeCustomerId); if (stripeInvoices != null) { foreach (var stripeInvoice in stripeInvoices) { invoices.Add(Transformations.TransformStripeInvoiceToInvoice(stripeInvoice, addAccountDetails)); } } #endregion return(invoices); }
public void TestPlans() { // Arrange EnsureTestPlansDeleted(); IPlanEntity plan = CreateMockPlanA(); plan.GeneratePaymentSystemId(); // Act - create StripePlan createdPlan = StripeManager.CreatePlan(plan); // Assert - create Assert.IsNotNull(createdPlan); // Act - update plan.Title = "Unit Test Plan - Name Changed"; StripePlan updatedPlan = StripeManager.UpdatePlan(plan); // Assert - update Assert.IsNotNull(updatedPlan); // Act - Delete StripeManager.DeletePlan(plan); // Assert try { StripePlanService planService = new StripePlanService(); planService.Get(TestPlanA_Id); Assert.Fail(); // We should not get to this line } catch (Exception ex) { // We should get an exception that says "No such plan" Assert.IsTrue(ex.Message.Contains("No such plan")); } }
public static SourceBalanceTransactions GetBalanceTransactionsForSource(string sourceId) { var sourceBalanceTransactions = new SourceBalanceTransactions(); sourceBalanceTransactions.Transactions = new List <BalanceTransaction>(); decimal totalGross = 0; decimal totalFees = 0; decimal totalNet = 0; //Get all balance transactions for the source var stripeBalanceTransactions = new StripeManager().GetBalanceTransactionsForSource(sourceId); if (stripeBalanceTransactions != null) { foreach (var stripeBalanceTransaction in stripeBalanceTransactions) { var balanceTransaction = Transformations.TransformStripeBalanceTransactionToBalanceTransaction(stripeBalanceTransaction); sourceBalanceTransactions.Transactions.Add(balanceTransaction); totalGross = totalGross + balanceTransaction.Amount; totalFees = totalFees + balanceTransaction.Fee; totalNet = totalNet + balanceTransaction.Net; } } sourceBalanceTransactions.TotalGross = totalGross; sourceBalanceTransactions.TotalFees = totalFees; sourceBalanceTransactions.TotalNet = totalNet; return(sourceBalanceTransactions); }
public static DataAccessResponseType DeprovisionAccount(Account account) { DataAccessResponseType response = new DataAccessResponseType(); if (account.AccountID == Guid.Empty) { response.isSuccess = false; response.ErrorMessage = "No account to deprovision"; return(response); } try { // 0. Get Account Users: account.Users = AccountUserManager.GetUsers(account.AccountID.ToString()); #region LOG ACTIVITY (Deprovisioning Started) if (account.Provisioned) { PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Deprovisioning_Started, "Deprovisioning of '" + account.AccountName + "' has started", "AccountID: '" + account.AccountID + "' SqlPartition: '" + account.SqlPartition + "' DocumentPartition: '" + account.DocumentPartition + "' StripeCustomerID: '" + account.StripeCustomerID + "'" ); } else if (!account.Provisioned) { //Account has not been provisioned, only delete the account and user objects, This will be a simple purge and not a full deprovisioning PlatformLogManager.LogActivity(CategoryType.Account, ActivityType.Account_Purge_Started, "Purging of unprovisioned account '" + account.AccountName + "' has started", "AccountID: '" + account.AccountID + "' Account Owner: '" + account.Users[0].UserName + "'"); } #endregion // Owners of accounts that have been provisioned will get an email, create a list of owner emails before all users are delted var accountOwnerEmails = AccountManager.GetAccountOwnerEmails(account.AccountID.ToString()); string accountOwners = string.Empty; foreach (string ownerEmail in accountOwnerEmails) { accountOwners += ownerEmail + " "; } #region STEPS 1-3 DELETE ACCOUNT USERS AND ACCOUNT // 1. Delete All Account Users AccountDeprovisioning.DeleteAllAccountUsers(account); // 2. Delete Account AccountDeprovisioning.DeleteAccount(account); // 3. Delete Customer in Stripe if the account has a StripeCustomerID if (account.StripeCustomerID != null) { try { var stripeManager = new StripeManager(); stripeManager.DeleteCustomer(account.StripeCustomerID); } catch { } } #endregion if (!account.Provisioned) { #region Log closure if account is not provisioned //Account has never been provisioned, since we already deleted the account and all associated users, we are done. Log activity completion and return result: PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Purged, "Purging of unprovisioned account '" + account.AccountName + "' has completed", "Account Owners: '" + accountOwners + "'", account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account) ); //Log the closed account PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Closed, "Unprovisioned", account.AccountNameKey, account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account)); response.isSuccess = true; response.SuccessMessage = "Purging of account '" + account.AccountID + "' Complete!"; #endregion } else { // 4. Clear SQL Data Schema & AccountDeprovisioning.DestroySqlSchemaAndTables(account); // 5. Clear Table Storage Data AccountDeprovisioning.DestroyTableStorageData(account); // 6. Clear Blob Storage Data AccountDeprovisioning.DestroyBlobStorageData(account); // 7. Clear Document Data (Retired) AccountDeprovisioning.DestroyDocumentCollection(account); // 8. Clear Search Indexes AccountDeprovisioning.DestroySearchIndexes(account); // 9. Decriment both STORAGE & SEARCH Partitions Sql.Statements.UpdateStatements.UpdatePartitionsTenantCounts(account.StoragePartition, account.SearchPartition); // 10. Log Activity #region Logging PlatformLogManager.LogActivity( CategoryType.GarbageCollection, ActivityType.GarbageCollection_ClosedAccounts, "All resources for account '" + account.AccountName + "' have been destroyed", "Purged resources now available to new accounts", account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account) ); PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Deprovisioned, "Deprovisioning of '" + account.AccountName + "' has completed", "SqlPartition: '" + account.SqlPartition + "'", account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account) ); //Log the closed account PlatformLogManager.LogActivity( CategoryType.Account, ActivityType.Account_Closed, "Deprovisioned", account.AccountNameKey + " | " + account.PaymentPlanName, account.AccountID.ToString(), account.AccountName, null, null, null, null, null, JsonConvert.SerializeObject(account)); #endregion // 11. Email all account users regarding closure: EmailManager.Send( accountOwnerEmails, Settings.Endpoints.Emails.FromAlerts, Settings.Copy.EmailMessages.DeprovisioningComplete.FromName, Settings.Copy.EmailMessages.DeprovisioningComplete.Subject, String.Format(Settings.Copy.EmailMessages.DeprovisioningComplete.Body, account.AccountName), true); // 12. Destroy ALL caches associated with an account AccountManager.DestroyAccountCaches(account.AccountID.ToString(), account.AccountNameKey, account.StripeCustomerID); // 13. Destroy subdomains try { var cloudFlareResult = CloudFlareManager.RemoveSubdomains(account.AccountNameKey); if (cloudFlareResult.isSuccess == false) { //Log exception and email platform admins PlatformExceptionsHelper.LogErrorAndAlertAdmins( cloudFlareResult.ErrorMessage, "attempting to remove cloudflare subdomains for the '" + account.AccountName + "' account during deprovisioning.", System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); } } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to remove cloudflare subdomains for the '" + account.AccountName + "' account during deprovisioning.", System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); } response.isSuccess = true; response.SuccessMessage = "Deprovisioning of account '" + account.AccountID + "' Complete!"; } //TODO: Log purged account into ClosedAccounts Table } catch (Exception e) { #region LOG ERROR (Deprovisioning Errors) //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to deprovision or purge account: " + account.AccountName, System.Reflection.MethodBase.GetCurrentMethod(), account.AccountID.ToString(), account.AccountName ); #endregion response.isSuccess = false; response.ErrorMessage = e.Message; } // Archive the closed account //ClosedAccountsStorageManager.ArchiveClosedAccount(account); return(response); }
public static BillingReport GetBillingReport(int sinceHoursAgo) { var billingReport = new BillingReport(); #region get from Redis //IDatabase cache = Sahara.Core.Settings.Azure.Redis.RedisMultiplexers.PlatformManager_Multiplexer.GetDatabase(); IDatabase cache = Sahara.Core.Settings.Azure.Redis.RedisMultiplexers.RedisMultiplexer.GetDatabase(); Object cachedBillingReport = null; try { cachedBillingReport = cache.HashGet( Sahara.Core.Common.Redis.PlatformManagerServer.Hashes.ReportsHash.Key, Sahara.Core.Common.Redis.PlatformManagerServer.Hashes.ReportsHash.Fields.Billing(sinceHoursAgo) ); if (((RedisValue)cachedBillingReport).HasValue) { billingReport = JsonConvert.DeserializeObject <BillingReport>((RedisValue)cachedBillingReport); } } catch { } #endregion #region Generate report if (((RedisValue)cachedBillingReport).IsNullOrEmpty) { var stripeManager = new StripeManager(); //Counts & Totals: var chargeCount = 0; //var failedChargeCount = 0; var refundCount = 0; var transferCount = 0; var transferCount_Pending = 0; var transferCount_Complete = 0; decimal totalGross = 0; decimal totalFees = 0; decimal totalRefunds = 0; decimal totalNet = 0; decimal totalTransfers = 0; decimal totalTransfers_Pending = 0; decimal totalTransfers_Complete = 0; //Get charges from time period: /*var stripeCharges = new List<StripeCharge>(); * * * //Since Stripe limit is 100 we break up the call into 100 item increments until we reach the last item: * var stripeChargesPending = stripeManager.GetCharges_SinceHoursAgo(sinceHoursAgo, null, null, true).ToList(); * * stripeCharges.AddRange(stripeChargesPending); * while (stripeChargesPending.Count == 100) * { * stripeChargesPending = stripeManager.GetCharges_SinceHoursAgo(sinceHoursAgo, stripeChargesPending[99].Id, null, true).ToList(); * stripeCharges.AddRange(stripeChargesPending); * } */ //Loop through all charges from time period and generate report data /* * foreach(StripeCharge stripeCharge in stripeCharges) * { * if (stripeCharge.Paid.HasValue) * { * if (stripeCharge.Paid.Value) * { * chargeCount++; * /*totalGross = totalGross + Sahara.Core.Common.Methods.Billing.ConvertStripeAmountToDecimals(stripeCharge.Amount.ToString()); * totalFees = totalFees + Sahara.Core.Common.Methods.Billing.ConvertStripeAmountToDecimals(stripeCharge.BalanceTransaction.Fee.ToString()); * totalNet = totalNet + Sahara.Core.Common.Methods.Billing.ConvertStripeAmountToDecimals(stripeCharge.BalanceTransaction.Net.ToString()); * if (stripeCharge.AmountRefunded.HasValue) * { * totalRefunds = totalRefunds + Sahara.Core.Common.Methods.Billing.ConvertStripeAmountToDecimals(stripeCharge.AmountRefunded.Value.ToString()); * } * if (stripeCharge.Refunded.HasValue) * { * if (stripeCharge.Refunded.Value) * { * refundCount++; * } * }* / * } * else if (!stripeCharge.Paid.Value) * { * failedChargeCount++; * } * } * * }*/ billingReport.BalanceTransactions = new List <Billing.Models.BalanceTransaction>(); billingReport.BalanceTransactions_Created = new List <Billing.Models.BalanceTransaction>(); billingReport.BalanceTransactions_Available = new List <Billing.Models.BalanceTransaction>(); //Since Stripe limit is 100 we break up the call into 100 item increments until we reach the last item: var balanceTransactions = PlatformBillingManager.GetBalanceTransaction_AvailableSinceHourssAgo(sinceHoursAgo); billingReport.BalanceTransactions.AddRange(balanceTransactions); while (balanceTransactions.Count == 100) { balanceTransactions = PlatformBillingManager.GetBalanceTransaction_AvailableSinceHourssAgo(sinceHoursAgo, balanceTransactions[99].BalanceTransactionID); billingReport.BalanceTransactions.AddRange(balanceTransactions); } //Split all results into 2 camps =============================================== foreach (var balanceTransaction in billingReport.BalanceTransactions) { if (balanceTransaction.Created >= DateTime.UtcNow.AddHours(sinceHoursAgo * -1)) { billingReport.BalanceTransactions_Created.Add(balanceTransaction); } else { billingReport.BalanceTransactions_Available.Add(balanceTransaction); } } //================================================================================================= //Loop through all balance transactions from ENTIRE time period to generate daily activity data for transactions foreach (var btr in billingReport.BalanceTransactions) { if (btr.Type == "transfer") { transferCount++; totalTransfers = totalTransfers + btr.Amount; if (btr.Status == "pending") { transferCount_Pending++; totalTransfers_Pending = totalTransfers_Pending + btr.Amount; } else { transferCount_Complete++; totalTransfers_Complete = totalTransfers_Complete + btr.Amount; } } } //================================================================================================= //Loop through all balance transactions from the CREATED time period to generate daily activity data for charges & refunds foreach (var btr in billingReport.BalanceTransactions_Created) { if (btr.Type == "charge") { chargeCount++; totalGross = totalGross + btr.Amount; totalFees = totalFees + btr.Fee; totalNet = totalNet + btr.Net; } else if (btr.Type == "refund") { refundCount++; totalRefunds = totalRefunds + btr.Amount; //totalGross = totalGross + btr.Amount; totalFees = totalFees + btr.Fee; totalNet = totalNet + btr.Net; } else if (btr.Type == "adjustment") { totalGross = totalGross + btr.Amount; totalFees = totalFees + btr.Fee; totalNet = totalNet + btr.Net; } else if (btr.Type == "application_fee" || btr.Type == "application_fee_refund") { totalGross = totalGross + btr.Amount; totalFees = totalFees + btr.Fee; totalNet = totalNet + btr.Net; } /* * else if (btr.Type == "transfer") * { * * transferCount++; * totalTransfers = totalTransfers + btr.Amount; * if (btr.Status == "pending") * { * transferCount_Pending++; * totalTransfers_Pending = totalTransfers_Pending + btr.Amount; * } * else * { * transferCount_Complete++; * totalTransfers_Complete = totalTransfers_Complete + btr.Amount; * } * }*/ } billingReport.ChargeCount = chargeCount; billingReport.RefundCount = refundCount; //billingReport.FailedChargeCount = failedChargeCount; billingReport.TransferCount = transferCount; billingReport.TransferCount_Pending = transferCount_Pending; billingReport.TransferCount_Complete = transferCount_Complete; billingReport.TotalGross = totalGross; billingReport.TotalFees = Math.Abs(totalFees); billingReport.TotalRefunds = Math.Abs(totalRefunds); billingReport.TotalNet = totalNet; billingReport.TotalTransfers = Math.Abs(totalTransfers); billingReport.TotalTransfers_Pending = Math.Abs(totalTransfers_Pending); billingReport.TotalTransfers_Complete = Math.Abs(totalTransfers_Complete); //============================================ billingReport.BillingIssues = false; //Check for any billing issues during this time period var latestBillingIssue = PlatformLogManager.GetPlatformLogByActivity(Logging.PlatformLogs.Types.ActivityType.Billing_Issue, 1); if (latestBillingIssue.Count > 0) { if (latestBillingIssue[0].Timestamp >= DateTime.UtcNow.AddHours(sinceHoursAgo * -1)) { billingReport.BillingIssues = true; } } #region Store into Redis try { //Store a copy in the Redis cache cache.HashSet( Sahara.Core.Common.Redis.PlatformManagerServer.Hashes.ReportsHash.Key, Sahara.Core.Common.Redis.PlatformManagerServer.Hashes.ReportsHash.Fields.Billing(sinceHoursAgo), JsonConvert.SerializeObject(billingReport), When.Always, CommandFlags.FireAndForget ); //Expire cache after set time cache.KeyExpire( Sahara.Core.Common.Redis.PlatformManagerServer.Hashes.ReportsHash.Key, Sahara.Core.Common.Redis.PlatformManagerServer.Hashes.ReportsHash.Expiration, CommandFlags.FireAndForget ); } catch { } #endregion } /*/TESTS! * billingReport.BalanceTransactions.Add(new BalanceTransaction { Type = "adjustment", Amount = Convert.ToDecimal(20.77), Fee = Convert.ToDecimal(20.77), Net = Convert.ToDecimal(20.77) }); * billingReport.BalanceTransactions.Add(new BalanceTransaction { Type = "application_fee", Amount = Convert.ToDecimal(20.77), Fee = Convert.ToDecimal(20.77), Net = Convert.ToDecimal(20.77) }); * billingReport.BalanceTransactions.Add(new BalanceTransaction { Type = "application_fee_refund", Amount = Convert.ToDecimal(20.77), Fee = Convert.ToDecimal(20.77), Net = Convert.ToDecimal(20.77) }); * billingReport.BalanceTransactions.Add(new BalanceTransaction { Type = "transfer_cancel", Amount = Convert.ToDecimal(20.77), Fee = Convert.ToDecimal(20.77), Net = Convert.ToDecimal(20.77) }); * billingReport.BalanceTransactions.Add(new BalanceTransaction { Type = "transfer_failure", Amount = Convert.ToDecimal(20.77), Fee = Convert.ToDecimal(20.77), Net = Convert.ToDecimal(20.77) }); */ #endregion return(billingReport); }
public static DataAccessResponseType RefundPayment(string accountId, string chargeId, decimal refundAmount) { var account = AccountManager.GetAccount(accountId); if (account == null) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "Can only makre refunds for valid accounts." }); } //Confirm that refund amount is greater than 0 if (refundAmount <= 0) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "Refund amount must be greater than 0." }); } //Confirm that the refund amount is correctly formated if (Sahara.Core.Common.Methods.Billing.IsDecimalInTwoPlaces(refundAmount)) { //Submit the refund var stripeManager = new StripeManager(); var refundAmountStripeInteger = Sahara.Core.Common.Methods.Billing.ConvertDecimalToStripeAmount(refundAmount); StripeRefund refundedCharge; var refundResponse = stripeManager.RefundPayment(chargeId, refundAmountStripeInteger, out refundedCharge); if (refundResponse.isSuccess) { //Email all acount owners regarding the refund. //Get account ownerEmail(s): var ownerEmails = AccountManager.GetAccountOwnerEmails(account.AccountID.ToString()); string refundAmountDollars = string.Empty; if (refundAmount.ToString().Substring(0, 1) == ".") { refundAmountDollars = refundAmount + " cents."; } else { refundAmountDollars = "$" + refundAmount; } EmailManager.Send( ownerEmails, Settings.Endpoints.Emails.FromRefunds, Settings.Copy.EmailMessages.ChargeRefunded.FromName, Settings.Copy.EmailMessages.ChargeRefunded.Subject, String.Format(Settings.Copy.EmailMessages.ChargeRefunded.Body, account.AccountName, refundAmountDollars), true); } return(refundResponse); } else { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "Refund amount must be a monetary value with 2 decimal places. Examples: '2.25' or '.50'" }); } }
public static DataAccessResponseType CreatePaymentPlan(PaymentPlan paymentPlan) { var response = new DataAccessResponseType(); var stripeManager = new StripeManager(); var frequencies = GetPaymentFrequencies(); #region Validate Input //Validate Plan Name var validationResponse = ValidationManager.IsValidPaymentPlanName(paymentPlan.PaymentPlanName); if (!validationResponse.isValid) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = validationResponse.validationMessage }); } if (paymentPlan.MaxCategorizationsPerSet > 80) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "Categories cannot be grouped in amounts greater than 80 per set" }); } if (paymentPlan.MaxProductsPerSet > 300) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "Products cannot be grouped in amounts greater than 300 per set" }); } if (paymentPlan.MaxProperties > 160) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot have more than 160 properties on an account" }); } if (paymentPlan.MaxValuesPerProperty > 60) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot have more than 60 values per property on an account" }); } if (paymentPlan.MaxTags > 5000) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot have more than 5000 tags on an account" }); } if (paymentPlan.MaxUsers > 300) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot have more than 300 users on an account" }); } if (paymentPlan.MaxImageGroups > 60) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot have more than 60 image groups on an account" }); } if (paymentPlan.MaxImageFormats > 240) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot have more than 240 image formats on an account" }); } if (paymentPlan.MaxImageGalleries > 30) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot have more than 30 image galleries on an account" }); } if (paymentPlan.MaxImagesPerGallery > 50) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot have more than 50 images per gallery on an account" }); } #endregion #region 1. STRIPE transaction (if applicable) if (paymentPlan.MonthlyRate != 0) { //Add to stripe first, if fails, respond with error and stop the process. foreach (PaymentFrequency frequency in frequencies) { // We ignore any payment plans that have no cost and or frequencies that are set to 0 // Stripe is only used to manage plans that have a cost associated to it above 0.0 if (frequency.PaymentFrequencyMonths != 0) { //Create the new Stripe plan ID var id = Sahara.Core.Common.Methods.Billing.GenerateStripePlanID(paymentPlan.PaymentPlanName, frequency.IntervalCount, frequency.Interval); //Check if plan exists in Stripe, return an error if it does if (stripeManager.PlanExists(id).isSuccess) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "Plan variant exists on Stripe. Operation aborted." }); } //Create the rest of the new Stripe plan var name = Sahara.Core.Common.Methods.Billing.GenerateStripePlanName(paymentPlan.PaymentPlanName, frequency.PaymentFrequencyName); var amount = Sahara.Core.Common.Methods.Billing.GenerateStripePlanAmountInCents(paymentPlan.MonthlyRate, frequency.PaymentFrequencyMonths, frequency.PriceBreak); try { stripeManager.CreatePlan( id, name, amount, frequency.Interval, frequency.IntervalCount ); } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to create a payment plan on Stripe", System.Reflection.MethodBase.GetCurrentMethod() ); return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "An error occurred while attempting to add a plan varient to Stripe. Operation aborted." }); } } } } else { } #endregion #region 2. SQL Transaction try { response.isSuccess = Sql.Statements.InsertStatements.InsertPaymentPlan(paymentPlan.PaymentPlanName, paymentPlan.Visible, paymentPlan.MonthlyRate, paymentPlan.MaxUsers, paymentPlan.MaxCategorizationsPerSet, paymentPlan.MaxProductsPerSet, paymentPlan.MaxProperties, paymentPlan.MaxValuesPerProperty, paymentPlan.MaxTags, paymentPlan.AllowSalesLeads, paymentPlan.MonthlySupportHours, paymentPlan.AllowLocationData, paymentPlan.AllowCustomOrdering, paymentPlan.AllowThemes, paymentPlan.AllowImageEnhancements, paymentPlan.MaxImageGroups, paymentPlan.MaxImageFormats, paymentPlan.MaxImageGalleries, paymentPlan.MaxImagesPerGallery).isSuccess; //Clear the cache and return results: PaymentPlanCaching.InvalidateAllCaches(); return(response); } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to insert a payment plan into SQL", System.Reflection.MethodBase.GetCurrentMethod() ); return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "Stripe transaction was successful, but there was an issue while attempting to add plan to the database. Operation aborted. " + e.Message }); } #endregion }
public static DataAccessResponseType DeletePaymentPlan(string paymentPlanName) { var stripeManager = new StripeManager(); var paymentPlan = GetPaymentPlan(paymentPlanName); var frequencies = GetPaymentFrequencies(); #region Validate Plan Deletion if (paymentPlanName.ToLower() == "unprovisioned") { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot delete the unprovisioned plan." }); } if (paymentPlanName.ToLower().Contains("trial") || paymentPlanName.ToLower().Contains("free")) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot delete the Free or Trial plans." }); } //Check if any accounts belong to the plan on SQL before deleting if (Sql.Statements.SelectStatements.AccountsWithPlanExists(paymentPlanName)) { return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "You cannot delete a plan that has accounts associated to it." }); } #endregion #region 1. Delete each plan/frequency varient on Stripe (if applicable) if (paymentPlan.MonthlyRate != 0) { //If paid account, delete each varient (only paid accounts are on Stripe) foreach (var frequency in frequencies) { if (frequency.PaymentFrequencyMonths != 0) { try { stripeManager.DeletePlan(Common.Methods.Billing.GenerateStripePlanID(paymentPlan.PaymentPlanName, frequency.IntervalCount, frequency.Interval)); } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to delete a payment plan on Stripe", System.Reflection.MethodBase.GetCurrentMethod() ); } } } } #endregion #region 2. Delete the plan on SQL try { var isSuccess = Sql.Statements.DeleteStatements.DeletePlan(paymentPlanName); //Clear the cache and return results: PaymentPlanCaching.InvalidateAllCaches(); return(new DataAccessResponseType { isSuccess = isSuccess }); } catch (Exception e) { //Log exception and email platform admins PlatformExceptionsHelper.LogExceptionAndAlertAdmins( e, "attempting to delete a payment plan in SQL", System.Reflection.MethodBase.GetCurrentMethod() ); return(new DataAccessResponseType { isSuccess = false, ErrorMessage = "An error occured while attempting to delete the plan on the databse. " + e.Message, }); } #endregion }
public static DataAccessResponseType PurgePlatform() { DataAccessResponseType response = new DataAccessResponseType(); //We only allow purging on local, debug & stage if (Sahara.Core.Settings.Environment.Current.ToLower() == "production") { response.isSuccess = false; response.ErrorMessage = "Cannot purge a production version of the platform"; return(response); } else if (Sahara.Core.Settings.Environment.Current.ToLower() != "staging" && Sahara.Core.Settings.Environment.Current.ToLower() != "stage" && Sahara.Core.Settings.Environment.Current.ToLower() != "debug" && Sahara.Core.Settings.Environment.Current.ToLower() != "test" && Sahara.Core.Settings.Environment.Current.ToLower() != "testing" && Sahara.Core.Settings.Environment.Current.ToLower() != "local") { response.isSuccess = false; response.ErrorMessage = "Can only purge a stage, test, debug or local version of the platform"; return(response); } else { //Deprovision All Accounts: DeprovisionAllAccounts(); //Clear Stripe Plans: var stripeManager = new StripeManager(); var planIDs = stripeManager.GetPlanIDs(); foreach (string planID in planIDs) { stripeManager.DeletePlan(planID); } //Delete All SQL Databases: DeleteAllSQLDatabases(); //Clear Platform Storage Accounts: ClearPlatformStorageAccounts(); /*====================================== * Delete AccountPartition Document Database * ========================================*/ /* RETIRED ---*/ //var client = Sahara.Core.Settings.Azure.DocumentDB.DocumentClients.AccountDocumentClient; var databasename = Sahara.Core.Settings.Azure.DocumentDB.AccountPartitionDatabaseId; Database accountDatabase = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.CreateDatabaseQuery().Where(db => db.Id == databasename).ToArray().FirstOrDefault(); if (accountDatabase != null) { //Create if not exists accountDatabase = Sahara.Core.Settings.Azure.DocumentDbClients.AccountDocumentClient.DeleteDatabaseAsync(accountDatabase.SelfLink).Result; } /*====================================== * FLUSH ALL REDIS CACHES * ========================================*/ var redisEndpoints = Sahara.Core.Settings.Azure.Redis.RedisMultiplexers.RedisMultiplexer.GetEndPoints(true); var redisServer = Sahara.Core.Settings.Azure.Redis.RedisMultiplexers.RedisMultiplexer.GetServer(redisEndpoints[0]); redisServer.FlushAllDatabases(); /* * var platformEndpoints = Sahara.Core.Settings.Azure.Redis.RedisMultiplexers.PlatformManager_Multiplexer.GetEndPoints(true); * var platformServer = Sahara.Core.Settings.Azure.Redis.RedisMultiplexers.PlatformManager_Multiplexer.GetServer(platformEndpoints[0]); * * var accountEndpoints = Sahara.Core.Settings.Azure.Redis.RedisMultiplexers.AccountManager_Multiplexer.GetEndPoints(true); * var accountServer = Sahara.Core.Settings.Azure.Redis.RedisMultiplexers.AccountManager_Multiplexer.GetServer(accountEndpoints[0]); * * platformServer.FlushAllDatabases(); * accountServer.FlushAllDatabases(); */ /*================================================================ * DELETE ALL AZURE SEARCH DATASOURCES, INDEXES & INDEXERS (LEGACY USING SINGLE PLAN) * ================================================================== * * SearchServiceClient searchServiceClient = Settings.Azure.Search.AccountsSearchServiceClient; * * //Delete all search indexes * var indexList = searchServiceClient.Indexes.List(); * foreach (Microsoft.Azure.Search.Models.Index index in indexList.Indexes) * { * searchServiceClient.Indexes.Delete(index.Name); * } * * //Delete all search indexers * var indexerList = searchServiceClient.Indexers.List(); * foreach (Microsoft.Azure.Search.Models.Indexer indexer in indexerList.Indexers) * { * searchServiceClient.Indexers.Delete(indexer.Name); * } * * //Delete all search datasources * var dataSourcesList = searchServiceClient.DataSources.List(); * foreach (Microsoft.Azure.Search.Models.DataSource datasource in dataSourcesList.DataSources) * { * searchServiceClient.DataSources.Delete(datasource.Name); * }*/ /*============================================================================== * DELETE ALL AZURE SEARCH DATASOURCES, INDEXES & INDEXERS (LOOP THROUGH ALL) * =============================================================================*/ //Refresh and get list: var searchPartitions = Settings.Azure.Search.RefreshSearchPartitions(); foreach (var searchPartition in searchPartitions) { SearchServiceClient searchServiceClient = Settings.Azure.Search.GetSearchPartitionClient(searchPartition.Name); //Delete all search indexes var indexList = searchServiceClient.Indexes.List(); foreach (Microsoft.Azure.Search.Models.Index index in indexList.Indexes) { searchServiceClient.Indexes.Delete(index.Name); } //Delete all search indexers var indexerList = searchServiceClient.Indexers.List(); foreach (Microsoft.Azure.Search.Models.Indexer indexer in indexerList.Indexers) { searchServiceClient.Indexers.Delete(indexer.Name); } //Delete all search datasources var dataSourcesList = searchServiceClient.DataSources.List(); foreach (Microsoft.Azure.Search.Models.DataSource datasource in dataSourcesList.DataSources) { searchServiceClient.DataSources.Delete(datasource.Name); } } /*====================================== * SEND BACK RESULTS * ========================================*/ response.isSuccess = true; response.SuccessMessage = "Platform has been purged."; return(response); } }