From e9174ba9f48e91046aff470873739d8a1fcb686b Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 19 Sep 2019 08:46:26 -0400 Subject: [PATCH] iap pre-purchase check --- .../Api/Request/IapCheckRequestModel.cs | 21 +++++++++++++++++ src/Core/Models/Business/BillingInfo.cs | 2 ++ src/Core/Services/IUserService.cs | 1 + .../Services/Implementations/UserService.cs | 23 +++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 src/Core/Models/Api/Request/IapCheckRequestModel.cs diff --git a/src/Core/Models/Api/Request/IapCheckRequestModel.cs b/src/Core/Models/Api/Request/IapCheckRequestModel.cs new file mode 100644 index 0000000000..c96a02486c --- /dev/null +++ b/src/Core/Models/Api/Request/IapCheckRequestModel.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Bit.Core.Enums; + +namespace Bit.Core.Models.Api +{ + public class IapCheckRequestModel : IValidatableObject + { + [Required] + public PaymentMethodType? PaymentMethodType { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) + { + if(PaymentMethodType != Enums.PaymentMethodType.AppleInApp) + { + yield return new ValidationResult("Not a supported in-app purchase payment method.", + new string[] { nameof(PaymentMethodType) }); + } + } + } +} diff --git a/src/Core/Models/Business/BillingInfo.cs b/src/Core/Models/Business/BillingInfo.cs index 8629698a86..b94d44ba7b 100644 --- a/src/Core/Models/Business/BillingInfo.cs +++ b/src/Core/Models/Business/BillingInfo.cs @@ -15,6 +15,8 @@ namespace Bit.Core.Models.Business public class BillingSource { + public BillingSource() { } + public BillingSource(PaymentMethod method) { if(method.Card != null) diff --git a/src/Core/Services/IUserService.cs b/src/Core/Services/IUserService.cs index 936abb9533..b4486b6564 100644 --- a/src/Core/Services/IUserService.cs +++ b/src/Core/Services/IUserService.cs @@ -45,6 +45,7 @@ namespace Bit.Core.Services Task SendDeleteConfirmationAsync(string email); Task> SignUpPremiumAsync(User user, string paymentToken, PaymentMethodType paymentMethodType, short additionalStorageGb, UserLicense license); + Task IapCheckAsync(User user, PaymentMethodType paymentMethodType); Task UpdateLicenseAsync(User user, UserLicense license); Task AdjustStorageAsync(User user, short storageAdjustmentGb); Task ReplacePaymentMethodAsync(User user, string paymentToken, PaymentMethodType paymentMethodType); diff --git a/src/Core/Services/Implementations/UserService.cs b/src/Core/Services/Implementations/UserService.cs index e1e297fcc9..40a213abf3 100644 --- a/src/Core/Services/Implementations/UserService.cs +++ b/src/Core/Services/Implementations/UserService.cs @@ -751,6 +751,29 @@ namespace Bit.Core.Services paymentIntentClientSecret); } + public async Task IapCheckAsync(User user, PaymentMethodType paymentMethodType) + { + if(paymentMethodType != PaymentMethodType.AppleInApp) + { + throw new BadRequestException("Payment method not supported for in-app purchases."); + } + + if(user.Premium) + { + throw new BadRequestException("Already a premium user."); + } + + if(!string.IsNullOrWhiteSpace(user.GatewayCustomerId)) + { + var customerService = new Stripe.CustomerService(); + var customer = await customerService.GetAsync(user.GatewayCustomerId); + if(customer != null && customer.Balance != 0) + { + throw new BadRequestException("Customer balance cannot exist when using in-app purchases."); + } + } + } + public async Task UpdateLicenseAsync(User user, UserLicense license) { if(!_globalSettings.SelfHosted)