mirror of
https://github.com/bitwarden/server.git
synced 2025-05-20 11:04:31 -05:00
process credit from ipn
This commit is contained in:
parent
312ced0e3b
commit
494b3f18b6
@ -1,6 +1,8 @@
|
|||||||
using Bit.Billing.Utilities;
|
using Bit.Billing.Utilities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models.Table;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -18,17 +20,29 @@ namespace Bit.Billing.Controllers
|
|||||||
private readonly PayPalClient _paypalClient;
|
private readonly PayPalClient _paypalClient;
|
||||||
private readonly PayPalIpnClient _paypalIpnClient;
|
private readonly PayPalIpnClient _paypalIpnClient;
|
||||||
private readonly ITransactionRepository _transactionRepository;
|
private readonly ITransactionRepository _transactionRepository;
|
||||||
|
private readonly IOrganizationRepository _organizationRepository;
|
||||||
|
private readonly IUserRepository _userRepository;
|
||||||
|
private readonly IMailService _mailService;
|
||||||
|
private readonly IPaymentService _paymentService;
|
||||||
|
|
||||||
public PayPalController(
|
public PayPalController(
|
||||||
IOptions<BillingSettings> billingSettings,
|
IOptions<BillingSettings> billingSettings,
|
||||||
PayPalClient paypalClient,
|
PayPalClient paypalClient,
|
||||||
PayPalIpnClient paypalIpnClient,
|
PayPalIpnClient paypalIpnClient,
|
||||||
ITransactionRepository transactionRepository)
|
ITransactionRepository transactionRepository,
|
||||||
|
IOrganizationRepository organizationRepository,
|
||||||
|
IUserRepository userRepository,
|
||||||
|
IMailService mailService,
|
||||||
|
IPaymentService paymentService)
|
||||||
{
|
{
|
||||||
_billingSettings = billingSettings?.Value;
|
_billingSettings = billingSettings?.Value;
|
||||||
_paypalClient = paypalClient;
|
_paypalClient = paypalClient;
|
||||||
_paypalIpnClient = paypalIpnClient;
|
_paypalIpnClient = paypalIpnClient;
|
||||||
_transactionRepository = transactionRepository;
|
_transactionRepository = transactionRepository;
|
||||||
|
_organizationRepository = organizationRepository;
|
||||||
|
_userRepository = userRepository;
|
||||||
|
_mailService = mailService;
|
||||||
|
_paymentService = paymentService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("webhook")]
|
[HttpPost("webhook")]
|
||||||
@ -197,7 +211,7 @@ namespace Bit.Billing.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _transactionRepository.CreateAsync(new Core.Models.Table.Transaction
|
var tx = new Transaction
|
||||||
{
|
{
|
||||||
Amount = ipnTransaction.McGross,
|
Amount = ipnTransaction.McGross,
|
||||||
CreationDate = ipnTransaction.PaymentDate,
|
CreationDate = ipnTransaction.PaymentDate,
|
||||||
@ -208,11 +222,35 @@ namespace Bit.Billing.Controllers
|
|||||||
GatewayId = ipnTransaction.TxnId,
|
GatewayId = ipnTransaction.TxnId,
|
||||||
PaymentMethodType = PaymentMethodType.PayPal,
|
PaymentMethodType = PaymentMethodType.PayPal,
|
||||||
Details = ipnTransaction.TxnId
|
Details = ipnTransaction.TxnId
|
||||||
});
|
};
|
||||||
|
await _transactionRepository.CreateAsync(tx);
|
||||||
|
|
||||||
if(ipnTransaction.IsAccountCredit())
|
if(ipnTransaction.IsAccountCredit())
|
||||||
{
|
{
|
||||||
// TODO: Issue Stripe credit to user/org account
|
if(tx.OrganizationId.HasValue)
|
||||||
|
{
|
||||||
|
var org = await _organizationRepository.GetByIdAsync(tx.OrganizationId.Value);
|
||||||
|
if(org != null)
|
||||||
|
{
|
||||||
|
if(await _paymentService.CreditAccountAsync(org, tx.Amount))
|
||||||
|
{
|
||||||
|
await _organizationRepository.ReplaceAsync(org);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var user = await _userRepository.GetByIdAsync(tx.UserId.Value);
|
||||||
|
if(user != null)
|
||||||
|
{
|
||||||
|
if(await _paymentService.CreditAccountAsync(user, tx.Amount))
|
||||||
|
{
|
||||||
|
await _userRepository.ReplaceAsync(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Send email about credit added?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Catch foreign key violations because user/org could have been deleted.
|
// Catch foreign key violations because user/org could have been deleted.
|
||||||
@ -246,7 +284,7 @@ namespace Bit.Billing.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
await _transactionRepository.ReplaceAsync(parentTransaction);
|
await _transactionRepository.ReplaceAsync(parentTransaction);
|
||||||
await _transactionRepository.CreateAsync(new Core.Models.Table.Transaction
|
await _transactionRepository.CreateAsync(new Transaction
|
||||||
{
|
{
|
||||||
Amount = ipnTransaction.McGross,
|
Amount = ipnTransaction.McGross,
|
||||||
CreationDate = ipnTransaction.PaymentDate,
|
CreationDate = ipnTransaction.PaymentDate,
|
||||||
|
@ -17,6 +17,7 @@ namespace Bit.Core.Services
|
|||||||
Task ReinstateSubscriptionAsync(ISubscriber subscriber);
|
Task ReinstateSubscriptionAsync(ISubscriber subscriber);
|
||||||
Task<bool> UpdatePaymentMethodAsync(ISubscriber subscriber, PaymentMethodType paymentMethodType,
|
Task<bool> UpdatePaymentMethodAsync(ISubscriber subscriber, PaymentMethodType paymentMethodType,
|
||||||
string paymentToken);
|
string paymentToken);
|
||||||
|
Task<bool> CreditAccountAsync(ISubscriber subscriber, decimal creditAmount);
|
||||||
Task<BillingInfo> GetBillingAsync(ISubscriber subscriber);
|
Task<BillingInfo> GetBillingAsync(ISubscriber subscriber);
|
||||||
Task<SubscriptionInfo> GetSubscriptionAsync(ISubscriber subscriber);
|
Task<SubscriptionInfo> GetSubscriptionAsync(ISubscriber subscriber);
|
||||||
}
|
}
|
||||||
|
@ -915,6 +915,33 @@ namespace Bit.Core.Services
|
|||||||
return createdCustomer;
|
return createdCustomer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> CreditAccountAsync(ISubscriber subscriber, decimal creditAmount)
|
||||||
|
{
|
||||||
|
var customerService = new CustomerService();
|
||||||
|
Customer customer = null;
|
||||||
|
var customerExists = subscriber.Gateway == GatewayType.Stripe &&
|
||||||
|
!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId);
|
||||||
|
if(customerExists)
|
||||||
|
{
|
||||||
|
customer = await customerService.GetAsync(subscriber.GatewaySubscriptionId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
customer = await customerService.CreateAsync(new CustomerCreateOptions
|
||||||
|
{
|
||||||
|
Email = subscriber.BillingEmailAddress(),
|
||||||
|
Description = subscriber.BillingName(),
|
||||||
|
});
|
||||||
|
subscriber.Gateway = GatewayType.Stripe;
|
||||||
|
subscriber.GatewayCustomerId = customer.Id;
|
||||||
|
}
|
||||||
|
await customerService.UpdateAsync(customer.Id, new CustomerUpdateOptions
|
||||||
|
{
|
||||||
|
AccountBalance = customer.AccountBalance - (long)(creditAmount * 100)
|
||||||
|
});
|
||||||
|
return !customerExists;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<BillingInfo> GetBillingAsync(ISubscriber subscriber)
|
public async Task<BillingInfo> GetBillingAsync(ISubscriber subscriber)
|
||||||
{
|
{
|
||||||
var billingInfo = new BillingInfo();
|
var billingInfo = new BillingInfo();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user