mirror of
https://github.com/bitwarden/server.git
synced 2025-01-22 21:51:22 +01:00
billing fixes and added gateway to subscriber
This commit is contained in:
parent
082b53e133
commit
cfc80f8d1e
8
src/Core/Enums/GatewayType.cs
Normal file
8
src/Core/Enums/GatewayType.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Bit.Core.Enums
|
||||||
|
{
|
||||||
|
public enum GatewayType : byte
|
||||||
|
{
|
||||||
|
Stripe = 0,
|
||||||
|
Braintree = 1
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,9 @@
|
|||||||
{
|
{
|
||||||
public enum PaymentMethodType : byte
|
public enum PaymentMethodType : byte
|
||||||
{
|
{
|
||||||
Card,
|
Card = 0,
|
||||||
BankAccount,
|
BankAccount = 1,
|
||||||
PayPal,
|
PayPal = 2,
|
||||||
Bitcoin
|
Bitcoin = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ namespace Bit.Core.Models.Api
|
|||||||
EndDate = sub.EndDate;
|
EndDate = sub.EndDate;
|
||||||
CancelledDate = sub.CancelledDate;
|
CancelledDate = sub.CancelledDate;
|
||||||
CancelAtEndDate = sub.CancelAtEndDate;
|
CancelAtEndDate = sub.CancelAtEndDate;
|
||||||
Cancelled = Cancelled;
|
Cancelled = sub.Cancelled;
|
||||||
if(sub.Items != null)
|
if(sub.Items != null)
|
||||||
{
|
{
|
||||||
Items = sub.Items.Select(i => new BillingSubscriptionItem(i));
|
Items = sub.Items.Select(i => new BillingSubscriptionItem(i));
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
namespace Bit.Core.Models.Table
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
|
||||||
|
namespace Bit.Core.Models.Table
|
||||||
{
|
{
|
||||||
public interface ISubscriber
|
public interface ISubscriber
|
||||||
{
|
{
|
||||||
string StripeCustomerId { get; set; }
|
GatewayType? Gateway { get; set; }
|
||||||
string StripeSubscriptionId { get; set; }
|
string GatewayCustomerId { get; set; }
|
||||||
|
string GatewaySubscriptionId { get; set; }
|
||||||
string BillingEmailAddress();
|
string BillingEmailAddress();
|
||||||
string BillingName();
|
string BillingName();
|
||||||
|
IPaymentService GetPaymentService(GlobalSettings globalSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
using Bit.Core.Exceptions;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Table
|
namespace Bit.Core.Models.Table
|
||||||
{
|
{
|
||||||
@ -19,8 +21,9 @@ namespace Bit.Core.Models.Table
|
|||||||
public bool UseTotp { get; set; }
|
public bool UseTotp { get; set; }
|
||||||
public long? Storage { get; set; }
|
public long? Storage { get; set; }
|
||||||
public short? MaxStorageGb { get; set; }
|
public short? MaxStorageGb { get; set; }
|
||||||
public string StripeCustomerId { get; set; }
|
public GatewayType? Gateway { get; set; }
|
||||||
public string StripeSubscriptionId { get; set; }
|
public string GatewayCustomerId { get; set; }
|
||||||
|
public string GatewaySubscriptionId { get; set; }
|
||||||
public bool Enabled { get; set; } = true;
|
public bool Enabled { get; set; } = true;
|
||||||
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
|
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
|
||||||
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
|
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
|
||||||
@ -63,5 +66,28 @@ namespace Bit.Core.Models.Table
|
|||||||
|
|
||||||
return maxStorageBytes - Storage.Value;
|
return maxStorageBytes - Storage.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IPaymentService GetPaymentService(GlobalSettings globalSettings)
|
||||||
|
{
|
||||||
|
if(Gateway == null)
|
||||||
|
{
|
||||||
|
throw new BadRequestException("No gateway.");
|
||||||
|
}
|
||||||
|
|
||||||
|
IPaymentService paymentService = null;
|
||||||
|
switch(Gateway)
|
||||||
|
{
|
||||||
|
case GatewayType.Stripe:
|
||||||
|
paymentService = new StripePaymentService();
|
||||||
|
break;
|
||||||
|
case GatewayType.Braintree:
|
||||||
|
paymentService = new BraintreePaymentService(globalSettings);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException("Unsupported gateway.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return paymentService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
|
using Bit.Core.Exceptions;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Table
|
namespace Bit.Core.Models.Table
|
||||||
{
|
{
|
||||||
@ -31,8 +32,9 @@ namespace Bit.Core.Models.Table
|
|||||||
public bool Premium { get; set; }
|
public bool Premium { get; set; }
|
||||||
public long? Storage { get; set; }
|
public long? Storage { get; set; }
|
||||||
public short? MaxStorageGb { get; set; }
|
public short? MaxStorageGb { get; set; }
|
||||||
public string StripeCustomerId { get; set; }
|
public GatewayType? Gateway { get; set; }
|
||||||
public string StripeSubscriptionId { get; set; }
|
public string GatewayCustomerId { get; set; }
|
||||||
|
public string GatewaySubscriptionId { get; set; }
|
||||||
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
|
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
|
||||||
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
|
public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
@ -139,14 +141,22 @@ namespace Bit.Core.Models.Table
|
|||||||
|
|
||||||
public IPaymentService GetPaymentService(GlobalSettings globalSettings)
|
public IPaymentService GetPaymentService(GlobalSettings globalSettings)
|
||||||
{
|
{
|
||||||
IPaymentService paymentService = null;
|
if(Gateway == null)
|
||||||
if(StripeSubscriptionId.StartsWith("sub_"))
|
|
||||||
{
|
{
|
||||||
paymentService = new StripePaymentService();
|
throw new BadRequestException("No gateway.");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
IPaymentService paymentService = null;
|
||||||
|
switch(Gateway)
|
||||||
{
|
{
|
||||||
paymentService = new BraintreePaymentService(globalSettings);
|
case GatewayType.Stripe:
|
||||||
|
paymentService = new StripePaymentService();
|
||||||
|
break;
|
||||||
|
case GatewayType.Braintree:
|
||||||
|
paymentService = new BraintreePaymentService(globalSettings);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException("Unsupported gateway.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return paymentService;
|
return paymentService;
|
||||||
|
@ -29,7 +29,7 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task AdjustStorageAsync(IStorableSubscriber storableSubscriber, int additionalStorage, string storagePlanId)
|
public async Task AdjustStorageAsync(IStorableSubscriber storableSubscriber, int additionalStorage, string storagePlanId)
|
||||||
{
|
{
|
||||||
var sub = await _gateway.Subscription.FindAsync(storableSubscriber.StripeSubscriptionId);
|
var sub = await _gateway.Subscription.FindAsync(storableSubscriber.GatewaySubscriptionId);
|
||||||
if(sub == null)
|
if(sub == null)
|
||||||
{
|
{
|
||||||
throw new GatewayException("Subscription was not found.");
|
throw new GatewayException("Subscription was not found.");
|
||||||
@ -82,17 +82,17 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task CancelAndRecoverChargesAsync(ISubscriber subscriber)
|
public async Task CancelAndRecoverChargesAsync(ISubscriber subscriber)
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrWhiteSpace(subscriber.StripeSubscriptionId))
|
if(!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
await _gateway.Subscription.CancelAsync(subscriber.StripeSubscriptionId);
|
await _gateway.Subscription.CancelAsync(subscriber.GatewaySubscriptionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(subscriber.StripeCustomerId))
|
if(string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var transactionRequest = new TransactionSearchRequest().CustomerId.Is(subscriber.StripeCustomerId);
|
var transactionRequest = new TransactionSearchRequest().CustomerId.Is(subscriber.GatewayCustomerId);
|
||||||
var transactions = _gateway.Transaction.Search(transactionRequest);
|
var transactions = _gateway.Transaction.Search(transactionRequest);
|
||||||
|
|
||||||
if((transactions?.MaximumCount ?? 0) > 0)
|
if((transactions?.MaximumCount ?? 0) > 0)
|
||||||
@ -103,7 +103,7 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await _gateway.Customer.DeleteAsync(subscriber.StripeCustomerId);
|
await _gateway.Customer.DeleteAsync(subscriber.GatewayCustomerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CancelSubscriptionAsync(ISubscriber subscriber, bool endOfPeriod = false)
|
public async Task CancelSubscriptionAsync(ISubscriber subscriber, bool endOfPeriod = false)
|
||||||
@ -113,12 +113,12 @@ namespace Bit.Core.Services
|
|||||||
throw new ArgumentNullException(nameof(subscriber));
|
throw new ArgumentNullException(nameof(subscriber));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(subscriber.StripeSubscriptionId))
|
if(string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
throw new GatewayException("No subscription.");
|
throw new GatewayException("No subscription.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var sub = await _gateway.Subscription.FindAsync(subscriber.StripeSubscriptionId);
|
var sub = await _gateway.Subscription.FindAsync(subscriber.GatewaySubscriptionId);
|
||||||
if(sub == null)
|
if(sub == null)
|
||||||
{
|
{
|
||||||
throw new GatewayException("Subscription was not found.");
|
throw new GatewayException("Subscription was not found.");
|
||||||
@ -138,7 +138,7 @@ namespace Bit.Core.Services
|
|||||||
NumberOfBillingCycles = sub.CurrentBillingCycle
|
NumberOfBillingCycles = sub.CurrentBillingCycle
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await _gateway.Subscription.UpdateAsync(subscriber.StripeSubscriptionId, req);
|
var result = await _gateway.Subscription.UpdateAsync(subscriber.GatewaySubscriptionId, req);
|
||||||
if(!result.IsSuccess())
|
if(!result.IsSuccess())
|
||||||
{
|
{
|
||||||
throw new GatewayException("Unable to cancel subscription.");
|
throw new GatewayException("Unable to cancel subscription.");
|
||||||
@ -146,7 +146,7 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var result = await _gateway.Subscription.CancelAsync(subscriber.StripeSubscriptionId);
|
var result = await _gateway.Subscription.CancelAsync(subscriber.GatewaySubscriptionId);
|
||||||
if(!result.IsSuccess())
|
if(!result.IsSuccess())
|
||||||
{
|
{
|
||||||
throw new GatewayException("Unable to cancel subscription.");
|
throw new GatewayException("Unable to cancel subscription.");
|
||||||
@ -157,9 +157,9 @@ namespace Bit.Core.Services
|
|||||||
public async Task<BillingInfo> GetBillingAsync(ISubscriber subscriber)
|
public async Task<BillingInfo> GetBillingAsync(ISubscriber subscriber)
|
||||||
{
|
{
|
||||||
var billingInfo = new BillingInfo();
|
var billingInfo = new BillingInfo();
|
||||||
if(!string.IsNullOrWhiteSpace(subscriber.StripeCustomerId))
|
if(!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
var customer = await _gateway.Customer.FindAsync(subscriber.StripeCustomerId);
|
var customer = await _gateway.Customer.FindAsync(subscriber.GatewayCustomerId);
|
||||||
if(customer != null)
|
if(customer != null)
|
||||||
{
|
{
|
||||||
if(customer.DefaultPaymentMethod != null)
|
if(customer.DefaultPaymentMethod != null)
|
||||||
@ -174,9 +174,9 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(subscriber.StripeSubscriptionId))
|
if(!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
var sub = await _gateway.Subscription.FindAsync(subscriber.StripeSubscriptionId);
|
var sub = await _gateway.Subscription.FindAsync(subscriber.GatewaySubscriptionId);
|
||||||
if(sub != null)
|
if(sub != null)
|
||||||
{
|
{
|
||||||
var plans = await _gateway.Plan.AllAsync();
|
var plans = await _gateway.Plan.AllAsync();
|
||||||
@ -184,7 +184,8 @@ namespace Bit.Core.Services
|
|||||||
billingInfo.Subscription = new BillingInfo.BillingSubscription(sub, plan);
|
billingInfo.Subscription = new BillingInfo.BillingSubscription(sub, plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sub.NextBillingDate.HasValue)
|
if(!billingInfo.Subscription.Cancelled && !billingInfo.Subscription.CancelAtEndDate &&
|
||||||
|
sub.NextBillingDate.HasValue)
|
||||||
{
|
{
|
||||||
billingInfo.UpcomingInvoice = new BillingInfo.BillingInvoice(sub);
|
billingInfo.UpcomingInvoice = new BillingInfo.BillingInvoice(sub);
|
||||||
}
|
}
|
||||||
@ -237,8 +238,9 @@ namespace Bit.Core.Services
|
|||||||
throw new GatewayException("Failed to create subscription.");
|
throw new GatewayException("Failed to create subscription.");
|
||||||
}
|
}
|
||||||
|
|
||||||
user.StripeCustomerId = customerResult.Target.Id;
|
user.Gateway = Enums.GatewayType.Braintree;
|
||||||
user.StripeSubscriptionId = subResult.Target.Id;
|
user.GatewayCustomerId = customerResult.Target.Id;
|
||||||
|
user.GatewaySubscriptionId = subResult.Target.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ReinstateSubscriptionAsync(ISubscriber subscriber)
|
public async Task ReinstateSubscriptionAsync(ISubscriber subscriber)
|
||||||
@ -248,12 +250,12 @@ namespace Bit.Core.Services
|
|||||||
throw new ArgumentNullException(nameof(subscriber));
|
throw new ArgumentNullException(nameof(subscriber));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(subscriber.StripeSubscriptionId))
|
if(string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
throw new GatewayException("No subscription.");
|
throw new GatewayException("No subscription.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var sub = await _gateway.Subscription.FindAsync(subscriber.StripeSubscriptionId);
|
var sub = await _gateway.Subscription.FindAsync(subscriber.GatewaySubscriptionId);
|
||||||
if(sub == null)
|
if(sub == null)
|
||||||
{
|
{
|
||||||
throw new GatewayException("Subscription was not found.");
|
throw new GatewayException("Subscription was not found.");
|
||||||
@ -270,7 +272,7 @@ namespace Bit.Core.Services
|
|||||||
NumberOfBillingCycles = null
|
NumberOfBillingCycles = null
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await _gateway.Subscription.UpdateAsync(subscriber.StripeSubscriptionId, req);
|
var result = await _gateway.Subscription.UpdateAsync(subscriber.GatewaySubscriptionId, req);
|
||||||
if(!result.IsSuccess())
|
if(!result.IsSuccess())
|
||||||
{
|
{
|
||||||
throw new GatewayException("Unable to reinstate subscription.");
|
throw new GatewayException("Unable to reinstate subscription.");
|
||||||
@ -284,12 +286,18 @@ namespace Bit.Core.Services
|
|||||||
throw new ArgumentNullException(nameof(subscriber));
|
throw new ArgumentNullException(nameof(subscriber));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(subscriber.Gateway.HasValue && subscriber.Gateway.Value != Enums.GatewayType.Braintree)
|
||||||
|
{
|
||||||
|
throw new GatewayException("Switching from one payment type to another is not supported. " +
|
||||||
|
"Contact us for assistance.");
|
||||||
|
}
|
||||||
|
|
||||||
var updatedSubscriber = false;
|
var updatedSubscriber = false;
|
||||||
Customer customer = null;
|
Customer customer = null;
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(subscriber.StripeCustomerId))
|
if(!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
customer = await _gateway.Customer.FindAsync(subscriber.StripeCustomerId);
|
customer = await _gateway.Customer.FindAsync(subscriber.GatewayCustomerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(customer == null)
|
if(customer == null)
|
||||||
@ -306,7 +314,8 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
customer = result.Target;
|
customer = result.Target;
|
||||||
subscriber.StripeCustomerId = customer.Id;
|
subscriber.Gateway = Enums.GatewayType.Braintree;
|
||||||
|
subscriber.GatewayCustomerId = customer.Id;
|
||||||
updatedSubscriber = true;
|
updatedSubscriber = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -95,7 +95,7 @@ namespace Bit.Core.Services
|
|||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(organization.StripeCustomerId))
|
if(string.IsNullOrWhiteSpace(organization.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
throw new BadRequestException("No payment method found.");
|
throw new BadRequestException("No payment method found.");
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ namespace Bit.Core.Services
|
|||||||
// TODO: Groups?
|
// TODO: Groups?
|
||||||
|
|
||||||
var subscriptionService = new StripeSubscriptionService();
|
var subscriptionService = new StripeSubscriptionService();
|
||||||
if(string.IsNullOrWhiteSpace(organization.StripeSubscriptionId))
|
if(string.IsNullOrWhiteSpace(organization.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
// They must have been on a free plan. Create new sub.
|
// They must have been on a free plan. Create new sub.
|
||||||
var subCreateOptions = new StripeSubscriptionCreateOptions
|
var subCreateOptions = new StripeSubscriptionCreateOptions
|
||||||
@ -190,7 +190,7 @@ namespace Bit.Core.Services
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await subscriptionService.CreateAsync(organization.StripeCustomerId, subCreateOptions);
|
await subscriptionService.CreateAsync(organization.GatewayCustomerId, subCreateOptions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -218,7 +218,7 @@ namespace Bit.Core.Services
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await subscriptionService.UpdateAsync(organization.StripeSubscriptionId, subUpdateOptions);
|
await subscriptionService.UpdateAsync(organization.GatewaySubscriptionId, subUpdateOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Update organization
|
// TODO: Update organization
|
||||||
@ -256,12 +256,12 @@ namespace Bit.Core.Services
|
|||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(organization.StripeCustomerId))
|
if(string.IsNullOrWhiteSpace(organization.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
throw new BadRequestException("No payment method found.");
|
throw new BadRequestException("No payment method found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(organization.StripeSubscriptionId))
|
if(string.IsNullOrWhiteSpace(organization.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
throw new BadRequestException("No subscription found.");
|
throw new BadRequestException("No subscription found.");
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
var subscriptionItemService = new StripeSubscriptionItemService();
|
var subscriptionItemService = new StripeSubscriptionItemService();
|
||||||
var subscriptionService = new StripeSubscriptionService();
|
var subscriptionService = new StripeSubscriptionService();
|
||||||
var sub = await subscriptionService.GetAsync(organization.StripeSubscriptionId);
|
var sub = await subscriptionService.GetAsync(organization.GatewaySubscriptionId);
|
||||||
if(sub == null)
|
if(sub == null)
|
||||||
{
|
{
|
||||||
throw new BadRequestException("Subscription not found.");
|
throw new BadRequestException("Subscription not found.");
|
||||||
@ -469,8 +469,9 @@ namespace Bit.Core.Services
|
|||||||
UseDirectory = plan.UseDirectory,
|
UseDirectory = plan.UseDirectory,
|
||||||
UseTotp = plan.UseTotp,
|
UseTotp = plan.UseTotp,
|
||||||
Plan = plan.Name,
|
Plan = plan.Name,
|
||||||
StripeCustomerId = customer?.Id,
|
Gateway = GatewayType.Stripe,
|
||||||
StripeSubscriptionId = subscription?.Id,
|
GatewayCustomerId = customer?.Id,
|
||||||
|
GatewaySubscriptionId = subscription?.Id,
|
||||||
Enabled = true,
|
Enabled = true,
|
||||||
CreationDate = DateTime.UtcNow,
|
CreationDate = DateTime.UtcNow,
|
||||||
RevisionDate = DateTime.UtcNow
|
RevisionDate = DateTime.UtcNow
|
||||||
@ -515,10 +516,10 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task DeleteAsync(Organization organization)
|
public async Task DeleteAsync(Organization organization)
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrWhiteSpace(organization.StripeSubscriptionId))
|
if(!string.IsNullOrWhiteSpace(organization.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
var subscriptionService = new StripeSubscriptionService();
|
var subscriptionService = new StripeSubscriptionService();
|
||||||
var canceledSub = await subscriptionService.CancelAsync(organization.StripeSubscriptionId, false);
|
var canceledSub = await subscriptionService.CancelAsync(organization.GatewaySubscriptionId, false);
|
||||||
if(!canceledSub.CanceledAt.HasValue)
|
if(!canceledSub.CanceledAt.HasValue)
|
||||||
{
|
{
|
||||||
throw new BadRequestException("Unable to cancel subscription.");
|
throw new BadRequestException("Unable to cancel subscription.");
|
||||||
@ -559,10 +560,10 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
await _organizationRepository.ReplaceAsync(organization);
|
await _organizationRepository.ReplaceAsync(organization);
|
||||||
|
|
||||||
if(updateBilling && !string.IsNullOrWhiteSpace(organization.StripeCustomerId))
|
if(updateBilling && !string.IsNullOrWhiteSpace(organization.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
var customerService = new StripeCustomerService();
|
var customerService = new StripeCustomerService();
|
||||||
await customerService.UpdateAsync(organization.StripeCustomerId, new StripeCustomerUpdateOptions
|
await customerService.UpdateAsync(organization.GatewayCustomerId, new StripeCustomerUpdateOptions
|
||||||
{
|
{
|
||||||
Email = organization.BillingEmail,
|
Email = organization.BillingEmail,
|
||||||
Description = organization.BusinessName
|
Description = organization.BusinessName
|
||||||
|
@ -60,8 +60,9 @@ namespace Bit.Core.Services
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
user.StripeCustomerId = customer.Id;
|
user.Gateway = Enums.GatewayType.Stripe;
|
||||||
user.StripeSubscriptionId = subscription.Id;
|
user.GatewayCustomerId = customer.Id;
|
||||||
|
user.GatewaySubscriptionId = subscription.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AdjustStorageAsync(IStorableSubscriber storableSubscriber, int additionalStorage,
|
public async Task AdjustStorageAsync(IStorableSubscriber storableSubscriber, int additionalStorage,
|
||||||
@ -69,7 +70,7 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
var subscriptionItemService = new StripeSubscriptionItemService();
|
var subscriptionItemService = new StripeSubscriptionItemService();
|
||||||
var subscriptionService = new StripeSubscriptionService();
|
var subscriptionService = new StripeSubscriptionService();
|
||||||
var sub = await subscriptionService.GetAsync(storableSubscriber.StripeSubscriptionId);
|
var sub = await subscriptionService.GetAsync(storableSubscriber.GatewaySubscriptionId);
|
||||||
if(sub == null)
|
if(sub == null)
|
||||||
{
|
{
|
||||||
throw new GatewayException("Subscription not found.");
|
throw new GatewayException("Subscription not found.");
|
||||||
@ -108,13 +109,13 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task CancelAndRecoverChargesAsync(ISubscriber subscriber)
|
public async Task CancelAndRecoverChargesAsync(ISubscriber subscriber)
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrWhiteSpace(subscriber.StripeSubscriptionId))
|
if(!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
var subscriptionService = new StripeSubscriptionService();
|
var subscriptionService = new StripeSubscriptionService();
|
||||||
await subscriptionService.CancelAsync(subscriber.StripeSubscriptionId, false);
|
await subscriptionService.CancelAsync(subscriber.GatewaySubscriptionId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(subscriber.StripeCustomerId))
|
if(string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -122,7 +123,7 @@ namespace Bit.Core.Services
|
|||||||
var chargeService = new StripeChargeService();
|
var chargeService = new StripeChargeService();
|
||||||
var charges = await chargeService.ListAsync(new StripeChargeListOptions
|
var charges = await chargeService.ListAsync(new StripeChargeListOptions
|
||||||
{
|
{
|
||||||
CustomerId = subscriber.StripeCustomerId
|
CustomerId = subscriber.GatewayCustomerId
|
||||||
});
|
});
|
||||||
|
|
||||||
if(charges?.Data != null)
|
if(charges?.Data != null)
|
||||||
@ -135,17 +136,17 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
var customerService = new StripeCustomerService();
|
var customerService = new StripeCustomerService();
|
||||||
await customerService.DeleteAsync(subscriber.StripeCustomerId);
|
await customerService.DeleteAsync(subscriber.GatewayCustomerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PreviewUpcomingInvoiceAndPayAsync(ISubscriber subscriber, string planId,
|
public async Task PreviewUpcomingInvoiceAndPayAsync(ISubscriber subscriber, string planId,
|
||||||
int prorateThreshold = 500)
|
int prorateThreshold = 500)
|
||||||
{
|
{
|
||||||
var invoiceService = new StripeInvoiceService();
|
var invoiceService = new StripeInvoiceService();
|
||||||
var upcomingPreview = await invoiceService.UpcomingAsync(subscriber.StripeCustomerId,
|
var upcomingPreview = await invoiceService.UpcomingAsync(subscriber.GatewayCustomerId,
|
||||||
new StripeUpcomingInvoiceOptions
|
new StripeUpcomingInvoiceOptions
|
||||||
{
|
{
|
||||||
SubscriptionId = subscriber.StripeSubscriptionId
|
SubscriptionId = subscriber.GatewaySubscriptionId
|
||||||
});
|
});
|
||||||
|
|
||||||
var prorationAmount = upcomingPreview.StripeInvoiceLineItems?.Data?
|
var prorationAmount = upcomingPreview.StripeInvoiceLineItems?.Data?
|
||||||
@ -156,10 +157,10 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
// Owes more than prorateThreshold on next invoice.
|
// Owes more than prorateThreshold on next invoice.
|
||||||
// Invoice them and pay now instead of waiting until next month.
|
// Invoice them and pay now instead of waiting until next month.
|
||||||
var invoice = await invoiceService.CreateAsync(subscriber.StripeCustomerId,
|
var invoice = await invoiceService.CreateAsync(subscriber.GatewayCustomerId,
|
||||||
new StripeInvoiceCreateOptions
|
new StripeInvoiceCreateOptions
|
||||||
{
|
{
|
||||||
SubscriptionId = subscriber.StripeSubscriptionId
|
SubscriptionId = subscriber.GatewaySubscriptionId
|
||||||
});
|
});
|
||||||
|
|
||||||
if(invoice.AmountDue > 0)
|
if(invoice.AmountDue > 0)
|
||||||
@ -178,13 +179,13 @@ namespace Bit.Core.Services
|
|||||||
throw new ArgumentNullException(nameof(subscriber));
|
throw new ArgumentNullException(nameof(subscriber));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(subscriber.StripeSubscriptionId))
|
if(string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
throw new GatewayException("No subscription.");
|
throw new GatewayException("No subscription.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var subscriptionService = new StripeSubscriptionService();
|
var subscriptionService = new StripeSubscriptionService();
|
||||||
var sub = await subscriptionService.GetAsync(subscriber.StripeSubscriptionId);
|
var sub = await subscriptionService.GetAsync(subscriber.GatewaySubscriptionId);
|
||||||
if(sub == null)
|
if(sub == null)
|
||||||
{
|
{
|
||||||
throw new GatewayException("Subscription was not found.");
|
throw new GatewayException("Subscription was not found.");
|
||||||
@ -209,13 +210,13 @@ namespace Bit.Core.Services
|
|||||||
throw new ArgumentNullException(nameof(subscriber));
|
throw new ArgumentNullException(nameof(subscriber));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(subscriber.StripeSubscriptionId))
|
if(string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
throw new GatewayException("No subscription.");
|
throw new GatewayException("No subscription.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var subscriptionService = new StripeSubscriptionService();
|
var subscriptionService = new StripeSubscriptionService();
|
||||||
var sub = await subscriptionService.GetAsync(subscriber.StripeSubscriptionId);
|
var sub = await subscriptionService.GetAsync(subscriber.GatewaySubscriptionId);
|
||||||
if(sub == null)
|
if(sub == null)
|
||||||
{
|
{
|
||||||
throw new GatewayException("Subscription was not found.");
|
throw new GatewayException("Subscription was not found.");
|
||||||
@ -241,15 +242,21 @@ namespace Bit.Core.Services
|
|||||||
throw new ArgumentNullException(nameof(subscriber));
|
throw new ArgumentNullException(nameof(subscriber));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(subscriber.Gateway.HasValue && subscriber.Gateway.Value != Enums.GatewayType.Stripe)
|
||||||
|
{
|
||||||
|
throw new GatewayException("Switching from one payment type to another is not supported. " +
|
||||||
|
"Contact us for assistance.");
|
||||||
|
}
|
||||||
|
|
||||||
var updatedSubscriber = false;
|
var updatedSubscriber = false;
|
||||||
|
|
||||||
var cardService = new StripeCardService();
|
var cardService = new StripeCardService();
|
||||||
var customerService = new StripeCustomerService();
|
var customerService = new StripeCustomerService();
|
||||||
StripeCustomer customer = null;
|
StripeCustomer customer = null;
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(subscriber.StripeCustomerId))
|
if(!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
customer = await customerService.GetAsync(subscriber.StripeCustomerId);
|
customer = await customerService.GetAsync(subscriber.GatewayCustomerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(customer == null)
|
if(customer == null)
|
||||||
@ -261,7 +268,8 @@ namespace Bit.Core.Services
|
|||||||
SourceToken = paymentToken
|
SourceToken = paymentToken
|
||||||
});
|
});
|
||||||
|
|
||||||
subscriber.StripeCustomerId = customer.Id;
|
subscriber.Gateway = Enums.GatewayType.Stripe;
|
||||||
|
subscriber.GatewayCustomerId = customer.Id;
|
||||||
updatedSubscriber = true;
|
updatedSubscriber = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -288,9 +296,9 @@ namespace Bit.Core.Services
|
|||||||
var chargeService = new StripeChargeService();
|
var chargeService = new StripeChargeService();
|
||||||
var invoiceService = new StripeInvoiceService();
|
var invoiceService = new StripeInvoiceService();
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(subscriber.StripeCustomerId))
|
if(!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
var customer = await customerService.GetAsync(subscriber.StripeCustomerId);
|
var customer = await customerService.GetAsync(subscriber.GatewayCustomerId);
|
||||||
if(customer != null)
|
if(customer != null)
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrWhiteSpace(customer.DefaultSourceId) && customer.Sources?.Data != null)
|
if(!string.IsNullOrWhiteSpace(customer.DefaultSourceId) && customer.Sources?.Data != null)
|
||||||
@ -324,19 +332,19 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(subscriber.StripeSubscriptionId))
|
if(!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
var sub = await subscriptionService.GetAsync(subscriber.StripeSubscriptionId);
|
var sub = await subscriptionService.GetAsync(subscriber.GatewaySubscriptionId);
|
||||||
if(sub != null)
|
if(sub != null)
|
||||||
{
|
{
|
||||||
billingInfo.Subscription = new BillingInfo.BillingSubscription(sub);
|
billingInfo.Subscription = new BillingInfo.BillingSubscription(sub);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!sub.CanceledAt.HasValue && !string.IsNullOrWhiteSpace(subscriber.StripeCustomerId))
|
if(!sub.CanceledAt.HasValue && !string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var upcomingInvoice = await invoiceService.UpcomingAsync(subscriber.StripeCustomerId);
|
var upcomingInvoice = await invoiceService.UpcomingAsync(subscriber.GatewayCustomerId);
|
||||||
if(upcomingInvoice != null)
|
if(upcomingInvoice != null)
|
||||||
{
|
{
|
||||||
billingInfo.UpcomingInvoice = new BillingInfo.BillingInvoice(upcomingInvoice);
|
billingInfo.UpcomingInvoice = new BillingInfo.BillingInvoice(upcomingInvoice);
|
||||||
|
@ -164,10 +164,10 @@ namespace Bit.Core.Services
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(user.StripeSubscriptionId))
|
if(!string.IsNullOrWhiteSpace(user.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
var subscriptionService = new StripeSubscriptionService();
|
var subscriptionService = new StripeSubscriptionService();
|
||||||
var canceledSub = await subscriptionService.CancelAsync(user.StripeSubscriptionId, false);
|
var canceledSub = await subscriptionService.CancelAsync(user.GatewaySubscriptionId, false);
|
||||||
if(!canceledSub.CanceledAt.HasValue)
|
if(!canceledSub.CanceledAt.HasValue)
|
||||||
{
|
{
|
||||||
throw new BadRequestException("Unable to cancel subscription.");
|
throw new BadRequestException("Unable to cancel subscription.");
|
||||||
@ -560,7 +560,16 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task ReplacePaymentMethodAsync(User user, string paymentToken)
|
public async Task ReplacePaymentMethodAsync(User user, string paymentToken)
|
||||||
{
|
{
|
||||||
var paymentService = user.GetPaymentService(_globalSettings);
|
IPaymentService paymentService = null;
|
||||||
|
if(paymentToken.StartsWith("tok_"))
|
||||||
|
{
|
||||||
|
paymentService = new StripePaymentService();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
paymentService = new BraintreePaymentService(_globalSettings);
|
||||||
|
}
|
||||||
|
|
||||||
var updated = await paymentService.UpdatePaymentMethodAsync(user, paymentToken);
|
var updated = await paymentService.UpdatePaymentMethodAsync(user, paymentToken);
|
||||||
if(updated)
|
if(updated)
|
||||||
{
|
{
|
||||||
|
@ -16,12 +16,12 @@ namespace Bit.Core.Utilities
|
|||||||
throw new ArgumentNullException(nameof(storableSubscriber));
|
throw new ArgumentNullException(nameof(storableSubscriber));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(storableSubscriber.StripeCustomerId))
|
if(string.IsNullOrWhiteSpace(storableSubscriber.GatewayCustomerId))
|
||||||
{
|
{
|
||||||
throw new BadRequestException("No payment method found.");
|
throw new BadRequestException("No payment method found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(storableSubscriber.StripeSubscriptionId))
|
if(string.IsNullOrWhiteSpace(storableSubscriber.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
throw new BadRequestException("No subscription found.");
|
throw new BadRequestException("No subscription found.");
|
||||||
}
|
}
|
||||||
|
@ -205,4 +205,7 @@
|
|||||||
<Build Include="dbo\Stored Procedures\User_UpdateStorage.sql" />
|
<Build Include="dbo\Stored Procedures\User_UpdateStorage.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Cipher_DeleteAttachment.sql" />
|
<Build Include="dbo\Stored Procedures\Cipher_DeleteAttachment.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<RefactorLog Include="Sql.refactorlog" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -12,8 +12,9 @@
|
|||||||
@UseTotp BIT,
|
@UseTotp BIT,
|
||||||
@Storage BIGINT,
|
@Storage BIGINT,
|
||||||
@MaxStorageGb SMALLINT,
|
@MaxStorageGb SMALLINT,
|
||||||
@StripeCustomerId VARCHAR(50),
|
@Gateway TINYINT,
|
||||||
@StripeSubscriptionId VARCHAR(50),
|
@GatewayCustomerId VARCHAR(50),
|
||||||
|
@GatewaySubscriptionId VARCHAR(50),
|
||||||
@Enabled BIT,
|
@Enabled BIT,
|
||||||
@CreationDate DATETIME2(7),
|
@CreationDate DATETIME2(7),
|
||||||
@RevisionDate DATETIME2(7)
|
@RevisionDate DATETIME2(7)
|
||||||
@ -36,8 +37,9 @@ BEGIN
|
|||||||
[UseTotp],
|
[UseTotp],
|
||||||
[Storage],
|
[Storage],
|
||||||
[MaxStorageGb],
|
[MaxStorageGb],
|
||||||
[StripeCustomerId],
|
[Gateway],
|
||||||
[StripeSubscriptionId],
|
[GatewayCustomerId],
|
||||||
|
[GatewaySubscriptionId],
|
||||||
[Enabled],
|
[Enabled],
|
||||||
[CreationDate],
|
[CreationDate],
|
||||||
[RevisionDate]
|
[RevisionDate]
|
||||||
@ -57,8 +59,9 @@ BEGIN
|
|||||||
@UseTotp,
|
@UseTotp,
|
||||||
@Storage,
|
@Storage,
|
||||||
@MaxStorageGb,
|
@MaxStorageGb,
|
||||||
@StripeCustomerId,
|
@Gateway,
|
||||||
@StripeSubscriptionId,
|
@GatewayCustomerId,
|
||||||
|
@GatewaySubscriptionId,
|
||||||
@Enabled,
|
@Enabled,
|
||||||
@CreationDate,
|
@CreationDate,
|
||||||
@RevisionDate
|
@RevisionDate
|
||||||
|
@ -12,8 +12,9 @@
|
|||||||
@UseTotp BIT,
|
@UseTotp BIT,
|
||||||
@Storage BIGINT,
|
@Storage BIGINT,
|
||||||
@MaxStorageGb SMALLINT,
|
@MaxStorageGb SMALLINT,
|
||||||
@StripeCustomerId VARCHAR(50),
|
@Gateway TINYINT,
|
||||||
@StripeSubscriptionId VARCHAR(50),
|
@GatewayCustomerId VARCHAR(50),
|
||||||
|
@GatewaySubscriptionId VARCHAR(50),
|
||||||
@Enabled BIT,
|
@Enabled BIT,
|
||||||
@CreationDate DATETIME2(7),
|
@CreationDate DATETIME2(7),
|
||||||
@RevisionDate DATETIME2(7)
|
@RevisionDate DATETIME2(7)
|
||||||
@ -37,8 +38,9 @@ BEGIN
|
|||||||
[UseTotp] = @UseTotp,
|
[UseTotp] = @UseTotp,
|
||||||
[Storage] = @Storage,
|
[Storage] = @Storage,
|
||||||
[MaxStorageGb] = @MaxStorageGb,
|
[MaxStorageGb] = @MaxStorageGb,
|
||||||
[StripeCustomerId] = @StripeCustomerId,
|
[Gateway] = @Gateway,
|
||||||
[StripeSubscriptionId] = @StripeSubscriptionId,
|
[GatewayCustomerId] = @GatewayCustomerId,
|
||||||
|
[GatewaySubscriptionId] = @GatewaySubscriptionId,
|
||||||
[Enabled] = @Enabled,
|
[Enabled] = @Enabled,
|
||||||
[CreationDate] = @CreationDate,
|
[CreationDate] = @CreationDate,
|
||||||
[RevisionDate] = @RevisionDate
|
[RevisionDate] = @RevisionDate
|
||||||
|
@ -18,8 +18,9 @@
|
|||||||
@Premium BIT,
|
@Premium BIT,
|
||||||
@Storage BIGINT,
|
@Storage BIGINT,
|
||||||
@MaxStorageGb SMALLINT,
|
@MaxStorageGb SMALLINT,
|
||||||
@StripeCustomerId VARCHAR(50),
|
@Gateway TINYINT,
|
||||||
@StripeSubscriptionId VARCHAR(50),
|
@GatewayCustomerId VARCHAR(50),
|
||||||
|
@GatewaySubscriptionId VARCHAR(50),
|
||||||
@CreationDate DATETIME2(7),
|
@CreationDate DATETIME2(7),
|
||||||
@RevisionDate DATETIME2(7)
|
@RevisionDate DATETIME2(7)
|
||||||
AS
|
AS
|
||||||
@ -47,8 +48,9 @@ BEGIN
|
|||||||
[Premium],
|
[Premium],
|
||||||
[Storage],
|
[Storage],
|
||||||
[MaxStorageGb],
|
[MaxStorageGb],
|
||||||
[StripeCustomerId],
|
[Gateway],
|
||||||
[StripeSubscriptionId],
|
[GatewayCustomerId],
|
||||||
|
[GatewaySubscriptionId],
|
||||||
[CreationDate],
|
[CreationDate],
|
||||||
[RevisionDate]
|
[RevisionDate]
|
||||||
)
|
)
|
||||||
@ -73,8 +75,9 @@ BEGIN
|
|||||||
@Premium,
|
@Premium,
|
||||||
@Storage,
|
@Storage,
|
||||||
@MaxStorageGb,
|
@MaxStorageGb,
|
||||||
@StripeCustomerId,
|
@Gateway,
|
||||||
@StripeSubscriptionId,
|
@GatewayCustomerId,
|
||||||
|
@GatewaySubscriptionId,
|
||||||
@CreationDate,
|
@CreationDate,
|
||||||
@RevisionDate
|
@RevisionDate
|
||||||
)
|
)
|
||||||
|
@ -18,8 +18,9 @@
|
|||||||
@Premium BIT,
|
@Premium BIT,
|
||||||
@Storage BIGINT,
|
@Storage BIGINT,
|
||||||
@MaxStorageGb SMALLINT,
|
@MaxStorageGb SMALLINT,
|
||||||
@StripeCustomerId VARCHAR(50),
|
@Gateway TINYINT,
|
||||||
@StripeSubscriptionId VARCHAR(50),
|
@GatewayCustomerId VARCHAR(50),
|
||||||
|
@GatewaySubscriptionId VARCHAR(50),
|
||||||
@CreationDate DATETIME2(7),
|
@CreationDate DATETIME2(7),
|
||||||
@RevisionDate DATETIME2(7)
|
@RevisionDate DATETIME2(7)
|
||||||
AS
|
AS
|
||||||
@ -47,8 +48,9 @@ BEGIN
|
|||||||
[Premium] = @Premium,
|
[Premium] = @Premium,
|
||||||
[Storage] = @Storage,
|
[Storage] = @Storage,
|
||||||
[MaxStorageGb] = @MaxStorageGb,
|
[MaxStorageGb] = @MaxStorageGb,
|
||||||
[StripeCustomerId] = @StripeCustomerId,
|
[Gateway] = @Gateway,
|
||||||
[StripeSubscriptionId] = @StripeSubscriptionId,
|
[GatewayCustomerId] = @GatewayCustomerId,
|
||||||
|
[GatewaySubscriptionId] = @GatewaySubscriptionId,
|
||||||
[CreationDate] = @CreationDate,
|
[CreationDate] = @CreationDate,
|
||||||
[RevisionDate] = @RevisionDate
|
[RevisionDate] = @RevisionDate
|
||||||
WHERE
|
WHERE
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
CREATE TABLE [dbo].[Organization] (
|
CREATE TABLE [dbo].[Organization] (
|
||||||
[Id] UNIQUEIDENTIFIER NOT NULL,
|
[Id] UNIQUEIDENTIFIER NOT NULL,
|
||||||
[Name] NVARCHAR (50) NOT NULL,
|
[Name] NVARCHAR (50) NOT NULL,
|
||||||
[BusinessName] NVARCHAR (50) NULL,
|
[BusinessName] NVARCHAR (50) NULL,
|
||||||
[BillingEmail] NVARCHAR (50) NOT NULL,
|
[BillingEmail] NVARCHAR (50) NOT NULL,
|
||||||
[Plan] NVARCHAR (50) NOT NULL,
|
[Plan] NVARCHAR (50) NOT NULL,
|
||||||
[PlanType] TINYINT NOT NULL,
|
[PlanType] TINYINT NOT NULL,
|
||||||
[Seats] SMALLINT NULL,
|
[Seats] SMALLINT NULL,
|
||||||
[MaxCollections] SMALLINT NULL,
|
[MaxCollections] SMALLINT NULL,
|
||||||
[UseGroups] BIT NOT NULL,
|
[UseGroups] BIT NOT NULL,
|
||||||
[UseDirectory] BIT NOT NULL,
|
[UseDirectory] BIT NOT NULL,
|
||||||
[UseTotp] BIT NOT NULL,
|
[UseTotp] BIT NOT NULL,
|
||||||
[Storage] BIGINT NULL,
|
[Storage] BIGINT NULL,
|
||||||
[MaxStorageGb] SMALLINT NULL,
|
[MaxStorageGb] SMALLINT NULL,
|
||||||
[StripeCustomerId] VARCHAR (50) NULL,
|
[Gateway] TINYINT NULL,
|
||||||
[StripeSubscriptionId] VARCHAR (50) NULL,
|
[GatewayCustomerId] VARCHAR (50) NULL,
|
||||||
[Enabled] BIT NOT NULL,
|
[GatewaySubscriptionId] VARCHAR (50) NULL,
|
||||||
[CreationDate] DATETIME2 (7) NOT NULL,
|
[Enabled] BIT NOT NULL,
|
||||||
[RevisionDate] DATETIME2 (7) NOT NULL,
|
[CreationDate] DATETIME2 (7) NOT NULL,
|
||||||
|
[RevisionDate] DATETIME2 (7) NOT NULL,
|
||||||
CONSTRAINT [PK_Organization] PRIMARY KEY CLUSTERED ([Id] ASC)
|
CONSTRAINT [PK_Organization] PRIMARY KEY CLUSTERED ([Id] ASC)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -18,8 +18,9 @@
|
|||||||
[Premium] BIT NOT NULL,
|
[Premium] BIT NOT NULL,
|
||||||
[Storage] BIGINT NULL,
|
[Storage] BIGINT NULL,
|
||||||
[MaxStorageGb] SMALLINT NULL,
|
[MaxStorageGb] SMALLINT NULL,
|
||||||
[StripeCustomerId] VARCHAR (50) NULL,
|
[Gateway] TINYINT NULL,
|
||||||
[StripeSubscriptionId] VARCHAR (50) NULL,
|
[GatewayCustomerId] VARCHAR (50) NULL,
|
||||||
|
[GatewaySubscriptionId] VARCHAR (50) NULL,
|
||||||
[CreationDate] DATETIME2 (7) NOT NULL,
|
[CreationDate] DATETIME2 (7) NOT NULL,
|
||||||
[RevisionDate] DATETIME2 (7) NOT NULL,
|
[RevisionDate] DATETIME2 (7) NOT NULL,
|
||||||
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED ([Id] ASC)
|
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED ([Id] ASC)
|
||||||
|
55
util/SqlUpdate/2017-07-28_00_Gateways.sql
Normal file
55
util/SqlUpdate/2017-07-28_00_Gateways.sql
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
EXEC sp_rename 'dbo.User.StripeSubscriptionId', 'GatewaySubscriptionId', 'COLUMN';
|
||||||
|
GO
|
||||||
|
EXEC sp_rename 'dbo.User.StripeCustomerId', 'GatewayCustomerId', 'COLUMN';
|
||||||
|
GO
|
||||||
|
|
||||||
|
EXEC sp_rename 'dbo.Organization.StripeSubscriptionId', 'GatewaySubscriptionId', 'COLUMN';
|
||||||
|
GO
|
||||||
|
EXEC sp_rename 'dbo.Organization.StripeCustomerId', 'GatewayCustomerId', 'COLUMN';
|
||||||
|
GO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
alter table [user] add [Gateway] TINYINT NULL
|
||||||
|
go
|
||||||
|
|
||||||
|
alter table [organization] add [Gateway] TINYINT NULL
|
||||||
|
go
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
update [user] set [Gateway] = 0 where GatewaySubscriptionId IS NOT NULL
|
||||||
|
go
|
||||||
|
|
||||||
|
update [organization] set [Gateway] = 0 where GatewaySubscriptionId IS NOT NULL
|
||||||
|
go
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
drop view [dbo].[OrganizationView]
|
||||||
|
go
|
||||||
|
|
||||||
|
CREATE VIEW [dbo].[OrganizationView]
|
||||||
|
AS
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
[dbo].[Organization]
|
||||||
|
GO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
drop view [dbo].[UserView]
|
||||||
|
go
|
||||||
|
|
||||||
|
CREATE VIEW [dbo].[UserView]
|
||||||
|
AS
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
[dbo].[User]
|
||||||
|
GO
|
Loading…
Reference in New Issue
Block a user