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();
+ });
+ }
}
}