Rename paywall to payment

This commit is contained in:
Kieran
2022-09-07 15:52:40 +01:00
parent c3dbecca2a
commit af62bd74eb
40 changed files with 439 additions and 388 deletions

View File

@@ -0,0 +1,16 @@
using VoidCat.Model.Payments;
namespace VoidCat.Services.Abstractions;
/// <summary>
/// Factory class to access service provider implementations
/// </summary>
public interface IPaymentFactory
{
/// <summary>
/// Create provider handler for specified service type
/// </summary>
/// <param name="svc"></param>
/// <returns></returns>
ValueTask<IPaymentProvider> CreateProvider(PaymentServices svc);
}

View File

@@ -1,11 +1,11 @@
using VoidCat.Model.Paywall;
using VoidCat.Model.Payments;
namespace VoidCat.Services.Abstractions;
/// <summary>
/// Paywall order store
/// Payment order store
/// </summary>
public interface IPaywallOrderStore : IBasicStore<PaywallOrder>
public interface IPaymentOrderStore : IBasicStore<PaymentOrder>
{
/// <summary>
/// Update the status of an order
@@ -13,5 +13,5 @@ public interface IPaywallOrderStore : IBasicStore<PaywallOrder>
/// <param name="order"></param>
/// <param name="status"></param>
/// <returns></returns>
ValueTask UpdateStatus(Guid order, PaywallOrderStatus status);
ValueTask UpdateStatus(Guid order, PaymentOrderStatus status);
}

View File

@@ -1,23 +1,23 @@
using VoidCat.Model.Paywall;
using VoidCat.Model.Payments;
namespace VoidCat.Services.Abstractions;
/// <summary>
/// Provider to generate orders for a specific config
/// </summary>
public interface IPaywallProvider
public interface IPaymentProvider
{
/// <summary>
/// Create an order with the provider
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
ValueTask<PaywallOrder?> CreateOrder(PaywallConfig file);
ValueTask<PaymentOrder?> CreateOrder(PaymentConfig file);
/// <summary>
/// Get the status of an existing order with the provider
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
ValueTask<PaywallOrder?> GetOrderStatus(Guid id);
ValueTask<PaymentOrder?> GetOrderStatus(Guid id);
}

View File

@@ -0,0 +1,10 @@
using VoidCat.Model.Payments;
namespace VoidCat.Services.Abstractions;
/// <summary>
/// Store for payment configs
/// </summary>
public interface IPaymentStore : IBasicStore<PaymentConfig>
{
}

View File

@@ -1,8 +0,0 @@
using VoidCat.Model.Paywall;
namespace VoidCat.Services.Abstractions;
public interface IPaywallFactory
{
ValueTask<IPaywallProvider> CreateProvider(PaymentServices svc);
}

View File

@@ -1,10 +0,0 @@
using VoidCat.Model.Paywall;
namespace VoidCat.Services.Abstractions;
/// <summary>
/// Store for paywall configs
/// </summary>
public interface IPaywallStore : IBasicStore<PaywallConfig>
{
}

View File

