diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs
index 067810c22f..a7308ffec0 100644
--- a/src/Core/Services/Implementations/OrganizationService.cs
+++ b/src/Core/Services/Implementations/OrganizationService.cs
@@ -476,6 +476,11 @@ namespace Bit.Core.Services
                 throw new BadRequestException("Plan does not allow additional storage.");
             }
 
+            if(signup.AdditionalStorageGb < 0)
+            {
+                throw new BadRequestException("You can't subtract storage!");
+            }
+
             if(!plan.CanBuyPremiumAccessAddon && signup.PremiumAccessAddon)
             {
                 throw new BadRequestException("This plan does not allow you to buy the premium access addon.");
@@ -486,6 +491,11 @@ namespace Bit.Core.Services
                 throw new BadRequestException("You do not have any seats!");
             }
 
+            if(signup.AdditionalSeats < 0)
+            {
+                throw new BadRequestException("You can't subtract seats!");
+            }
+
             if(!plan.CanBuyAdditionalSeats && signup.AdditionalSeats > 0)
             {
                 throw new BadRequestException("Plan does not allow additional users.");
@@ -498,96 +508,10 @@ namespace Bit.Core.Services
                     $"{plan.MaxAdditionalSeats.GetValueOrDefault(0)} additional users.");
             }
 
-            var customerService = new CustomerService();
-            var subscriptionService = new SubscriptionService();
-            Customer customer = null;
-            Subscription subscription = null;
-
-            // Pre-generate the org id so that we can save it with the Stripe subscription..
-            var newOrgId = CoreHelpers.GenerateComb();
-
-            if(plan.Type == PlanType.Free)
-            {
-                var adminCount =
-                    await _organizationUserRepository.GetCountByFreeOrganizationAdminUserAsync(signup.Owner.Id);
-                if(adminCount > 0)
-                {
-                    throw new BadRequestException("You can only be an admin of one free organization.");
-                }
-            }
-            else
-            {
-                customer = await customerService.CreateAsync(new CustomerCreateOptions
-                {
-                    Description = signup.BusinessName,
-                    Email = signup.BillingEmail,
-                    SourceToken = signup.PaymentToken
-                });
-
-                var subCreateOptions = new SubscriptionCreateOptions
-                {
-                    CustomerId = customer.Id,
-                    TrialPeriodDays = plan.TrialPeriodDays,
-                    Items = new List<SubscriptionItemOption>(),
-                    Metadata = new Dictionary<string, string> {
-                        { "organizationId", newOrgId.ToString() }
-                    }
-                };
-
-                if(plan.StripePlanId != null)
-                {
-                    subCreateOptions.Items.Add(new SubscriptionItemOption
-                    {
-                        PlanId = plan.StripePlanId,
-                        Quantity = 1
-                    });
-                }
-
-                if(signup.AdditionalSeats > 0 && plan.StripeSeatPlanId != null)
-                {
-                    subCreateOptions.Items.Add(new SubscriptionItemOption
-                    {
-                        PlanId = plan.StripeSeatPlanId,
-                        Quantity = signup.AdditionalSeats
-                    });
-                }
-
-                if(signup.AdditionalStorageGb > 0)
-                {
-                    subCreateOptions.Items.Add(new SubscriptionItemOption
-                    {
-                        PlanId = plan.StripeStoragePlanId,
-                        Quantity = signup.AdditionalStorageGb
-                    });
-                }
-
-                if(signup.PremiumAccessAddon && plan.StripePremiumAccessPlanId != null)
-                {
-                    subCreateOptions.Items.Add(new SubscriptionItemOption
-                    {
-                        PlanId = plan.StripePremiumAccessPlanId,
-                        Quantity = 1
-                    });
-                }
-
-                try
-                {
-                    subscription = await subscriptionService.CreateAsync(subCreateOptions);
-                }
-                catch(StripeException)
-                {
-                    if(customer != null)
-                    {
-                        await customerService.DeleteAsync(customer.Id);
-                    }
-
-                    throw;
-                }
-            }
-
             var organization = new Organization
             {
-                Id = newOrgId,
+                // Pre-generate the org id so that we can save it with the Stripe subscription..
+                Id = CoreHelpers.GenerateComb(),
                 Name = signup.Name,
                 BillingEmail = signup.BillingEmail,
                 BusinessName = signup.BusinessName,
@@ -605,16 +529,43 @@ namespace Bit.Core.Services
                 SelfHost = plan.SelfHost,
                 UsersGetPremium = plan.UsersGetPremium || signup.PremiumAccessAddon,
                 Plan = plan.Name,
-                Gateway = plan.Type == PlanType.Free ? null : (GatewayType?)GatewayType.Stripe,
-                GatewayCustomerId = customer?.Id,
-                GatewaySubscriptionId = subscription?.Id,
+                Gateway = null,
                 Enabled = true,
-                ExpirationDate = subscription?.CurrentPeriodEnd,
                 LicenseKey = CoreHelpers.SecureRandomString(20),
                 CreationDate = DateTime.UtcNow,
                 RevisionDate = DateTime.UtcNow
             };
 
