btcpayserver/BTCPayServer/Services/InvoiceActivator.cs
Andrew Camilleri bbbaacc350
Generic Forms (#4561)
* Custom Forms

* Update BTCPayServer.Data/Migrations/20230125085242_AddForms.cs

* Cleanups

* Explain public form

* Add store branding

* Add form name to POS form

* add tests

* fix migration

* Minor cleanups

* Code improvements

* Add form validation

Closes #4317.

* Adapt form validation for Bootstrap 5

* update logic for forms

* pr changes

* Minor code cleanup

* Remove unused parameters

* Refactor Form data handling to avoid O(n3) issues

* Rename Hidden to Constant

* Pre-populate FormView from the query string params

* Fix test

---------

Co-authored-by: d11n <mail@dennisreimann.de>
Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
2023-02-20 19:35:54 +09:00

96 lines
4.6 KiB
C#

using System;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Data;
using BTCPayServer.Events;
using BTCPayServer.Logging;
using BTCPayServer.Payments;
using BTCPayServer.Payments.Bitcoin;
using BTCPayServer.Services.Invoices;
using NBitcoin;
namespace BTCPayServer.Services
{
public class InvoiceActivator
{
private readonly InvoiceRepository _invoiceRepository;
private readonly EventAggregator _eventAggregator;
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
private readonly PaymentMethodHandlerDictionary _paymentMethodHandlerDictionary;
private readonly WalletRepository _walletRepository;
public InvoiceActivator(
InvoiceRepository invoiceRepository,
EventAggregator eventAggregator,
BTCPayNetworkProvider btcPayNetworkProvider,
PaymentMethodHandlerDictionary paymentMethodHandlerDictionary,
WalletRepository walletRepository)
{
_invoiceRepository = invoiceRepository;
_eventAggregator = eventAggregator;
_btcPayNetworkProvider = btcPayNetworkProvider;
_paymentMethodHandlerDictionary = paymentMethodHandlerDictionary;
_walletRepository = walletRepository;
}
public async Task<bool> ActivateInvoicePaymentMethod(PaymentMethodId paymentMethodId, InvoiceEntity invoice, StoreData store)
{
if (invoice.GetInvoiceState().Status != InvoiceStatusLegacy.New)
return false;
bool success = false;
var eligibleMethodToActivate = invoice.GetPaymentMethod(paymentMethodId);
if (!eligibleMethodToActivate.GetPaymentMethodDetails().Activated)
{
var payHandler = _paymentMethodHandlerDictionary[paymentMethodId];
var supportPayMethod = invoice.GetSupportedPaymentMethod()
.Single(method => method.PaymentId == paymentMethodId);
var paymentMethod = invoice.GetPaymentMethod(paymentMethodId);
var network = _btcPayNetworkProvider.GetNetwork(paymentMethodId.CryptoCode);
var prepare = payHandler.PreparePayment(supportPayMethod, store, network);
InvoiceLogs logs = new InvoiceLogs();
try
{
var pmis = invoice.GetPaymentMethods().Select(method => method.GetId()).ToHashSet();
logs.Write($"{paymentMethodId}: Activating", InvoiceEventData.EventSeverity.Info);
var newDetails = await
payHandler.CreatePaymentMethodDetails(logs, supportPayMethod, paymentMethod, store, network,
prepare, pmis);
eligibleMethodToActivate.SetPaymentMethodDetails(newDetails);
await _invoiceRepository.UpdateInvoicePaymentMethod(invoice.Id, eligibleMethodToActivate);
if (newDetails is BitcoinLikeOnChainPaymentMethod bp)
{
var walletId = new WalletId(store.Id, paymentMethodId.CryptoCode);
if (bp.GetDepositAddress(((BTCPayNetwork)_btcPayNetworkProvider.GetNetwork(paymentMethodId.CryptoCode)).NBitcoinNetwork) is BitcoinAddress address)
{
await _walletRepository.EnsureWalletObjectLink(
new WalletObjectId(
walletId,
WalletObjectData.Types.Address,
address.ToString()),
new WalletObjectId(
walletId,
WalletObjectData.Types.Invoice,
invoice.Id));
}
}
_eventAggregator.Publish(new InvoicePaymentMethodActivated(paymentMethodId, invoice));
_eventAggregator.Publish(new InvoiceNeedUpdateEvent(invoice.Id));
success = true;
}
catch (PaymentMethodUnavailableException ex)
{
logs.Write($"{paymentMethodId}: Payment method unavailable ({ex.Message})", InvoiceEventData.EventSeverity.Error);
}
catch (Exception ex)
{
logs.Write($"{paymentMethodId}: Unexpected exception ({ex})", InvoiceEventData.EventSeverity.Error);
}
await _invoiceRepository.AddInvoiceLogs(invoice.Id, logs);
}
return success;
}
}
}