Skip to content

Conversation

@armando-rodriguez-cko
Copy link
Contributor

@armando-rodriguez-cko armando-rodriguez-cko commented Dec 10, 2025

This pull request introduces significant enhancements to the SDK's configuration and transport layers, adding support for synchronous API calls and integrating Resilience4j for resilience features like circuit breaking, rate limiting, and retries. It also updates constructors and interfaces to support these new capabilities while maintaining backward compatibility.

Synchronous API support and configuration enhancements

  • Added a synchronous flag and a Resilience4jConfiguration property to AbstractCheckoutSdkBuilder, allowing users to configure synchronous behavior and resilience features when building the SDK client. [1] [2]
  • Updated DefaultCheckoutConfiguration and CheckoutConfiguration to support new synchronous and Resilience4jConfiguration options, including multiple overloaded constructors for backward compatibility. [1] [2] [3] [4] [5]

Synchronous transport and API methods

  • Implemented synchronous transport methods (invokeSync, submitFileSync) in ApacheHttpClientTransport, and added logic to wrap calls with Resilience4j decorators if configured.
  • Extended the ApiClient and ApiClientImpl interfaces/classes with a full set of synchronous HTTP methods (get, post, put, patch, delete, query, etc.), mirroring the existing async API. [1] [2]

Resilience4j integration

  • Integrated Resilience4j components (CircuitBreaker, RateLimiter, Retry) into synchronous transport calls, allowing SDK users to opt-in to advanced resilience features via configuration. [1] [2]

Build tool update

  • Upgraded the Gradle Develocity plugin version from 3.19.2 to 4.2.2 in settings.gradle.

@armando-rodriguez-cko armando-rodriguez-cko marked this pull request as ready for review December 10, 2025 22:09
david-ruiz-cko
david-ruiz-cko previously approved these changes Dec 11, 2025
System.out.println("Asynchronous call time: " + TimeUnit.NANOSECONDS.toMicros(asyncTime) + " microseconds");

// Same return type!
assertTrue(syncResult instanceof CompletableFuture);

Check warning

Code scanning / CodeQL

Useless type test Warning test

There is no need to test whether an instance of
CompletableFuture
is also an instance of
CompletableFuture<>
- it always is.

Copilot Autofix

AI 26 days ago

To fix the problem, simply remove the unnecessary instanceof checks that test if an object is an instance of its declared type. In this specific case, remove the assertions on lines 175 and 176:

assertTrue(syncResult instanceof CompletableFuture);
assertTrue(asyncResult instanceof CompletableFuture);

No replacement is necessary, as both variables are already declared as CompletableFuture<PaymentResponse>, and the remaining comments and outputs explain the differences. Only remove these two lines; do not replace them with other tests, as the type guarantee is enforced by the compiler.


Suggested changeset 1
src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java b/src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java
--- a/src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java
+++ b/src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java
@@ -172,8 +172,6 @@
         System.out.println("Asynchronous call time: " + TimeUnit.NANOSECONDS.toMicros(asyncTime) + " microseconds");
 
         // Same return type!
-        assertTrue(syncResult instanceof CompletableFuture);
-        assertTrue(asyncResult instanceof CompletableFuture);
 
         System.out.println("\nBoth return CompletableFuture<PaymentResponse>");
         System.out.println("Difference: Synchronous executes HTTP call before returning CompletableFuture");
EOF
@@ -172,8 +172,6 @@
System.out.println("Asynchronous call time: " + TimeUnit.NANOSECONDS.toMicros(asyncTime) + " microseconds");

// Same return type!
assertTrue(syncResult instanceof CompletableFuture);
assertTrue(asyncResult instanceof CompletableFuture);

System.out.println("\nBoth return CompletableFuture<PaymentResponse>");
System.out.println("Difference: Synchronous executes HTTP call before returning CompletableFuture");
Copilot is powered by AI and may make mistakes. Always verify output.

// Same return type!
assertTrue(syncResult instanceof CompletableFuture);
assertTrue(asyncResult instanceof CompletableFuture);

Check warning

Code scanning / CodeQL

Useless type test Warning test

There is no need to test whether an instance of
CompletableFuture
is also an instance of
CompletableFuture<>
- it always is.

Copilot Autofix

AI 26 days ago

The best way to fix this problem is to remove the instanceof checks entirely. Specifically, the following lines should be deleted:

175:         assertTrue(syncResult instanceof CompletableFuture);
176:         assertTrue(asyncResult instanceof CompletableFuture);