+            if(plan.Type == PlanType.Free)
+            {
+                var adminCount =
+                    await _organizationUserRepository.GetCountByFreeOrganizationAdminUserAsync(signup.Owner.Id);
+                if(adminCount > 0)
+                {
+                    throw new BadRequestException("You can only be an admin of one free organization.");
+                }
+            }
+            else
+            {
+                PaymentMethodType paymentMethodType;
+                if(signup.PaymentToken.StartsWith("btok_"))
+                {
+                    paymentMethodType = PaymentMethodType.BankAccount;
+                }
+                else if(signup.PaymentToken.StartsWith("tok_"))
+                {
+                    paymentMethodType = PaymentMethodType.Card;
+                }
+                else
+                {
+                    paymentMethodType = PaymentMethodType.PayPal;
+                }
+
+                await _stripePaymentService.PurchaseOrganizationAsync(organization, paymentMethodType,
+                    signup.PaymentToken, plan, signup.AdditionalStorageGb, signup.AdditionalSeats,
+                    signup.PremiumAccessAddon);
+            }
+
             return await SignUpAsync(organization, signup.Owner.Id, signup.OwnerKey, signup.CollectionName, true);
         }
 
diff --git a/src/Core/Services/Implementations/StripePaymentService.cs b/src/Core/Services/Implementations/StripePaymentService.cs
index 3a23e857df..18d4fb280c 100644
--- a/src/Core/Services/Implementations/StripePaymentService.cs
+++ b/src/Core/Services/Implementations/StripePaymentService.cs
@@ -30,6 +30,126 @@ namespace Bit.Core.Services
             };
         }
 
