2017-09-13 08:47:34 +02:00
using BTCPayServer.Authentication ;
using Microsoft.Extensions.Logging ;
using BTCPayServer.Filters ;
using BTCPayServer.Logging ;
using BTCPayServer.Models ;
using Microsoft.AspNetCore.Mvc ;
using NBitpayClient ;
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Threading.Tasks ;
using BTCPayServer.Data ;
2017-09-15 09:06:57 +02:00
using BTCPayServer.Servcices.Invoices ;
2017-09-13 08:47:34 +02:00
namespace BTCPayServer.Controllers
{
public partial class InvoiceController
{
[HttpPost]
[Route("invoices")]
[MediaTypeConstraint("application/json")]
[BitpayAPIConstraint]
public async Task < DataWrapper < InvoiceResponse > > CreateInvoice ( [ FromBody ] Invoice invoice )
{
var bitToken = await CheckTokenPermissionAsync ( Facade . Merchant , invoice . Token ) ;
var store = await FindStore ( bitToken ) ;
return await CreateInvoiceCore ( invoice , store ) ;
}
[HttpGet]
[Route("invoices/{id}")]
[BitpayAPIConstraint]
public async Task < DataWrapper < InvoiceResponse > > GetInvoice ( string id , string token )
{
var bitToken = await CheckTokenPermissionAsync ( Facade . Merchant , token ) ;
var store = await FindStore ( bitToken ) ;
var invoice = await _InvoiceRepository . GetInvoice ( store . Id , id ) ;
if ( invoice = = null )
throw new BitpayHttpException ( 404 , "Object not found" ) ;
2017-09-25 18:31:43 +02:00
var resp = invoice . EntityToDTO ( _ExternalUrl ) ;
2017-09-13 08:47:34 +02:00
return new DataWrapper < InvoiceResponse > ( resp ) ;
}
[HttpGet]
[Route("invoices")]
[BitpayAPIConstraint]
public async Task < DataWrapper < InvoiceResponse [ ] > > GetInvoices (
string token ,
DateTimeOffset ? dateStart = null ,
DateTimeOffset ? dateEnd = null ,
string orderId = null ,
string itemCode = null ,
string status = null ,
int? limit = null ,
int? offset = null )
{
if ( dateEnd ! = null )
dateEnd = dateEnd . Value + TimeSpan . FromDays ( 1 ) ; //Should include the end day
var bitToken = await CheckTokenPermissionAsync ( Facade . Merchant , token ) ;
var store = await FindStore ( bitToken ) ;
var query = new InvoiceQuery ( )
{
Count = limit ,
Skip = offset ,
EndDate = dateEnd ,
StartDate = dateStart ,
OrderId = orderId ,
ItemCode = itemCode ,
Status = status ,
StoreId = store . Id
} ;
var entities = ( await _InvoiceRepository . GetInvoices ( query ) )
2017-09-25 18:31:43 +02:00
. Select ( ( o ) = > o . EntityToDTO ( _ExternalUrl ) ) . ToArray ( ) ;
2017-09-13 08:47:34 +02:00
return DataWrapper . Create ( entities ) ;
}
2017-09-25 18:31:43 +02:00
private async Task < BitTokenEntity > CheckTokenPermissionAsync ( Facade facade , string expectedToken )
2017-09-13 08:47:34 +02:00
{
if ( facade = = null )
throw new ArgumentNullException ( nameof ( facade ) ) ;
2017-09-25 18:31:43 +02:00
var actualTokens = ( await _TokenRepository . GetTokens ( this . GetBitIdentity ( ) . SIN ) ) . Where ( t = > t . Active ) . ToArray ( ) ;
actualTokens = actualTokens . SelectMany ( t = > GetCompatibleTokens ( t ) ) . ToArray ( ) ;
var actualToken = actualTokens . FirstOrDefault ( a = > a . Value . Equals ( expectedToken , StringComparison . Ordinal ) ) ;
if ( expectedToken = = null | | actualToken = = null )
2017-09-13 08:47:34 +02:00
{
Logs . PayServer . LogDebug ( $"No token found for facade {facade} for SIN {this.GetBitIdentity().SIN}" ) ;
2017-09-25 18:31:43 +02:00
throw new BitpayHttpException ( 401 , $"This endpoint does not support the `{actualTokens.Select(a => a.Name).Concat(new[] { " user " }).FirstOrDefault()}` facade" ) ;
2017-09-13 08:47:34 +02:00
}
return actualToken ;
}
2017-09-25 18:31:43 +02:00
private IEnumerable < BitTokenEntity > GetCompatibleTokens ( BitTokenEntity token )
{
if ( token . Name = = Facade . Merchant . ToString ( ) )
{
yield return token . Clone ( Facade . User ) ;
yield return token . Clone ( Facade . PointOfSale ) ;
}
if ( token . Name = = Facade . PointOfSale . ToString ( ) )
{
yield return token . Clone ( Facade . User ) ;
}
yield return token ;
}
2017-09-13 08:47:34 +02:00
private async Task < StoreData > FindStore ( BitTokenEntity bitToken )
{
var store = await _StoreRepository . FindStore ( bitToken . PairedId ) ;
if ( store = = null )
throw new BitpayHttpException ( 401 , "Unknown store" ) ;
return store ;
}
}
}