Skip to content

Commit

Permalink
Endpoints refactor; Added OptionsExtensions (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
tl-Roberto-Mancinelli authored Nov 27, 2024
1 parent 09349d9 commit 852d7b9
Show file tree
Hide file tree
Showing 17 changed files with 254 additions and 89 deletions.
10 changes: 2 additions & 8 deletions src/TrueLayer/Auth/AuthApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using TrueLayer.Common;
using TrueLayer.Extensions;

namespace TrueLayer.Auth
Expand All @@ -18,12 +17,7 @@ public AuthApi(IApiClient apiClient, TrueLayerOptions options)
{
_apiClient = apiClient.NotNull(nameof(apiClient));
_options = options.NotNull(nameof(options));

var baseUri = (options.UseSandbox ?? true)
? TrueLayerBaseUris.SandboxAuthBaseUri
: TrueLayerBaseUris.ProdAuthBaseUri;

_baseUri = options.Auth?.Uri ?? baseUri;
_baseUri = options.GetAuthBaseUri();
}

/// <inheritdoc />
Expand All @@ -44,7 +38,7 @@ public async ValueTask<ApiResponse<GetAuthTokenResponse>> GetAuthToken(GetAuthTo
}

return await _apiClient.PostAsync<GetAuthTokenResponse>(
_baseUri.Append("connect/token"), new FormUrlEncodedContent(values), null, cancellationToken);
_baseUri.Append(AuthEndpoints.Token), new FormUrlEncodedContent(values), null, cancellationToken);
}
}
}
7 changes: 7 additions & 0 deletions src/TrueLayer/Auth/AuthEndpoints.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TrueLayer.Auth
{
internal static class AuthEndpoints
{
internal const string Token = "connect/token";
}
}
5 changes: 0 additions & 5 deletions src/TrueLayer/Extensions/UriExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using TrueLayer.Serialization;

namespace TrueLayer.Extensions
{
Expand Down Expand Up @@ -34,8 +32,5 @@ public static Uri AppendQueryParameters(this Uri uri, IDictionary<string, string

return uriBuilder.Uri;
}

public static string ToJson<T>(this ApiResponse<T> response)
=> JsonSerializer.Serialize(response, SerializerOptions.Default);
}
}
4 changes: 2 additions & 2 deletions src/TrueLayer/Mandates/IMandatesApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace TrueLayer.Mandates
{
using TrueLayer.Mandates.Model;
using TrueLayer.Models;
using Model;
using Models;
using AuthorizationResponseUnion = OneOf<
Models.AuthorisationFlowResponse.AuthorizationFlowAuthorizing,
Models.AuthorisationFlowResponse.AuthorizationFlowAuthorizationFailed>;
Expand Down
39 changes: 17 additions & 22 deletions src/TrueLayer/Mandates/MandatesApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Threading.Tasks;
using OneOf;
using TrueLayer.Auth;
using TrueLayer.Common;
using TrueLayer.Extensions;
using TrueLayer.Mandates.Model;
using TrueLayer.Models;
Expand Down Expand Up @@ -35,12 +34,8 @@ public MandatesApi(IApiClient apiClient, IAuthApi auth, TrueLayerOptions options

options.Payments.NotNull(nameof(options.Payments))!.Validate();

var baseUri = (options.UseSandbox ?? true)
? TrueLayerBaseUris.SandboxApiBaseUri
: TrueLayerBaseUris.ProdApiBaseUri;

_baseUri = (options.Payments.Uri ?? baseUri)
.Append("/v3/mandates/");
_baseUri = options.GetApiBaseUri()
.Append(MandatesEndpoints.V3Mandates);
}

/// <inheritdoc />
Expand All @@ -49,7 +44,7 @@ public async Task<ApiResponse<CreateMandateResponse>> CreateMandate(CreateMandat
mandateRequest.NotNull(nameof(mandateRequest));
idempotencyKey.NotNullOrWhiteSpace(nameof(idempotencyKey));
var type = mandateRequest.Mandate.Match(t0 => t0.Type, t1 => t1.Type);
ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{type}"), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{type}"), cancellationToken);

