diff --git a/src/TrueLayer/PaymentsProviders/IPaymentsProvidersApi.cs b/src/TrueLayer/PaymentsProviders/IPaymentsProvidersApi.cs index 0f2dbd2f..8a659fd2 100644 --- a/src/TrueLayer/PaymentsProviders/IPaymentsProvidersApi.cs +++ b/src/TrueLayer/PaymentsProviders/IPaymentsProvidersApi.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Threading.Tasks; using TrueLayer.PaymentsProviders.Model; @@ -14,5 +15,12 @@ public interface IPaymentsProvidersApi /// The provider identifier /// An API response that includes the payments provider details if successful, otherwise problem details Task> GetPaymentsProvider(string id); + + /// + /// Search for payments providers matching the given criteria + /// + /// The provider search request + /// An API response that includes all the providers that match the criteria specified on the request + Task> SearchPaymentsProviders(SearchPaymentsProvidersRequest searchPaymentsProvidersRequest); } } diff --git a/src/TrueLayer/PaymentsProviders/Model/AuthorizationFlow.cs b/src/TrueLayer/PaymentsProviders/Model/AuthorizationFlow.cs new file mode 100644 index 00000000..92b6386e --- /dev/null +++ b/src/TrueLayer/PaymentsProviders/Model/AuthorizationFlow.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using TrueLayer.Models; + +namespace TrueLayer.PaymentsProviders.Model; + +public record AuthorizationFlow(AuthorizationFlowConfiguration Configuration); + +public record AuthorizationFlowConfiguration(Dictionary? Redirect = null, Form? Form = null, + Consent? Consent = null); + +public record Form(List InputTypes); + +public record Consent(ConsentRequirements Requirements); + +public record ConsentRequirements(Dictionary Pis, Dictionary? Ais = null); diff --git a/src/TrueLayer/PaymentsProviders/Model/SearchPaymentsProvidersRequest.cs b/src/TrueLayer/PaymentsProviders/Model/SearchPaymentsProvidersRequest.cs new file mode 100644 index 00000000..c0998948 --- /dev/null +++ b/src/TrueLayer/PaymentsProviders/Model/SearchPaymentsProvidersRequest.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using TrueLayer.Models; + +namespace TrueLayer.PaymentsProviders.Model; + +public record SearchPaymentsProvidersRequest(AuthorizationFlow AuthorizationFlow, + List? Countries = null, + List? Currencies = null, + List? ReleaseChannels = null, + List? CustomerSegments = null, + Capabilities? Capabilities = null); diff --git a/src/TrueLayer/PaymentsProviders/Model/SearchPaymentsProvidersResponse.cs b/src/TrueLayer/PaymentsProviders/Model/SearchPaymentsProvidersResponse.cs new file mode 100644 index 00000000..88afb65f --- /dev/null +++ b/src/TrueLayer/PaymentsProviders/Model/SearchPaymentsProvidersResponse.cs @@ -0,0 +1,5 @@ +using System.Collections.Generic; + +namespace TrueLayer.PaymentsProviders.Model; + +public record SearchPaymentsProvidersResponse(List Items); diff --git a/src/TrueLayer/PaymentsProviders/PaymentsProvidersApi.cs b/src/TrueLayer/PaymentsProviders/PaymentsProvidersApi.cs index 91f9a45f..3cd8e018 100644 --- a/src/TrueLayer/PaymentsProviders/PaymentsProvidersApi.cs +++ b/src/TrueLayer/PaymentsProviders/PaymentsProvidersApi.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using TrueLayer.Auth; using TrueLayer.Common; @@ -47,5 +48,23 @@ public async Task> GetPaymentsProvider(string id) accessToken: authResponse.Data!.AccessToken ); } + + public async Task> SearchPaymentsProviders(SearchPaymentsProvidersRequest searchPaymentsProvidersRequest) + { + searchPaymentsProvidersRequest.NotNull(nameof(searchPaymentsProvidersRequest)); + + ApiResponse authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest("payments")); + + if (!authResponse.IsSuccessful) + { + return new(authResponse.StatusCode, authResponse.TraceId); + } + + return await _apiClient.PostAsync( + _baseUri.Append("/search"), + request: searchPaymentsProvidersRequest, + accessToken: authResponse.Data!.AccessToken + ); + } } } diff --git a/test/TrueLayer.AcceptanceTests/PaymentsProvidersTests.cs b/test/TrueLayer.AcceptanceTests/PaymentsProvidersTests.cs index 6c582ba6..cec54ff8 100644 --- a/test/TrueLayer.AcceptanceTests/PaymentsProvidersTests.cs +++ b/test/TrueLayer.AcceptanceTests/PaymentsProvidersTests.cs @@ -1,14 +1,19 @@ +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using OneOf; using Shouldly; +using TrueLayer.Models; using TrueLayer.Payments.Model; +using TrueLayer.PaymentsProviders.Model; using Xunit; +using AuthorizationFlow = TrueLayer.PaymentsProviders.Model.AuthorizationFlow; +using Provider = TrueLayer.Payments.Model.Provider; namespace TrueLayer.AcceptanceTests { - using ProviderUnion = OneOf; using AccountIdentifierUnion = OneOf; + using ProviderUnion = OneOf; public class PaymentProvidersTests : IClassFixture { @@ -54,5 +59,27 @@ public async Task Can_get_payments_provider_with_mandates_capabilities() response.Data.Capabilities.Mandates?.VrpSweeping.ShouldNotBeNull(); response.Data.Capabilities.Mandates?.VrpSweeping?.ReleaseChannel.ShouldNotBeNullOrWhiteSpace(); } + + [Fact] + public async Task Can_search_payments_providers() + { + var searchRequest = new SearchPaymentsProvidersRequest( + new AuthorizationFlow(new AuthorizationFlowConfiguration()) + ); + + var response = await _fixture.Client.PaymentsProviders.SearchPaymentsProviders(searchRequest); + + response.IsSuccessful.ShouldBeTrue(); + response.Data.ShouldNotBeNull(); + response.Data.Items.ShouldNotBeNull().ShouldNotBeEmpty(); + response.Data.Items.ForEach(pp => + { + pp.Id.ShouldNotBeEmpty(); + pp.DisplayName.ShouldNotBeNullOrWhiteSpace(); + pp.CountryCode.ShouldNotBeNullOrWhiteSpace(); + pp.Capabilities.Mandates?.VrpSweeping.ShouldNotBeNull(); + pp.Capabilities.Mandates?.VrpSweeping?.ReleaseChannel.ShouldNotBeNullOrWhiteSpace(); + }); + } } }