mirror of
https://github.com/bitwarden/server.git
synced 2025-04-16 02:28:13 -05:00
braintree webhooks
This commit is contained in:
parent
c2df445ac2
commit
f998b988ca
@ -4,5 +4,6 @@
|
|||||||
{
|
{
|
||||||
public virtual string StripeWebhookKey { get; set; }
|
public virtual string StripeWebhookKey { get; set; }
|
||||||
public virtual string StripeWebhookSecret { get; set; }
|
public virtual string StripeWebhookSecret { get; set; }
|
||||||
|
public virtual string BraintreeWebhookKey { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
142
src/Billing/Controllers/BraintreeController.cs
Normal file
142
src/Billing/Controllers/BraintreeController.cs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
using Bit.Core;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
using Braintree;
|
||||||
|
using Braintree.Exceptions;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bit.Billing.Controllers
|
||||||
|
{
|
||||||
|
[Route("braintree")]
|
||||||
|
public class BraintreeController : Controller
|
||||||
|
{
|
||||||
|
private static BraintreeGateway _gateway;
|
||||||
|
private readonly BillingSettings _billingSettings;
|
||||||
|
private readonly IHostingEnvironment _hostingEnvironment;
|
||||||
|
private readonly IOrganizationService _organizationService;
|
||||||
|
private readonly IUserService _userService;
|
||||||
|
|
||||||
|
public BraintreeController(
|
||||||
|
IOptions<BillingSettings> billingSettings,
|
||||||
|
GlobalSettings globalSettings,
|
||||||
|
IHostingEnvironment hostingEnvironment,
|
||||||
|
IOrganizationService organizationService,
|
||||||
|
IUserService userService)
|
||||||
|
{
|
||||||
|
if(_gateway == null)
|
||||||
|
{
|
||||||
|
_gateway = new BraintreeGateway
|
||||||
|
{
|
||||||
|
Environment = globalSettings.Braintree.Production ?
|
||||||
|
Braintree.Environment.PRODUCTION : Braintree.Environment.SANDBOX,
|
||||||
|
MerchantId = globalSettings.Braintree.MerchantId,
|
||||||
|
PublicKey = globalSettings.Braintree.PublicKey,
|
||||||
|
PrivateKey = globalSettings.Braintree.PrivateKey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_billingSettings = billingSettings?.Value;
|
||||||
|
_hostingEnvironment = hostingEnvironment;
|
||||||
|
_organizationService = organizationService;
|
||||||
|
_userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("webhook")]
|
||||||
|
public async Task<IActionResult> PostWebhook([FromQuery] string key)
|
||||||
|
{
|
||||||
|
if(key != _billingSettings.BraintreeWebhookKey)
|
||||||
|
{
|
||||||
|
return new BadRequestResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
var payload = Request.Form["bt_payload"];
|
||||||
|
var signature = Request.Form["bt_signature"];
|
||||||
|
|
||||||
|
WebhookNotification notification;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
notification = _gateway.WebhookNotification.Parse(signature, payload);
|
||||||
|
}
|
||||||
|
catch(InvalidSignatureException)
|
||||||
|
{
|
||||||
|
return new BadRequestResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(notification.Kind == WebhookKind.SUBSCRIPTION_CANCELED ||
|
||||||
|
notification.Kind == WebhookKind.SUBSCRIPTION_WENT_ACTIVE ||
|
||||||
|
notification.Kind == WebhookKind.SUBSCRIPTION_WENT_PAST_DUE ||
|
||||||
|
notification.Kind == WebhookKind.SUBSCRIPTION_CHARGED_SUCCESSFULLY ||
|
||||||
|
notification.Kind == WebhookKind.SUBSCRIPTION_CHARGED_UNSUCCESSFULLY ||
|
||||||
|
notification.Kind == WebhookKind.SUBSCRIPTION_EXPIRED ||
|
||||||
|
notification.Kind == WebhookKind.SUBSCRIPTION_TRIAL_ENDED)
|
||||||
|
{
|
||||||
|
var ids = GetIdsFromId(notification.Subscription.Id);
|
||||||
|
|
||||||
|
if((notification.Kind == WebhookKind.SUBSCRIPTION_CANCELED ||
|
||||||
|
notification.Kind == WebhookKind.SUBSCRIPTION_EXPIRED) &&
|
||||||
|
(notification.Subscription.Status == SubscriptionStatus.CANCELED ||
|
||||||
|
notification.Subscription.Status == SubscriptionStatus.EXPIRED))
|
||||||
|
{
|
||||||
|
// org
|
||||||
|
if(ids.Item1.HasValue)
|
||||||
|
{
|
||||||
|
await _organizationService.DisableAsync(ids.Item1.Value,
|
||||||
|
notification.Subscription.BillingPeriodEndDate);
|
||||||
|
}
|
||||||
|
// user
|
||||||
|
else if(ids.Item2.HasValue)
|
||||||
|
{
|
||||||
|
await _userService.DisablePremiumAsync(ids.Item2.Value,
|
||||||
|
notification.Subscription.BillingPeriodEndDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// org
|
||||||
|
if(ids.Item1.HasValue)
|
||||||
|
{
|
||||||
|
await _organizationService.UpdateExpirationDateAsync(ids.Item1.Value,
|
||||||
|
notification.Subscription.BillingPeriodEndDate);
|
||||||
|
}
|
||||||
|
// user
|
||||||
|
else if(ids.Item2.HasValue)
|
||||||
|
{
|
||||||
|
await _userService.UpdatePremiumExpirationAsync(ids.Item2.Value,
|
||||||
|
notification.Subscription.BillingPeriodEndDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OkResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Tuple<Guid?, Guid?> GetIdsFromId(string id)
|
||||||
|
{
|
||||||
|
Guid? orgId = null;
|
||||||
|
Guid? userId = null;
|
||||||
|
|
||||||
|
if(id.Length >= 33)
|
||||||
|
{
|
||||||
|
var type = id[0];
|
||||||
|
var entityIdString = id.Substring(1, 32);
|
||||||
|
Guid entityId;
|
||||||
|
if(Guid.TryParse(entityIdString, out entityId))
|
||||||
|
{
|
||||||
|
if(type == 'o')
|
||||||
|
{
|
||||||
|
orgId = entityId;
|
||||||
|
}
|
||||||
|
else if(type == 'u')
|
||||||
|
{
|
||||||
|
userId = entityId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Tuple<Guid?, Guid?>(orgId, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,8 @@
|
|||||||
},
|
},
|
||||||
"billingSettings": {
|
"billingSettings": {
|
||||||
"stripeWebhookKey": "SECRET",
|
"stripeWebhookKey": "SECRET",
|
||||||
"stripeWebhookSecret": "SECRET"
|
"stripeWebhookSecret": "SECRET",
|
||||||
|
"braintreeWebhookKey": "SECRET"
|
||||||
},
|
},
|
||||||
"braintree": {
|
"braintree": {
|
||||||
"production": false,
|
"production": false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user