if (!authResponse.IsSuccessful)
{
Expand All @@ -73,7 +68,7 @@ public async Task<ApiResponse<MandateDetailUnion>> GetMandate(string mandateId,
mandateId.NotNullOrWhiteSpace(nameof(mandateId));
mandateId.NotAUrl(nameof(mandateId));

ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);

if (!authResponse.IsSuccessful)
{
Expand All @@ -90,7 +85,7 @@ public async Task<ApiResponse<MandateDetailUnion>> GetMandate(string mandateId,
/// <inheritdoc />
public async Task<ApiResponse<ResourceCollection<MandateDetailUnion>>> ListMandates(ListMandatesQuery query, MandateType mandateType, CancellationToken cancellationToken = default)
{
ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);

if (!authResponse.IsSuccessful)
{
Expand All @@ -117,15 +112,15 @@ public async Task<ApiResponse<AuthorizationResponseUnion>> StartAuthorizationFlo
mandateId.NotAUrl(nameof(mandateId));
request.NotNull(nameof(request));
idempotencyKey.NotNullOrWhiteSpace(nameof(idempotencyKey));
ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);

if (!authResponse.IsSuccessful)
{
return new(authResponse.StatusCode, authResponse.TraceId);
}

return await _apiClient.PostAsync<AuthorizationResponseUnion>(
_baseUri.Append($"{mandateId}/authorization-flow"),
_baseUri.Append(mandateId).Append(MandatesEndpoints.AuthorizationFlow),
request,
idempotencyKey,
authResponse.Data!.AccessToken,
Expand All @@ -141,15 +136,15 @@ public async Task<ApiResponse<AuthorizationResponseUnion>> SubmitProviderSelecti
mandateId.NotAUrl(nameof(mandateId));
request.NotNull(nameof(request));
idempotencyKey.NotNullOrWhiteSpace(nameof(idempotencyKey));
ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);

if (!authResponse.IsSuccessful)
{
return new(authResponse.StatusCode, authResponse.TraceId);
}

return await _apiClient.PostAsync<AuthorizationResponseUnion>(
_baseUri.Append($"{mandateId}/authorization-flow/actions/provider-selection"),
_baseUri.Append(mandateId).Append(MandatesEndpoints.ProviderSelection),
request,
idempotencyKey,
authResponse.Data!.AccessToken,
Expand All @@ -163,15 +158,15 @@ public async Task<ApiResponse<AuthorizationResponseUnion>> SubmitConsent(string
mandateId.NotNullOrWhiteSpace(nameof(mandateId));
mandateId.NotAUrl(nameof(mandateId));
idempotencyKey.NotNullOrWhiteSpace(nameof(idempotencyKey));
ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);

if (!authResponse.IsSuccessful)
{
return new(authResponse.StatusCode, authResponse.TraceId);
}

return await _apiClient.PostAsync<AuthorizationResponseUnion>(
_baseUri.Append($"{mandateId}/authorization-flow/actions/consent"),
_baseUri.Append(mandateId).Append(MandatesEndpoints.Consent),
null,
idempotencyKey,
authResponse.Data!.AccessToken,
Expand All @@ -186,15 +181,15 @@ public async Task<ApiResponse<GetConfirmationOfFundsResponse>> GetConfirmationOf
mandateId.NotNullOrWhiteSpace(nameof(mandateId));
mandateId.NotAUrl(nameof(mandateId));

ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);

if (!authResponse.IsSuccessful)
{
return new(authResponse.StatusCode, authResponse.TraceId);
}

return await _apiClient.GetAsync<GetConfirmationOfFundsResponse>(
_baseUri.Append($"{mandateId}/funds?amount_in_minor={amountInMinor}&currency={currency}"),
_baseUri.Append(mandateId).Append(MandatesEndpoints.Funds).Append($"?amount_in_minor={amountInMinor}&currency={currency}"),
authResponse.Data!.AccessToken,
cancellationToken: cancellationToken
);
Expand All @@ -206,15 +201,15 @@ public async Task<ApiResponse<GetConstraintsResponse>> GetMandateConstraints(str
mandateId.NotNullOrWhiteSpace(nameof(mandateId));
mandateId.NotAUrl(nameof(mandateId));

ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);

if (!authResponse.IsSuccessful)
{
return new(authResponse.StatusCode, authResponse.TraceId);
}

return await _apiClient.GetAsync<GetConstraintsResponse>(
_baseUri.Append($"{mandateId}/constraints"),
_baseUri.Append(mandateId).Append(MandatesEndpoints.Constraints),
authResponse.Data!.AccessToken,
cancellationToken: cancellationToken
);
Expand All @@ -226,15 +221,15 @@ public async Task<ApiResponse> RevokeMandate(string mandateId, string idempotenc
mandateId.NotNullOrWhiteSpace(nameof(mandateId));
mandateId.NotAUrl(nameof(mandateId));

ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest($"recurring_payments:{mandateType.AsString()}"), cancellationToken);

if (!authResponse.IsSuccessful)
{
return new(authResponse.StatusCode, authResponse.TraceId);
}

return await _apiClient.PostAsync(
_baseUri.Append($"{mandateId}/revoke"),
_baseUri.Append(mandateId).Append(MandatesEndpoints.Revoke),
null,
idempotencyKey,
authResponse.Data!.AccessToken,
Expand Down
12 changes: 12 additions & 0 deletions src/TrueLayer/Mandates/MandatesEdnpoints.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace TrueLayer.Mandates;

internal static class MandatesEndpoints
{
internal static readonly string V3Mandates = new("/v3/mandates/");
internal static readonly string AuthorizationFlow = new("/authorization-flow");
internal static readonly string ProviderSelection = new("/authorization-flow/actions/provider-selection");
internal static readonly string Consent = new("/authorization-flow/actions/consent");
internal static readonly string Funds = new("/funds");
internal static readonly string Constraints = new("/constraints");
internal static readonly string Revoke = new("/revoke");
}
1 change: 0 additions & 1 deletion src/TrueLayer/Mandates/Model/MandateDetail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using TrueLayer.Payments.Model;
using TrueLayer.Serialization;
using static TrueLayer.Mandates.Model.Beneficiary;
using static TrueLayer.Mandates.Model.MandateDetail;

namespace TrueLayer.Mandates.Model
{
Expand Down
21 changes: 8 additions & 13 deletions src/TrueLayer/MerchantAccounts/MerchantAccountsApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Threading;
using System.Threading.Tasks;
using TrueLayer.Auth;
using TrueLayer.Common;
using TrueLayer.Extensions;
using TrueLayer.MerchantAccounts.Model;
using TrueLayer.Models;
Expand All @@ -24,18 +23,14 @@ public MerchantAccountsApi(IApiClient apiClient, IAuthApi auth, TrueLayerOptions

options.Payments.NotNull(nameof(options.Payments))!.Validate();

var baseUri = (options.UseSandbox ?? true)
? TrueLayerBaseUris.SandboxApiBaseUri
: TrueLayerBaseUris.ProdApiBaseUri;

_baseUri = (options.Payments.Uri ?? baseUri)
.Append("/v3/merchant-accounts");
_baseUri = _baseUri = options.GetApiBaseUri()
.Append(MerchantAccountsEndpoints.V3MerchantAccounts);
}

/// <inheritdoc />
public async Task<ApiResponse<ResourceCollection<MerchantAccount>>> ListMerchantAccounts(CancellationToken cancellationToken = default)
{
ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest(AuthorizationScope.Payments), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest(AuthorizationScope.Payments), cancellationToken);

if (!authResponse.IsSuccessful)
{
Expand All @@ -55,7 +50,7 @@ public async Task<ApiResponse<MerchantAccount>> GetMerchantAccount(string id, Ca
id.NotNullOrWhiteSpace(nameof(id));
id.NotAUrl(nameof(id));

ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest(AuthorizationScope.Payments), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest(AuthorizationScope.Payments), cancellationToken);

if (!authResponse.IsSuccessful)
{
Expand All @@ -77,15 +72,15 @@ public async Task<ApiResponse<GetPaymentSourcesResponse>> GetPaymentSources(stri
userId.NotNullOrWhiteSpace(nameof(userId));
userId.NotAUrl(nameof(userId));

ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest(AuthorizationScope.Payments), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest(AuthorizationScope.Payments), cancellationToken);

if (!authResponse.IsSuccessful)
{
return new(authResponse.StatusCode, authResponse.TraceId);
}

return await _apiClient.GetAsync<GetPaymentSourcesResponse>(
_baseUri.Append($"{merchantAccountId}/payment-sources?user_id={userId}"),
_baseUri.Append(merchantAccountId).Append($"/payment-sources?user_id={userId}"),
authResponse.Data!.AccessToken,
cancellationToken: cancellationToken
);
Expand All @@ -105,7 +100,7 @@ public async Task<ApiResponse<GetTransactionsResponse>> GetTransactions(
to.GreaterThan(from, nameof(to), nameof(from));
cursor.NotAUrl(nameof(cursor));

ApiResponse<GetAuthTokenResponse> authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest(AuthorizationScope.Payments), cancellationToken);
var authResponse = await _auth.GetAuthToken(new GetAuthTokenRequest(AuthorizationScope.Payments), cancellationToken);

if (!authResponse.IsSuccessful)
{
Expand All @@ -118,7 +113,7 @@ public async Task<ApiResponse<GetTransactionsResponse>> GetTransactions(
};

return await _apiClient.GetAsync<GetTransactionsResponse>(
_baseUri.Append($"/{merchantAccountId}/transactions")
_baseUri.Append(merchantAccountId).Append(MerchantAccountsEndpoints.Transactions)
.AppendQueryParameters(new Dictionary<string, string?>
{
["from"] = from.ToString("yyyy-MM-ddTHH:MM:ssZ"),
Expand Down
7 changes: 7 additions & 0 deletions src/TrueLayer/MerchantAccounts/MerchantAccountsEndpoints.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TrueLayer.MerchantAccounts;

internal static class MerchantAccountsEndpoints
{
internal const string V3MerchantAccounts = "/v3/merchant-accounts";
internal const string Transactions = "/transactions";
}
Loading

0 comments on commit 852d7b9

Please sign in to comment.