mirror of
https://github.com/bitwarden/server.git
synced 2025-05-20 19:14:32 -05:00
stripe charge hooks and fixes to pp refunds
This commit is contained in:
parent
1bf1d83b26
commit
4ade9a229b
@ -73,7 +73,8 @@ namespace Bit.Billing.Controllers
|
|||||||
Type = sale.GetCreditFromCustom() ? TransactionType.Credit : TransactionType.Charge,
|
Type = sale.GetCreditFromCustom() ? TransactionType.Credit : TransactionType.Charge,
|
||||||
Gateway = GatewayType.PayPal,
|
Gateway = GatewayType.PayPal,
|
||||||
GatewayId = sale.Id,
|
GatewayId = sale.Id,
|
||||||
PaymentMethodType = PaymentMethodType.PayPal
|
PaymentMethodType = PaymentMethodType.PayPal,
|
||||||
|
Details = sale.Id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,6 +87,20 @@ namespace Bit.Billing.Controllers
|
|||||||
GatewayType.PayPal, refund.Id);
|
GatewayType.PayPal, refund.Id);
|
||||||
if(refundTransaction == null)
|
if(refundTransaction == null)
|
||||||
{
|
{
|
||||||
|
var saleTransaction = await _transactionRepository.GetByGatewayIdAsync(
|
||||||
|
GatewayType.PayPal, refund.SaleId);
|
||||||
|
if(saleTransaction == null)
|
||||||
|
{
|
||||||
|
return new BadRequestResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
saleTransaction.RefundedAmount = refund.TotalRefundedAmount.ValueAmount;
|
||||||
|
if(saleTransaction.RefundedAmount == saleTransaction.Amount)
|
||||||
|
{
|
||||||
|
saleTransaction.Refunded = true;
|
||||||
|
}
|
||||||
|
await _transactionRepository.ReplaceAsync(saleTransaction);
|
||||||
|
|
||||||
var ids = refund.GetIdsFromCustom();
|
var ids = refund.GetIdsFromCustom();
|
||||||
if(ids.Item1.HasValue || ids.Item2.HasValue)
|
if(ids.Item1.HasValue || ids.Item2.HasValue)
|
||||||
{
|
{
|
||||||
@ -98,18 +113,10 @@ namespace Bit.Billing.Controllers
|
|||||||
Type = TransactionType.Refund,
|
Type = TransactionType.Refund,
|
||||||
Gateway = GatewayType.PayPal,
|
Gateway = GatewayType.PayPal,
|
||||||
GatewayId = refund.Id,
|
GatewayId = refund.Id,
|
||||||
PaymentMethodType = PaymentMethodType.PayPal
|
PaymentMethodType = PaymentMethodType.PayPal,
|
||||||
|
Details = refund.Id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var saleTransaction = await _transactionRepository.GetByGatewayIdAsync(
|
|
||||||
GatewayType.PayPal, refund.SaleId);
|
|
||||||
if(saleTransaction != null)
|
|
||||||
{
|
|
||||||
saleTransaction.Refunded = true;
|
|
||||||
saleTransaction.RefundedAmount = refund.TotalRefundedAmount.ValueAmount;
|
|
||||||
await _transactionRepository.ReplaceAsync(saleTransaction);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Bit.Core.Models.Table;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models.Table;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -20,6 +21,7 @@ namespace Bit.Billing.Controllers
|
|||||||
private readonly IHostingEnvironment _hostingEnvironment;
|
private readonly IHostingEnvironment _hostingEnvironment;
|
||||||
private readonly IOrganizationService _organizationService;
|
private readonly IOrganizationService _organizationService;
|
||||||
private readonly IOrganizationRepository _organizationRepository;
|
private readonly IOrganizationRepository _organizationRepository;
|
||||||
|
private readonly ITransactionRepository _transactionRepository;
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly IMailService _mailService;
|
private readonly IMailService _mailService;
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ namespace Bit.Billing.Controllers
|
|||||||
IHostingEnvironment hostingEnvironment,
|
IHostingEnvironment hostingEnvironment,
|
||||||
IOrganizationService organizationService,
|
IOrganizationService organizationService,
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
|
ITransactionRepository transactionRepository,
|
||||||
IUserService userService,
|
IUserService userService,
|
||||||
IMailService mailService)
|
IMailService mailService)
|
||||||
{
|
{
|
||||||
@ -35,6 +38,7 @@ namespace Bit.Billing.Controllers
|
|||||||
_hostingEnvironment = hostingEnvironment;
|
_hostingEnvironment = hostingEnvironment;
|
||||||
_organizationService = organizationService;
|
_organizationService = organizationService;
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
|
_transactionRepository = transactionRepository;
|
||||||
_userService = userService;
|
_userService = userService;
|
||||||
_mailService = mailService;
|
_mailService = mailService;
|
||||||
}
|
}
|
||||||
@ -65,7 +69,6 @@ namespace Bit.Billing.Controllers
|
|||||||
return new BadRequestResult();
|
return new BadRequestResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
var invUpcoming = parsedEvent.Type.Equals("invoice.upcoming");
|
|
||||||
var subDeleted = parsedEvent.Type.Equals("customer.subscription.deleted");
|
var subDeleted = parsedEvent.Type.Equals("customer.subscription.deleted");
|
||||||
var subUpdated = parsedEvent.Type.Equals("customer.subscription.updated");
|
var subUpdated = parsedEvent.Type.Equals("customer.subscription.updated");
|
||||||
|
|
||||||
@ -112,7 +115,7 @@ namespace Bit.Billing.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(invUpcoming)
|
else if(parsedEvent.Type.Equals("invoice.upcoming"))
|
||||||
{
|
{
|
||||||
var invoice = parsedEvent.Data.Object as Invoice;
|
var invoice = parsedEvent.Data.Object as Invoice;
|
||||||
if(invoice == null)
|
if(invoice == null)
|
||||||
@ -155,6 +158,115 @@ namespace Bit.Billing.Controllers
|
|||||||
invoice.NextPaymentAttempt.Value, items, ids.Item1.HasValue);
|
invoice.NextPaymentAttempt.Value, items, ids.Item1.HasValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(parsedEvent.Type.Equals("charge.succeeded"))
|
||||||
|
{
|
||||||
|
var charge = parsedEvent.Data.Object as Charge;
|
||||||
|
if(charge == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Charge is null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(charge.InvoiceId == null)
|
||||||
|
{
|
||||||
|
return new OkResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
var chargeTransaction = await _transactionRepository.GetByGatewayIdAsync(
|
||||||
|
GatewayType.Stripe, charge.Id);
|
||||||
|
if(chargeTransaction == null)
|
||||||
|
{
|
||||||
|
var invoiceService = new InvoiceService();
|
||||||
|
var invoice = await invoiceService.GetAsync(charge.InvoiceId);
|
||||||
|
if(invoice == null)
|
||||||
|
{
|
||||||
|
return new OkResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
var subscriptionService = new SubscriptionService();
|
||||||
|
var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId);
|
||||||
|
if(subscription == null)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
await _transactionRepository.CreateAsync(tx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(parsedEvent.Type.Equals("charge.refunded"))
|
||||||
|
{
|
||||||
|
var charge = parsedEvent.Data.Object as Charge;
|
||||||
|
if(charge == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Charge is null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var chargeTransaction = await _transactionRepository.GetByGatewayIdAsync(
|
||||||
|
GatewayType.Stripe, charge.Id);
|
||||||
|
if(chargeTransaction == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Cannot find refunded charge.");
|
||||||
|
}
|
||||||
|
|
||||||
|
chargeTransaction.RefundedAmount = charge.AmountRefunded / 100M;
|
||||||
|
if(charge.Refunded)
|
||||||
|
{
|
||||||
|
chargeTransaction.Refunded = true;
|
||||||
|
}
|
||||||
|
await _transactionRepository.ReplaceAsync(chargeTransaction);
|
||||||
|
|
||||||
|
foreach(var refund in charge.Refunds)
|
||||||
|
{
|
||||||
|
var refundTransaction = await _transactionRepository.GetByGatewayIdAsync(
|
||||||
|
GatewayType.Stripe, refund.Id);
|
||||||
|
if(refundTransaction != null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _transactionRepository.CreateAsync(new Transaction
|
||||||
|
{
|
||||||
|
Amount = refund.Amount / 100M,
|
||||||
|
CreationDate = refund.Created,
|
||||||
|
OrganizationId = chargeTransaction.OrganizationId,
|
||||||
|
UserId = chargeTransaction.UserId,
|
||||||
|
Type = TransactionType.Refund,
|
||||||
|
Gateway = GatewayType.Stripe,
|
||||||
|
GatewayId = refund.Id,
|
||||||
|
PaymentMethodType = chargeTransaction.PaymentMethodType,
|
||||||
|
Details = chargeTransaction.Details
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new OkResult();
|
return new OkResult();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user