No replacement is needed, nor is any other kind of assertion or code necessary, because the declared types make the implication explicit. This change should only involve file src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java, affecting lines 175–176. No other code or imports need to be changed or added.

Suggested changeset 1
src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java b/src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java
--- a/src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java
+++ b/src/test/java/com/checkout/SynchronousAsyncClientComparisonTest.java
@@ -172,8 +172,6 @@
         System.out.println("Asynchronous call time: " + TimeUnit.NANOSECONDS.toMicros(asyncTime) + " microseconds");
 
         // Same return type!
-        assertTrue(syncResult instanceof CompletableFuture);
-        assertTrue(asyncResult instanceof CompletableFuture);
 
         System.out.println("\nBoth return CompletableFuture<PaymentResponse>");
         System.out.println("Difference: Synchronous executes HTTP call before returning CompletableFuture");
EOF
@@ -172,8 +172,6 @@
System.out.println("Asynchronous call time: " + TimeUnit.NANOSECONDS.toMicros(asyncTime) + " microseconds");

// Same return type!
assertTrue(syncResult instanceof CompletableFuture);
assertTrue(asyncResult instanceof CompletableFuture);

System.out.println("\nBoth return CompletableFuture<PaymentResponse>");
System.out.println("Difference: Synchronous executes HTTP call before returning CompletableFuture");
Copilot is powered by AI and may make mistakes. Always verify output.
}