+        public async Task PurchaseOrganizationAsync(Organization org, PaymentMethodType paymentMethodType,
+            string paymentToken, Models.StaticStore.Plan plan, short additionalStorageGb,
+            short additionalSeats, bool premiumAccessAddon)
+        {
+            var invoiceService = new InvoiceService();
+            var customerService = new CustomerService();
+
+            Braintree.Customer braintreeCustomer = null;
+            string stipeCustomerSourceToken = null;
+            var stripeCustomerMetadata = new Dictionary<string, string>();
+            var stripePaymentMethod = paymentMethodType == PaymentMethodType.Card ||
+                paymentMethodType == PaymentMethodType.BankAccount;
+
+            if(stripePaymentMethod)
+            {
+                stipeCustomerSourceToken = paymentToken;
+            }
+            else if(paymentMethodType == PaymentMethodType.PayPal)
+            {
+                var randomSuffix = Utilities.CoreHelpers.RandomString(3, upper: false, numeric: false);
+                var customerResult = await _btGateway.Customer.CreateAsync(new Braintree.CustomerRequest
+                {
+                    PaymentMethodNonce = paymentToken,
+                    Email = org.BillingEmail,
+                    Id = "o" + org.Id.ToString("N").ToLower() + randomSuffix
+                });
+
+                if(!customerResult.IsSuccess() || customerResult.Target.PaymentMethods.Length == 0)
+                {
+                    throw new GatewayException("Failed to create PayPal customer record.");
+                }
+
+                braintreeCustomer = customerResult.Target;
+                stripeCustomerMetadata.Add("btCustomerId", braintreeCustomer.Id);
+            }
+            else
+            {
+                throw new GatewayException("Payment method is not supported at this time.");
+            }
+
+            var subCreateOptions = new SubscriptionCreateOptions
+            {
+                TrialPeriodDays = plan.TrialPeriodDays,
+                Items = new List<SubscriptionItemOption>(),
+                Metadata = new Dictionary<string, string>
+                {
+                    ["organizationId"] = org.Id.ToString()
+                }
+            };
+
+            if(plan.StripePlanId != null)
+            {
+                subCreateOptions.Items.Add(new SubscriptionItemOption
+                {
+                    PlanId = plan.StripePlanId,
+                    Quantity = 1
+                });
+            }
+
+            if(additionalSeats > 0 && plan.StripeSeatPlanId != null)
+            {
+                subCreateOptions.Items.Add(new SubscriptionItemOption
+                {
+                    PlanId = plan.StripeSeatPlanId,
+                    Quantity = additionalSeats
+                });
+            }
+
+            if(additionalStorageGb > 0)
+            {
+                subCreateOptions.Items.Add(new SubscriptionItemOption
+                {
+                    PlanId = plan.StripeStoragePlanId,
+                    Quantity = additionalStorageGb
+                });
+            }
+
+            if(premiumAccessAddon && plan.StripePremiumAccessPlanId != null)
+            {
+                subCreateOptions.Items.Add(new SubscriptionItemOption
+                {
+                    PlanId = plan.StripePremiumAccessPlanId,
+                    Quantity = 1
+                });
+            }
+
+            Customer customer = null;
+            Subscription subscription = null;
+            try
+            {
+                customer = await customerService.CreateAsync(new CustomerCreateOptions
+                {
+                    Description = org.BusinessName,
+                    Email = org.BillingEmail,
+                    SourceToken = stipeCustomerSourceToken,
+                    Metadata = stripeCustomerMetadata
+                });
+                subCreateOptions.CustomerId = customer.Id;
+                var subscriptionService = new SubscriptionService();
+                subscription = await subscriptionService.CreateAsync(subCreateOptions);
+            }
+            catch(Exception e)
+            {
+                if(customer != null)
+                {
+                    await customerService.DeleteAsync(customer.Id);
+                }
+                if(braintreeCustomer != null)
+                {
+                    await _btGateway.Customer.DeleteAsync(braintreeCustomer.Id);
+                }
+                throw e;
+            }
+
+            org.Gateway = GatewayType.Stripe;
+            org.GatewayCustomerId = customer.Id;
+            org.GatewaySubscriptionId = subscription.Id;
+            org.ExpirationDate = subscription.CurrentPeriodEnd;
+        }
+
         public async Task PurchasePremiumAsync(User user, PaymentMethodType paymentMethodType, string paymentToken,
             short additionalStorageGb)
         {
diff --git a/src/Core/Services/Implementations/UserService.cs b/src/Core/Services/Implementations/UserService.cs
index af15171f7f..9201cf45bf 100644
--- a/src/Core/Services/Implementations/UserService.cs
+++ b/src/Core/Services/Implementations/UserService.cs
@@ -682,6 +682,11 @@ namespace Bit.Core.Services
                 throw new BadRequestException("Already a premium user.");
             }
 
+            if(additionalStorageGb < 0)
+            {
+                throw new BadRequestException("You can't subtract storage!");
+            }
+
             IPaymentService paymentService = null;
             if(_globalSettings.SelfHosted)
             {