1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-04 01:22:50 -05:00

[PM-5548] Eliminate in-app purchase logic (#3640)

* Eliminate in-app purchase logic

* Totally remove obsolete and unused properties / types

* Remove unused enum values

* Restore token update
This commit is contained in:
Matt Bishop
2024-01-11 15:26:32 -05:00
committed by GitHub
parent b9c6e00c2d
commit 23f9d2261d
20 changed files with 19 additions and 809 deletions

View File

@ -30,7 +30,6 @@ namespace Bit.Billing.Controllers;
[Route("stripe")]
public class StripeController : Controller
{
private const decimal PremiumPlanAppleIapPrice = 14.99M;
private const string PremiumPlanId = "premium-annually";
private const string PremiumPlanIdAppStore = "premium-annually-app";
@ -42,7 +41,6 @@ public class StripeController : Controller
private readonly IOrganizationRepository _organizationRepository;
private readonly ITransactionRepository _transactionRepository;
private readonly IUserService _userService;
private readonly IAppleIapService _appleIapService;
private readonly IMailService _mailService;
private readonly ILogger<StripeController> _logger;
private readonly BraintreeGateway _btGateway;
@ -64,7 +62,6 @@ public class StripeController : Controller
IOrganizationRepository organizationRepository,
ITransactionRepository transactionRepository,
IUserService userService,
IAppleIapService appleIapService,
IMailService mailService,
IReferenceEventService referenceEventService,
ILogger<StripeController> logger,
@ -82,7 +79,6 @@ public class StripeController : Controller
_organizationRepository = organizationRepository;
_transactionRepository = transactionRepository;
_userService = userService;
_appleIapService = appleIapService;
_mailService = mailService;
_referenceEventService = referenceEventService;
_taxRateRepository = taxRateRepository;
@ -681,10 +677,6 @@ public class StripeController : Controller
{
var customerService = new CustomerService();
var customer = await customerService.GetAsync(invoice.CustomerId);
if (customer?.Metadata?.ContainsKey("appleReceipt") ?? false)
{
return await AttemptToPayInvoiceWithAppleReceiptAsync(invoice, customer);
}
if (customer?.Metadata?.ContainsKey("btCustomerId") ?? false)
{
@ -699,99 +691,6 @@ public class StripeController : Controller
return false;
}
private async Task<bool> AttemptToPayInvoiceWithAppleReceiptAsync(Invoice invoice, Customer customer)
{
if (!customer?.Metadata?.ContainsKey("appleReceipt") ?? true)
{
return false;
}
var originalAppleReceiptTransactionId = customer.Metadata["appleReceipt"];
var appleReceiptRecord = await _appleIapService.GetReceiptAsync(originalAppleReceiptTransactionId);
if (string.IsNullOrWhiteSpace(appleReceiptRecord?.Item1) || !appleReceiptRecord.Item2.HasValue)
{
return false;
}
var subscriptionService = new SubscriptionService();
var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId);
var ids = GetIdsFromMetaData(subscription?.Metadata);
if (!ids.Item2.HasValue)
{
// Apple receipt is only for user subscriptions
return false;
}
if (appleReceiptRecord.Item2.Value != ids.Item2.Value)
{
_logger.LogError("User Ids for Apple Receipt and subscription do not match: {0} != {1}.",
appleReceiptRecord.Item2.Value, ids.Item2.Value);
return false;
}
var appleReceiptStatus = await _appleIapService.GetVerifiedReceiptStatusAsync(appleReceiptRecord.Item1);
if (appleReceiptStatus == null)
{
// TODO: cancel sub if receipt is cancelled?
return false;
}
var receiptExpiration = appleReceiptStatus.GetLastExpiresDate().GetValueOrDefault(DateTime.MinValue);
var invoiceDue = invoice.DueDate.GetValueOrDefault(DateTime.MinValue);
if (receiptExpiration <= invoiceDue)
{
_logger.LogWarning("Apple receipt expiration is before invoice due date. {0} <= {1}",
receiptExpiration, invoiceDue);
return false;
}
var receiptLastTransactionId = appleReceiptStatus.GetLastTransactionId();
var existingTransaction = await _transactionRepository.GetByGatewayIdAsync(
GatewayType.AppStore, receiptLastTransactionId);
if (existingTransaction != null)
{
_logger.LogWarning("There is already an existing transaction for this Apple receipt.",
receiptLastTransactionId);
return false;
}
var appleTransaction = appleReceiptStatus.BuildTransactionFromLastTransaction(
PremiumPlanAppleIapPrice, ids.Item2.Value);
appleTransaction.Type = TransactionType.Charge;
var invoiceService = new InvoiceService();
try
{
await invoiceService.UpdateAsync(invoice.Id, new InvoiceUpdateOptions
{
Metadata = new Dictionary<string, string>
{
["appleReceipt"] = appleReceiptStatus.GetOriginalTransactionId(),
["appleReceiptTransactionId"] = receiptLastTransactionId
}
});
await _transactionRepository.CreateAsync(appleTransaction);
await invoiceService.PayAsync(invoice.Id, new InvoicePayOptions { PaidOutOfBand = true });
}
catch (Exception e)
{
if (e.Message.Contains("Invoice is already paid"))
{
await invoiceService.UpdateAsync(invoice.Id, new InvoiceUpdateOptions
{
Metadata = invoice.Metadata
});
}
else
{
throw;
}
}
return true;
}
private async Task<bool> AttemptToPayInvoiceWithBraintreeAsync(Invoice invoice, Customer customer)
{
_logger.LogDebug("Attempting to pay invoice with Braintree");