diff --git a/src/Mollie.Api/Client/BalanceClient.cs b/src/Mollie.Api/Client/BalanceClient.cs index ffe21cc1..b5c1bfea 100644 --- a/src/Mollie.Api/Client/BalanceClient.cs +++ b/src/Mollie.Api/Client/BalanceClient.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.Balance.Response; using Mollie.Api.Models.Balance.Response.BalanceReport; using Mollie.Api.Models.Balance.Response.BalanceTransaction; @@ -16,6 +17,9 @@ public class BalanceClient : BaseMollieClient, IBalanceClient { public BalanceClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public BalanceClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetBalanceAsync(string balanceId) { ValidateRequiredUrlParameter(nameof(balanceId), balanceId); return await GetAsync($"balances/{balanceId}").ConfigureAwait(false); diff --git a/src/Mollie.Api/Client/BaseMollieClient.cs b/src/Mollie.Api/Client/BaseMollieClient.cs index 07755bdd..3eb16e6c 100644 --- a/src/Mollie.Api/Client/BaseMollieClient.cs +++ b/src/Mollie.Api/Client/BaseMollieClient.cs @@ -8,6 +8,8 @@ using System.Threading.Tasks; using Mollie.Api.Extensions; using Mollie.Api.Framework; +using Mollie.Api.Framework.Authentication; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Framework.Idempotency; using Mollie.Api.Models.Error; using Mollie.Api.Models.Url; @@ -17,7 +19,7 @@ namespace Mollie.Api.Client { public abstract class BaseMollieClient : IDisposable { public const string ApiEndPoint = "https://api.mollie.com/v2/"; private readonly string _apiEndpoint = ApiEndPoint; - private readonly string _apiKey; + private readonly IBearerTokenRetriever _bearerTokenRetriever; private readonly HttpClient _httpClient; private readonly JsonConverterService _jsonConverterService; @@ -33,7 +35,14 @@ protected BaseMollieClient(string apiKey, HttpClient? httpClient = null) { _jsonConverterService = new JsonConverterService(); _createdHttpClient = httpClient == null; _httpClient = httpClient ?? new HttpClient(); - _apiKey = apiKey; + _bearerTokenRetriever = new DefaultBearerTokenRetriever(apiKey); + } + + protected BaseMollieClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) { + _jsonConverterService = new JsonConverterService(); + _createdHttpClient = httpClient == null; + _httpClient = httpClient ?? new HttpClient(); + _bearerTokenRetriever = bearerTokenRetriever; } protected BaseMollieClient(HttpClient? httpClient = null, string apiEndpoint = ApiEndPoint) { @@ -41,7 +50,7 @@ protected BaseMollieClient(HttpClient? httpClient = null, string apiEndpoint = A _jsonConverterService = new JsonConverterService(); _createdHttpClient = httpClient == null; _httpClient = httpClient ?? new HttpClient(); - _apiKey = string.Empty; + _bearerTokenRetriever = new DefaultBearerTokenRetriever(string.Empty); } public IDisposable WithIdempotencyKey(string value) { @@ -99,7 +108,8 @@ private async Task ProcessHttpResponseMessage(HttpResponseMessage response } protected void ValidateApiKeyIsOauthAccesstoken(bool isConstructor = false) { - if (!_apiKey.StartsWith("access_")) { + string apiKey = _bearerTokenRetriever.GetBearerToken(); + if (!apiKey.StartsWith("access_")) { if (isConstructor) { throw new InvalidOperationException( "The provided token isn't an oauth token. You have invoked the method with oauth parameters thus an oauth accesstoken is required."); @@ -124,7 +134,7 @@ private void ValidateUrlLink(UrlLink urlObject) { protected virtual HttpRequestMessage CreateHttpRequest(HttpMethod method, string relativeUri, HttpContent? content = null) { HttpRequestMessage httpRequest = new HttpRequestMessage(method, new Uri(new Uri(_apiEndpoint), relativeUri)); httpRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey); + httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _bearerTokenRetriever.GetBearerToken()); httpRequest.Headers.Add("User-Agent", GetUserAgent()); var idemPotencyKey = _idempotencyKey.Value ?? Guid.NewGuid().ToString(); httpRequest.Headers.Add("Idempotency-Key", idemPotencyKey); diff --git a/src/Mollie.Api/Client/CaptureClient.cs b/src/Mollie.Api/Client/CaptureClient.cs index bfcb5fb1..1400f52d 100644 --- a/src/Mollie.Api/Client/CaptureClient.cs +++ b/src/Mollie.Api/Client/CaptureClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.Capture.Request; using Mollie.Api.Models.Capture.Response; using Mollie.Api.Models.List.Response; @@ -14,6 +15,9 @@ public class CaptureClient : BaseMollieClient, ICaptureClient { public CaptureClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public CaptureClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetCaptureAsync(string paymentId, string captureId, bool testmode = false) { ValidateRequiredUrlParameter(nameof(paymentId), paymentId); ValidateRequiredUrlParameter(nameof(captureId), captureId); diff --git a/src/Mollie.Api/Client/ChargebackClient.cs b/src/Mollie.Api/Client/ChargebackClient.cs index 1e3ea12a..00e9fcf8 100644 --- a/src/Mollie.Api/Client/ChargebackClient.cs +++ b/src/Mollie.Api/Client/ChargebackClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.Chargeback.Response; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Url; @@ -12,6 +13,9 @@ public class ChargebackClient : BaseMollieClient, IChargebackClient { public ChargebackClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public ChargebackClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetChargebackAsync(string paymentId, string chargebackId, bool testmode = false) { ValidateRequiredUrlParameter(nameof(paymentId), paymentId); ValidateRequiredUrlParameter(nameof(chargebackId), chargebackId); diff --git a/src/Mollie.Api/Client/ClientLinkClient.cs b/src/Mollie.Api/Client/ClientLinkClient.cs index 908162e4..4ea6a2b0 100644 --- a/src/Mollie.Api/Client/ClientLinkClient.cs +++ b/src/Mollie.Api/Client/ClientLinkClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.ClientLink.Request; using Mollie.Api.Models.ClientLink.Response; @@ -17,6 +18,11 @@ public ClientLinkClient(string clientId, string oauthAccessToken, HttpClient? ht _clientId = clientId; } + public ClientLinkClient(string clientId, IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) + : base(bearerTokenRetriever, httpClient) { + _clientId = clientId; + } + public async Task CreateClientLinkAsync(ClientLinkRequest request) { return await PostAsync($"client-links", request) diff --git a/src/Mollie.Api/Client/CustomerClient.cs b/src/Mollie.Api/Client/CustomerClient.cs index e326beb2..bf7c554d 100644 --- a/src/Mollie.Api/Client/CustomerClient.cs +++ b/src/Mollie.Api/Client/CustomerClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models; using Mollie.Api.Models.Customer.Request; using Mollie.Api.Models.Customer.Response; @@ -16,6 +17,9 @@ public class CustomerClient : BaseMollieClient, ICustomerClient { public CustomerClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public CustomerClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task CreateCustomerAsync(CustomerRequest request) { return await PostAsync($"customers", request).ConfigureAwait(false); } diff --git a/src/Mollie.Api/Client/InvoiceClient.cs b/src/Mollie.Api/Client/InvoiceClient.cs index 8284e62e..a2d9a045 100644 --- a/src/Mollie.Api/Client/InvoiceClient.cs +++ b/src/Mollie.Api/Client/InvoiceClient.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.Invoice.Response; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Url; @@ -13,6 +14,9 @@ public class InvoiceClient : OauthBaseMollieClient, IInvoiceClient { public InvoiceClient(string oauthAccessToken, HttpClient? httpClient = null) : base(oauthAccessToken, httpClient) { } + public InvoiceClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetInvoiceAsync(string invoiceId) { ValidateRequiredUrlParameter(nameof(invoiceId), invoiceId); return await GetAsync($"invoices/{invoiceId}").ConfigureAwait(false); diff --git a/src/Mollie.Api/Client/MandateClient.cs b/src/Mollie.Api/Client/MandateClient.cs index 15a26902..c73fdec0 100644 --- a/src/Mollie.Api/Client/MandateClient.cs +++ b/src/Mollie.Api/Client/MandateClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Mandate.Request; @@ -14,6 +15,9 @@ public class MandateClient : BaseMollieClient, IMandateClient { public MandateClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public MandateClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetMandateAsync(string customerId, string mandateId, bool testmode = false) { ValidateRequiredUrlParameter(nameof(customerId), customerId); ValidateRequiredUrlParameter(nameof(mandateId), mandateId); diff --git a/src/Mollie.Api/Client/OauthBaseMollieClient.cs b/src/Mollie.Api/Client/OauthBaseMollieClient.cs index 1f9f5555..31e6aa57 100644 --- a/src/Mollie.Api/Client/OauthBaseMollieClient.cs +++ b/src/Mollie.Api/Client/OauthBaseMollieClient.cs @@ -1,9 +1,20 @@ using System; using System.Net.Http; +using Mollie.Api.Framework.Authentication.Abstract; namespace Mollie.Api.Client { public class OauthBaseMollieClient : BaseMollieClient { - public OauthBaseMollieClient(string oauthAccessToken, HttpClient? httpClient = null) : base(oauthAccessToken, httpClient) { + protected OauthBaseMollieClient(string oauthAccessToken, HttpClient? httpClient = null) + : base(oauthAccessToken, httpClient) { + ValidateApiKeyIsOauthAccesstoken(oauthAccessToken); + } + + protected OauthBaseMollieClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) + : base(bearerTokenRetriever, httpClient) { + ValidateApiKeyIsOauthAccesstoken(bearerTokenRetriever.GetBearerToken()); + } + + private void ValidateApiKeyIsOauthAccesstoken(string oauthAccessToken) { if (string.IsNullOrWhiteSpace(oauthAccessToken)) { throw new ArgumentNullException(nameof(oauthAccessToken), "Mollie API key cannot be empty"); } diff --git a/src/Mollie.Api/Client/OnboardingClient.cs b/src/Mollie.Api/Client/OnboardingClient.cs index 701fb39d..e1cef40a 100644 --- a/src/Mollie.Api/Client/OnboardingClient.cs +++ b/src/Mollie.Api/Client/OnboardingClient.cs @@ -3,12 +3,16 @@ using Mollie.Api.Models.Onboarding.Response; using System.Net.Http; using System.Threading.Tasks; +using Mollie.Api.Framework.Authentication.Abstract; namespace Mollie.Api.Client { public class OnboardingClient : BaseMollieClient, IOnboardingClient { public OnboardingClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public OnboardingClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetOnboardingStatusAsync() { return await GetAsync("onboarding/me").ConfigureAwait(false); } diff --git a/src/Mollie.Api/Client/OrderClient.cs b/src/Mollie.Api/Client/OrderClient.cs index 97566c3d..bc3c8956 100644 --- a/src/Mollie.Api/Client/OrderClient.cs +++ b/src/Mollie.Api/Client/OrderClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Order.Request; @@ -16,6 +17,9 @@ public class OrderClient : BaseMollieClient, IOrderClient { public OrderClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public OrderClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task CreateOrderAsync(OrderRequest orderRequest) { return await PostAsync("orders", orderRequest).ConfigureAwait(false); } diff --git a/src/Mollie.Api/Client/OrganizationClient.cs b/src/Mollie.Api/Client/OrganizationClient.cs index f9e86853..b5d4dddd 100644 --- a/src/Mollie.Api/Client/OrganizationClient.cs +++ b/src/Mollie.Api/Client/OrganizationClient.cs @@ -1,6 +1,7 @@ using System.Net.Http; using System.Threading.Tasks; using Mollie.Api.Client.Abstract; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Organization; using Mollie.Api.Models.Url; @@ -10,6 +11,9 @@ public class OrganizationClient : OauthBaseMollieClient, IOrganizationClient { public OrganizationClient(string oauthAccessToken, HttpClient? httpClient = null) : base(oauthAccessToken, httpClient) { } + public OrganizationClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetCurrentOrganizationAsync() { return await GetAsync($"organizations/me").ConfigureAwait(false); } diff --git a/src/Mollie.Api/Client/PaymentClient.cs b/src/Mollie.Api/Client/PaymentClient.cs index 2f13e526..d04dfad1 100644 --- a/src/Mollie.Api/Client/PaymentClient.cs +++ b/src/Mollie.Api/Client/PaymentClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Payment.Request; @@ -14,6 +15,9 @@ public class PaymentClient : BaseMollieClient, IPaymentClient { public PaymentClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public PaymentClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task CreatePaymentAsync(PaymentRequest paymentRequest, bool includeQrCode = false) { if (!string.IsNullOrWhiteSpace(paymentRequest.ProfileId) || paymentRequest.Testmode.HasValue || paymentRequest.ApplicationFee != null) { ValidateApiKeyIsOauthAccesstoken(); diff --git a/src/Mollie.Api/Client/PaymentLinkClient.cs b/src/Mollie.Api/Client/PaymentLinkClient.cs index 5ea2d778..3fe03e68 100644 --- a/src/Mollie.Api/Client/PaymentLinkClient.cs +++ b/src/Mollie.Api/Client/PaymentLinkClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Payment.Response; @@ -16,6 +17,9 @@ public class PaymentLinkClient : BaseMollieClient, IPaymentLinkClient { public PaymentLinkClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public PaymentLinkClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task CreatePaymentLinkAsync(PaymentLinkRequest paymentLinkRequest) { if (!string.IsNullOrWhiteSpace(paymentLinkRequest.ProfileId) || paymentLinkRequest.Testmode.HasValue) diff --git a/src/Mollie.Api/Client/PaymentMethodClient.cs b/src/Mollie.Api/Client/PaymentMethodClient.cs index a13bc0ad..df23ba12 100644 --- a/src/Mollie.Api/Client/PaymentMethodClient.cs +++ b/src/Mollie.Api/Client/PaymentMethodClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Payment; @@ -16,6 +17,9 @@ public class PaymentMethodClient : BaseMollieClient, IPaymentMethodClient public PaymentMethodClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public PaymentMethodClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetPaymentMethodAsync( string paymentMethod, bool includeIssuers = false, diff --git a/src/Mollie.Api/Client/PermissionClient.cs b/src/Mollie.Api/Client/PermissionClient.cs index 7034dede..c1abc52c 100644 --- a/src/Mollie.Api/Client/PermissionClient.cs +++ b/src/Mollie.Api/Client/PermissionClient.cs @@ -1,6 +1,7 @@ using System.Net.Http; using System.Threading.Tasks; using Mollie.Api.Client.Abstract; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Permission.Response; using Mollie.Api.Models.Url; @@ -10,6 +11,9 @@ public class PermissionClient : OauthBaseMollieClient, IPermissionClient { public PermissionClient(string oauthAccessToken, HttpClient? httpClient = null) : base(oauthAccessToken, httpClient) { } + public PermissionClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetPermissionAsync(string permissionId) { ValidateRequiredUrlParameter(nameof(permissionId), permissionId); return await GetAsync($"permissions/{permissionId}").ConfigureAwait(false); diff --git a/src/Mollie.Api/Client/ProfileClient.cs b/src/Mollie.Api/Client/ProfileClient.cs index a585315b..5ad55cea 100644 --- a/src/Mollie.Api/Client/ProfileClient.cs +++ b/src/Mollie.Api/Client/ProfileClient.cs @@ -1,6 +1,7 @@ using System.Net.Http; using System.Threading.Tasks; using Mollie.Api.Client.Abstract; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.PaymentMethod.Response; using Mollie.Api.Models.Profile.Request; @@ -12,6 +13,9 @@ public class ProfileClient : BaseMollieClient, IProfileClient { public ProfileClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public ProfileClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task CreateProfileAsync(ProfileRequest request) { return await PostAsync("profiles", request).ConfigureAwait(false); } diff --git a/src/Mollie.Api/Client/RefundClient.cs b/src/Mollie.Api/Client/RefundClient.cs index cf23b322..6d26e253 100644 --- a/src/Mollie.Api/Client/RefundClient.cs +++ b/src/Mollie.Api/Client/RefundClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Order.Request; using Mollie.Api.Models.Order.Response; @@ -15,6 +16,9 @@ public class RefundClient : BaseMollieClient, IRefundClient { public RefundClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public RefundClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task CreatePaymentRefundAsync(string paymentId, RefundRequest refundRequest) { ValidateRequiredUrlParameter(nameof(paymentId), paymentId); diff --git a/src/Mollie.Api/Client/SettlementClient.cs b/src/Mollie.Api/Client/SettlementClient.cs index c8a60555..9b1ba424 100644 --- a/src/Mollie.Api/Client/SettlementClient.cs +++ b/src/Mollie.Api/Client/SettlementClient.cs @@ -1,6 +1,7 @@ using System.Net.Http; using System.Threading.Tasks; using Mollie.Api.Client.Abstract; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.Capture.Response; using Mollie.Api.Models.Chargeback.Response; using Mollie.Api.Models.List.Response; @@ -14,6 +15,9 @@ public class SettlementClient : BaseMollieClient, ISettlementClient { public SettlementClient(string oauthAccessToken, HttpClient? httpClient = null) : base(oauthAccessToken, httpClient) { } + public SettlementClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetSettlementAsync(string settlementId) { ValidateRequiredUrlParameter(nameof(settlementId), settlementId); return await GetAsync($"settlements/{settlementId}").ConfigureAwait(false); diff --git a/src/Mollie.Api/Client/ShipmentClient.cs b/src/Mollie.Api/Client/ShipmentClient.cs index d8551c09..bf57a000 100644 --- a/src/Mollie.Api/Client/ShipmentClient.cs +++ b/src/Mollie.Api/Client/ShipmentClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Shipment.Request; using Mollie.Api.Models.Shipment.Response; @@ -14,6 +15,9 @@ public class ShipmentClient : BaseMollieClient, IShipmentClient { public ShipmentClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public ShipmentClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task CreateShipmentAsync(string orderId, ShipmentRequest shipmentRequest) { ValidateRequiredUrlParameter(nameof(orderId), orderId); return await PostAsync($"orders/{orderId}/shipments", shipmentRequest) diff --git a/src/Mollie.Api/Client/SubscriptionClient.cs b/src/Mollie.Api/Client/SubscriptionClient.cs index e2ff16d2..f3afd8f5 100644 --- a/src/Mollie.Api/Client/SubscriptionClient.cs +++ b/src/Mollie.Api/Client/SubscriptionClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Payment.Response; @@ -15,6 +16,9 @@ public class SubscriptionClient : BaseMollieClient, ISubscriptionClient { public SubscriptionClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public SubscriptionClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task> GetSubscriptionListAsync(string customerId, string? from = null, int? limit = null, string? profileId = null, bool testmode = false) { ValidateRequiredUrlParameter(nameof(customerId), customerId); var queryParameters = BuildQueryParameters(profileId, testmode); diff --git a/src/Mollie.Api/Client/TerminalClient.cs b/src/Mollie.Api/Client/TerminalClient.cs index dbca1538..e57c0ea7 100644 --- a/src/Mollie.Api/Client/TerminalClient.cs +++ b/src/Mollie.Api/Client/TerminalClient.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Mollie.Api.Client.Abstract; using Mollie.Api.Extensions; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.List.Response; using Mollie.Api.Models.Terminal.Response; using Mollie.Api.Models.Url; @@ -12,6 +13,9 @@ public class TerminalClient : BaseMollieClient, ITerminalClient { public TerminalClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public TerminalClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task GetTerminalAsync(string terminalId) { ValidateRequiredUrlParameter(nameof(terminalId), terminalId); return await GetAsync($"terminals/{terminalId}").ConfigureAwait(false); diff --git a/src/Mollie.Api/Client/WalletClient.cs b/src/Mollie.Api/Client/WalletClient.cs index 5f7ff87b..c9efc1d6 100644 --- a/src/Mollie.Api/Client/WalletClient.cs +++ b/src/Mollie.Api/Client/WalletClient.cs @@ -1,6 +1,7 @@ using System.Net.Http; using System.Threading.Tasks; using Mollie.Api.Client.Abstract; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Models.Wallet.Request; using Mollie.Api.Models.Wallet.Response; @@ -9,6 +10,9 @@ public class WalletClient : BaseMollieClient, IWalletClient { public WalletClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { } + public WalletClient(IBearerTokenRetriever bearerTokenRetriever, HttpClient? httpClient = null) : base(bearerTokenRetriever, httpClient) { + } + public async Task RequestApplePayPaymentSessionAsync(ApplePayPaymentSessionRequest request) { return await PostAsync("wallets/applepay/sessions", request).ConfigureAwait(false); } diff --git a/src/Mollie.Api/DependencyInjection.cs b/src/Mollie.Api/DependencyInjection.cs index 91665c8d..bb28e82e 100644 --- a/src/Mollie.Api/DependencyInjection.cs +++ b/src/Mollie.Api/DependencyInjection.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection; using Mollie.Api.Client; using Mollie.Api.Client.Abstract; +using Mollie.Api.Framework.Authentication; +using Mollie.Api.Framework.Authentication.Abstract; using Mollie.Api.Options; using Polly; @@ -12,53 +14,56 @@ public static IServiceCollection AddMollieApi( this IServiceCollection services, Action mollieOptionsDelegate) { - MollieOptions mollieOptions = new MollieOptions(); + MollieOptions mollieOptions = new(); mollieOptionsDelegate.Invoke(mollieOptions); + IBearerTokenRetriever bearerTokenRetriever = mollieOptions.BearerTokenRetriever ?? + new DefaultBearerTokenRetriever(mollieOptions.ApiKey); + RegisterMollieApiClient(services, httpClient => - new BalanceClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new BalanceClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new CaptureClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new CaptureClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new ChargebackClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new ChargebackClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => new ConnectClient(mollieOptions.ClientId, mollieOptions.ClientSecret, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new CustomerClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new CustomerClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new InvoiceClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new InvoiceClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new MandateClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new MandateClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new OnboardingClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new OnboardingClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new OrderClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new OrderClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new OrganizationClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new OrganizationClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new PaymentClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new PaymentClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new PaymentLinkClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new PaymentLinkClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new PaymentMethodClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new PaymentMethodClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new PermissionClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new PermissionClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new ProfileClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new ProfileClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new RefundClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new RefundClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new SettlementClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new SettlementClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new ShipmentClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new ShipmentClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new SubscriptionClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new SubscriptionClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new TerminalClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new TerminalClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new ClientLinkClient(mollieOptions.ClientId, mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new ClientLinkClient(mollieOptions.ClientId, bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); RegisterMollieApiClient(services, httpClient => - new WalletClient(mollieOptions.ApiKey, httpClient), mollieOptions.RetryPolicy); + new WalletClient(bearerTokenRetriever, httpClient), mollieOptions.RetryPolicy); return services; } diff --git a/src/Mollie.Api/Framework/Authentication/Abstract/IBearerTokenRetriever.cs b/src/Mollie.Api/Framework/Authentication/Abstract/IBearerTokenRetriever.cs new file mode 100644 index 00000000..781d7cd3 --- /dev/null +++ b/src/Mollie.Api/Framework/Authentication/Abstract/IBearerTokenRetriever.cs @@ -0,0 +1,5 @@ +namespace Mollie.Api.Framework.Authentication.Abstract; + +public interface IBearerTokenRetriever { + public string GetBearerToken(); +} diff --git a/src/Mollie.Api/Framework/Authentication/DefaultBearerTokenRetriever.cs b/src/Mollie.Api/Framework/Authentication/DefaultBearerTokenRetriever.cs new file mode 100644 index 00000000..6896f3d0 --- /dev/null +++ b/src/Mollie.Api/Framework/Authentication/DefaultBearerTokenRetriever.cs @@ -0,0 +1,9 @@ +using Mollie.Api.Framework.Authentication.Abstract; + +namespace Mollie.Api.Framework.Authentication; + +public class DefaultBearerTokenRetriever(string apiKey) : IBearerTokenRetriever { + public string GetBearerToken() { + return apiKey; + } +} diff --git a/src/Mollie.Api/Options/MollieOptions.cs b/src/Mollie.Api/Options/MollieOptions.cs index abce1b77..b4a71e44 100644 --- a/src/Mollie.Api/Options/MollieOptions.cs +++ b/src/Mollie.Api/Options/MollieOptions.cs @@ -1,4 +1,5 @@ using System.Net.Http; +using Mollie.Api.Framework.Authentication.Abstract; using Polly; namespace Mollie.Api.Options { @@ -12,16 +13,21 @@ public record MollieOptions { /// (Optional) ClientId used by Connect API /// public string ClientId { get; set; } = string.Empty; - + /// /// (Optional) ClientSecret used by Connect API /// /// public string ClientSecret { get; set; } = string.Empty; - + /// /// (Optional) Polly retry policy for failed requests /// public IAsyncPolicy? RetryPolicy { get; set; } + + /// + /// (Optional) Set a custom bearer token retrieval, in case you have a multi-tenant setup with multiple API keys + /// + public IBearerTokenRetriever? BearerTokenRetriever { get; set; } = null; } -} \ No newline at end of file +}