using System; using System.Collections.Generic; using System.Threading.Tasks; using BTCPayServer.Data; using BTCPayServer.Models.InvoicingModels; using BTCPayServer.Rating; using BTCPayServer.Services.Invoices; using BTCPayServer.Services.Rates; using NBitcoin; using NBitpayClient; using Newtonsoft.Json.Linq; using InvoiceResponse = BTCPayServer.Models.InvoiceResponse; namespace BTCPayServer.Payments { /// /// This class customize invoice creation by the creation of payment details for the PaymentMethod during invoice creation /// public interface IPaymentMethodHandler { /// /// Create needed to track payments of this invoice /// /// /// /// /// /// /// Task CreatePaymentMethodDetails(ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetworkBase network, object preparePaymentObject); /// /// This method called before the rate have been fetched /// /// /// /// /// object PreparePayment(ISupportedPaymentMethod supportedPaymentMethod, StoreData store, BTCPayNetworkBase network); void PrepareInvoiceDto(InvoiceResponse invoiceResponse, InvoiceEntity invoiceEntity, InvoiceCryptoInfo invoiceCryptoInfo, PaymentMethodAccounting accounting, PaymentMethod info); void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse); string GetCryptoImage(PaymentMethodId paymentMethodId); string GetPaymentMethodName(PaymentMethodId paymentMethodId); Task IsPaymentMethodAllowedBasedOnInvoiceAmount(StoreBlob storeBlob, Dictionary> rate, Money amount, PaymentMethodId paymentMethodId); IEnumerable GetSupportedPaymentMethods(); ISupportedPaymentMethod DeserializeSupportedPaymentMethod(PaymentMethodId paymentMethodId, JToken value); string GetTransactionLink(PaymentMethodId paymentMethodId, params object[] args); } public interface IPaymentMethodHandler : IPaymentMethodHandler where TSupportedPaymentMethod : ISupportedPaymentMethod where TBTCPayNetwork : BTCPayNetworkBase { Task CreatePaymentMethodDetails(TSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, TBTCPayNetwork network, object preparePaymentObject); } public abstract class PaymentMethodHandlerBase : IPaymentMethodHandler< TSupportedPaymentMethod, TBTCPayNetwork> where TSupportedPaymentMethod : ISupportedPaymentMethod where TBTCPayNetwork : BTCPayNetworkBase { public abstract PaymentTypes PaymentType { get; } public abstract Task CreatePaymentMethodDetails( TSupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, TBTCPayNetwork network, object preparePaymentObject); public abstract void PrepareInvoiceDto(InvoiceResponse invoiceResponse, InvoiceEntity invoiceEntity, InvoiceCryptoInfo invoiceCryptoInfo, PaymentMethodAccounting accounting, PaymentMethod info); public abstract void PreparePaymentModel(PaymentModel model, InvoiceResponse invoiceResponse); public abstract string GetCryptoImage(PaymentMethodId paymentMethodId); public abstract string GetPaymentMethodName(PaymentMethodId paymentMethodId); public abstract Task IsPaymentMethodAllowedBasedOnInvoiceAmount(StoreBlob storeBlob, Dictionary> rate, Money amount, PaymentMethodId paymentMethodId); public abstract IEnumerable GetSupportedPaymentMethods(); public abstract ISupportedPaymentMethod DeserializeSupportedPaymentMethod(PaymentMethodId paymentMethodId, JToken value); public abstract string GetTransactionLink(PaymentMethodId paymentMethodId, params object[] args); public virtual object PreparePayment(TSupportedPaymentMethod supportedPaymentMethod, StoreData store, BTCPayNetworkBase network) { return null; } public Task CreatePaymentMethodDetails(ISupportedPaymentMethod supportedPaymentMethod, PaymentMethod paymentMethod, StoreData store, BTCPayNetworkBase network, object preparePaymentObject) { if (supportedPaymentMethod is TSupportedPaymentMethod method && network is TBTCPayNetwork correctNetwork) { return CreatePaymentMethodDetails(method, paymentMethod, store, correctNetwork, preparePaymentObject); } throw new NotSupportedException("Invalid supportedPaymentMethod"); } object IPaymentMethodHandler.PreparePayment(ISupportedPaymentMethod supportedPaymentMethod, StoreData store, BTCPayNetworkBase network) { if (supportedPaymentMethod is TSupportedPaymentMethod method) { return PreparePayment(method, store, network); } throw new NotSupportedException("Invalid supportedPaymentMethod"); } } }