diff --git a/BTCPayServer.Client/Models/InvoicePaymentMethodDataModel.cs b/BTCPayServer.Client/Models/InvoicePaymentMethodDataModel.cs index fa07b4e09..81dcbb66e 100644 --- a/BTCPayServer.Client/Models/InvoicePaymentMethodDataModel.cs +++ b/BTCPayServer.Client/Models/InvoicePaymentMethodDataModel.cs @@ -33,6 +33,8 @@ namespace BTCPayServer.Client.Models public List Payments { get; set; } public string PaymentMethod { get; set; } + public string CryptoCode { get; set; } + public class Payment { public string Id { get; set; } diff --git a/BTCPayServer.Client/Models/PayoutData.cs b/BTCPayServer.Client/Models/PayoutData.cs index 71a74fa72..993cf0b91 100644 --- a/BTCPayServer.Client/Models/PayoutData.cs +++ b/BTCPayServer.Client/Models/PayoutData.cs @@ -21,6 +21,7 @@ namespace BTCPayServer.Client.Models public string PullPaymentId { get; set; } public string Destination { get; set; } public string PaymentMethod { get; set; } + public string CryptoCode { get; set; } [JsonConverter(typeof(NumericStringJsonConverter))] public decimal Amount { get; set; } [JsonConverter(typeof(NumericStringJsonConverter))] diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index 9ca1756d9..280c7cdd1 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -437,6 +437,8 @@ namespace BTCPayServer.Tests Assert.Equal(payout.Id, payout2.Id); Assert.Equal(destination, payout2.Destination); Assert.Equal(PayoutState.AwaitingApproval, payout.State); + Assert.Equal("BTC", payout2.PaymentMethod); + Assert.Equal("BTC", payout2.CryptoCode); Assert.Null(payout.PaymentMethodAmount); Logs.Tester.LogInformation("Can't overdraft"); @@ -1186,6 +1188,7 @@ namespace BTCPayServer.Tests Assert.Single(paymentMethods); var paymentMethod = paymentMethods.First(); Assert.Equal("BTC", paymentMethod.PaymentMethod); + Assert.Equal("BTC", paymentMethod.CryptoCode); Assert.Empty(paymentMethod.Payments); diff --git a/BTCPayServer/Controllers/GreenField/InvoiceController.cs b/BTCPayServer/Controllers/GreenField/InvoiceController.cs index db3fd6acf..2aaf7e96b 100644 --- a/BTCPayServer/Controllers/GreenField/InvoiceController.cs +++ b/BTCPayServer/Controllers/GreenField/InvoiceController.cs @@ -1,8 +1,8 @@ +#nullable enable using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using System.Globalization; using BTCPayServer.Abstractions.Constants; using BTCPayServer.Client; using BTCPayServer.Client.Models; @@ -49,14 +49,14 @@ namespace BTCPayServer.Controllers.GreenField [Authorize(Policy = Policies.CanViewInvoices, AuthenticationSchemes = AuthenticationSchemes.Greenfield)] [HttpGet("~/api/v1/stores/{storeId}/invoices")] - public async Task GetInvoices(string storeId, [FromQuery] string[] orderId = null, [FromQuery] string[] status = null, + public async Task GetInvoices(string storeId, [FromQuery] string[]? orderId = null, [FromQuery] string[]? status = null, [FromQuery] [ModelBinder(typeof(ModelBinders.DateTimeOffsetModelBinder))] DateTimeOffset? startDate = null, [FromQuery] [ModelBinder(typeof(ModelBinders.DateTimeOffsetModelBinder))] DateTimeOffset? endDate = null, - [FromQuery] string textSearch = null, + [FromQuery] string? textSearch = null, [FromQuery] bool includeArchived = false, [FromQuery] int? skip = null, [FromQuery] int? take = null @@ -354,6 +354,7 @@ namespace BTCPayServer.Controllers.GreenField { Activated = details.Activated, PaymentMethod = method.GetId().ToStringNormalized(), + CryptoCode = method.GetId().CryptoCode, Destination = details.GetPaymentDestination(), Rate = method.Rate, Due = accounting.DueUncapped.ToDecimal(MoneyUnit.BTC), diff --git a/BTCPayServer/Controllers/GreenField/PullPaymentController.cs b/BTCPayServer/Controllers/GreenField/PullPaymentController.cs index afdce2d69..dd762a22b 100644 --- a/BTCPayServer/Controllers/GreenField/PullPaymentController.cs +++ b/BTCPayServer/Controllers/GreenField/PullPaymentController.cs @@ -1,3 +1,4 @@ +#nullable enable using System; using System.Collections.Generic; using System.Linq; @@ -98,7 +99,7 @@ namespace BTCPayServer.Controllers.GreenField { ModelState.AddModelError(nameof(request.Period), $"The period should be positive"); } - PaymentMethodId[] paymentMethods = null; + PaymentMethodId?[]? paymentMethods = null; if (request.PaymentMethods is { } paymentMethodsStr) { paymentMethods = paymentMethodsStr.Select(s => @@ -218,6 +219,7 @@ namespace BTCPayServer.Controllers.GreenField }; model.Destination = blob.Destination; model.PaymentMethod = p.PaymentMethodId; + model.CryptoCode = p.GetPaymentMethodId().CryptoCode; return model; } @@ -245,7 +247,7 @@ namespace BTCPayServer.Controllers.GreenField if (pp is null) return PullPaymentNotFound(); var ppBlob = pp.GetBlob(); - var destination = await payoutHandler.ParseClaimDestination(paymentMethodId,request.Destination, true); + var destination = await payoutHandler.ParseClaimDestination(paymentMethodId, request!.Destination, true); if (destination.destination is null) { ModelState.AddModelError(nameof(request.Destination), destination.error??"The destination is invalid for the payment specified"); @@ -338,7 +340,7 @@ namespace BTCPayServer.Controllers.GreenField var payout = await ctx.Payouts.GetPayout(payoutId, storeId, true, true); if (payout is null) return PayoutNotFound(); - RateResult rateResult = null; + RateResult? rateResult = null; try { rateResult = await _pullPaymentService.GetRate(payout, approvePayoutRequest?.RateRule, cancellationToken); @@ -357,7 +359,7 @@ namespace BTCPayServer.Controllers.GreenField var result = await _pullPaymentService.Approve(new PullPaymentHostedService.PayoutApproval() { PayoutId = payoutId, - Revision = revision.Value, + Revision = revision!.Value, Rate = rateResult.BidAsk.Ask }); var errorMessage = PullPaymentHostedService.PayoutApproval.GetErrorMessage(result); diff --git a/BTCPayServer/wwwroot/swagger/v1/swagger.template.invoices.json b/BTCPayServer/wwwroot/swagger/v1/swagger.template.invoices.json index 4e6707e4a..0f5f8291b 100644 --- a/BTCPayServer/wwwroot/swagger/v1/swagger.template.invoices.json +++ b/BTCPayServer/wwwroot/swagger/v1/swagger.template.invoices.json @@ -1152,7 +1152,11 @@ "properties": { "paymentMethod": { "type": "string", - "description": "The payment method" + "description": "Payment method available for the invoice (e.g., \"BTC\" or \"BTC-LightningNetwork\" or \"BTC-LNURLPAY\")" + }, + "cryptoCode": { + "type": "string", + "description": "Crypto code of the payment method (e.g., \"BTC\" or \"LTC\")" }, "destination": { "type": "string", diff --git a/BTCPayServer/wwwroot/swagger/v1/swagger.template.pull-payments.json b/BTCPayServer/wwwroot/swagger/v1/swagger.template.pull-payments.json index 08506b221..83a0757b4 100644 --- a/BTCPayServer/wwwroot/swagger/v1/swagger.template.pull-payments.json +++ b/BTCPayServer/wwwroot/swagger/v1/swagger.template.pull-payments.json @@ -313,6 +313,46 @@ "security": [] } }, + "/api/v1/pull-payments/{pullPaymentId}/payouts/{payoutId}": { + "parameters": [ + { + "name": "pullPaymentId", + "in": "path", + "required": true, + "description": "The ID of the pull payment", + "schema": { "type": "string" } + }, + { + "name": "payoutId", + "in": "path", + "required": true, + "description": "The ID of the pull payment payout", + "schema": { "type": "string" } + } + ], + "get": { + "summary": "Get Payout", + "operationId": "PullPayments_GetPayout", + "description": "Get payout", + "responses": { + "200": { + "description": "A specific payout of a pull payment", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayoutData" + } + } + } + }, + "404": { + "description": "Pull payment payout not found" + } + }, + "tags": [ "Pull payments (Public)", "Pull payments payout (Public)" ], + "security": [] + } + }, "/api/v1/stores/{storeId}/payouts/{payoutId}": { "parameters": [ { @@ -554,7 +594,12 @@ "paymentMethod": { "type": "string", "example": "BTC", - "description": "The payment method of the payout" + "description": "The payment method of the payout (e.g., \"BTC\" or \"BTC_LightningLike\"" + }, + "cryptoCode": { + "type": "string", + "example": "BTC", + "description": "Crypto code of the payment method of the payout (e.g., \"BTC\" or \"LTC\")" }, "paymentMethodAmount": { "type": "string",