mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 16:12:49 -05:00
paymentservice with stripe & braintree implem.
This commit is contained in:
72
src/Core/Services/Implementations/BraintreePaymentService.cs
Normal file
72
src/Core/Services/Implementations/BraintreePaymentService.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Table;
|
||||
using Braintree;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class BraintreePaymentService : IPaymentService
|
||||
{
|
||||
private readonly BraintreeGateway _gateway;
|
||||
|
||||
public BraintreePaymentService(
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
_gateway = new BraintreeGateway
|
||||
{
|
||||
Environment = globalSettings.Braintree.Production ?
|
||||
Braintree.Environment.PRODUCTION : Braintree.Environment.SANDBOX,
|
||||
MerchantId = globalSettings.Braintree.MerchantId,
|
||||
PublicKey = globalSettings.Braintree.PublicKey,
|
||||
PrivateKey = globalSettings.Braintree.PrivateKey
|
||||
};
|
||||
}
|
||||
|
||||
public async Task PurchasePremiumAsync(User user, string paymentToken, short additionalStorageGb)
|
||||
{
|
||||
var customerResult = await _gateway.Customer.CreateAsync(new CustomerRequest
|
||||
{
|
||||
PaymentMethodNonce = paymentToken,
|
||||
Email = user.Email
|
||||
});
|
||||
|
||||
if(!customerResult.IsSuccess())
|
||||
{
|
||||
// error, throw something
|
||||
}
|
||||
|
||||
var subId = "u" + user.Id.ToString("N").ToLower() +
|
||||
Utilities.CoreHelpers.RandomString(3, upper: false, numeric: false);
|
||||
|
||||
var subRequest = new SubscriptionRequest
|
||||
{
|
||||
Id = subId,
|
||||
PaymentMethodToken = paymentToken,
|
||||
PlanId = "premium-annually"
|
||||
};
|
||||
|
||||
if(additionalStorageGb > 0)
|
||||
{
|
||||
subRequest.AddOns.Add = new AddAddOnRequest[]
|
||||
{
|
||||
new AddAddOnRequest
|
||||
{
|
||||
InheritedFromId = "storage-gb-annually",
|
||||
Quantity = additionalStorageGb
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var subResult = await _gateway.Subscription.CreateAsync(subRequest);
|
||||
|
||||
if(!subResult.IsSuccess())
|
||||
{
|
||||
await _gateway.Customer.DeleteAsync(customerResult.Target.Id);
|
||||
// error, throw something
|
||||
}
|
||||
|
||||
user.StripeCustomerId = customerResult.Target.Id;
|
||||
user.StripeSubscriptionId = subResult.Target.Id;
|
||||
}
|
||||
}
|
||||
}
|
70
src/Core/Services/Implementations/StripePaymentService.cs
Normal file
70
src/Core/Services/Implementations/StripePaymentService.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Table;
|
||||
using Stripe;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class StripePaymentService : IPaymentService
|
||||
{
|
||||
private const string PremiumPlanId = "premium-annually";
|
||||
private const string StoragePlanId = "storage-gb-annually";
|
||||
|
||||
public StripePaymentService(
|
||||
GlobalSettings globalSettings)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public async Task PurchasePremiumAsync(User user, string paymentToken, short additionalStorageGb)
|
||||
{
|
||||
var customerService = new StripeCustomerService();
|
||||
var customer = await customerService.CreateAsync(new StripeCustomerCreateOptions
|
||||
{
|
||||
Description = user.Name,
|
||||
Email = user.Email,
|
||||
SourceToken = paymentToken
|
||||
});
|
||||
|
||||
var subCreateOptions = new StripeSubscriptionCreateOptions
|
||||
{
|
||||
Items = new List<StripeSubscriptionItemOption>(),
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
["userId"] = user.Id.ToString()
|
||||
}
|
||||
};
|
||||
|
||||
subCreateOptions.Items.Add(new StripeSubscriptionItemOption
|
||||
{
|
||||
PlanId = PremiumPlanId,
|
||||
Quantity = 1
|
||||
});
|
||||
|
||||
if(additionalStorageGb > 0)
|
||||
{
|
||||
subCreateOptions.Items.Add(new StripeSubscriptionItemOption
|
||||
{
|
||||
PlanId = StoragePlanId,
|
||||
Quantity = additionalStorageGb
|
||||
});
|
||||
}
|
||||
|
||||
StripeSubscription subscription = null;
|
||||
try
|
||||
{
|
||||
var subscriptionService = new StripeSubscriptionService();
|
||||
subscription = await subscriptionService.CreateAsync(customer.Id, subCreateOptions);
|
||||
}
|
||||
catch(StripeException)
|
||||
{
|
||||
await customerService.DeleteAsync(customer.Id);
|
||||
throw;
|
||||
}
|
||||
|
||||
user.StripeCustomerId = customer.Id;
|
||||
user.StripeSubscriptionId = subscription.Id;
|
||||
}
|
||||
}
|
||||
}
|
@ -514,55 +514,12 @@ namespace Bit.Core.Services
|
||||
throw new BadRequestException("Already a premium user.");
|
||||
}
|
||||
|
||||
var customerService = new StripeCustomerService();
|
||||
var customer = await customerService.CreateAsync(new StripeCustomerCreateOptions
|
||||
{
|
||||
Description = user.Name,
|
||||
Email = user.Email,
|
||||
SourceToken = paymentToken
|
||||
});
|
||||
|
||||
var subCreateOptions = new StripeSubscriptionCreateOptions
|
||||
{
|
||||
Items = new List<StripeSubscriptionItemOption>(),
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
["userId"] = user.Id.ToString()
|
||||
}
|
||||
};
|
||||
|
||||
subCreateOptions.Items.Add(new StripeSubscriptionItemOption
|
||||
{
|
||||
PlanId = PremiumPlanId,
|
||||
Quantity = 1
|
||||
});
|
||||
|
||||
if(additionalStorageGb > 0)
|
||||
{
|
||||
subCreateOptions.Items.Add(new StripeSubscriptionItemOption
|
||||
{
|
||||
PlanId = StoragePlanId,
|
||||
Quantity = additionalStorageGb
|
||||
});
|
||||
}
|
||||
|
||||
StripeSubscription subscription = null;
|
||||
try
|
||||
{
|
||||
var subscriptionService = new StripeSubscriptionService();
|
||||
subscription = await subscriptionService.CreateAsync(customer.Id, subCreateOptions);
|
||||
}
|
||||
catch(StripeException)
|
||||
{
|
||||
await customerService.DeleteAsync(customer.Id);
|
||||
throw;
|
||||
}
|
||||
IPaymentService paymentService = new StripePaymentService(_globalSettings);
|
||||
await paymentService.PurchasePremiumAsync(user, paymentToken, additionalStorageGb);
|
||||
|
||||
user.Premium = true;
|
||||
user.MaxStorageGb = (short)(1 + additionalStorageGb);
|
||||
user.RevisionDate = DateTime.UtcNow;
|
||||
user.StripeCustomerId = customer.Id;
|
||||
user.StripeSubscriptionId = subscription.Id;
|
||||
|
||||
try
|
||||
{
|
||||
@ -570,7 +527,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
catch
|
||||
{
|
||||
await BillingHelpers.CancelAndRecoverChargesAsync(subscription.Id, customer.Id);
|
||||
await BillingHelpers.CancelAndRecoverChargesAsync(user.StripeSubscriptionId, user.StripeCustomerId);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user