From bf3072cf644ec001e50eb0c3649ce6c3f954c6fa Mon Sep 17 00:00:00 2001 From: gcatanese Date: Mon, 21 Jul 2025 16:29:16 +0200 Subject: [PATCH 01/10] Add javadoc and tests --- src/main/java/com/adyen/Service.java | 152 ++++++++++++++--------- src/test/java/com/adyen/ServiceTest.java | 101 +++++++++++++++ 2 files changed, 195 insertions(+), 58 deletions(-) create mode 100644 src/test/java/com/adyen/ServiceTest.java diff --git a/src/main/java/com/adyen/Service.java b/src/main/java/com/adyen/Service.java index 8d1fb877b..52c960e28 100644 --- a/src/main/java/com/adyen/Service.java +++ b/src/main/java/com/adyen/Service.java @@ -22,71 +22,107 @@ import com.adyen.enums.Environment; -/** Parent class for all Service implementations */ +/** + * A generic service that provides shared functionality for all API services. + * It handles client and configuration management. + */ public class Service { - private boolean isApiKeyRequired = false; - private Client client; - - protected Service(Client client) { - this.client = client; - } - - public Client getClient() { - return client; - } + private boolean isApiKeyRequired = false; + private Client client; - public void setClient(Client client) { - this.client = client; - } - - public boolean isApiKeyRequired() { - return isApiKeyRequired; - } + /** + * Constructs a new Service. + * + * @param client The client used to make API calls. + */ + protected Service(Client client) { + this.client = client; + } - public void setApiKeyRequired(boolean apiKeyRequired) { - isApiKeyRequired = apiKeyRequired; - } + /** + * Gets the client used by this service. + * + * @return The client. + */ + public Client getClient() { + return client; + } - protected String createBaseURL(String url) { - Config config = this.getClient().getConfig(); - if (config.getEnvironment() != Environment.LIVE) { - return url.replaceFirst("-live", "-test"); + /** + * Sets the client to be used by this service. + * + * @param client The client. + */ + public void setClient(Client client) { + this.client = client; } - if (url.contains("pal-")) { - if (config.getLiveEndpointUrlPrefix() == null) { - throw new IllegalArgumentException("please provide a live url prefix in the client"); - } - url = - url.replaceFirst( - "https://pal-test.adyen.com/pal/servlet/", - "https://" - + config.getLiveEndpointUrlPrefix() - + "-pal-live.adyenpayments.com/pal/servlet/"); + /** + * Returns true if the service requires an API key. + * + * @return A boolean indicating if an API key is required. + */ + public boolean isApiKeyRequired() { + return isApiKeyRequired; } - if (url.contains("checkout-")) { - if (config.getLiveEndpointUrlPrefix() == null) { - throw new IllegalArgumentException("please provide a live url prefix in the client"); - } - if (url.contains("/possdk/v68")) { - // Temporary until they fix possdk - url = - url.replaceFirst( - "https://checkout-test.adyen.com/", - "https://" - + config.getLiveEndpointUrlPrefix() - + "-checkout-live.adyenpayments.com/"); - } else { - url = - url.replaceFirst( - "https://checkout-test.adyen.com/", - "https://" - + config.getLiveEndpointUrlPrefix() - + "-checkout-live.adyenpayments.com/checkout/"); - } + /** + * Sets if the service requires an API key. + * + * @param apiKeyRequired A boolean indicating if an API key is required. + */ + public void setApiKeyRequired(boolean apiKeyRequired) { + isApiKeyRequired = apiKeyRequired; } - return url.replaceFirst("-test", "-live"); - } -} + /** + * Creates the base URL for a specific API endpoint. It dynamically constructs the URL + * based on the client's configured {@link Environment}. + * + * @param url The base URL template. + * @return The fully constructed base URL for the target environment. + * @throws IllegalArgumentException if the live URL prefix is required but not configured. + */ + protected String createBaseURL(String url) { + Config config = this.getClient().getConfig(); + if (config.getEnvironment() != Environment.LIVE) { + return url.replaceFirst("-live", "-test"); + } + + if (url.contains("pal-")) { + if (config.getLiveEndpointUrlPrefix() == null) { + throw new IllegalArgumentException("please provide a live url prefix in the client"); + } + url = + url.replaceFirst( + "https://pal-test.adyen.com/pal/servlet/", + "https://" + + config.getLiveEndpointUrlPrefix() + + "-pal-live.adyenpayments.com/pal/servlet/"); + } + + if (url.contains("checkout-")) { + if (config.getLiveEndpointUrlPrefix() == null) { + throw new IllegalArgumentException("please provide a live url prefix in the client"); + } + if (url.contains("/possdk/v68")) { + // Temporary until they fix possdk + url = + url.replaceFirst( + "https://checkout-test.adyen.com/", + "https://" + + config.getLiveEndpointUrlPrefix() + + "-checkout-live.adyenpayments.com/"); + } else { + url = + url.replaceFirst( + "https://checkout-test.adyen.com/", + "https://" + + config.getLiveEndpointUrlPrefix() + + "-checkout-live.adyenpayments.com/checkout/"); + } + } + + return url.replaceFirst("-test", "-live"); + } +} \ No newline at end of file diff --git a/src/test/java/com/adyen/ServiceTest.java b/src/test/java/com/adyen/ServiceTest.java new file mode 100644 index 000000000..199896e37 --- /dev/null +++ b/src/test/java/com/adyen/ServiceTest.java @@ -0,0 +1,101 @@ +package com.adyen; + +import com.adyen.enums.Environment; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * Tests for {@link Service#createBaseURL(String)}. + */ +public class ServiceTest extends BaseTest { + + private Client client; + private Config config; + private Service service; + + @Before + public void setUp() { + config = new Config() + .environment(Environment.LIVE); + client = new Client(config); + service = new Service(client); + } + + @Test + public void testCreateBaseURLForTestEnvironment() { + config.setEnvironment(Environment.TEST); + String liveUrl = "https://balanceplatform-api-live.adyen.com/bcl/v2/balanceAccounts"; + String expectedUrl = "https://balanceplatform-api-test.adyen.com/bcl/v2/balanceAccounts"; + + String actualUrl = service.createBaseURL(liveUrl); + // verify Live url is converted to Test url + assertEquals(expectedUrl, actualUrl); + } + + @Test + public void testCreateBaseURLForLiveEnvironment() { + + String testUrl = "https://balanceplatform-api-test.adyen.com/bcl/v2/balanceAccounts"; + String expectedUrl = "https://balanceplatform-api-live.adyen.com/bcl/v2/balanceAccounts"; + + String actualUrl = service.createBaseURL(testUrl); + // verify Test url is converted to Live url + assertEquals(expectedUrl, actualUrl); + } + + @Test + public void testLivePalUrlWithPrefix() { + + config.setLiveEndpointUrlPrefix("123456789-company"); + String testUrl = "https://pal-test.adyen.com/pal/servlet/v52/initiate"; + String expectedUrl = "https://123456789-company-pal-live.adyenpayments.com/pal/servlet/v52/initiate"; + + String actualUrl = service.createBaseURL(testUrl); + assertEquals(expectedUrl, actualUrl); + } + + @Test + public void testLivePalUrlWithoutPrefix() { + String testUrl = "https://pal-test.adyen.com/pal/servlet/v52/initiate"; + try { + service.createBaseURL(testUrl); + fail("Expected an IllegalArgumentException to be thrown"); + } catch (IllegalArgumentException e) { + assertEquals("please provide a live url prefix in the client", e.getMessage()); + } + } + + @Test + public void testLiveCheckoutUrlWithPrefix() { + config.setLiveEndpointUrlPrefix("123456789-company"); + String testUrl = "https://checkout-test.adyen.com/v68/payments"; + String expectedUrl = "https://123456789-company-checkout-live.adyenpayments.com/checkout/v68/payments"; + + String actualUrl = service.createBaseURL(testUrl); + assertEquals(expectedUrl, actualUrl); + } + + @Test + public void testLiveCheckoutUrlWithoutPrefix() { + String testUrl = "https://checkout-test.adyen.com/v68/payments"; + try { + service.createBaseURL(testUrl); + fail("Expected an IllegalArgumentException to be thrown"); + } catch (IllegalArgumentException e) { + assertEquals("please provide a live url prefix in the client", e.getMessage()); + } + } + + @Test + public void testLiveCheckoutPosSdkUrlWithPrefix() { + config.setLiveEndpointUrlPrefix("123456789-company"); + String testUrl = "https://checkout-test.adyen.com/possdk/v68/sessions"; + String expectedUrl = "https://123456789-company-checkout-live.adyenpayments.com/possdk/v68/sessions"; + + String actualUrl = service.createBaseURL(testUrl); + assertEquals(expectedUrl, actualUrl); + } +} \ No newline at end of file From bf4fbfcef75f29bf9afa3ccb417895a37c3444c0 Mon Sep 17 00:00:00 2001 From: gcatanese Date: Mon, 21 Jul 2025 16:29:43 +0200 Subject: [PATCH 02/10] Minor edit in README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 43c8e5bf7..f35f59224 100644 --- a/README.md +++ b/README.md @@ -122,8 +122,8 @@ import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.service.checkout.ModificationsApi -// Setup Client and Service -Client client = new Client("Your X-API-KEY", Environment.LIVE, "Your live URL prefix"); +// Setup Client and Service passing prefix +Client client = new Client("Your X-API-KEY", Environment.LIVE, "mycompany123"); ModificationsApi modificationsApi = new ModificationsApi(client); ... @@ -135,8 +135,8 @@ import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.service.checkout.PaymentLinksApi -// Setup Client and Service -Client client = new Client("Your username", "Your password", Environment.LIVE, "Your live URL prefix", "Your application name"); +// Setup Client and Service passing prefix and +Client client = new Client("Your username", "Your password", Environment.LIVE, "mycompany123", "Your application name"); PaymentLinksApi paymentLinksApi = new PaymentLinksApi(client); ... From f263e623e149a3763c8944686c1d792c4a413c8d Mon Sep 17 00:00:00 2001 From: gcatanese Date: Mon, 21 Jul 2025 16:30:41 +0200 Subject: [PATCH 03/10] Convert field to local var --- src/test/java/com/adyen/ServiceTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/com/adyen/ServiceTest.java b/src/test/java/com/adyen/ServiceTest.java index 199896e37..788149638 100644 --- a/src/test/java/com/adyen/ServiceTest.java +++ b/src/test/java/com/adyen/ServiceTest.java @@ -12,7 +12,6 @@ */ public class ServiceTest extends BaseTest { - private Client client; private Config config; private Service service; @@ -20,7 +19,7 @@ public class ServiceTest extends BaseTest { public void setUp() { config = new Config() .environment(Environment.LIVE); - client = new Client(config); + Client client = new Client(config); service = new Service(client); } From 604a1fc9a934620957040adeb3224752c532d059 Mon Sep 17 00:00:00 2001 From: gcatanese Date: Tue, 22 Jul 2025 10:29:05 +0200 Subject: [PATCH 04/10] Javadoc and tidy up --- src/main/java/com/adyen/Client.java | 129 ++++++++++------------------ src/main/java/com/adyen/Config.java | 10 ++- 2 files changed, 51 insertions(+), 88 deletions(-) diff --git a/src/main/java/com/adyen/Client.java b/src/main/java/com/adyen/Client.java index fb9163a4e..7a214053f 100644 --- a/src/main/java/com/adyen/Client.java +++ b/src/main/java/com/adyen/Client.java @@ -18,19 +18,22 @@ public class Client { public static final String TERMINAL_API_ENDPOINT_APSE = "https://terminal-api-live-apse.adyen.com"; + /** + * Create Client instance (empty config) + */ public Client() { this.config = new Config(); } + /** + * Create Client instance with the given configuration + * @param config Configuration + */ public Client(Config config) { this.config = config; this.setEnvironment(config.environment, config.liveEndpointUrlPrefix); } - public Client(String username, String password, Environment environment, String applicationName) { - this(username, password, environment, null, applicationName); - } - /** * Use this constructor to create client for client certificate authentication along with API key. * Note: Client certificate authentication is only applicable for PAL and Checkout services in @@ -44,6 +47,29 @@ public Client(SSLContext sslContext, String apiKey) { this.config.setSSLContext(sslContext); } + /** + * Create Client instance + * @param username HTTP basic username + * @param password HTTP basic password + * @param environment Environment (Test or Live) + * @param liveEndpointUrlPrefix Prefix required for Live integrations + */ + public Client( + String username, + String password, + Environment environment, + String liveEndpointUrlPrefix) { + this(username, password, environment, liveEndpointUrlPrefix, null); + } + + /** + * Create Client instance + * @param username HTTP basic username + * @param password HTTP basic password + * @param environment Environment (Test or Live) + * @param liveEndpointUrlPrefix Prefix required for Live integrations + * @param applicationName Application name (additional name/tag passed in HTTP requests) + */ public Client( String username, String password, @@ -58,46 +84,20 @@ public Client( } /** - * @param username your merchant account Username - * @param password your merchant accont Password - * @param environment This defines the payment environment live or test - * @param connectionTimeoutMillis Provide the time to time out - * @deprecated As of library version 1.6.1, timeouts should be set by {@link #setTimeouts(int - * connectionTimeoutMillis, int readTimeoutMillis)} or directly by {@link - * com.adyen.Config#setConnectionTimeoutMillis(int connectionTimeoutMillis)}. + * Create Client instance + * @param apiKey API Key + * @param environment Environment (Test or Live) */ - @Deprecated - public Client( - String username, String password, Environment environment, int connectionTimeoutMillis) { - this(username, password, environment, null); - this.config.setConnectionTimeoutMillis(connectionTimeoutMillis); - } - - /** - * @param username your merchant account Username - * @param password your merchant accont Password - * @param environment This defines the payment environment live or test - * @param connectionTimeoutMillis Provide the time to time out - * @param liveEndpointUrlPrefix provide the merchant specific url - * @deprecated As of library version 1.6.1, timeouts should be set by {@link #setTimeouts(int - * connectionTimeoutMillis, int readTimeoutMillis)} or directly by {@link - * com.adyen.Config#setConnectionTimeoutMillis(int connectionTimeoutMillis)}. - */ - @Deprecated - public Client( - String username, - String password, - Environment environment, - int connectionTimeoutMillis, - String liveEndpointUrlPrefix) { - this(username, password, environment, liveEndpointUrlPrefix, null); - this.config.setConnectionTimeoutMillis(connectionTimeoutMillis); - } - public Client(String apiKey, Environment environment) { this(apiKey, environment, null); } + /** + * Create Client instance + * @param apiKey API Key + * @param environment Environment (Test or Live) + * @param liveEndpointUrlPrefix Prefix required for the live integrations + */ public Client(String apiKey, Environment environment, String liveEndpointUrlPrefix) { this.config = new Config(); this.config.setApiKey(apiKey); @@ -105,52 +105,9 @@ public Client(String apiKey, Environment environment, String liveEndpointUrlPref } /** - * @param apiKey Defines the api key that can be retrieved by back office - * @param environment This defines the payment environment live or test - * @param connectionTimeoutMillis Provide the time to time out - * @deprecated As of library version 1.6.1, timeouts should be set by {@link #setTimeouts(int - * connectionTimeoutMillis, int readTimeoutMillis)} or directly by {@link - * com.adyen.Config#setConnectionTimeoutMillis(int connectionTimeoutMillis)}. - */ - @Deprecated - public Client(String apiKey, Environment environment, int connectionTimeoutMillis) { - this(apiKey, environment); - this.config.setConnectionTimeoutMillis(connectionTimeoutMillis); - } - - /** - * @param apiKey Defines the api key that can be retrieved by back office - * @param environment This defines the payment environment live or test - * @param connectionTimeoutMillis Provide the time to time out - * @param liveEndpointUrlPrefix provide the merchant specific url - * @deprecated As of library version 1.6.1, timeouts should be set by {@link #setTimeouts(int - * connectionTimeoutMillis, int readTimeoutMillis)} or directly by {@link - * com.adyen.Config#setConnectionTimeoutMillis(int connectionTimeoutMillis)}. - */ - @Deprecated - public Client( - String apiKey, - Environment environment, - int connectionTimeoutMillis, - String liveEndpointUrlPrefix) { - this(apiKey, environment, liveEndpointUrlPrefix); - this.config.setConnectionTimeoutMillis(connectionTimeoutMillis); - } - - /** - * @param environment This defines the payment environment live or test - * @deprecated As of library version 1.5.4, replaced by {@link #setEnvironment(Environment - * environment, String liveEndpointUrlPrefix)}. - */ - @Deprecated - public void setEnvironment(Environment environment) { - this.setEnvironment(environment, null); - } - - /** - * @param environment This defines the payment environment live or test - * @param liveEndpointUrlPrefix Provide the unique live url prefix from the "API URLs and - * Response" menu in the Adyen Customer Area + * Set Environment, together with the live endpoint url prefix. + * @param environment Environment (Test or Live) + * @param liveEndpointUrlPrefix The unique live url prefix (required for live integrations) */ public void setEnvironment(Environment environment, String liveEndpointUrlPrefix) { config.setEnvironment(environment); @@ -161,8 +118,10 @@ public void setEnvironment(Environment environment, String liveEndpointUrlPrefix } /** + * Retrieve the Terminal Cloud endpoint based on Region and Environment * @param region The region for which the endpoint is requested. If null or the region is not * found, defaults to default EU endpoint. + * @param environment Environment (Test or Live) */ public String retrieveCloudEndpoint(Region region, Environment environment) { // Check the environment for TEST and get the endpoint diff --git a/src/main/java/com/adyen/Config.java b/src/main/java/com/adyen/Config.java index 989dd3f45..08a8ca2aa 100644 --- a/src/main/java/com/adyen/Config.java +++ b/src/main/java/com/adyen/Config.java @@ -6,21 +6,25 @@ import javax.net.ssl.SSLContext; public class Config { + // API key authentication + protected String apiKey; + // Basic authentication protected String username; protected String password; + // Environment: Test or Live protected Environment environment; - /** Application name: used as HTTP client User-Agent */ + // Application name: used as HTTP client User-Agent protected String applicationName; - protected String apiKey; + // HTTP Client options protected int connectionTimeoutMillis = 60 * 1000; // default 60 sec protected int readTimeoutMillis = 60 * 1000; // default 60 sec protected int connectionRequestTimeoutMillis = 60 * 1000; // default 60 sec protected int defaultKeepAliveMillis = 60 * 1000; // default 60 sec protected Boolean protocolUpgradeEnabled; - // Terminal API Specific + // Terminal API configuration protected String terminalApiCloudEndpoint; protected String terminalApiLocalEndpoint; protected String liveEndpointUrlPrefix; From 7966cd9ed8a849ba014ad3772a695f996afc3c26 Mon Sep 17 00:00:00 2001 From: gcatanese Date: Tue, 22 Jul 2025 10:29:20 +0200 Subject: [PATCH 05/10] Improve test to follow best practises --- .../java/com/adyen/httpclient/ClientTest.java | 289 ++++++++++-------- 1 file changed, 161 insertions(+), 128 deletions(-) diff --git a/src/test/java/com/adyen/httpclient/ClientTest.java b/src/test/java/com/adyen/httpclient/ClientTest.java index f2c1668af..ed10c9057 100644 --- a/src/test/java/com/adyen/httpclient/ClientTest.java +++ b/src/test/java/com/adyen/httpclient/ClientTest.java @@ -9,10 +9,12 @@ import com.adyen.enums.Environment; import com.adyen.enums.Region; import com.adyen.model.RequestOptions; + import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; import javax.net.ssl.SSLContext; + import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; import org.apache.hc.core5.http.Header; import org.junit.Assert; @@ -24,132 +26,163 @@ public class ClientTest extends BaseTest { - @Mock private SSLContext clientCertificateAuthSSLContext; - - @Mock private String apiKey; - - @Test - public void testConfigTestClient() { - Config config = new Config(); - config.setEnvironment(Environment.TEST); - config.setApiKey(apiKey); - Client client = new Client(config); - assertEquals(Environment.TEST, client.getConfig().getEnvironment()); - } - - @Test - public void testConfigLiveClient() { - Config config = new Config(); - config.setEnvironment(Environment.LIVE); - config.setLiveEndpointUrlPrefix("prefix"); - config.setApiKey(apiKey); - Client client = new Client(config); - assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); - assertEquals("prefix", client.getConfig().getLiveEndpointUrlPrefix()); - } - - private static Stream provideCloudTestEndpointTestCases() { - return Stream.of( - Arguments.of(null, Environment.TEST, "https://terminal-api-test.adyen.com"), - Arguments.of(Region.EU, Environment.TEST, "https://terminal-api-test.adyen.com"), - Arguments.of(Region.AU, Environment.TEST, "https://terminal-api-test.adyen.com"), - Arguments.of(Region.US, Environment.TEST, "https://terminal-api-test.adyen.com"), - Arguments.of(Region.APSE, Environment.TEST, "https://terminal-api-test.adyen.com")); - } - - @ParameterizedTest - @MethodSource("provideCloudTestEndpointTestCases") - public void testGetCloudEndpointForTestEnvironment( - Region region, Environment environment, String expectedEndpoint) { - Config testConfig = new Config(); - testConfig.setEnvironment(Environment.TEST); - testConfig.setTerminalApiRegion(region); - Client testClient = new Client(testConfig); - assertEquals(expectedEndpoint, testConfig.getTerminalApiCloudEndpoint()); - } - - private static Stream provideCloudLiveEndpointTestCases() { - return Stream.of( - Arguments.of(null, Environment.LIVE, "https://terminal-api-live.adyen.com"), - Arguments.of(Region.EU, Environment.LIVE, "https://terminal-api-live.adyen.com"), - Arguments.of(Region.AU, Environment.LIVE, "https://terminal-api-live-au.adyen.com"), - Arguments.of(Region.US, Environment.LIVE, "https://terminal-api-live-us.adyen.com"), - Arguments.of(Region.APSE, Environment.LIVE, "https://terminal-api-live-apse.adyen.com")); - } - - @ParameterizedTest - @MethodSource("provideCloudLiveEndpointTestCases") - public void testGetCloudEndpointForLiveEnvironment( - Region region, Environment environment, String expectedEndpoint) { - Config liveConfig = new Config(); - liveConfig.setEnvironment(Environment.LIVE); - liveConfig.setTerminalApiRegion(region); - Client liveClient = new Client(liveConfig); - assertEquals(expectedEndpoint, liveConfig.getTerminalApiCloudEndpoint()); - } - - @Test - public void testUnmappedIndiaRegionThrowsException() { - Config config = new Config(); - config.setEnvironment(Environment.LIVE); - config.setTerminalApiRegion(Region.IN); - - Assert.assertThrows(IllegalArgumentException.class, () -> new Client(config)); - } - - @Test - public void testClientCertificateAuth() { - Client client = new Client(clientCertificateAuthSSLContext, apiKey); - assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); - } - - @Test - public void testRequestOptionsBuilderPattern() { - HashMap map = new HashMap<>(); - map.put("thing", "thing"); - RequestOptions requestOptions = - new RequestOptions() - .idempotencyKey("idempotency") - .requestedVerificationCodeHeader("headers") - .additionalServiceHeaders(map); - assertEquals(requestOptions.getAdditionalServiceHeaders(), map); - } - - @Test - public void testUserAgentWithApplicationName() throws Exception { - - AdyenHttpClient client = new AdyenHttpClient(); - HttpUriRequestBase requestWithAppName = - client.createRequest( - "https://chekout.adyen.com", - "{}", - new Config().applicationName("test-app"), - true, - null, - ApiConstants.HttpMethod.POST, - Map.of()); - - Header userAgent = requestWithAppName.getFirstHeader("User-Agent"); - assertNotNull(userAgent); - assertEquals("test-app " + Client.LIB_NAME + "/" + Client.LIB_VERSION, userAgent.getValue()); - } - - @Test - public void testUserAgentWithoutApplicationName() throws Exception { - - AdyenHttpClient client = new AdyenHttpClient(); - HttpUriRequestBase requestWithoutAppName = - client.createRequest( - "https://chekout.adyen.com", - "{}", - new Config(), - true, - null, - ApiConstants.HttpMethod.POST, - Map.of()); - - Header userAgent = requestWithoutAppName.getFirstHeader("User-Agent"); - assertNotNull(userAgent); - assertEquals(Client.LIB_NAME + "/" + Client.LIB_VERSION, userAgent.getValue()); - } + @Mock + private SSLContext clientCertificateAuthSSLContext; + + @Mock + private String apiKey; + + @Test + public void testConfigTestClient() { + Config config = new Config(); + config.setEnvironment(Environment.TEST); + config.setApiKey(apiKey); + Client client = new Client(config); + assertEquals(Environment.TEST, client.getConfig().getEnvironment()); + } + + @Test + public void testConfigLiveClient() { + Config config = new Config() + .environment(Environment.LIVE) + .liveEndpointUrlPrefix("myCompany") + .apiKey(apiKey); + Client client = new Client(config); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); + } + + @Test + public void testConstructorConfigLiveClient() { + Client client = new Client(apiKey, Environment.LIVE, "myCompany"); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); + } + + @Test + public void testConfigLiveClientWithBasicAuth() { + Client client = new Client("", "", Environment.LIVE, "myCompany"); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); + assertNull(client.getConfig().getApiKey()); + assertNull(client.getConfig().getApplicationName()); + } + + @Test + public void testConfigLiveClientWithBasicAuthAndApplication() { + Client client = new Client("", "", Environment.LIVE, "myCompany", "myApplication"); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); + assertEquals("myApplication", client.getConfig().getApplicationName()); + assertNull(client.getConfig().getApiKey()); + } + + private static Stream provideCloudTestEndpointTestCases() { + return Stream.of( + Arguments.of(null, Environment.TEST, "https://terminal-api-test.adyen.com"), + Arguments.of(Region.EU, Environment.TEST, "https://terminal-api-test.adyen.com"), + Arguments.of(Region.AU, Environment.TEST, "https://terminal-api-test.adyen.com"), + Arguments.of(Region.US, Environment.TEST, "https://terminal-api-test.adyen.com"), + Arguments.of(Region.APSE, Environment.TEST, "https://terminal-api-test.adyen.com")); + } + + @ParameterizedTest + @MethodSource("provideCloudTestEndpointTestCases") + public void testGetCloudEndpointForTestEnvironment( + Region region, Environment environment, String expectedEndpoint) { + Config config = new Config() + .environment(environment) + .terminalApiRegion(region) + .apiKey(apiKey); + Client client = new Client(config); + + assertEquals(expectedEndpoint, config.getTerminalApiCloudEndpoint()); + } + + private static Stream provideCloudLiveEndpointTestCases() { + return Stream.of( + Arguments.of(null, Environment.LIVE, "https://terminal-api-live.adyen.com"), + Arguments.of(Region.EU, Environment.LIVE, "https://terminal-api-live.adyen.com"), + Arguments.of(Region.AU, Environment.LIVE, "https://terminal-api-live-au.adyen.com"), + Arguments.of(Region.US, Environment.LIVE, "https://terminal-api-live-us.adyen.com"), + Arguments.of(Region.APSE, Environment.LIVE, "https://terminal-api-live-apse.adyen.com")); + } + + @ParameterizedTest + @MethodSource("provideCloudLiveEndpointTestCases") + public void testGetCloudEndpointForLiveEnvironment( + Region region, Environment environment, String expectedEndpoint) { + Config config = new Config() + .environment(environment) + .terminalApiRegion(region) + .apiKey(apiKey); + Client client = new Client(config); + + assertEquals(expectedEndpoint, config.getTerminalApiCloudEndpoint()); + } + + @Test + public void testUnmappedIndiaRegionThrowsException() { + Config config = new Config(); + config.setEnvironment(Environment.LIVE); + config.setTerminalApiRegion(Region.IN); + + Assert.assertThrows(IllegalArgumentException.class, () -> new Client(config)); + } + + @Test + public void testClientCertificateAuth() { + Client client = new Client(clientCertificateAuthSSLContext, apiKey); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + } + + @Test + public void testRequestOptionsBuilderPattern() { + HashMap map = new HashMap<>(); + map.put("thing", "thing"); + RequestOptions requestOptions = + new RequestOptions() + .idempotencyKey("idempotency") + .requestedVerificationCodeHeader("headers") + .additionalServiceHeaders(map); + assertEquals(requestOptions.getAdditionalServiceHeaders(), map); + } + + @Test + public void testUserAgentWithApplicationName() throws Exception { + + AdyenHttpClient client = new AdyenHttpClient(); + HttpUriRequestBase requestWithAppName = + client.createRequest( + "https://chekout.adyen.com", + "{}", + new Config().applicationName("test-app"), + true, + null, + ApiConstants.HttpMethod.POST, + Map.of()); + + Header userAgent = requestWithAppName.getFirstHeader("User-Agent"); + assertNotNull(userAgent); + assertEquals("test-app " + Client.LIB_NAME + "/" + Client.LIB_VERSION, userAgent.getValue()); + } + + @Test + public void testUserAgentWithoutApplicationName() throws Exception { + + AdyenHttpClient client = new AdyenHttpClient(); + HttpUriRequestBase requestWithoutAppName = + client.createRequest( + "https://chekout.adyen.com", + "{}", + new Config(), + true, + null, + ApiConstants.HttpMethod.POST, + Map.of()); + + Header userAgent = requestWithoutAppName.getFirstHeader("User-Agent"); + assertNotNull(userAgent); + assertEquals(Client.LIB_NAME + "/" + Client.LIB_VERSION, userAgent.getValue()); + } } From 93e5fd9a49dcd63d8cd61c2faceb2ecb9ec24fd0 Mon Sep 17 00:00:00 2001 From: gcatanese Date: Tue, 22 Jul 2025 10:29:52 +0200 Subject: [PATCH 06/10] Update README to follow best practises --- README.md | 98 ++++++++++++++++++++++++------------------------------- 1 file changed, 42 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index f35f59224..7fedaaf79 100644 --- a/README.md +++ b/README.md @@ -81,8 +81,10 @@ Alternatively, you can download the [release on GitHub](https://github.com/Adyen ### General use with API key -Every API the library supports is represented by a service object. The name of the service matching the corresponding -API is listed in the [Supported API versions](#supported-api-versions) section of this document. +For every API, one or more corresponding service classes can be found in the folder with the same name. +Check the [Supported API versions](#supported-api-versions). + +**Note**: For requests on `live` environment, you must define the [Live URL Prefix](https://docs.adyen.com/development-resources/live-endpoints#live-url-prefix) in the Client object: ~~~~ java // Import the required classes @@ -91,8 +93,13 @@ import com.adyen.enums.Environment; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.*; -// Setup Client and Service -Client client = new Client("Your X-API-KEY", Environment.TEST); +// Setup Client using Config object +Config config = new Config() + .environment(Environment.LIVE) + .liveEndpointUrlPrefix("myCompany") + .apiKey(apiKey); +Client client = new Client(config); + PaymentsApi paymentsApi = new PaymentsApi(client); // Create PaymentRequest @@ -114,20 +121,6 @@ PaymentResponse paymentResponse = paymentsApi.payments(paymentRequest); ~~~~ -### General use with API key for live environment -For requests on live environment, you need to pass the [Live URL Prefix](https://docs.adyen.com/development-resources/live-endpoints#live-url-prefix) to the Client object: -~~~~ java -// Import the required classes -import com.adyen.Client; -import com.adyen.enums.Environment; -import com.adyen.service.checkout.ModificationsApi - -// Setup Client and Service passing prefix -Client client = new Client("Your X-API-KEY", Environment.LIVE, "mycompany123"); -ModificationsApi modificationsApi = new ModificationsApi(client); - -... -~~~~ ### General use with basic auth ~~~~ java // Import the required classes @@ -135,8 +128,11 @@ import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.service.checkout.PaymentLinksApi -// Setup Client and Service passing prefix and -Client client = new Client("Your username", "Your password", Environment.LIVE, "mycompany123", "Your application name"); +// Setup Client and Service passing prefix +Client client = new Client("Your username", "Your password", Environment.LIVE, "mycompany123"); +// Or setup Client and Service passing prefix and application name +//Client client = new Client("Your username", "Your password", Environment.LIVE, "mycompany123", "Your application name"); + PaymentLinksApi paymentLinksApi = new PaymentLinksApi(client); ... @@ -150,6 +146,23 @@ import com.adyen.model.checkout.PaymentRequest; // Deserialize using built-in function PaymentRequest paymentRequest = PaymentRequest.fromJson("YOUR_JSON_STRING"); ~~~~ +### Error handling + +Use a try-catch block to handle API errors. Catch the `ApiException` to inspect the response and handle specific cases: +~~~~ +try { + service.getPaymentLink("1234"); +} catch (ApiException e) { + // Obtain response + int statusCode = e.getStatusCode(); + String responseBody = e.getResponseBody(); + // Check ApiError object + ApiError apiError = e.getError(); + String errorCode = apiError.getErrorCode(); + List invalidFields = apiError.getInvalidFields(); + .... +} +~~~~ ### Using notification webhooks parser ~~~~ java // Import the required classes @@ -289,27 +302,9 @@ Client client = new Client(sslContext, apiKey); // Use the client ~~~~ -### Classic Platforms Error Handling - -When requests fail, the library throws exceptions. For Classic AFP endpoints like [Create Account Holder](https://docs.adyen.com/api-explorer/Account/6/post/createAccountHolder), you can decode further details from the exception: - -```java -Client client = new Client("Your YOUR_API_KEY", Environment.TEST); -ClassicPlatformAccountApi api = new ClassicPlatformAccountApi(client); -CreateAccountHolderRequest request = new CreateAccountHolderRequest(); - -try { - api.createAccountHolder(request); -} catch (ApiException e) { - CreateAccountHolderResponse error = CreateAccountHolderResponse.fromJson(e.getResponseBody()); - // inspect the error - System.out.println(e.getStatusCode()); - System.out.println(error.getInvalidFields()); -} -``` ## Using the Cloud Terminal API Integration -In order to submit In-Person requests with [Terminal API over Cloud](https://docs.adyen.com/point-of-sale/design-your-integration/choose-your-architecture/cloud/) you need to initialize the client in a similar way as the steps listed above for Ecommerce transactions, but make sure to include `TerminalCloudAPI`: +For In-Person Payments integration with [Terminal API over Cloud](https://docs.adyen.com/point-of-sale/design-your-integration/choose-your-architecture/cloud/), setup the Client including the closest [Region](https://docs.adyen.com/point-of-sale/design-your-integration/terminal-api/#cloud): ``` java // Step 1: Import the required classes import com.adyen.Client; @@ -319,13 +314,11 @@ import com.adyen.model.nexo.*; import com.adyen.model.terminal.*; // Step 2: Initialize the client object -Client client = new Client("Your YOUR_API_KEY", Environment.TEST); - -// for LIVE environment use -// Config config = new Config(); -// config.setEnvironment(Environment.LIVE); -// config.setTerminalApiRegion(Region.EU); -// Client client = new Client(config); +Config config = new Config() + .environment(Environment.LIVE) + .terminalApiRegion(Region.EU) + .apiKey(apiKey); +Client client = new Client(config); // Step 3: Initialize the API object TerminalCloudAPI terminalCloudApi = new TerminalCloudAPI(client); @@ -545,9 +538,7 @@ TerminalAPIRequest terminalAPIPaymentRequest = new TerminalAPIRequest(); TerminalAPIResponse terminalAPIResponse = terminalLocalAPI.request(terminalAPIRequest); ``` - ### Example integrations - For a closer look at how our Java library works, you can clone one of our example integrations: * [Java Spring Boot example integration](https://github.com/adyen-examples/adyen-java-spring-online-payments). * [Kotlin Spring Boot example integration](https://github.com/adyen-examples/adyen-kotlin-spring-online-payments). @@ -558,20 +549,15 @@ These include commented code, highlighting key features and concepts, and exampl We value your input! Help us enhance our API Libraries and improve the integration experience by providing your feedback. Please take a moment to fill out [our feedback form](https://forms.gle/A4EERrR6CWgKWe5r9) to share your thoughts, suggestions or ideas. ## Contributing - - -We encourage you to contribute to this repository, so everyone can benefit from new features, bug fixes, and any other improvements. - +We encourage you to contribute to this repository, so everyone can benefit from new features, bug fixes, and any other improvements. Have a look at our [contributing guidelines](CONTRIBUTING.md) to find out how to raise a pull request. - - + ## Support If you have a feature request, or spotted a bug or a technical problem, [create an issue here](https://github.com/Adyen/adyen-java-api-library/issues/new/choose). For other questions, [contact our Support Team](https://www.adyen.help/hc/en-us/requests/new?ticket_form_id=39.0.0705420). - - + ## Licence This repository is available under the [MIT license](https://github.com/Adyen/adyen-java-api-library/blob/main/LICENSE). From 1ef9e0f559352ecaf289443b332d2a0c686fbcde Mon Sep 17 00:00:00 2001 From: gcatanese Date: Tue, 22 Jul 2025 11:01:57 +0200 Subject: [PATCH 07/10] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7fedaaf79..f6923663d 100644 --- a/README.md +++ b/README.md @@ -303,8 +303,8 @@ Client client = new Client(sslContext, apiKey); ~~~~ -## Using the Cloud Terminal API Integration -For In-Person Payments integration with [Terminal API over Cloud](https://docs.adyen.com/point-of-sale/design-your-integration/choose-your-architecture/cloud/), setup the Client including the closest [Region](https://docs.adyen.com/point-of-sale/design-your-integration/terminal-api/#cloud): +## Using the Cloud Terminal API +For In-Person Payments integration with the [Cloud Terminal API](https://docs.adyen.com/point-of-sale/design-your-integration/choose-your-architecture/cloud/), you must setup the Client **setting the closest** [Region](https://docs.adyen.com/point-of-sale/design-your-integration/terminal-api/#cloud): ``` java // Step 1: Import the required classes import com.adyen.Client; From e6deed072d938bd5fc0682de94c88c4e4d92f891 Mon Sep 17 00:00:00 2001 From: gcatanese Date: Tue, 22 Jul 2025 11:03:02 +0200 Subject: [PATCH 08/10] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6923663d..725e454bf 100644 --- a/README.md +++ b/README.md @@ -304,7 +304,7 @@ Client client = new Client(sslContext, apiKey); ## Using the Cloud Terminal API -For In-Person Payments integration with the [Cloud Terminal API](https://docs.adyen.com/point-of-sale/design-your-integration/choose-your-architecture/cloud/), you must setup the Client **setting the closest** [Region](https://docs.adyen.com/point-of-sale/design-your-integration/terminal-api/#cloud): +For In-Person Payments integration with the [Cloud Terminal API](https://docs.adyen.com/point-of-sale/design-your-integration/choose-your-architecture/cloud/), you must initialise the Client **setting the closest** [Region](https://docs.adyen.com/point-of-sale/design-your-integration/terminal-api/#cloud): ``` java // Step 1: Import the required classes import com.adyen.Client; From daa253744ca4aad5ca16479b2148987439e0dfcb Mon Sep 17 00:00:00 2001 From: gcatanese Date: Tue, 22 Jul 2025 11:14:50 +0200 Subject: [PATCH 09/10] Improve code and indentation --- src/main/java/com/adyen/Client.java | 16 +- src/main/java/com/adyen/Service.java | 184 +++++------ src/test/java/com/adyen/ServiceTest.java | 179 +++++----- .../java/com/adyen/httpclient/ClientTest.java | 311 +++++++++--------- 4 files changed, 338 insertions(+), 352 deletions(-) diff --git a/src/main/java/com/adyen/Client.java b/src/main/java/com/adyen/Client.java index 7a214053f..45de7bdd4 100644 --- a/src/main/java/com/adyen/Client.java +++ b/src/main/java/com/adyen/Client.java @@ -18,15 +18,14 @@ public class Client { public static final String TERMINAL_API_ENDPOINT_APSE = "https://terminal-api-live-apse.adyen.com"; - /** - * Create Client instance (empty config) - */ + /** Create Client instance (empty config) */ public Client() { this.config = new Config(); } /** * Create Client instance with the given configuration + * * @param config Configuration */ public Client(Config config) { @@ -49,21 +48,20 @@ public Client(SSLContext sslContext, String apiKey) { /** * Create Client instance + * * @param username HTTP basic username * @param password HTTP basic password * @param environment Environment (Test or Live) * @param liveEndpointUrlPrefix Prefix required for Live integrations */ public Client( - String username, - String password, - Environment environment, - String liveEndpointUrlPrefix) { + String username, String password, Environment environment, String liveEndpointUrlPrefix) { this(username, password, environment, liveEndpointUrlPrefix, null); } /** * Create Client instance + * * @param username HTTP basic username * @param password HTTP basic password * @param environment Environment (Test or Live) @@ -85,6 +83,7 @@ public Client( /** * Create Client instance + * * @param apiKey API Key * @param environment Environment (Test or Live) */ @@ -94,6 +93,7 @@ public Client(String apiKey, Environment environment) { /** * Create Client instance + * * @param apiKey API Key * @param environment Environment (Test or Live) * @param liveEndpointUrlPrefix Prefix required for the live integrations @@ -106,6 +106,7 @@ public Client(String apiKey, Environment environment, String liveEndpointUrlPref /** * Set Environment, together with the live endpoint url prefix. + * * @param environment Environment (Test or Live) * @param liveEndpointUrlPrefix The unique live url prefix (required for live integrations) */ @@ -119,6 +120,7 @@ public void setEnvironment(Environment environment, String liveEndpointUrlPrefix /** * Retrieve the Terminal Cloud endpoint based on Region and Environment + * * @param region The region for which the endpoint is requested. If null or the region is not * found, defaults to default EU endpoint. * @param environment Environment (Test or Live) diff --git a/src/main/java/com/adyen/Service.java b/src/main/java/com/adyen/Service.java index 52c960e28..6a05ed1c9 100644 --- a/src/main/java/com/adyen/Service.java +++ b/src/main/java/com/adyen/Service.java @@ -23,106 +23,106 @@ import com.adyen.enums.Environment; /** - * A generic service that provides shared functionality for all API services. - * It handles client and configuration management. + * A generic service that provides shared functionality for all API services. It handles client and + * configuration management. */ public class Service { - private boolean isApiKeyRequired = false; - private Client client; + private boolean isApiKeyRequired = false; + private Client client; - /** - * Constructs a new Service. - * - * @param client The client used to make API calls. - */ - protected Service(Client client) { - this.client = client; - } + /** + * Constructs a new Service. + * + * @param client The client used to make API calls. + */ + protected Service(Client client) { + this.client = client; + } - /** - * Gets the client used by this service. - * - * @return The client. - */ - public Client getClient() { - return client; - } + /** + * Gets the client used by this service. + * + * @return The client. + */ + public Client getClient() { + return client; + } - /** - * Sets the client to be used by this service. - * - * @param client The client. - */ - public void setClient(Client client) { - this.client = client; - } + /** + * Sets the client to be used by this service. + * + * @param client The client. + */ + public void setClient(Client client) { + this.client = client; + } - /** - * Returns true if the service requires an API key. - * - * @return A boolean indicating if an API key is required. - */ - public boolean isApiKeyRequired() { - return isApiKeyRequired; - } + /** + * Returns true if the service requires an API key. + * + * @return A boolean indicating if an API key is required. + */ + public boolean isApiKeyRequired() { + return isApiKeyRequired; + } - /** - * Sets if the service requires an API key. - * - * @param apiKeyRequired A boolean indicating if an API key is required. - */ - public void setApiKeyRequired(boolean apiKeyRequired) { - isApiKeyRequired = apiKeyRequired; - } + /** + * Sets if the service requires an API key. + * + * @param apiKeyRequired A boolean indicating if an API key is required. + */ + public void setApiKeyRequired(boolean apiKeyRequired) { + isApiKeyRequired = apiKeyRequired; + } - /** - * Creates the base URL for a specific API endpoint. It dynamically constructs the URL - * based on the client's configured {@link Environment}. - * - * @param url The base URL template. - * @return The fully constructed base URL for the target environment. - * @throws IllegalArgumentException if the live URL prefix is required but not configured. - */ - protected String createBaseURL(String url) { - Config config = this.getClient().getConfig(); - if (config.getEnvironment() != Environment.LIVE) { - return url.replaceFirst("-live", "-test"); - } - - if (url.contains("pal-")) { - if (config.getLiveEndpointUrlPrefix() == null) { - throw new IllegalArgumentException("please provide a live url prefix in the client"); - } - url = - url.replaceFirst( - "https://pal-test.adyen.com/pal/servlet/", - "https://" - + config.getLiveEndpointUrlPrefix() - + "-pal-live.adyenpayments.com/pal/servlet/"); - } + /** + * Creates the base URL for a specific API endpoint. It dynamically constructs the URL based on + * the client's configured {@link Environment}. + * + * @param url The base URL template. + * @return The fully constructed base URL for the target environment. + * @throws IllegalArgumentException if the live URL prefix is required but not configured. + */ + protected String createBaseURL(String url) { + Config config = this.getClient().getConfig(); + if (config.getEnvironment() != Environment.LIVE) { + return url.replaceFirst("-live", "-test"); + } - if (url.contains("checkout-")) { - if (config.getLiveEndpointUrlPrefix() == null) { - throw new IllegalArgumentException("please provide a live url prefix in the client"); - } - if (url.contains("/possdk/v68")) { - // Temporary until they fix possdk - url = - url.replaceFirst( - "https://checkout-test.adyen.com/", - "https://" - + config.getLiveEndpointUrlPrefix() - + "-checkout-live.adyenpayments.com/"); - } else { - url = - url.replaceFirst( - "https://checkout-test.adyen.com/", - "https://" - + config.getLiveEndpointUrlPrefix() - + "-checkout-live.adyenpayments.com/checkout/"); - } - } + if (url.contains("pal-")) { + if (config.getLiveEndpointUrlPrefix() == null) { + throw new IllegalArgumentException("please provide a live url prefix in the client"); + } + url = + url.replaceFirst( + "https://pal-test.adyen.com/pal/servlet/", + "https://" + + config.getLiveEndpointUrlPrefix() + + "-pal-live.adyenpayments.com/pal/servlet/"); + } - return url.replaceFirst("-test", "-live"); + if (url.contains("checkout-")) { + if (config.getLiveEndpointUrlPrefix() == null) { + throw new IllegalArgumentException("please provide a live url prefix in the client"); + } + if (url.contains("/possdk/v68")) { + // Temporary until they fix possdk + url = + url.replaceFirst( + "https://checkout-test.adyen.com/", + "https://" + + config.getLiveEndpointUrlPrefix() + + "-checkout-live.adyenpayments.com/"); + } else { + url = + url.replaceFirst( + "https://checkout-test.adyen.com/", + "https://" + + config.getLiveEndpointUrlPrefix() + + "-checkout-live.adyenpayments.com/checkout/"); + } } -} \ No newline at end of file + + return url.replaceFirst("-test", "-live"); + } +} diff --git a/src/test/java/com/adyen/ServiceTest.java b/src/test/java/com/adyen/ServiceTest.java index 788149638..cae243117 100644 --- a/src/test/java/com/adyen/ServiceTest.java +++ b/src/test/java/com/adyen/ServiceTest.java @@ -1,100 +1,95 @@ package com.adyen; +import static org.junit.Assert.*; + import com.adyen.enums.Environment; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -/** - * Tests for {@link Service#createBaseURL(String)}. - */ +/** Tests for {@link Service#createBaseURL(String)}. */ public class ServiceTest extends BaseTest { - private Config config; - private Service service; - - @Before - public void setUp() { - config = new Config() - .environment(Environment.LIVE); - Client client = new Client(config); - service = new Service(client); - } - - @Test - public void testCreateBaseURLForTestEnvironment() { - config.setEnvironment(Environment.TEST); - String liveUrl = "https://balanceplatform-api-live.adyen.com/bcl/v2/balanceAccounts"; - String expectedUrl = "https://balanceplatform-api-test.adyen.com/bcl/v2/balanceAccounts"; - - String actualUrl = service.createBaseURL(liveUrl); - // verify Live url is converted to Test url - assertEquals(expectedUrl, actualUrl); - } - - @Test - public void testCreateBaseURLForLiveEnvironment() { - - String testUrl = "https://balanceplatform-api-test.adyen.com/bcl/v2/balanceAccounts"; - String expectedUrl = "https://balanceplatform-api-live.adyen.com/bcl/v2/balanceAccounts"; - - String actualUrl = service.createBaseURL(testUrl); - // verify Test url is converted to Live url - assertEquals(expectedUrl, actualUrl); - } - - @Test - public void testLivePalUrlWithPrefix() { - - config.setLiveEndpointUrlPrefix("123456789-company"); - String testUrl = "https://pal-test.adyen.com/pal/servlet/v52/initiate"; - String expectedUrl = "https://123456789-company-pal-live.adyenpayments.com/pal/servlet/v52/initiate"; - - String actualUrl = service.createBaseURL(testUrl); - assertEquals(expectedUrl, actualUrl); - } - - @Test - public void testLivePalUrlWithoutPrefix() { - String testUrl = "https://pal-test.adyen.com/pal/servlet/v52/initiate"; - try { - service.createBaseURL(testUrl); - fail("Expected an IllegalArgumentException to be thrown"); - } catch (IllegalArgumentException e) { - assertEquals("please provide a live url prefix in the client", e.getMessage()); - } - } - - @Test - public void testLiveCheckoutUrlWithPrefix() { - config.setLiveEndpointUrlPrefix("123456789-company"); - String testUrl = "https://checkout-test.adyen.com/v68/payments"; - String expectedUrl = "https://123456789-company-checkout-live.adyenpayments.com/checkout/v68/payments"; - - String actualUrl = service.createBaseURL(testUrl); - assertEquals(expectedUrl, actualUrl); - } - - @Test - public void testLiveCheckoutUrlWithoutPrefix() { - String testUrl = "https://checkout-test.adyen.com/v68/payments"; - try { - service.createBaseURL(testUrl); - fail("Expected an IllegalArgumentException to be thrown"); - } catch (IllegalArgumentException e) { - assertEquals("please provide a live url prefix in the client", e.getMessage()); - } - } - - @Test - public void testLiveCheckoutPosSdkUrlWithPrefix() { - config.setLiveEndpointUrlPrefix("123456789-company"); - String testUrl = "https://checkout-test.adyen.com/possdk/v68/sessions"; - String expectedUrl = "https://123456789-company-checkout-live.adyenpayments.com/possdk/v68/sessions"; - - String actualUrl = service.createBaseURL(testUrl); - assertEquals(expectedUrl, actualUrl); - } -} \ No newline at end of file + private Config config; + private Service service; + + @Before + public void setUp() { + config = new Config().environment(Environment.LIVE); + Client client = new Client(config); + service = new Service(client); + } + + @Test + public void testCreateBaseURLForTestEnvironment() { + config.setEnvironment(Environment.TEST); + String liveUrl = "https://balanceplatform-api-live.adyen.com/bcl/v2/balanceAccounts"; + String expectedUrl = "https://balanceplatform-api-test.adyen.com/bcl/v2/balanceAccounts"; + + String actualUrl = service.createBaseURL(liveUrl); + // verify Live url is converted to Test url + assertEquals(expectedUrl, actualUrl); + } + + @Test + public void testCreateBaseURLForLiveEnvironment() { + + String testUrl = "https://balanceplatform-api-test.adyen.com/bcl/v2/balanceAccounts"; + String expectedUrl = "https://balanceplatform-api-live.adyen.com/bcl/v2/balanceAccounts"; + + String actualUrl = service.createBaseURL(testUrl); + // verify Test url is converted to Live url + assertEquals(expectedUrl, actualUrl); + } + + @Test + public void testLivePalUrlWithPrefix() { + + config.setLiveEndpointUrlPrefix("123456789-company"); + String testUrl = "https://pal-test.adyen.com/pal/servlet/v52/initiate"; + String expectedUrl = + "https://123456789-company-pal-live.adyenpayments.com/pal/servlet/v52/initiate"; + + String actualUrl = service.createBaseURL(testUrl); + assertEquals(expectedUrl, actualUrl); + } + + @Test + public void testLivePalUrlWithoutPrefix() { + String testUrl = "https://pal-test.adyen.com/pal/servlet/v52/initiate"; + + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> service.createBaseURL(testUrl)); + assertEquals("please provide a live url prefix in the client", e.getMessage()); + } + + @Test + public void testLiveCheckoutUrlWithPrefix() { + config.setLiveEndpointUrlPrefix("123456789-company"); + String testUrl = "https://checkout-test.adyen.com/v68/payments"; + String expectedUrl = + "https://123456789-company-checkout-live.adyenpayments.com/checkout/v68/payments"; + + String actualUrl = service.createBaseURL(testUrl); + assertEquals(expectedUrl, actualUrl); + } + + @Test + public void testLiveCheckoutUrlWithoutPrefix() { + String testUrl = "https://checkout-test.adyen.com/v68/payments"; + + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> service.createBaseURL(testUrl)); + assertEquals("please provide a live url prefix in the client", e.getMessage()); + } + + @Test + public void testLiveCheckoutPosSdkUrlWithPrefix() { + config.setLiveEndpointUrlPrefix("123456789-company"); + String testUrl = "https://checkout-test.adyen.com/possdk/v68/sessions"; + String expectedUrl = + "https://123456789-company-checkout-live.adyenpayments.com/possdk/v68/sessions"; + + String actualUrl = service.createBaseURL(testUrl); + assertEquals(expectedUrl, actualUrl); + } +} diff --git a/src/test/java/com/adyen/httpclient/ClientTest.java b/src/test/java/com/adyen/httpclient/ClientTest.java index ed10c9057..f7b176a74 100644 --- a/src/test/java/com/adyen/httpclient/ClientTest.java +++ b/src/test/java/com/adyen/httpclient/ClientTest.java @@ -9,12 +9,10 @@ import com.adyen.enums.Environment; import com.adyen.enums.Region; import com.adyen.model.RequestOptions; - import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; import javax.net.ssl.SSLContext; - import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; import org.apache.hc.core5.http.Header; import org.junit.Assert; @@ -26,163 +24,154 @@ public class ClientTest extends BaseTest { - @Mock - private SSLContext clientCertificateAuthSSLContext; - - @Mock - private String apiKey; - - @Test - public void testConfigTestClient() { - Config config = new Config(); - config.setEnvironment(Environment.TEST); - config.setApiKey(apiKey); - Client client = new Client(config); - assertEquals(Environment.TEST, client.getConfig().getEnvironment()); - } - - @Test - public void testConfigLiveClient() { - Config config = new Config() - .environment(Environment.LIVE) - .liveEndpointUrlPrefix("myCompany") - .apiKey(apiKey); - Client client = new Client(config); - assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); - assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); - } - - @Test - public void testConstructorConfigLiveClient() { - Client client = new Client(apiKey, Environment.LIVE, "myCompany"); - assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); - assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); - } - - @Test - public void testConfigLiveClientWithBasicAuth() { - Client client = new Client("", "", Environment.LIVE, "myCompany"); - assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); - assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); - assertNull(client.getConfig().getApiKey()); - assertNull(client.getConfig().getApplicationName()); - } - - @Test - public void testConfigLiveClientWithBasicAuthAndApplication() { - Client client = new Client("", "", Environment.LIVE, "myCompany", "myApplication"); - assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); - assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); - assertEquals("myApplication", client.getConfig().getApplicationName()); - assertNull(client.getConfig().getApiKey()); - } - - private static Stream provideCloudTestEndpointTestCases() { - return Stream.of( - Arguments.of(null, Environment.TEST, "https://terminal-api-test.adyen.com"), - Arguments.of(Region.EU, Environment.TEST, "https://terminal-api-test.adyen.com"), - Arguments.of(Region.AU, Environment.TEST, "https://terminal-api-test.adyen.com"), - Arguments.of(Region.US, Environment.TEST, "https://terminal-api-test.adyen.com"), - Arguments.of(Region.APSE, Environment.TEST, "https://terminal-api-test.adyen.com")); - } - - @ParameterizedTest - @MethodSource("provideCloudTestEndpointTestCases") - public void testGetCloudEndpointForTestEnvironment( - Region region, Environment environment, String expectedEndpoint) { - Config config = new Config() - .environment(environment) - .terminalApiRegion(region) - .apiKey(apiKey); - Client client = new Client(config); - - assertEquals(expectedEndpoint, config.getTerminalApiCloudEndpoint()); - } - - private static Stream provideCloudLiveEndpointTestCases() { - return Stream.of( - Arguments.of(null, Environment.LIVE, "https://terminal-api-live.adyen.com"), - Arguments.of(Region.EU, Environment.LIVE, "https://terminal-api-live.adyen.com"), - Arguments.of(Region.AU, Environment.LIVE, "https://terminal-api-live-au.adyen.com"), - Arguments.of(Region.US, Environment.LIVE, "https://terminal-api-live-us.adyen.com"), - Arguments.of(Region.APSE, Environment.LIVE, "https://terminal-api-live-apse.adyen.com")); - } - - @ParameterizedTest - @MethodSource("provideCloudLiveEndpointTestCases") - public void testGetCloudEndpointForLiveEnvironment( - Region region, Environment environment, String expectedEndpoint) { - Config config = new Config() - .environment(environment) - .terminalApiRegion(region) - .apiKey(apiKey); - Client client = new Client(config); - - assertEquals(expectedEndpoint, config.getTerminalApiCloudEndpoint()); - } - - @Test - public void testUnmappedIndiaRegionThrowsException() { - Config config = new Config(); - config.setEnvironment(Environment.LIVE); - config.setTerminalApiRegion(Region.IN); - - Assert.assertThrows(IllegalArgumentException.class, () -> new Client(config)); - } - - @Test - public void testClientCertificateAuth() { - Client client = new Client(clientCertificateAuthSSLContext, apiKey); - assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); - } - - @Test - public void testRequestOptionsBuilderPattern() { - HashMap map = new HashMap<>(); - map.put("thing", "thing"); - RequestOptions requestOptions = - new RequestOptions() - .idempotencyKey("idempotency") - .requestedVerificationCodeHeader("headers") - .additionalServiceHeaders(map); - assertEquals(requestOptions.getAdditionalServiceHeaders(), map); - } - - @Test - public void testUserAgentWithApplicationName() throws Exception { - - AdyenHttpClient client = new AdyenHttpClient(); - HttpUriRequestBase requestWithAppName = - client.createRequest( - "https://chekout.adyen.com", - "{}", - new Config().applicationName("test-app"), - true, - null, - ApiConstants.HttpMethod.POST, - Map.of()); - - Header userAgent = requestWithAppName.getFirstHeader("User-Agent"); - assertNotNull(userAgent); - assertEquals("test-app " + Client.LIB_NAME + "/" + Client.LIB_VERSION, userAgent.getValue()); - } - - @Test - public void testUserAgentWithoutApplicationName() throws Exception { - - AdyenHttpClient client = new AdyenHttpClient(); - HttpUriRequestBase requestWithoutAppName = - client.createRequest( - "https://chekout.adyen.com", - "{}", - new Config(), - true, - null, - ApiConstants.HttpMethod.POST, - Map.of()); - - Header userAgent = requestWithoutAppName.getFirstHeader("User-Agent"); - assertNotNull(userAgent); - assertEquals(Client.LIB_NAME + "/" + Client.LIB_VERSION, userAgent.getValue()); - } + @Mock private SSLContext clientCertificateAuthSSLContext; + + @Test + public void testConfigTestClient() { + Config config = new Config(); + config.setEnvironment(Environment.TEST); + config.setApiKey("Your-X-API-KEY"); + Client client = new Client(config); + assertEquals(Environment.TEST, client.getConfig().getEnvironment()); + } + + @Test + public void testConfigLiveClient() { + Config config = + new Config() + .environment(Environment.LIVE) + .liveEndpointUrlPrefix("myCompany") + .apiKey("Your-X-API-KEY"); + Client client = new Client(config); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); + } + + @Test + public void testConstructorConfigLiveClient() { + Client client = new Client("Your-X-API-KEY", Environment.LIVE, "myCompany"); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); + } + + @Test + public void testConfigLiveClientWithBasicAuth() { + Client client = new Client("", "", Environment.LIVE, "myCompany"); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); + assertNull(client.getConfig().getApiKey()); + assertNull(client.getConfig().getApplicationName()); + } + + @Test + public void testConfigLiveClientWithBasicAuthAndApplication() { + Client client = new Client("", "", Environment.LIVE, "myCompany", "myApplication"); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + assertEquals("myCompany", client.getConfig().getLiveEndpointUrlPrefix()); + assertEquals("myApplication", client.getConfig().getApplicationName()); + assertNull(client.getConfig().getApiKey()); + } + + private static Stream provideCloudTestEndpointTestCases() { + return Stream.of( + Arguments.of(null, Environment.TEST, "https://terminal-api-test.adyen.com"), + Arguments.of(Region.EU, Environment.TEST, "https://terminal-api-test.adyen.com"), + Arguments.of(Region.AU, Environment.TEST, "https://terminal-api-test.adyen.com"), + Arguments.of(Region.US, Environment.TEST, "https://terminal-api-test.adyen.com"), + Arguments.of(Region.APSE, Environment.TEST, "https://terminal-api-test.adyen.com")); + } + + @ParameterizedTest + @MethodSource("provideCloudTestEndpointTestCases") + public void testGetCloudEndpointForTestEnvironment( + Region region, Environment environment, String expectedEndpoint) { + Config config = new Config().environment(environment).terminalApiRegion(region).apiKey("Your-X-API-KEY"); + Client client = new Client(config); + + assertEquals(expectedEndpoint, config.getTerminalApiCloudEndpoint()); + } + + private static Stream provideCloudLiveEndpointTestCases() { + return Stream.of( + Arguments.of(null, Environment.LIVE, "https://terminal-api-live.adyen.com"), + Arguments.of(Region.EU, Environment.LIVE, "https://terminal-api-live.adyen.com"), + Arguments.of(Region.AU, Environment.LIVE, "https://terminal-api-live-au.adyen.com"), + Arguments.of(Region.US, Environment.LIVE, "https://terminal-api-live-us.adyen.com"), + Arguments.of(Region.APSE, Environment.LIVE, "https://terminal-api-live-apse.adyen.com")); + } + + @ParameterizedTest + @MethodSource("provideCloudLiveEndpointTestCases") + public void testGetCloudEndpointForLiveEnvironment( + Region region, Environment environment, String expectedEndpoint) { + Config config = new Config().environment(environment).terminalApiRegion(region).apiKey("Your-X-API-KEY"); + Client client = new Client(config); + + assertEquals(expectedEndpoint, config.getTerminalApiCloudEndpoint()); + } + + @Test + public void testUnmappedIndiaRegionThrowsException() { + Config config = new Config(); + config.setEnvironment(Environment.LIVE); + config.setTerminalApiRegion(Region.IN); + + Assert.assertThrows(IllegalArgumentException.class, () -> new Client(config)); + } + + @Test + public void testClientCertificateAuth() { + Client client = new Client(clientCertificateAuthSSLContext, "Your-X-API-KEY"); + assertEquals(Environment.LIVE, client.getConfig().getEnvironment()); + } + + @Test + public void testRequestOptionsBuilderPattern() { + HashMap map = new HashMap<>(); + map.put("thing", "thing"); + RequestOptions requestOptions = + new RequestOptions() + .idempotencyKey("idempotency") + .requestedVerificationCodeHeader("headers") + .additionalServiceHeaders(map); + assertEquals(requestOptions.getAdditionalServiceHeaders(), map); + } + + @Test + public void testUserAgentWithApplicationName() throws Exception { + + AdyenHttpClient client = new AdyenHttpClient(); + HttpUriRequestBase requestWithAppName = + client.createRequest( + "https://chekout.adyen.com", + "{}", + new Config().applicationName("test-app"), + true, + null, + ApiConstants.HttpMethod.POST, + Map.of()); + + Header userAgent = requestWithAppName.getFirstHeader("User-Agent"); + assertNotNull(userAgent); + assertEquals("test-app " + Client.LIB_NAME + "/" + Client.LIB_VERSION, userAgent.getValue()); + } + + @Test + public void testUserAgentWithoutApplicationName() throws Exception { + + AdyenHttpClient client = new AdyenHttpClient(); + HttpUriRequestBase requestWithoutAppName = + client.createRequest( + "https://chekout.adyen.com", + "{}", + new Config(), + true, + null, + ApiConstants.HttpMethod.POST, + Map.of()); + + Header userAgent = requestWithoutAppName.getFirstHeader("User-Agent"); + assertNotNull(userAgent); + assertEquals(Client.LIB_NAME + "/" + Client.LIB_VERSION, userAgent.getValue()); + } } From e0d4cc9a6723a33d52c3a44c933a9159e945b029 Mon Sep 17 00:00:00 2001 From: gcatanese Date: Tue, 5 Aug 2025 08:50:47 +0200 Subject: [PATCH 10/10] Minor edit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 725e454bf..327b593ab 100644 --- a/README.md +++ b/README.md @@ -304,7 +304,7 @@ Client client = new Client(sslContext, apiKey); ## Using the Cloud Terminal API -For In-Person Payments integration with the [Cloud Terminal API](https://docs.adyen.com/point-of-sale/design-your-integration/choose-your-architecture/cloud/), you must initialise the Client **setting the closest** [Region](https://docs.adyen.com/point-of-sale/design-your-integration/terminal-api/#cloud): +For In-Person Payments integrations with the [Cloud Terminal API](https://docs.adyen.com/point-of-sale/design-your-integration/choose-your-architecture/cloud/), you must initialise the Client **setting the closest** [Region](https://docs.adyen.com/point-of-sale/design-your-integration/terminal-api/#cloud): ``` java // Step 1: Import the required classes import com.adyen.Client;