diff --git a/src/Billing/Controllers/PayPalController.cs b/src/Billing/Controllers/PayPalController.cs index 2f456b54e..572887cac 100644 --- a/src/Billing/Controllers/PayPalController.cs +++ b/src/Billing/Controllers/PayPalController.cs @@ -47,7 +47,7 @@ namespace Bit.Billing.Controllers body = await reader.ReadToEndAsync(); } - if(body == null) + if(string.IsNullOrWhiteSpace(body)) { return new BadRequestResult(); } diff --git a/src/Billing/Controllers/StripeController.cs b/src/Billing/Controllers/StripeController.cs index 55ef492b3..1dfdaff5b 100644 --- a/src/Billing/Controllers/StripeController.cs +++ b/src/Billing/Controllers/StripeController.cs @@ -176,65 +176,79 @@ namespace Bit.Billing.Controllers throw new Exception("Charge is null."); } - if(charge.InvoiceId == null) + var chargeTransaction = await _transactionRepository.GetByGatewayIdAsync( + GatewayType.Stripe, charge.Id); + if(chargeTransaction != null) { return new OkResult(); } - var chargeTransaction = await _transactionRepository.GetByGatewayIdAsync( - GatewayType.Stripe, charge.Id); - if(chargeTransaction == null) + Tuple ids = null; + Subscription subscription = null; + var subscriptionService = new SubscriptionService(); + + if(charge.InvoiceId != null) { var invoiceService = new InvoiceService(); var invoice = await invoiceService.GetAsync(charge.InvoiceId); - if(invoice == null) + if(invoice?.SubscriptionId != null) + { + subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); + ids = GetIdsFromMetaData(subscription?.Metadata); + } + } + + if(subscription == null || ids == null || (ids.Item1.HasValue && ids.Item2.HasValue)) + { + var subscriptions = await subscriptionService.ListAsync(new SubscriptionListOptions + { + CustomerId = charge.CustomerId + }); + foreach(var sub in subscriptions) + { + ids = GetIdsFromMetaData(sub.Metadata); + if(ids.Item1.HasValue || ids.Item2.HasValue) + { + subscription = sub; + break; + } + } + } + + if(ids.Item1.HasValue || ids.Item2.HasValue) + { + var tx = new Transaction + { + Amount = charge.Amount / 100M, + CreationDate = charge.Created, + OrganizationId = ids.Item1, + UserId = ids.Item2, + Type = TransactionType.Charge, + Gateway = GatewayType.Stripe, + GatewayId = charge.Id + }; + + if(charge.Source is Card card) + { + tx.PaymentMethodType = PaymentMethodType.Card; + tx.Details = $"{card.Brand}, *{card.Last4}"; + } + else if(charge.Source is BankAccount bankAccount) + { + tx.PaymentMethodType = PaymentMethodType.BankAccount; + tx.Details = $"{bankAccount.BankName}, *{bankAccount.Last4}"; + } + else { return new OkResult(); } - var subscriptionService = new SubscriptionService(); - var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); - if(subscription == null) + try { - return new OkResult(); - } - - var ids = GetIdsFromMetaData(subscription.Metadata); - if(ids.Item1.HasValue || ids.Item2.HasValue) - { - var tx = new Transaction - { - Amount = charge.Amount / 100M, - CreationDate = charge.Created, - OrganizationId = ids.Item1, - UserId = ids.Item2, - Type = TransactionType.Charge, - Gateway = GatewayType.Stripe, - GatewayId = charge.Id - }; - - if(charge.Source is Card card) - { - tx.PaymentMethodType = PaymentMethodType.Card; - tx.Details = $"{card.Brand}, *{card.Last4}"; - } - else if(charge.Source is BankAccount bankAccount) - { - tx.PaymentMethodType = PaymentMethodType.BankAccount; - tx.Details = $"{bankAccount.BankName}, *{bankAccount.Last4}"; - } - else - { - return new OkResult(); - } - - try - { - await _transactionRepository.CreateAsync(tx); - } - // Catch foreign key violations because user/org could have been deleted. - catch(SqlException e) when(e.Number == 547) { } + await _transactionRepository.CreateAsync(tx); } + // Catch foreign key violations because user/org could have been deleted. + catch(SqlException e) when(e.Number == 547) { } } } else if(parsedEvent.Type.Equals("charge.refunded")) @@ -317,7 +331,7 @@ namespace Bit.Billing.Controllers private Tuple GetIdsFromMetaData(IDictionary metaData) { - if(metaData == null) + if(metaData == null || !metaData.Any()) { return new Tuple(null, null); } diff --git a/src/Billing/appsettings.Production.json b/src/Billing/appsettings.Production.json index 370128a2e..4679bf9ca 100644 --- a/src/Billing/appsettings.Production.json +++ b/src/Billing/appsettings.Production.json @@ -18,7 +18,7 @@ }, "billingSettings": { "payPal": { - "production": false + "production": true } } }