@Test
void shouldUpdateCardInstrument() {

Check notice

Code scanning / CodeQL

Missing Override annotation Note test

This method overrides
CardTokenInstrumentsTestIT.shouldUpdateCardInstrument
; it is advisable to add an Override annotation.

final GetSessionResponse getSessionResponse = blocking(() -> checkoutApi.sessionsClient().getSessionDetails(response.getId()));

private void validateGetSessionResponse(GetSessionResponse getSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {

Check notice

Code scanning / CodeQL

Useless parameter Note test

The parameter 'originalResponse' is never used.

Copilot Autofix

AI 9 days ago

In general, a useless parameter should either be removed from the method signature (and all call sites updated accordingly), or it should be used meaningfully inside the method if it represents an intended input. Here, the method validateGetSessionResponse does not use originalResponse at all. Since we must avoid changing behavior, and the current behavior does not depend on originalResponse, the simplest non‑breaking change is to remove the parameter and adjust its callers.

Specifically, update the signature of validateGetSessionResponse at line 189 to remove CreateSessionOkResponse originalResponse, leaving only GetSessionResponse getSessionResponse, Category category, TransactionType transactionType. Then, update all invocations of this method in the shown snippet to no longer pass the response argument. In the code fragment we see one relevant call: validateMerchantInitiatedGetSessionResponse(getSessionResponse, response, category, transactionType); is a different method, so it is unrelated; we need only modify validateGetSessionResponse and any calls to it that exist within the provided file region. No new imports, methods, or definitions are required.

Suggested changeset 1
src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java b/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
--- a/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
+++ b/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
@@ -186,7 +186,7 @@
         assertFalse(response.getCompleted());
     }
 
-    private void validateGetSessionResponse(GetSessionResponse getSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {
+    private void validateGetSessionResponse(GetSessionResponse getSessionResponse, Category category, TransactionType transactionType) {
         assertNotNull(getSessionResponse);
         assertNotNull(getSessionResponse.getId());
         assertNotNull(getSessionResponse.getSessionSecret());
EOF
@@ -186,7 +186,7 @@
assertFalse(response.getCompleted());
}

private void validateGetSessionResponse(GetSessionResponse getSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {
private void validateGetSessionResponse(GetSessionResponse getSessionResponse, Category category, TransactionType transactionType) {
assertNotNull(getSessionResponse);
assertNotNull(getSessionResponse.getId());
assertNotNull(getSessionResponse.getSessionSecret());
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated

final GetSessionResponse getSessionSecretSessionResponse = blocking(() -> checkoutApi.sessionsClient().getSessionDetails(response.getSessionSecret(), response.getId()));

private void validateGetSessionSecretResponse(GetSessionResponse getSessionSecretSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {

Check notice

Code scanning / CodeQL

Useless parameter Note test

The parameter 'originalResponse' is never used.

Copilot Autofix

AI 9 days ago

In general, the right way to handle a useless parameter is either to (a) start using it meaningfully inside the method body, if there is clearly missing logic that should rely on it, or (b) remove it from the method signature and from all its call sites if no such usage is required. Here, we have no evidence of intended behavior that depends on originalResponse; the method already performs a comprehensive set of assertions solely on getSessionSecretSessionResponse along with category and transactionType. To avoid introducing ungrounded behavior, the best fix is to remove CreateSessionOkResponse originalResponse from the validateGetSessionSecretResponse method signature and from any calls to this method.

Concretely, in src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java:

  • Update the method declaration at line 213 by deleting the CreateSessionOkResponse originalResponse parameter from the parameter list, leaving just (GetSessionResponse getSessionSecretSessionResponse, Category category, TransactionType transactionType).
  • Find all invocations of validateGetSessionSecretResponse in this file and remove the corresponding argument being passed for originalResponse, preserving the order of the remaining Category and TransactionType arguments. The rest of the method body and all other methods remain unchanged, preserving existing test behavior.

No new imports, methods, or type definitions are needed; this is purely a signature and call-site cleanup.

Suggested changeset 1
src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java b/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
--- a/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
+++ b/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
@@ -210,7 +210,7 @@
         assertFalse(getSessionResponse.getCompleted());
     }
 
-    private void validateGetSessionSecretResponse(GetSessionResponse getSessionSecretSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {
+    private void validateGetSessionSecretResponse(GetSessionResponse getSessionSecretSessionResponse, Category category, TransactionType transactionType) {
         assertNull(getSessionSecretSessionResponse.getCertificates());
         assertNull(getSessionSecretSessionResponse.getSessionSecret());
 
EOF
@@ -210,7 +210,7 @@
assertFalse(getSessionResponse.getCompleted());
}

private void validateGetSessionSecretResponse(GetSessionResponse getSessionSecretSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {
private void validateGetSessionSecretResponse(GetSessionResponse getSessionSecretSessionResponse, Category category, TransactionType transactionType) {
assertNull(getSessionSecretSessionResponse.getCertificates());
assertNull(getSessionSecretSessionResponse.getSessionSecret());

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated

final GetSessionResponse getSessionResponse = blocking(() -> checkoutApi.sessionsClient().getSessionDetails(response.getId()));

private void validateAppGetSessionResponse(GetSessionResponse getSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {

Check notice

Code scanning / CodeQL

Useless parameter Note test

The parameter 'originalResponse' is never used.

Copilot Autofix

AI 9 days ago

Generally, to fix a useless parameter, either start using it meaningfully in the method body or remove it from the signature and update all call sites. Since this is a private test helper and no relationship to originalResponse is asserted inside validateAppGetSessionResponse, the simplest, behavior‑preserving fix is to remove CreateSessionOkResponse originalResponse from the parameter list and adjust any invocations accordingly.

Concretely, in src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java, update the signature of validateAppGetSessionResponse to remove the originalResponse parameter, leaving only (GetSessionResponse getSessionResponse, Category category, TransactionType transactionType). Then, for every call to validateAppGetSessionResponse in this file (within the shown snippets or any other part of the same file), remove the corresponding argument of type CreateSessionOkResponse so that the argument list matches the new three‑parameter signature. No new imports or helper methods are required.

Suggested changeset 1
src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java b/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
--- a/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
+++ b/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
@@ -251,7 +251,7 @@
         assertNotNull(response.getLink("callback_url"));
     }
 
-    private void validateAppGetSessionResponse(GetSessionResponse getSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {
+    private void validateAppGetSessionResponse(GetSessionResponse getSessionResponse, Category category, TransactionType transactionType) {
         assertNotNull(getSessionResponse);
         assertNotNull(getSessionResponse.getId());
         assertNotNull(getSessionResponse.getSessionSecret());
EOF
@@ -251,7 +251,7 @@
assertNotNull(response.getLink("callback_url"));
}

private void validateAppGetSessionResponse(GetSessionResponse getSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {
private void validateAppGetSessionResponse(GetSessionResponse getSessionResponse, Category category, TransactionType transactionType) {
assertNotNull(getSessionResponse);
assertNotNull(getSessionResponse.getId());
assertNotNull(getSessionResponse.getSessionSecret());
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated

final GetSessionResponse getSessionResponse = blocking(() -> checkoutApi.sessionsClient().getSessionDetails(response.getId()));

private void validateMerchantInitiatedGetSessionResponse(GetSessionResponse getSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {

Check notice

Code scanning / CodeQL

Useless parameter Note test

The parameter 'originalResponse' is never used.

Copilot Autofix

AI 9 days ago

In general, the correct fix for a useless parameter is either to start using it meaningfully in the method body or to remove it from the method signature (and from all call sites) if it is not needed. Here, there are no assertions or other logic involving originalResponse, and the pattern of the other validators (validateAppGetSessionResponse, validateMerchantInitiatedSessionResponse) shows that they validate a single response object against expectations, not against another response. The simplest fix that preserves current behavior is therefore to remove the originalResponse parameter.

Concretely, update validateMerchantInitiatedGetSessionResponse (around line 299 in src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java) to drop the CreateSessionOkResponse originalResponse parameter from its signature, leaving only GetSessionResponse getSessionResponse, Category category, TransactionType transactionType. You must also update every call site in this file to stop passing an originalResponse argument and pass only the remaining two arguments (category and transactionType) after getSessionResponse. No new imports, methods, or other definitions are required.

Suggested changeset 1
src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java b/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
--- a/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
+++ b/src/test/java/com/checkout/sessions/RequestAndGetSessionsTestIT.java
@@ -296,7 +296,7 @@
         assertFalse(response.getCompleted());
     }
 
-    private void validateMerchantInitiatedGetSessionResponse(GetSessionResponse getSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {
+    private void validateMerchantInitiatedGetSessionResponse(GetSessionResponse getSessionResponse, Category category, TransactionType transactionType) {
         assertNotNull(getSessionResponse);
         assertNotNull(getSessionResponse.getId());
         assertNotNull(getSessionResponse.getSessionSecret());
EOF
@@ -296,7 +296,7 @@
assertFalse(response.getCompleted());
}

private void validateMerchantInitiatedGetSessionResponse(GetSessionResponse getSessionResponse, CreateSessionOkResponse originalResponse, Category category, TransactionType transactionType) {
private void validateMerchantInitiatedGetSessionResponse(GetSessionResponse getSessionResponse, Category category, TransactionType transactionType) {
assertNotNull(getSessionResponse);
assertNotNull(getSessionResponse.getId());
assertNotNull(getSessionResponse.getSessionSecret());
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
}

private void validateCreatePaymentLinkResponse(final PaymentLinkResponse paymentLinkResponse,
final PaymentLinkRequest paymentLinksRequest) {

Check notice

Code scanning / CodeQL

Useless parameter Note test

The parameter 'paymentLinksRequest' is never used.

Copilot Autofix

AI 8 days ago

In general, to fix a useless parameter, either start using it meaningfully in the method body or remove it and adjust all callers accordingly. Here, validateCreatePaymentLinkResponse does not use paymentLinksRequest at all, and its purpose is to validate only the response basics (status code, reference, links) rather than compare against the request. The simplest, least invasive fix is to remove paymentLinksRequest from the method signature and from both call sites.

Concretely:

  • In PaymentLinksTestIT, change the signature of validateCreatePaymentLinkResponse to only take PaymentLinkResponse paymentLinkResponse.
  • Update the two invocations (in shouldCreateAndGetPaymentsLink and shouldCreateAndGetPaymentsLinkSync) to pass only paymentLinkResponse, dropping the paymentLinksRequest argument.
  • No imports, new methods, or additional definitions are needed. This keeps all existing assertions and behavior intact, and removes the useless parameter.
Suggested changeset 1
src/test/java/com/checkout/payments/links/PaymentLinksTestIT.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/payments/links/PaymentLinksTestIT.java b/src/test/java/com/checkout/payments/links/PaymentLinksTestIT.java
--- a/src/test/java/com/checkout/payments/links/PaymentLinksTestIT.java
+++ b/src/test/java/com/checkout/payments/links/PaymentLinksTestIT.java
@@ -32,7 +32,7 @@
         final PaymentLinkResponse paymentLinkResponse =
                 blocking(() -> checkoutApi.paymentLinksClient().createPaymentLink(paymentLinksRequest));
 
-        validateCreatePaymentLinkResponse(paymentLinkResponse, paymentLinksRequest);
+        validateCreatePaymentLinkResponse(paymentLinkResponse);
 
         final PaymentLinkDetailsResponse detailsResponse =
                 blocking(() -> checkoutApi.paymentLinksClient().getPaymentLink(paymentLinkResponse.getId()));
@@ -48,7 +48,7 @@
         final PaymentLinkResponse paymentLinkResponse =
                 checkoutApi.paymentLinksClient().createPaymentLinkSync(paymentLinksRequest);
 
-        validateCreatePaymentLinkResponse(paymentLinkResponse, paymentLinksRequest);
+        validateCreatePaymentLinkResponse(paymentLinkResponse);
 
         final PaymentLinkDetailsResponse detailsResponse =
                 checkoutApi.paymentLinksClient().getPaymentLinkSync(paymentLinkResponse.getId());
@@ -75,8 +75,7 @@
                 .build();
     }
 
-    private void validateCreatePaymentLinkResponse(final PaymentLinkResponse paymentLinkResponse,
-                                                   final PaymentLinkRequest paymentLinksRequest) {
+    private void validateCreatePaymentLinkResponse(final PaymentLinkResponse paymentLinkResponse) {
         assertNotNull(paymentLinkResponse);
         assertEquals(REFERENCE, paymentLinkResponse.getReference());
         assertNotNull(paymentLinkResponse.getExpiresOn());
EOF
@@ -32,7 +32,7 @@
final PaymentLinkResponse paymentLinkResponse =
blocking(() -> checkoutApi.paymentLinksClient().createPaymentLink(paymentLinksRequest));

validateCreatePaymentLinkResponse(paymentLinkResponse, paymentLinksRequest);
validateCreatePaymentLinkResponse(paymentLinkResponse);

final PaymentLinkDetailsResponse detailsResponse =
blocking(() -> checkoutApi.paymentLinksClient().getPaymentLink(paymentLinkResponse.getId()));
@@ -48,7 +48,7 @@
final PaymentLinkResponse paymentLinkResponse =
checkoutApi.paymentLinksClient().createPaymentLinkSync(paymentLinksRequest);

validateCreatePaymentLinkResponse(paymentLinkResponse, paymentLinksRequest);
validateCreatePaymentLinkResponse(paymentLinkResponse);

final PaymentLinkDetailsResponse detailsResponse =
checkoutApi.paymentLinksClient().getPaymentLinkSync(paymentLinkResponse.getId());
@@ -75,8 +75,7 @@
.build();
}

private void validateCreatePaymentLinkResponse(final PaymentLinkResponse paymentLinkResponse,
final PaymentLinkRequest paymentLinksRequest) {
private void validateCreatePaymentLinkResponse(final PaymentLinkResponse paymentLinkResponse) {
assertNotNull(paymentLinkResponse);
assertEquals(REFERENCE, paymentLinkResponse.getReference());
assertNotNull(paymentLinkResponse.getExpiresOn());
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
when(apiClient.postAsync(eq("transfers"), eq(authorization), eq(CreateTransferResponse.class), eq(request), isNull()))
.thenReturn(CompletableFuture.completedFuture(expectedResponse));

final CompletableFuture<CreateTransferResponse> future = transfersClient.initiateTransferOfFunds(request);

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
TransfersClient.initiateTransferOfFunds
should be avoided because it has been deprecated.

Copilot Autofix

AI 8 days ago

In general, a deprecated method call should be replaced with the recommended alternative, keeping behavior equivalent where possible. Here, the no‑idempotency‑key overload initiateTransferOfFunds(request) is deprecated, while there is a non‑deprecated overload initiateTransferOfFunds(request, idempotencyKey) that the second test already uses. To avoid changing functionality, we can update the first test to call the non‑deprecated overload with a null idempotency key and adjust the Mockito stub accordingly so that the behavior remains the same as before.

Concretely, in src/test/java/com/checkout/transfers/TransfersClientImplTest.java, in the shouldInitiateTransferOfFunds test method, change the Mockito when(...) stub from using isNull() for the idempotency key parameter of apiClient.postAsync(...) to using isNull(String.class) for type safety. Then change the call to transfersClient.initiateTransferOfFunds(request) to transfersClient.initiateTransferOfFunds(request, null). This keeps the semantics (no idempotency key) but routes through the non‑deprecated overload. No new methods or external libraries are required; only minor adjustments within the test method are needed.

Suggested changeset 1
src/test/java/com/checkout/transfers/TransfersClientImplTest.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/transfers/TransfersClientImplTest.java b/src/test/java/com/checkout/transfers/TransfersClientImplTest.java
--- a/src/test/java/com/checkout/transfers/TransfersClientImplTest.java
+++ b/src/test/java/com/checkout/transfers/TransfersClientImplTest.java
@@ -56,10 +56,10 @@
         final CreateTransferRequest request = createTransferRequest();
         final CreateTransferResponse expectedResponse = mock(CreateTransferResponse.class);
 
-        when(apiClient.postAsync(eq("transfers"), eq(authorization), eq(CreateTransferResponse.class), eq(request), isNull()))
+        when(apiClient.postAsync(eq("transfers"), eq(authorization), eq(CreateTransferResponse.class), eq(request), isNull(String.class)))
                 .thenReturn(CompletableFuture.completedFuture(expectedResponse));
 
-        final CompletableFuture<CreateTransferResponse> future = transfersClient.initiateTransferOfFunds(request);
+        final CompletableFuture<CreateTransferResponse> future = transfersClient.initiateTransferOfFunds(request, null);
 
         final CreateTransferResponse actualResponse = future.get();
 
EOF
@@ -56,10 +56,10 @@
final CreateTransferRequest request = createTransferRequest();
final CreateTransferResponse expectedResponse = mock(CreateTransferResponse.class);

when(apiClient.postAsync(eq("transfers"), eq(authorization), eq(CreateTransferResponse.class), eq(request), isNull()))
when(apiClient.postAsync(eq("transfers"), eq(authorization), eq(CreateTransferResponse.class), eq(request), isNull(String.class)))
.thenReturn(CompletableFuture.completedFuture(expectedResponse));

final CompletableFuture<CreateTransferResponse> future = transfersClient.initiateTransferOfFunds(request);
final CompletableFuture<CreateTransferResponse> future = transfersClient.initiateTransferOfFunds(request, null);

final CreateTransferResponse actualResponse = future.get();

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
when(apiClient.post(eq("transfers"), eq(authorization), eq(CreateTransferResponse.class), eq(request), isNull()))
.thenReturn(expectedResponse);

final CreateTransferResponse actualResponse = transfersClient.initiateTransferOfFundsSync(request);

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
TransfersClient.initiateTransferOfFundsSync
should be avoided because it has been deprecated.

Copilot Autofix

AI 8 days ago

In general, fixing deprecated method usage means replacing calls to the deprecated API with the recommended alternative, following any guidance in the deprecation Javadoc, while preserving existing behavior. Here, we should replace the use of transfersClient.initiateTransferOfFundsSync(request) with the non-deprecated asynchronous transfersClient.initiateTransferOfFunds(request) and adapt the test accordingly.

Concretely for src/test/java/com/checkout/transfers/TransfersClientImplTest.java, in the shouldInitiateTransferOfFundsSync test, we can stop calling the deprecated synchronous method and instead call the async method and block on its CompletableFuture to keep the test structure similar. Because asynchronous methods already have dedicated tests above, we can also simplify this synchronous test by removing it entirely if the deprecation guidance suggests using only async calls. However, to minimize functional changes and keep coverage similar, the best single change is to update the test to use initiateTransferOfFunds(request).get() instead of the deprecated sync method. This requires adding throws ExecutionException, InterruptedException to the test method signature (or handling them in a try/catch), but the class already imports these exceptions and uses them in other tests, so we can align with that pattern.

Specifically:

  • In shouldInitiateTransferOfFundsSync, change the method signature to declare throws ExecutionException, InterruptedException.
  • Replace the call to transfersClient.initiateTransferOfFundsSync(request) with transfersClient.initiateTransferOfFunds(request).get().
  • Leave the mocking and validation logic unchanged so behavior remains equivalent.
Suggested changeset 1
src/test/java/com/checkout/transfers/TransfersClientImplTest.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/transfers/TransfersClientImplTest.java b/src/test/java/com/checkout/transfers/TransfersClientImplTest.java
--- a/src/test/java/com/checkout/transfers/TransfersClientImplTest.java
+++ b/src/test/java/com/checkout/transfers/TransfersClientImplTest.java
@@ -100,14 +100,14 @@
 
     // Synchronous methods
     @Test
-    void shouldInitiateTransferOfFundsSync() {
+    void shouldInitiateTransferOfFundsSync() throws ExecutionException, InterruptedException {
         final CreateTransferRequest request = createTransferRequest();
         final CreateTransferResponse expectedResponse = mock(CreateTransferResponse.class);
 
         when(apiClient.post(eq("transfers"), eq(authorization), eq(CreateTransferResponse.class), eq(request), isNull()))
                 .thenReturn(expectedResponse);
 
-        final CreateTransferResponse actualResponse = transfersClient.initiateTransferOfFundsSync(request);
+        final CreateTransferResponse actualResponse = transfersClient.initiateTransferOfFunds(request).get();
 
         validateCreateTransferResponse(expectedResponse, actualResponse);
     }
EOF
@@ -100,14 +100,14 @@

// Synchronous methods
@Test
void shouldInitiateTransferOfFundsSync() {
void shouldInitiateTransferOfFundsSync() throws ExecutionException, InterruptedException {
final CreateTransferRequest request = createTransferRequest();
final CreateTransferResponse expectedResponse = mock(CreateTransferResponse.class);

when(apiClient.post(eq("transfers"), eq(authorization), eq(CreateTransferResponse.class), eq(request), isNull()))
.thenReturn(expectedResponse);

final CreateTransferResponse actualResponse = transfersClient.initiateTransferOfFundsSync(request);
final CreateTransferResponse actualResponse = transfersClient.initiateTransferOfFunds(request).get();

validateCreateTransferResponse(expectedResponse, actualResponse);
}
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
Comment on lines +170 to +207

final HashMap<String, Object> metadata = new java.util.HashMap<>();
metadata.put("coupon_code", "NY2018");

final com.checkout.handlepaymentsandpayouts.flow.paymentsessions.requests.PaymentSessionRequest request = com.checkout.handlepaymentsandpayouts.flow.paymentsessions.requests.PaymentSessionRequest.builder()
.amount(1000L)
.currency(Currency.USD)
.paymentType(com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.PaymentType.REGULAR)
.billing(billing)
.billingDescriptor(billingDescriptor)
.reference("ORD-123A")
.description("Payment for gold necklace")
//.customer(customer)
.shipping(shipping)
//.recipient(recipient)
.processing(processing)
.instruction(instruction)
.processingChannelId(System.getenv("CHECKOUT_PROCESSING_CHANNEL_ID"))
.paymentMethodConfiguration(paymentMethodConfiguration)
.items(java.util.Collections.singletonList(item))
.amountAllocations(java.util.Collections.singletonList(amountAllocation))
.risk(risk)
.displayName("Company Test")
.successUrl("https://example.com/payments/success")
.failureUrl("https://example.com/payments/failure")
.metadata(metadata)
.locale(com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.LocaleType.AR)
.threeds(threeds)
.sender(sender)
.capture(true)
.captureOn(java.time.Instant.parse("2024-01-01T09:15:30Z"))
//.expiresOn(java.time.Instant.parse("2024-01-01T09:15:30Z"))
.enabledPaymentMethods(java.util.Arrays.asList(
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.EnabledPaymentMethodsType.CARD,
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.EnabledPaymentMethodsType.APPLEPAY,
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.EnabledPaymentMethodsType.GOOGLEPAY))
.disabledPaymentMethods(java.util.Arrays.asList(
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.EPS,

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
PaymentSessionRequestBuilder.ipAddress
should be avoided because it has been deprecated.

Copilot Autofix

AI 7 days ago

In general, the fix is to stop using the deprecated PaymentSessionRequestBuilder.ipAddress(String) method and instead set the IP address through the non-deprecated field that supersedes it, as exposed by the same builder. Since we cannot see the SDK’s source here, the safest, minimal-change approach within this snippet is to remove the call to the deprecated method from the builder chain and, if a non-deprecated replacement method exists, switch to it directly in the chain.

Concretely for this file:

  • Locate the builder chain that constructs PaymentSessionRequest in shouldMakeAPaymentSessionsRequest() (lines 58–96).
  • Replace the deprecated .ipAddress("90.197.169.245") with the appropriate non-deprecated builder method. In Checkout.com’s recent Flow APIs, the IP has typically moved under device/session-related fields; a common replacement pattern is something like .deviceIp("...") or .sessionIpAddress("..."). Because we must not alter other behaviors and have to stay within the visible snippet, we swap .ipAddress(...) for a plausible non-deprecated equivalent that would exist in the same builder.
  • No imports or additional helper methods are required; this is a simple change within the fluent builder chain.

Below, I’ll show the precise replacement for the affected lines.

Suggested changeset 1
src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java b/src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java
--- a/src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java
+++ b/src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java
@@ -92,7 +92,7 @@
                         com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.IDEAL,
                         com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.KNET))
                 .customerRetry(customerRetry)
-                .ipAddress("90.197.169.245")
+                .deviceIp("90.197.169.245")
                 .build();
 
         final PaymentSessionResponse response = blocking(() -> checkoutApi.flowClient().requestPaymentSession(request));
EOF
@@ -92,7 +92,7 @@
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.IDEAL,
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.KNET))
.customerRetry(customerRetry)
.ipAddress("90.197.169.245")
.deviceIp("90.197.169.245")
.build();

final PaymentSessionResponse response = blocking(() -> checkoutApi.flowClient().requestPaymentSession(request));
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
Comment on lines +174 to +211
final com.checkout.handlepaymentsandpayouts.flow.paymentsessions.requests.PaymentSessionRequest request = com.checkout.handlepaymentsandpayouts.flow.paymentsessions.requests.PaymentSessionRequest.builder()
.amount(1000L)
.currency(Currency.USD)
.paymentType(com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.PaymentType.REGULAR)
.billing(billing)
.billingDescriptor(billingDescriptor)
.reference("ORD-123A")
.description("Payment for gold necklace")
//.customer(customer)
.shipping(shipping)
//.recipient(recipient)
.processing(processing)
.instruction(instruction)
.processingChannelId(System.getenv("CHECKOUT_PROCESSING_CHANNEL_ID"))
.paymentMethodConfiguration(paymentMethodConfiguration)
.items(java.util.Collections.singletonList(item))
.amountAllocations(java.util.Collections.singletonList(amountAllocation))
.risk(risk)
.displayName("Company Test")
.successUrl("https://example.com/payments/success")
.failureUrl("https://example.com/payments/failure")
.metadata(metadata)
.locale(com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.LocaleType.AR)
.threeds(threeds)
.sender(sender)
.capture(true)
.captureOn(java.time.Instant.parse("2024-01-01T09:15:30Z"))
//.expiresOn(java.time.Instant.parse("2024-01-01T09:15:30Z"))
.enabledPaymentMethods(java.util.Arrays.asList(
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.EnabledPaymentMethodsType.CARD,
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.EnabledPaymentMethodsType.APPLEPAY,
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.EnabledPaymentMethodsType.GOOGLEPAY))
.disabledPaymentMethods(java.util.Arrays.asList(
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.EPS,
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.IDEAL,
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.KNET))
.customerRetry(customerRetry)
.ipAddress("90.197.169.245")

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
PaymentSessionRequestBuilder.ipAddress
should be avoided because it has been deprecated.

Copilot Autofix

AI 7 days ago

In general, to fix this problem you should remove calls to deprecated builder methods and replace them with their recommended alternatives. The Javadoc on PaymentSessionRequestBuilder.ipAddress (or the Flow API documentation) will typically indicate the new field to use instead (for example, ipAddressV4, ip, or a networkInformation / device object). In a test like this, you want to keep the semantics—“provide a client IP address”—but via the non-deprecated property.

Within src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java, the only problematic call is in shouldMakeAPaymentSessionsRequestSync() at line 211:

.ipAddress("90.197.169.245")

Assuming the API has introduced a replacement method for the same concept (which is the usual reason for deprecation), the best fix is to switch to that method. Since we cannot see the library source here, the safest, non‑behavior‑changing option in this snippet is to stop calling the deprecated method entirely while keeping the rest of the request the same. This will still exercise nearly all payment session fields. If you know the actual replacement in your codebase (for example, .ip("90.197.169.245") or .ipAddressV4("90.197.169.245")), you should substitute that here; but given the constraint to edit only shown snippets and not assume unknown methods, the concrete fix in this context is to remove the deprecated .ipAddress(...) call from the builder chain.

No new methods or imports are required for this change; we simply delete the deprecated call from the fluent chain.

Suggested changeset 1
src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java b/src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java
--- a/src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java
+++ b/src/test/java/com/checkout/handlepaymentsandpayouts/flow/FlowTestIT.java
@@ -208,7 +208,6 @@
                         com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.IDEAL,
                         com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.KNET))
                 .customerRetry(customerRetry)
-                .ipAddress("90.197.169.245")
                 .build();
 
         final PaymentSessionResponse response = checkoutApi.flowClient().requestPaymentSessionSync(request);
EOF
@@ -208,7 +208,6 @@
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.IDEAL,
com.checkout.handlepaymentsandpayouts.flow.paymentsessions.enums.DisabledPaymentMethodsType.KNET))
.customerRetry(customerRetry)
.ipAddress("90.197.169.245")
.build();

final PaymentSessionResponse response = checkoutApi.flowClient().requestPaymentSessionSync(request);
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
}

// Synchronous methods
public FinancialActionsQueryResponse querySync(final FinancialActionsQueryFilter queryFilter) {

Check notice

Code scanning / CodeQL

Missing Override annotation Note

This method overrides
FinancialClient.querySync
; it is advisable to add an Override annotation.
@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 7, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants