1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-20 11:04:31 -05:00

bitpay invoice api

This commit is contained in:
Kyle Spearrin 2019-02-21 22:43:37 -05:00
parent d514fcdaeb
commit fdaa9504d5
11 changed files with 144 additions and 0 deletions

View File

@ -1,11 +1,21 @@
using System;
using Microsoft.AspNetCore.Mvc;
using Bit.Core.Models.Api;
using System.Threading.Tasks;
using Bit.Core.Utilities;
using Microsoft.AspNetCore.Authorization;
namespace Bit.Api.Controllers
{
public class MiscController : Controller
{
private readonly BitPayClient _bitPayClient;
public MiscController(BitPayClient bitPayClient)
{
_bitPayClient = bitPayClient;
}
[HttpGet("~/alive")]
[HttpGet("~/now")]
public DateTime Get()
@ -28,5 +38,14 @@ namespace Bit.Api.Controllers
Headers = HttpContext.Request?.Headers,
});
}
[Authorize("Application")]
[HttpPost("~/bitpay-invoice")]
[SelfHosted(NotSelfHostedOnly = true)]
public async Task<string> PostBitPayInvoice([FromBody]BitPayInvoiceRequestModel model)
{
var invoice = await _bitPayClient.CreateInvoiceAsync(model.ToBitpayClientInvoice());
return invoice.Url;
}
}
}

View File

@ -63,6 +63,8 @@ namespace Bit.Api
// Rate limiting
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
// BitPay
services.AddSingleton<BitPayClient>();
}
// Identity

View File

@ -14,6 +14,9 @@
},
"braintree": {
"production": true
},
"bitPay": {
"production": true
}
}
}

View File

@ -62,6 +62,10 @@
"merchantId": "SECRET",
"publicKey": "SECRET",
"privateKey": "SECRET"
},
"bitPay": {
"production": false,
"base58Secret": "SECRET"
}
},
"IpRateLimitOptions": {

View File

@ -43,6 +43,9 @@ namespace Bit.Billing
services.AddSingleton<Utilities.PayPalClient>();
services.AddSingleton<Utilities.PayPalIpnClient>();
// BitPay Client
services.AddSingleton<BitPayClient>();
// Context
services.AddScoped<CurrentContext>();

View File

@ -14,6 +14,9 @@
},
"braintree": {
"production": true
},
"bitPay": {
"production": true
}
},
"billingSettings": {

View File

@ -51,6 +51,10 @@
"merchantId": "SECRET",
"publicKey": "SECRET",
"privateKey": "SECRET"
},
"bitPay": {
"production": false,
"base58Secret": "SECRET"
}
},
"billingSettings": {

View File

@ -25,6 +25,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.1.3" />
<PackageReference Include="NBitpayClient" Version="1.0.0.31" />
<PackageReference Include="Npgsql" Version="4.0.4" />
<PackageReference Include="Quartz" Version="3.0.7" />
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />

View File

@ -31,6 +31,7 @@ namespace Bit.Core
public virtual YubicoSettings Yubico { get; set; } = new YubicoSettings();
public virtual DuoSettings Duo { get; set; } = new DuoSettings();
public virtual BraintreeSettings Braintree { get; set; } = new BraintreeSettings();
public virtual BitPaySettings BitPay { get; set; } = new BitPaySettings();
public class BaseServiceUriSettings
{
@ -186,6 +187,12 @@ namespace Bit.Core
public string PrivateKey { get; set; }
}
public class BitPaySettings
{
public bool Production { get; set; }
public string Base58Secret { get; set; }
}
public class InstallationSettings
{
public Guid Id { get; set; }

View File

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Models.Api
{
public class BitPayInvoiceRequestModel : IValidatableObject
{
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public bool Credit { get; set; }
[Required]
public decimal? Amount { get; set; }
public string ReturnUrl { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public NBitpayClient.Invoice ToBitpayClientInvoice()
{
var inv = new NBitpayClient.Invoice
{
Price = Amount.Value,
Currency = "USD",
RedirectURL = ReturnUrl,
BuyerEmail = Email,
Buyer = new NBitpayClient.Buyer
{
email = Email,
Name = Name
}
};
var posData = string.Empty;
if(UserId.HasValue)
{
posData = "userId:" + UserId.Value;
}
else if(OrganizationId.HasValue)
{
posData = "organizationId:" + OrganizationId.Value;
}
if(Credit)
{
posData += ",accountCredit:1";
inv.ItemDesc = "Bitwarden Account Credit";
}
else
{
inv.ItemDesc = "Bitwarden";
}
inv.PosData = posData;
return inv;
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(!UserId.HasValue && !OrganizationId.HasValue)
{
yield return new ValidationResult("User or Ooganization is required.");
}
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Threading.Tasks;
namespace Bit.Core.Utilities
{
public class BitPayClient
{
private readonly NBitpayClient.Bitpay _bpClient;
public BitPayClient(GlobalSettings globalSettings)
{
var btcSecret = new NBitcoin.BitcoinSecret(globalSettings.BitPay.Base58Secret,
globalSettings.BitPay.Production ? null : NBitcoin.Network.TestNet);
_bpClient = new NBitpayClient.Bitpay(btcSecret.PrivateKey,
new Uri(globalSettings.BitPay.Production ? "https://bitpay.com/" : "https://test.bitpay.com/"));
}
public Task<bool> TestAccessAsync()
{
return _bpClient.TestAccessAsync(NBitpayClient.Facade.Merchant);
}
public Task<NBitpayClient.Invoice> GetInvoiceAsync(string id)
{
return _bpClient.GetInvoiceAsync(id);
}
public Task<NBitpayClient.Invoice> CreateInvoiceAsync(NBitpayClient.Invoice invoice)
{
return _bpClient.CreateInvoiceAsync(invoice);
}
}
}