@@ -10,17 +10,17 @@ namespace VoidCat.Services.Files;
public sealed class FileInfoManager
{
private readonly IFileMetadataStore _metadataStore;
private readonly IPaywallStore _paywallStore;
private readonly IPaymentStore _paymentStore;
private readonly IStatsReporter _statsReporter;
private readonly IUserStore _userStore;
private readonly IVirusScanStore _virusScanStore;
private readonly IUserUploadsStore _userUploadsStore;
public FileInfoManager(IFileMetadataStore metadataStore, IPaywallStore paywallStore, IStatsReporter statsReporter,
public FileInfoManager(IFileMetadataStore metadataStore, IPaymentStore paymentStore, IStatsReporter statsReporter,
IUserStore userStore, IVirusScanStore virusScanStore, IUserUploadsStore userUploadsStore)
{
_metadataStore = metadataStore;
_paywallStore = paywallStore;
_paymentStore = paymentStore;
_statsReporter = statsReporter;
_userStore = userStore;
_virusScanStore = virusScanStore;
@@ -75,7 +75,7 @@ public sealed class FileInfoManager
public async ValueTask Delete(Guid id)
{
await _metadataStore.Delete(id);
await _paywallStore.Delete(id);
await _paymentStore.Delete(id);
await _statsReporter.Delete(id);
await _virusScanStore.Delete(id);
}
@@ -84,11 +84,11 @@ public sealed class FileInfoManager
where TMeta : VoidFileMeta where TFile : VoidFile<TMeta>, new()
{
var meta = _metadataStore.Get<TMeta>(id);
var paywall = _paywallStore.Get(id);
var payment = _paymentStore.Get(id);
var bandwidth = _statsReporter.GetBandwidth(id);
var virusScan = _virusScanStore.GetByFile(id);
var uploader = _userUploadsStore.Uploader(id);
await Task.WhenAll(meta.AsTask(), paywall.AsTask(), bandwidth.AsTask(), virusScan.AsTask(), uploader.AsTask());
await Task.WhenAll(meta.AsTask(), payment.AsTask(), bandwidth.AsTask(), virusScan.AsTask(), uploader.AsTask());
if (meta.Result == default) return default;
var user = uploader.Result.HasValue ? await _userStore.Get<PublicVoidUser>(uploader.Result.Value) : null;
@@ -97,7 +97,7 @@ public sealed class FileInfoManager
{
Id = id,
Metadata = meta.Result,
Paywall = paywall.Result,
Payment = payment.Result,
Bandwidth = bandwidth.Result,
Uploader = user?.Flags.HasFlag(VoidUserFlags.PublicProfile) == true ? user : null,
VirusScan = virusScan.Result

View File

@@ -0,0 +1,27 @@
using FluentMigrator;
namespace VoidCat.Services.Migrations.Database;
[Migration(20220908_1527)]
public class PaywallToPayments : Migration
{
public override void Up()
{
Rename.Table("Paywall")
.To("Payment");
Rename.Table("PaywallOrder")
.To("PaymentOrder");
Rename.Table("PaywallStrike")
.To("PaymentStrike");
Rename.Table("PaywallOrderLightning")
.To("PaymentOrderLightning");
}
public override void Down()
{
// yolo
}
}

View File

@@ -3,7 +3,7 @@ using Newtonsoft.Json;
using VoidCat.Model;
using VoidCat.Services.Abstractions;
using VoidCat.Services.Files;
using VoidCat.Services.Paywall;
using VoidCat.Services.Payment;
using VoidCat.Services.Users;
namespace VoidCat.Services.Migrations;
@@ -15,20 +15,20 @@ public class MigrateToPostgres : IMigration
private readonly VoidSettings _settings;
private readonly IFileMetadataStore _fileMetadata;
private readonly ICache _cache;
private readonly IPaywallStore _paywallStore;
private readonly IPaymentStore _paymentStore;
private readonly IUserStore _userStore;
private readonly IUserUploadsStore _userUploads;
private readonly FileStoreFactory _fileStore;
public MigrateToPostgres(VoidSettings settings, ILogger<MigrateToPostgres> logger, IFileMetadataStore fileMetadata,
ICache cache, IPaywallStore paywallStore, IUserStore userStore, IUserUploadsStore userUploads,
ICache cache, IPaymentStore paymentStore, IUserStore userStore, IUserUploadsStore userUploads,
FileStoreFactory fileStore)
{
_logger = logger;
_settings = settings;
_fileMetadata = fileMetadata;
_cache = cache;
_paywallStore = paywallStore;
_paymentStore = paymentStore;
_userStore = userStore;
_userUploads = userUploads;
_fileStore = fileStore;
@@ -99,7 +99,7 @@ public class MigrateToPostgres : IMigration
private async Task MigratePaywall()
{
var cachePaywallStore = new CachePaywallStore(_cache);
var cachePaywallStore = new CachePaymentStore(_cache);
var files = await _fileMetadata.ListFiles<VoidFileMeta>(new(0, int.MaxValue));
await foreach (var file in files.Results)
@@ -109,7 +109,7 @@ public class MigrateToPostgres : IMigration
var old = await cachePaywallStore.Get(file.Id);
if (old != default)
{
await _paywallStore.Add(file.Id, old);
await _paymentStore.Add(file.Id, old);
_logger.LogInformation("Migrated paywall config for {File}", file.Id);
}
}
@@ -165,4 +165,4 @@ public class MigrateToPostgres : IMigration
[JsonConverter(typeof(Base58GuidConverter))]
public Guid? Uploader { get; set; }
}
}
}

View File

@@ -0,0 +1,26 @@
using VoidCat.Model.Payments;
using VoidCat.Services.Abstractions;
namespace VoidCat.Services.Payment;
/// <inheritdoc cref="IPaymentOrderStore"/>
public class CachePaymentOrderStore : BasicCacheStore<PaymentOrder>, IPaymentOrderStore
{
public CachePaymentOrderStore(ICache cache) : base(cache)
{
}
/// <inheritdoc />
public async ValueTask UpdateStatus(Guid order, PaymentOrderStatus status)
{
var old = await Get(order);
if (old == default) return;
old.Status = status;
await Add(order, old);
}
/// <inheritdoc />
protected override string MapKey(Guid id) => $"payment:order:{id}";
}

View File

@@ -0,0 +1,28 @@
using VoidCat.Model.Payments;
using VoidCat.Services.Abstractions;
namespace VoidCat.Services.Payment;
/// <inheritdoc cref="IPaymentStore"/>
public class CachePaymentStore : BasicCacheStore<PaymentConfig>, IPaymentStore
{
public CachePaymentStore(ICache database)
: base(database)
{
}
/// <inheritdoc />
public override async ValueTask<PaymentConfig?> Get(Guid id)
{
var cfg = await Cache.Get<NoPaymentConfig>(MapKey(id));
return cfg?.Service switch
{
PaymentServices.None => cfg,
PaymentServices.Strike => await Cache.Get<StrikePaymentConfig>(MapKey(id)),
_ => default
};
}
/// <inheritdoc />
protected override string MapKey(Guid id) => $"payment:config:{id}";
}

View File

@@ -0,0 +1,23 @@
using VoidCat.Model.Payments;
using VoidCat.Services.Abstractions;
namespace VoidCat.Services.Payment;
public class PaymentFactory : IPaymentFactory
{
private readonly IServiceProvider _services;
public PaymentFactory(IServiceProvider services)
{
_services = services;
}
public ValueTask<IPaymentProvider> CreateProvider(PaymentServices svc)
{
return ValueTask.FromResult<IPaymentProvider>(svc switch
{
PaymentServices.Strike => _services.GetRequiredService<StrikePaymentProvider>(),
_ => throw new ArgumentException("Must have a payment config", nameof(svc))
});
}
}

View File

@@ -0,0 +1,32 @@
using VoidCat.Model;
using VoidCat.Services.Abstractions;
using VoidCat.Services.Strike;
namespace VoidCat.Services.Payment;
public static class PaymentStartup
{
/// <summary>
/// Add services required to use payment functions
/// </summary>
/// <param name="services"></param>
/// <param name="settings"></param>
public static void AddPaymentServices(this IServiceCollection services, VoidSettings settings)
{
services.AddTransient<IPaymentFactory, PaymentFactory>();
if (settings.HasPostgres())
{
services.AddTransient<IPaymentStore, PostgresPaymentStore>();
services.AddTransient<IPaymentOrderStore, PostgresPaymentOrderStore>();
}
else
{
services.AddTransient<IPaymentStore, CachePaymentStore>();
services.AddTransient<IPaymentOrderStore, CachePaymentOrderStore>();
}
// strike
services.AddTransient<StrikeApi>();
services.AddTransient<StrikePaymentProvider>();
}
}

View File

@@ -1,33 +1,33 @@
using Dapper;
using VoidCat.Model.Paywall;
using VoidCat.Model.Payments;
using VoidCat.Services.Abstractions;
namespace VoidCat.Services.Paywall;
namespace VoidCat.Services.Payment;
/// <inheritdoc />
public class PostgresPaywallOrderStore : IPaywallOrderStore
public class PostgresPaymentOrderStore : IPaymentOrderStore
{
private readonly PostgresConnectionFactory _connection;
public PostgresPaywallOrderStore(PostgresConnectionFactory connection)
public PostgresPaymentOrderStore(PostgresConnectionFactory connection)
{
_connection = connection;
}
/// <inheritdoc />
public async ValueTask<PaywallOrder?> Get(Guid id)
public async ValueTask<PaymentOrder?> Get(Guid id)
{
await using var conn = await _connection.Get();
var order = await conn.QuerySingleOrDefaultAsync<DtoPaywallOrder>(
@"select * from ""PaywallOrder"" where ""Id"" = :id", new {id});
var order = await conn.QuerySingleOrDefaultAsync<DtoPaymentOrder>(
@"select * from ""PaymentOrder"" where ""Id"" = :id", new {id});
if (order.Service is PaymentServices.Strike)
{
var lnDetails = await conn.QuerySingleAsync<LightningPaywallOrder>(
@"select * from ""PaywallOrderLightning"" where ""Order"" = :id", new
var lnDetails = await conn.QuerySingleAsync<LightningPaymentOrder>(
@"select * from ""PaymentOrderLightning"" where ""Order"" = :id", new
{
id = order.Id
});
return new LightningPaywallOrder
return new LightningPaymentOrder
{
Id = order.Id,
File = order.File,
@@ -43,18 +43,18 @@ public class PostgresPaywallOrderStore : IPaywallOrderStore
}
/// <inheritdoc />
public ValueTask<IReadOnlyList<PaywallOrder>> Get(Guid[] ids)
public ValueTask<IReadOnlyList<PaymentOrder>> Get(Guid[] ids)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public async ValueTask Add(Guid id, PaywallOrder obj)
public async ValueTask Add(Guid id, PaymentOrder obj)
{
await using var conn = await _connection.Get();
await using var txn = await conn.BeginTransactionAsync();
await conn.ExecuteAsync(
@"insert into ""PaywallOrder""(""Id"", ""File"", ""Service"", ""Currency"", ""Amount"", ""Status"")
@"insert into ""PaymentOrder""(""Id"", ""File"", ""Service"", ""Currency"", ""Amount"", ""Status"")
values(:id, :file, :service, :currency, :amt, :status)",
new
{
@@ -66,10 +66,10 @@ values(:id, :file, :service, :currency, :amt, :status)",
status = (int) obj.Status
});
if (obj is LightningPaywallOrder ln)
if (obj is LightningPaymentOrder ln)
{
await conn.ExecuteAsync(
@"insert into ""PaywallOrderLightning""(""Order"", ""Invoice"", ""Expire"") values(:order, :invoice, :expire)",
@"insert into ""PaymentOrderLightning""(""Order"", ""Invoice"", ""Expire"") values(:order, :invoice, :expire)",
new
{
order = id,
@@ -85,20 +85,20 @@ values(:id, :file, :service, :currency, :amt, :status)",
public async ValueTask Delete(Guid id)
{
await using var conn = await _connection.Get();
await conn.ExecuteAsync(@"delete from ""PaywallOrder"" where ""Id"" = :id", new {id});
await conn.ExecuteAsync(@"delete from ""PaymentOrder"" where ""Id"" = :id", new {id});
}
/// <inheritdoc />
public async ValueTask UpdateStatus(Guid order, PaywallOrderStatus status)
public async ValueTask UpdateStatus(Guid order, PaymentOrderStatus status)
{
await using var conn = await _connection.Get();
await conn.ExecuteAsync(@"update ""PaywallOrder"" set ""Status"" = :status where ""Id"" = :id",
await conn.ExecuteAsync(@"update ""PaymentOrder"" set ""Status"" = :status where ""Id"" = :id",
new {id = order, status = (int) status});
}
private sealed class DtoPaywallOrder : PaywallOrder
private sealed class DtoPaymentOrder : PaymentOrder
{
public PaywallCurrencies Currency { get; init; }
public PaymentCurrencies Currency { get; init; }
public decimal Amount { get; init; }
}
}

View File

@@ -1,25 +1,25 @@
using Dapper;
using VoidCat.Model.Paywall;
using VoidCat.Model.Payments;
using VoidCat.Services.Abstractions;
namespace VoidCat.Services.Paywall;
namespace VoidCat.Services.Payment;
/// <inheritdoc />
public sealed class PostgresPaywallStore : IPaywallStore
public sealed class PostgresPaymentStore : IPaymentStore
{
private readonly PostgresConnectionFactory _connection;
public PostgresPaywallStore(PostgresConnectionFactory connection)
public PostgresPaymentStore(PostgresConnectionFactory connection)
{
_connection = connection;
}
/// <inheritdoc />
public async ValueTask<PaywallConfig?> Get(Guid id)
public async ValueTask<PaymentConfig?> Get(Guid id)
{
await using var conn = await _connection.Get();
var svc = await conn.QuerySingleOrDefaultAsync<DtoPaywallConfig>(
@"select * from ""Paywall"" where ""File"" = :file", new {file = id});
var svc = await conn.QuerySingleOrDefaultAsync<DtoPaymentConfig>(
@"select * from ""Payment"" where ""File"" = :file", new {file = id});
if (svc != default)
{
switch (svc.Service)
@@ -28,8 +28,8 @@ public sealed class PostgresPaywallStore : IPaywallStore
{
var handle =
await conn.ExecuteScalarAsync<string>(
@"select ""Handle"" from ""PaywallStrike"" where ""File"" = :file", new {file = id});
return new StrikePaywallConfig
@"select ""Handle"" from ""PaymentStrike"" where ""File"" = :file", new {file = id});
return new StrikePaymentConfig
{
Cost = new(svc.Amount, svc.Currency),
File = svc.File,
@@ -44,18 +44,18 @@ public sealed class PostgresPaywallStore : IPaywallStore
}
/// <inheritdoc />
public ValueTask<IReadOnlyList<PaywallConfig>> Get(Guid[] ids)
public ValueTask<IReadOnlyList<PaymentConfig>> Get(Guid[] ids)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public async ValueTask Add(Guid id, PaywallConfig obj)
public async ValueTask Add(Guid id, PaymentConfig obj)
{
await using var conn = await _connection.Get();
await using var txn = await conn.BeginTransactionAsync();
await conn.ExecuteAsync(
@"insert into ""Paywall""(""File"", ""Service"", ""Amount"", ""Currency"") values(:file, :service, :amount, :currency)
@"insert into ""Payment""(""File"", ""Service"", ""Amount"", ""Currency"") values(:file, :service, :amount, :currency)
on conflict(""File"") do update set ""Service"" = :service, ""Amount"" = :amount, ""Currency"" = :currency",
new
{
@@ -65,9 +65,9 @@ on conflict(""File"") do update set ""Service"" = :service, ""Amount"" = :amount
currency = obj.Cost.Currency
});
if (obj is StrikePaywallConfig sc)
if (obj is StrikePaymentConfig sc)
{
await conn.ExecuteAsync(@"insert into ""PaywallStrike""(""File"", ""Handle"") values(:file, :handle)
await conn.ExecuteAsync(@"insert into ""PaymentStrike""(""File"", ""Handle"") values(:file, :handle)
on conflict(""File"") do update set ""Handle"" = :handle", new
{
file = id,
@@ -82,12 +82,12 @@ on conflict(""File"") do update set ""Handle"" = :handle", new
public async ValueTask Delete(Guid id)
{
await using var conn = await _connection.Get();
await conn.ExecuteAsync(@"delete from ""Paywall"" where ""File"" = :file", new {file = id});
await conn.ExecuteAsync(@"delete from ""Payment"" where ""File"" = :file", new {file = id});
}
private sealed class DtoPaywallConfig : PaywallConfig
private sealed class DtoPaymentConfig : PaymentConfig
{
public PaywallCurrencies Currency { get; init; }
public PaymentCurrencies Currency { get; init; }
public decimal Amount { get; init; }
}
}

View File

@@ -1,19 +1,19 @@
using System.Globalization;
using VoidCat.Model;
using VoidCat.Model.Paywall;
using VoidCat.Model.Payments;
using VoidCat.Services.Abstractions;
using VoidCat.Services.Strike;
namespace VoidCat.Services.Paywall;
namespace VoidCat.Services.Payment;
/// <inheritdoc />
public class StrikePaywallProvider : IPaywallProvider
public class StrikePaymentProvider : IPaymentProvider
{
private readonly ILogger<StrikePaywallProvider> _logger;
private readonly ILogger<StrikePaymentProvider> _logger;
private readonly StrikeApi _strike;
private readonly IPaywallOrderStore _orderStore;
private readonly IPaymentOrderStore _orderStore;
public StrikePaywallProvider(ILogger<StrikePaywallProvider> logger, StrikeApi strike, IPaywallOrderStore orderStore)
public StrikePaymentProvider(ILogger<StrikePaymentProvider> logger, StrikeApi strike, IPaymentOrderStore orderStore)
{
_logger = logger;
_strike = strike;
@@ -21,9 +21,9 @@ public class StrikePaywallProvider : IPaywallProvider
}
/// <inheritdoc />
public async ValueTask<PaywallOrder?> CreateOrder(PaywallConfig config)
public async ValueTask<PaymentOrder?> CreateOrder(PaymentConfig config)
{
IsStrikePaywall(config, out var strikeConfig);
IsStrikePayment(config, out var strikeConfig);
_logger.LogInformation("Generating invoice for {Currency} {Amount}", config.Cost.Currency, config.Cost.Amount);
var currency = MapCurrency(strikeConfig.Cost.Currency);
@@ -57,13 +57,13 @@ public class StrikePaywallProvider : IPaywallProvider
var quote = await _strike.GetInvoiceQuote(invoice.InvoiceId);
if (quote != default)
{
var order = new LightningPaywallOrder
var order = new LightningPaymentOrder
{
Id = invoice.InvoiceId,
File = config.File,
Service = PaymentServices.Strike,
Price = config.Cost,
Status = PaywallOrderStatus.Unpaid,
Status = PaymentOrderStatus.Unpaid,
Invoice = quote.LnInvoice!,
Expire = DateTime.SpecifyKind(quote.Expiration.DateTime, DateTimeKind.Utc)
};
@@ -80,10 +80,10 @@ public class StrikePaywallProvider : IPaywallProvider
}
/// <inheritdoc />
public async ValueTask<PaywallOrder?> GetOrderStatus(Guid id)
public async ValueTask<PaymentOrder?> GetOrderStatus(Guid id)
{
var order = await _orderStore.Get(id);
if (order is {Status: PaywallOrderStatus.Paid or PaywallOrderStatus.Expired}) return order;
if (order is {Status: PaymentOrderStatus.Paid or PaymentOrderStatus.Expired}) return order;
var providerOrder = await _strike.GetInvoice(id);
if (providerOrder != default)
@@ -104,44 +104,44 @@ public class StrikePaywallProvider : IPaywallProvider
return default;
}
private PaywallOrderStatus MapStatus(InvoiceState providerOrderState)
private PaymentOrderStatus MapStatus(InvoiceState providerOrderState)
=> providerOrderState switch
{
InvoiceState.UNPAID => PaywallOrderStatus.Unpaid,
InvoiceState.PENDING => PaywallOrderStatus.Unpaid,
InvoiceState.PAID => PaywallOrderStatus.Paid,
InvoiceState.CANCELLED => PaywallOrderStatus.Expired,
InvoiceState.UNPAID => PaymentOrderStatus.Unpaid,
InvoiceState.PENDING => PaymentOrderStatus.Unpaid,
InvoiceState.PAID => PaymentOrderStatus.Paid,
InvoiceState.CANCELLED => PaymentOrderStatus.Expired,
_ => throw new ArgumentOutOfRangeException(nameof(providerOrderState), providerOrderState, null)
};
private static Currencies MapCurrency(PaywallCurrencies c)
private static Currencies MapCurrency(PaymentCurrencies c)
=> c switch
{
PaywallCurrencies.BTC => Currencies.BTC,
PaywallCurrencies.USD => Currencies.USD,
PaywallCurrencies.EUR => Currencies.EUR,
PaywallCurrencies.GBP => Currencies.GBP,
PaymentCurrencies.BTC => Currencies.BTC,
PaymentCurrencies.USD => Currencies.USD,
PaymentCurrencies.EUR => Currencies.EUR,
PaymentCurrencies.GBP => Currencies.GBP,
_ => throw new ArgumentOutOfRangeException(nameof(c), c, null)
};
private static PaywallCurrencies MapCurrency(Currencies c)
private static PaymentCurrencies MapCurrency(Currencies c)
=> c switch
{
Currencies.BTC => PaywallCurrencies.BTC,
Currencies.USD => PaywallCurrencies.USD,
Currencies.USDT => PaywallCurrencies.USD,
Currencies.EUR => PaywallCurrencies.EUR,
Currencies.GBP => PaywallCurrencies.GBP,
Currencies.BTC => PaymentCurrencies.BTC,
Currencies.USD => PaymentCurrencies.USD,
Currencies.USDT => PaymentCurrencies.USD,
Currencies.EUR => PaymentCurrencies.EUR,
Currencies.GBP => PaymentCurrencies.GBP,
_ => throw new ArgumentOutOfRangeException(nameof(c), c, null)
};
private static void IsStrikePaywall(PaywallConfig? cfg, out StrikePaywallConfig strikeConfig)
private static void IsStrikePayment(PaymentConfig? cfg, out StrikePaymentConfig strikeConfig)
{
if (cfg?.Service != PaymentServices.Strike)
{
throw new ArgumentException("Must be strike paywall");
throw new ArgumentException("Must be strike Payment");
}
strikeConfig = (cfg as StrikePaywallConfig)!;
strikeConfig = (cfg as StrikePaymentConfig)!;
}
}

View File

@@ -1,26 +0,0 @@
using VoidCat.Model.Paywall;
using VoidCat.Services.Abstractions;
namespace VoidCat.Services.Paywall;
/// <inheritdoc cref="IPaywallOrderStore"/>
public class CachePaywallOrderStore : BasicCacheStore<PaywallOrder>, IPaywallOrderStore
{
public CachePaywallOrderStore(ICache cache) : base(cache)
{
}
/// <inheritdoc />
public async ValueTask UpdateStatus(Guid order, PaywallOrderStatus status)
{
var old = await Get(order);
if (old == default) return;
old.Status = status;
await Add(order, old);
}
/// <inheritdoc />
protected override string MapKey(Guid id) => $"paywall:order:{id}";
}

View File

@@ -1,28 +0,0 @@
using VoidCat.Model.Paywall;
using VoidCat.Services.Abstractions;
namespace VoidCat.Services.Paywall;
/// <inheritdoc cref="IPaywallStore"/>
public class CachePaywallStore : BasicCacheStore<PaywallConfig>, IPaywallStore
{
public CachePaywallStore(ICache database)
: base(database)
{
}
/// <inheritdoc />
public override async ValueTask<PaywallConfig?> Get(Guid id)
{
var cfg = await Cache.Get<NoPaywallConfig>(MapKey(id));
return cfg?.Service switch
{
PaymentServices.None => cfg,
PaymentServices.Strike => await Cache.Get<StrikePaywallConfig>(MapKey(id)),
_ => default
};
}
/// <inheritdoc />
protected override string MapKey(Guid id) => $"paywall:config:{id}";
}

View File

@@ -1,23 +0,0 @@
using VoidCat.Model.Paywall;
using VoidCat.Services.Abstractions;
namespace VoidCat.Services.Paywall;
public class PaywallFactory : IPaywallFactory
{
private readonly IServiceProvider _services;
public PaywallFactory(IServiceProvider services)
{
_services = services;
}
public ValueTask<IPaywallProvider> CreateProvider(PaymentServices svc)
{
return ValueTask.FromResult<IPaywallProvider>(svc switch
{
PaymentServices.Strike => _services.GetRequiredService<StrikePaywallProvider>(),
_ => throw new ArgumentException("Must have a paywall config", nameof(svc))
});
}
}

View File

@@ -1,32 +0,0 @@
using VoidCat.Model;
using VoidCat.Services.Abstractions;
using VoidCat.Services.Strike;
namespace VoidCat.Services.Paywall;
public static class PaywallStartup
{
/// <summary>
/// Add services required to use paywall functions
/// </summary>
/// <param name="services"></param>
/// <param name="settings"></param>
public static void AddPaywallServices(this IServiceCollection services, VoidSettings settings)
{
services.AddTransient<IPaywallFactory, PaywallFactory>();
if (settings.HasPostgres())
{
services.AddTransient<IPaywallStore, PostgresPaywallStore>();
services.AddTransient<IPaywallOrderStore, PostgresPaywallOrderStore>();
}
else
{
services.AddTransient<IPaywallStore, CachePaywallStore>();
services.AddTransient<IPaywallOrderStore, CachePaywallOrderStore>();
}
// strike
services.AddTransient<StrikeApi>();
services.AddTransient<StrikePaywallProvider>();
}
}