From 965cc0591533492f3e260963aadf48e335e51097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20Rodr=C3=ADguez?= <127134616+armando-rodriguez-cko@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:00:16 +0100 Subject: [PATCH 1/4] fix(payments): align retry and customer retry types with the spec customer_retry on POST /hosted-payments and POST /payment-links only accepts max_attempts (0 to 5), so it now uses CustomerRetry instead of PaymentRetryRequest. PaymentRetryRequest.enabled is no longer deprecated: it is the required switch for asynchronous retries on POST /payments. The payment retry response gains attemptsMade, and the request payment retry response no longer reports a max_attempts the API did not return. --- .../flow/entities/CustomerRetry.java | 9 +- .../requests/PaymentSessionCreateRequest.java | 2 +- .../retry/Retry.java | 15 +-- .../payments/hosted/HostedPaymentRequest.java | 6 +- .../payments/links/PaymentLinkRequest.java | 6 +- .../request/DowntimeRetryRequest.java | 7 +- .../payments/request/DunningRetryRequest.java | 13 +- .../payments/request/PaymentRequest.java | 2 +- .../payments/request/PaymentRetryRequest.java | 33 +++-- .../payments/response/GetPaymentResponse.java | 4 + .../payments/response/PaymentResponse.java | 4 + .../response/PaymentRetryResponse.java | 28 ++++- src/test/java/com/checkout/TestHelper.java | 6 +- .../CustomerRetrySerializationTest.java | 90 ++++++++++++++ .../retry/RetrySerializationTest.java | 48 ++++++++ .../PaymentRetryRequestSerializationTest.java | 114 +++++++++--------- ...PaymentRetryResponseSerializationTest.java | 60 +++++++++ 17 files changed, 351 insertions(+), 96 deletions(-) create mode 100644 src/test/java/com/checkout/handlepaymentsandpayouts/flow/entities/CustomerRetrySerializationTest.java create mode 100644 src/test/java/com/checkout/handlepaymentsandpayouts/payments/postpayments/responses/requestapaymentorpayoutresponsecreated/retry/RetrySerializationTest.java create mode 100644 src/test/java/com/checkout/payments/response/PaymentRetryResponseSerializationTest.java diff --git a/src/main/java/com/checkout/handlepaymentsandpayouts/flow/entities/CustomerRetry.java b/src/main/java/com/checkout/handlepaymentsandpayouts/flow/entities/CustomerRetry.java index bcc2384e2..7ffc83fdf 100644 --- a/src/main/java/com/checkout/handlepaymentsandpayouts/flow/entities/CustomerRetry.java +++ b/src/main/java/com/checkout/handlepaymentsandpayouts/flow/entities/CustomerRetry.java @@ -6,7 +6,9 @@ import lombok.NoArgsConstructor; /** - * Configuration for asynchronous retries + * Configures the parameters for customer retries. A customer retry is a payment attempt performed by the + * customer on the checkout page. This differs from authorization request retries performed in the back end + * by Checkout.com. Used by hosted payments, payment links and payment sessions. */ @Data @Builder @@ -15,8 +17,9 @@ public final class CustomerRetry { /** - * The maximum number of authorization retry attempts, excluding the initial authorization. Default: 5 - * [Optional] + * The maximum number of customer retry attempts, excluding the initial payment attempt. + * Minimum 0, maximum 5. Default: 5. The SDK sends 5 when not set. + * [Optional] for hosted payments and payment links; [Required] for payment sessions. */ @Builder.Default private Integer maxAttempts = 5; diff --git a/src/main/java/com/checkout/handlepaymentsandpayouts/flow/requests/PaymentSessionCreateRequest.java b/src/main/java/com/checkout/handlepaymentsandpayouts/flow/requests/PaymentSessionCreateRequest.java index 781a9dbb9..1edfcdd4b 100644 --- a/src/main/java/com/checkout/handlepaymentsandpayouts/flow/requests/PaymentSessionCreateRequest.java +++ b/src/main/java/com/checkout/handlepaymentsandpayouts/flow/requests/PaymentSessionCreateRequest.java @@ -48,7 +48,7 @@ public final class PaymentSessionCreateRequest extends PaymentSessionCreateBase private PaymentMethodConfiguration paymentMethodConfiguration; /** - * Configuration for asynchronous retries. + * Configuration for customer retries. When sent, max_attempts is required. * [Optional] */ private CustomerRetry customerRetry; diff --git a/src/main/java/com/checkout/handlepaymentsandpayouts/payments/postpayments/responses/requestapaymentorpayoutresponsecreated/retry/Retry.java b/src/main/java/com/checkout/handlepaymentsandpayouts/payments/postpayments/responses/requestapaymentorpayoutresponsecreated/retry/Retry.java index 83ff9b159..ad2cfb1f5 100644 --- a/src/main/java/com/checkout/handlepaymentsandpayouts/payments/postpayments/responses/requestapaymentorpayoutresponsecreated/retry/Retry.java +++ b/src/main/java/com/checkout/handlepaymentsandpayouts/payments/postpayments/responses/requestapaymentorpayoutresponsecreated/retry/Retry.java @@ -1,16 +1,14 @@ package com.checkout.handlepaymentsandpayouts.payments.postpayments.responses.requestapaymentorpayoutresponsecreated.retry; -import lombok.Builder; - import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.time.Instant; /** - * retry - * Configuration relating to asynchronous retries + * Configuration relating to asynchronous retries. */ @Data @Builder @@ -20,17 +18,16 @@ public final class Retry { /** * Indicates whether asynchronous retries are enabled for the payment. - * [Optional] + * [Required] */ private Boolean enabled; /** - * Default: 6 The maximum number of authorization retry attempts, excluding the initial authorization. + * The maximum number of authorization retry attempts, excluding the initial authorization. + * Minimum 1, maximum 15. Default: 6. * [Optional] - * [ 1 .. 15 ] */ - @Builder.Default - private Integer maxAttempts = 6; + private Integer maxAttempts; /** * A timestamp that details the date on which the retry schedule expires, in ISO 8601 format. diff --git a/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java b/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java index 0cbb4d44f..469356686 100644 --- a/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java +++ b/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java @@ -5,6 +5,7 @@ import com.checkout.common.CustomerRequest; import com.checkout.common.PaymentSourceType; import com.checkout.common.Product; +import com.checkout.handlepaymentsandpayouts.flow.entities.CustomerRetry; import com.checkout.payments.AuthorizationType; import com.checkout.payments.BillingDescriptor; import com.checkout.payments.BillingInformation; @@ -17,7 +18,6 @@ import com.checkout.payments.RiskRequest; import com.checkout.payments.ShippingDetails; import com.checkout.payments.ThreeDSRequest; -import com.checkout.payments.request.PaymentRetryRequest; import com.checkout.payments.sender.Sender; import com.checkout.payments.PaymentMethodConfiguration; import com.google.gson.annotations.SerializedName; @@ -177,10 +177,10 @@ public final class HostedPaymentRequest { private RiskRequest risk; /** - * The customer retry configuration for failed payments. + * Configures the parameters for customer retries (payment attempts performed by the customer on the checkout page). * [Optional] */ - private PaymentRetryRequest customerRetry; + private CustomerRetry customerRetry; /** * The sender of the payment. Required for financial regulations in some jurisdictions. diff --git a/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java b/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java index 37ea56804..ee689f43d 100644 --- a/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java +++ b/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java @@ -5,6 +5,7 @@ import com.checkout.common.CustomerRequest; import com.checkout.common.PaymentSourceType; import com.checkout.common.Product; +import com.checkout.handlepaymentsandpayouts.flow.entities.CustomerRetry; import com.checkout.payments.AuthorizationType; import com.checkout.payments.BillingDescriptor; import com.checkout.payments.BillingInformation; @@ -18,7 +19,6 @@ import com.checkout.payments.ShippingDetails; import com.checkout.payments.ThreeDSRequest; import com.checkout.payments.PaymentInstruction; -import com.checkout.payments.request.PaymentRetryRequest; import com.checkout.payments.sender.PaymentSender; import com.google.gson.annotations.SerializedName; import lombok.Builder; @@ -171,10 +171,10 @@ public final class PaymentLinkRequest { private RiskRequest risk; /** - * The customer retry configuration for failed payments. + * Configures the parameters for customer retries (payment attempts performed by the customer on the checkout page). * [Optional] */ - private PaymentRetryRequest customerRetry; + private CustomerRetry customerRetry; /** * The sender of the payment. Required for financial regulations in some jurisdictions. diff --git a/src/main/java/com/checkout/payments/request/DowntimeRetryRequest.java b/src/main/java/com/checkout/payments/request/DowntimeRetryRequest.java index 422ace8da..52942d662 100644 --- a/src/main/java/com/checkout/payments/request/DowntimeRetryRequest.java +++ b/src/main/java/com/checkout/payments/request/DowntimeRetryRequest.java @@ -5,6 +5,9 @@ import lombok.Data; import lombok.NoArgsConstructor; +/** + * Configuration of Downtime retries. + */ @Data @Builder @AllArgsConstructor @@ -12,8 +15,8 @@ public final class DowntimeRetryRequest { /** - * Whether downtime retries are enabled. - * [Optional] + * Indicates if Checkout.com retries the payment when it's declined due to issuer or acquirer downtime. + * [Required] */ private Boolean enabled; diff --git a/src/main/java/com/checkout/payments/request/DunningRetryRequest.java b/src/main/java/com/checkout/payments/request/DunningRetryRequest.java index ee2d22263..61c677e59 100644 --- a/src/main/java/com/checkout/payments/request/DunningRetryRequest.java +++ b/src/main/java/com/checkout/payments/request/DunningRetryRequest.java @@ -5,6 +5,9 @@ import lombok.Data; import lombok.NoArgsConstructor; +/** + * Configuration of Dunning retries. + */ @Data @Builder @AllArgsConstructor @@ -12,19 +15,21 @@ public final class DunningRetryRequest { /** - * Whether dunning retries are enabled. - * [Optional] + * Indicates if Checkout.com retries the payment when it's declined with a supported decline code. + * [Required] */ private Boolean enabled; /** - * The maximum number of retry attempts. + * The maximum number of authorization retry attempts, excluding the initial authorization. + * Minimum 1, maximum 15. Default: 6. * [Optional] */ private Integer maxAttempts; /** - * The number of days after which retries stop. + * The maximum number of days between the initial request and the final retry attempt. + * Minimum 1, maximum 60. Default: 30. * [Optional] */ private Integer endAfterDays; diff --git a/src/main/java/com/checkout/payments/request/PaymentRequest.java b/src/main/java/com/checkout/payments/request/PaymentRequest.java index 78913fcb9..6c93a7f1e 100644 --- a/src/main/java/com/checkout/payments/request/PaymentRequest.java +++ b/src/main/java/com/checkout/payments/request/PaymentRequest.java @@ -253,7 +253,7 @@ public final class PaymentRequest { private List items; /** - * The retry configuration for failed payment attempts. + * Configuration of asynchronous retries. * [Optional] */ private PaymentRetryRequest retry; diff --git a/src/main/java/com/checkout/payments/request/PaymentRetryRequest.java b/src/main/java/com/checkout/payments/request/PaymentRetryRequest.java index 0603d8664..8ef213368 100644 --- a/src/main/java/com/checkout/payments/request/PaymentRetryRequest.java +++ b/src/main/java/com/checkout/payments/request/PaymentRetryRequest.java @@ -5,12 +5,21 @@ import lombok.Data; import lombok.NoArgsConstructor; +/** + * Configuration of asynchronous retries. + */ @Data @Builder @AllArgsConstructor @NoArgsConstructor public final class PaymentRetryRequest { + /** + * Indicates whether asynchronous retries are enabled for the payment. + * [Required] + */ + private Boolean enabled; + /** * Configuration of asynchronous Dunning retries. * [Optional] @@ -23,24 +32,24 @@ public final class PaymentRetryRequest { */ private DowntimeRetryRequest downtime; - // ======================================== - // Deprecated — use dunning.enabled instead - // ======================================== - - /** - * @deprecated Use {@link DunningRetryRequest#enabled} via {@link #dunning} instead. - */ - @Deprecated - private Boolean enabled; - /** - * @deprecated Use {@link DunningRetryRequest#maxAttempts} via {@link #dunning} instead. + * Not part of the retry object in the API. If set, it is still sent at the top level of retry, + * where the API does not read it. + * [Optional] + * + * @deprecated Use {@link DunningRetryRequest#getMaxAttempts()} via {@link #dunning} instead. + * This property will be removed in the next major version. */ @Deprecated private Integer maxAttempts; /** - * @deprecated Use {@link DunningRetryRequest#endAfterDays} via {@link #dunning} instead. + * Not part of the retry object in the API. If set, it is still sent at the top level of retry, + * where the API does not read it. + * [Optional] + * + * @deprecated Use {@link DunningRetryRequest#getEndAfterDays()} via {@link #dunning} instead. + * This property will be removed in the next major version. */ @Deprecated private Integer endAfterDays; diff --git a/src/main/java/com/checkout/payments/response/GetPaymentResponse.java b/src/main/java/com/checkout/payments/response/GetPaymentResponse.java index 65056d394..193aeba55 100644 --- a/src/main/java/com/checkout/payments/response/GetPaymentResponse.java +++ b/src/main/java/com/checkout/payments/response/GetPaymentResponse.java @@ -116,6 +116,10 @@ public final class GetPaymentResponse extends Resource { private List actions; + /** + * Configuration relating to asynchronous retries. + * [Optional] + */ private PaymentRetryResponse retry; private PanProcessedType panTypeProcessed; diff --git a/src/main/java/com/checkout/payments/response/PaymentResponse.java b/src/main/java/com/checkout/payments/response/PaymentResponse.java index 35ca5d6c2..1d63dcfa1 100644 --- a/src/main/java/com/checkout/payments/response/PaymentResponse.java +++ b/src/main/java/com/checkout/payments/response/PaymentResponse.java @@ -74,6 +74,10 @@ public final class PaymentResponse extends Resource implements Serializable { private String schemeId; + /** + * Configuration relating to asynchronous retries. + * [Optional] + */ private PaymentRetryResponse retry; private String paymentIp; diff --git a/src/main/java/com/checkout/payments/response/PaymentRetryResponse.java b/src/main/java/com/checkout/payments/response/PaymentRetryResponse.java index 574257771..e810c96d4 100644 --- a/src/main/java/com/checkout/payments/response/PaymentRetryResponse.java +++ b/src/main/java/com/checkout/payments/response/PaymentRetryResponse.java @@ -1,24 +1,50 @@ package com.checkout.payments.response; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import java.time.Instant; +/** + * Configuration relating to asynchronous retries. Returned by request a payment and by get payment details. + */ @Data @Builder +@NoArgsConstructor +@AllArgsConstructor public final class PaymentRetryResponse { /** * Indicates whether asynchronous retries are enabled for the payment. - * [Optional] + * [Required] */ private Boolean enabled; + /** + * The number of retries attempted so far. Minimum 0. Returned by get payment details only. + * [Optional] + */ + private Integer attemptsMade; + + /** + * The maximum number of authorization retry attempts, excluding the initial authorization. + * Minimum 1, maximum 15. Default: 6. + * [Optional] + */ private Integer maxAttempts; + /** + * A timestamp that details the date on which the retry schedule expires, in ISO 8601 format. + * [Optional] + */ private Instant endsOn; + /** + * A timestamp that details the date on which the next authorization attempt will take place, in ISO 8601 format. + * [Optional] + */ private Instant nextAttemptOn; } diff --git a/src/test/java/com/checkout/TestHelper.java b/src/test/java/com/checkout/TestHelper.java index e3ebe0e01..10dec700d 100644 --- a/src/test/java/com/checkout/TestHelper.java +++ b/src/test/java/com/checkout/TestHelper.java @@ -13,6 +13,7 @@ import com.checkout.common.PaymentSourceType; import com.checkout.common.Phone; import com.checkout.common.Product; +import com.checkout.handlepaymentsandpayouts.flow.entities.CustomerRetry; import com.checkout.instruments.previous.InstrumentCustomerRequest; import com.checkout.payments.Applepay; import com.checkout.payments.BillingDescriptor; @@ -36,7 +37,6 @@ import com.checkout.payments.hosted.HostedPaymentRequest; import com.checkout.payments.PaymentPurposeType; import com.checkout.payments.links.PaymentLinkRequest; -import com.checkout.payments.request.PaymentRetryRequest; import com.checkout.payments.request.source.contexts.PaymentContextsKlarnaSource; import com.checkout.payments.request.source.contexts.PaymentContextsPayPalSource; import com.checkout.payments.request.source.contexts.PaymentContextsStcpaySource; @@ -169,7 +169,7 @@ public static PaymentLinkRequest createPaymentLinksRequest(final String referenc .metadata(Collections.singletonMap("key", "value")) .threeDS(createThreeDS()) .risk(RiskRequest.builder().enabled(false).build()) - .customerRetry(PaymentRetryRequest.builder() + .customerRetry(CustomerRetry.builder() .maxAttempts(3) .build()) .sender(PaymentInstrumentSender.builder() @@ -265,7 +265,7 @@ public static HostedPaymentRequest createHostedPaymentRequest(final String refer .risk(RiskRequest.builder() .enabled(false) .build()) - .customerRetry(PaymentRetryRequest.builder() + .customerRetry(CustomerRetry.builder() .maxAttempts(2) .build()) .sender(PaymentInstrumentSender.builder() diff --git a/src/test/java/com/checkout/handlepaymentsandpayouts/flow/entities/CustomerRetrySerializationTest.java b/src/test/java/com/checkout/handlepaymentsandpayouts/flow/entities/CustomerRetrySerializationTest.java new file mode 100644 index 000000000..cca9997c7 --- /dev/null +++ b/src/test/java/com/checkout/handlepaymentsandpayouts/flow/entities/CustomerRetrySerializationTest.java @@ -0,0 +1,90 @@ +package com.checkout.handlepaymentsandpayouts.flow.entities; + +import com.checkout.GsonSerializer; +import com.checkout.handlepaymentsandpayouts.flow.requests.PaymentSessionCreateRequest; +import com.checkout.payments.hosted.HostedPaymentRequest; +import com.checkout.payments.links.PaymentLinkRequest; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class CustomerRetrySerializationTest { + + private final GsonSerializer serializer = new GsonSerializer(); + + @Test + void shouldSerializeSwaggerExample() { + final String json = serializer.toJson(CustomerRetry.builder().maxAttempts(2).build()); + + assertEquals("{\"max_attempts\":2}", json); + } + + @Test + void shouldSendDefaultFiveWhenNotSet() { + assertEquals("{\"max_attempts\":5}", serializer.toJson(CustomerRetry.builder().build())); + } + + @Test + void shouldSerializeZeroAttempts() { + final String json = serializer.toJson(CustomerRetry.builder().maxAttempts(0).build()); + + assertEquals("{\"max_attempts\":0}", json); + } + + @Test + void shouldRoundTrip() { + final CustomerRetry original = CustomerRetry.builder().maxAttempts(3).build(); + + final CustomerRetry deserialized = serializer.fromJson(serializer.toJson(original), CustomerRetry.class); + + assertEquals(original, deserialized); + assertEquals(3, deserialized.getMaxAttempts()); + } + + @Test + void shouldDeserializeSwaggerExample() { + final CustomerRetry retry = serializer.fromJson("{\"max_attempts\":2}", CustomerRetry.class); + + assertEquals(2, retry.getMaxAttempts()); + } + + @Test + void shouldSendOnlyMaxAttemptsFromHostedPayments() { + final HostedPaymentRequest request = HostedPaymentRequest.builder() + .customerRetry(CustomerRetry.builder().maxAttempts(2).build()) + .build(); + + final String json = serializer.toJson(request); + + assertCustomerRetryIsExactly(json); + } + + @Test + void shouldSendOnlyMaxAttemptsFromPaymentLinks() { + final PaymentLinkRequest request = PaymentLinkRequest.builder() + .customerRetry(CustomerRetry.builder().maxAttempts(2).build()) + .build(); + + final String json = serializer.toJson(request); + + assertCustomerRetryIsExactly(json); + } + + @Test + void shouldSendOnlyMaxAttemptsFromPaymentSessions() { + final PaymentSessionCreateRequest request = PaymentSessionCreateRequest.builder() + .customerRetry(CustomerRetry.builder().maxAttempts(2).build()) + .build(); + + final String json = serializer.toJson(request); + + assertCustomerRetryIsExactly(json); + } + + private static void assertCustomerRetryIsExactly(final String json) { + final JsonObject customerRetry = JsonParser.parseString(json).getAsJsonObject().getAsJsonObject("customer_retry"); + assertEquals("{\"max_attempts\":2}", customerRetry.toString()); + } +} diff --git a/src/test/java/com/checkout/handlepaymentsandpayouts/payments/postpayments/responses/requestapaymentorpayoutresponsecreated/retry/RetrySerializationTest.java b/src/test/java/com/checkout/handlepaymentsandpayouts/payments/postpayments/responses/requestapaymentorpayoutresponsecreated/retry/RetrySerializationTest.java new file mode 100644 index 000000000..1cb9910f7 --- /dev/null +++ b/src/test/java/com/checkout/handlepaymentsandpayouts/payments/postpayments/responses/requestapaymentorpayoutresponsecreated/retry/RetrySerializationTest.java @@ -0,0 +1,48 @@ +package com.checkout.handlepaymentsandpayouts.payments.postpayments.responses.requestapaymentorpayoutresponsecreated.retry; + +import com.checkout.GsonSerializer; +import org.junit.jupiter.api.Test; + +import java.time.Instant; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class RetrySerializationTest { + + private final GsonSerializer serializer = new GsonSerializer(); + + @Test + void shouldDeserializeAllProperties() { + final String json = "{\"enabled\":true,\"max_attempts\":6," + + "\"ends_on\":\"2019-08-24T14:15:22Z\",\"next_attempt_on\":\"2019-08-25T14:15:22Z\"}"; + + final Retry retry = serializer.fromJson(json, Retry.class); + + assertTrue(retry.getEnabled()); + assertEquals(6, retry.getMaxAttempts()); + assertEquals(Instant.parse("2019-08-24T14:15:22Z"), retry.getEndsOn()); + assertEquals(Instant.parse("2019-08-25T14:15:22Z"), retry.getNextAttemptOn()); + } + + @Test + void shouldNotInventMaxAttemptsWhenAbsent() { + assertNull(serializer.fromJson("{\"enabled\":true}", Retry.class).getMaxAttempts()); + } + + @Test + void shouldRoundTrip() { + final Retry original = Retry.builder() + .enabled(false) + .maxAttempts(1) + .endsOn(Instant.parse("2019-08-24T14:15:22Z")) + .nextAttemptOn(Instant.parse("2019-08-25T14:15:22Z")) + .build(); + + final String json = serializer.toJson(original); + + assertTrue(json.contains("\"enabled\":false")); + assertEquals(original, serializer.fromJson(json, Retry.class)); + } +} diff --git a/src/test/java/com/checkout/payments/request/PaymentRetryRequestSerializationTest.java b/src/test/java/com/checkout/payments/request/PaymentRetryRequestSerializationTest.java index 2922a5ad3..9e59b0451 100644 --- a/src/test/java/com/checkout/payments/request/PaymentRetryRequestSerializationTest.java +++ b/src/test/java/com/checkout/payments/request/PaymentRetryRequestSerializationTest.java @@ -3,8 +3,8 @@ import com.checkout.GsonSerializer; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -16,6 +16,7 @@ class PaymentRetryRequestSerializationTest { @Test void shouldSerializeWithDunningConfig() { final PaymentRetryRequest request = PaymentRetryRequest.builder() + .enabled(true) .dunning(DunningRetryRequest.builder() .enabled(true) .maxAttempts(3) @@ -23,104 +24,109 @@ void shouldSerializeWithDunningConfig() { .build()) .build(); - final String json = serializer.toJson(request); - - assertNotNull(json); - assertTrue(json.contains("\"dunning\"")); - assertTrue(json.contains("\"enabled\":true")); - assertTrue(json.contains("\"max_attempts\":3")); - assertTrue(json.contains("\"end_after_days\":7")); + assertEquals("{\"enabled\":true,\"dunning\":{\"enabled\":true,\"max_attempts\":3,\"end_after_days\":7}}", + serializer.toJson(request)); } @Test void shouldSerializeWithDowntimeConfig() { final PaymentRetryRequest request = PaymentRetryRequest.builder() - .downtime(DowntimeRetryRequest.builder() - .enabled(true) - .build()) + .enabled(true) + .downtime(DowntimeRetryRequest.builder().enabled(true).build()) .build(); - final String json = serializer.toJson(request); - - assertNotNull(json); - assertTrue(json.contains("\"downtime\"")); - assertTrue(json.contains("\"enabled\":true")); + assertEquals("{\"enabled\":true,\"downtime\":{\"enabled\":true}}", serializer.toJson(request)); } @Test void shouldSerializeWithBothDunningAndDowntime() { final PaymentRetryRequest request = PaymentRetryRequest.builder() + .enabled(true) .dunning(DunningRetryRequest.builder() .enabled(true) .maxAttempts(5) .endAfterDays(14) .build()) - .downtime(DowntimeRetryRequest.builder() - .enabled(false) - .build()) + .downtime(DowntimeRetryRequest.builder().enabled(false).build()) .build(); - assertDoesNotThrow(() -> serializer.toJson(request)); + assertEquals("{\"enabled\":true," + + "\"dunning\":{\"enabled\":true,\"max_attempts\":5,\"end_after_days\":14}," + + "\"downtime\":{\"enabled\":false}}", + serializer.toJson(request)); } @Test - void shouldDeserializeDunningFromJson() { - final String json = "{" - + "\"dunning\":{" - + " \"enabled\":true," - + " \"max_attempts\":3," - + " \"end_after_days\":7" - + "}," - + "\"downtime\":{" - + " \"enabled\":false" - + "}" - + "}"; + void shouldSerializeEnabledFalseEverywhere() { + final PaymentRetryRequest request = PaymentRetryRequest.builder() + .enabled(false) + .dunning(DunningRetryRequest.builder().enabled(false).build()) + .downtime(DowntimeRetryRequest.builder().enabled(false).build()) + .build(); + + assertEquals("{\"enabled\":false,\"dunning\":{\"enabled\":false},\"downtime\":{\"enabled\":false}}", + serializer.toJson(request)); + } + + @Test + @SuppressWarnings("deprecation") + void shouldStillSendDeprecatedTopLevelFields() { + final PaymentRetryRequest request = PaymentRetryRequest.builder() + .enabled(true) + .maxAttempts(4) + .endAfterDays(10) + .build(); + + assertEquals("{\"enabled\":true,\"max_attempts\":4,\"end_after_days\":10}", serializer.toJson(request)); + } + + @Test + void shouldDeserializeFromJson() { + final String json = "{\"enabled\":true," + + "\"dunning\":{\"enabled\":true,\"max_attempts\":3,\"end_after_days\":7}," + + "\"downtime\":{\"enabled\":false}}"; final PaymentRetryRequest request = serializer.fromJson(json, PaymentRetryRequest.class); - assertNotNull(request); - assertNotNull(request.getDunning()); + assertTrue(request.getEnabled()); assertTrue(request.getDunning().getEnabled()); assertEquals(3, request.getDunning().getMaxAttempts()); assertEquals(7, request.getDunning().getEndAfterDays()); - assertNotNull(request.getDowntime()); - assertEquals(false, request.getDowntime().getEnabled()); + assertFalse(request.getDowntime().getEnabled()); } @Test - void shouldRoundTripSerialize() { + @SuppressWarnings("deprecation") + void shouldRoundTripAllProperties() { final PaymentRetryRequest original = PaymentRetryRequest.builder() + .enabled(true) + .maxAttempts(2) + .endAfterDays(3) .dunning(DunningRetryRequest.builder() .enabled(true) - .maxAttempts(3) - .endAfterDays(7) - .build()) - .downtime(DowntimeRetryRequest.builder() - .enabled(true) + .maxAttempts(15) + .endAfterDays(60) .build()) + .downtime(DowntimeRetryRequest.builder().enabled(true).build()) .build(); final String json = serializer.toJson(original); - final PaymentRetryRequest deserialized = serializer.fromJson(json, PaymentRetryRequest.class); - - assertNotNull(deserialized); - assertNotNull(deserialized.getDunning()); - assertEquals(true, deserialized.getDunning().getEnabled()); - assertEquals(3, deserialized.getDunning().getMaxAttempts()); - assertEquals(7, deserialized.getDunning().getEndAfterDays()); - assertNotNull(deserialized.getDowntime()); - assertEquals(true, deserialized.getDowntime().getEnabled()); + + assertEquals("{\"enabled\":true," + + "\"dunning\":{\"enabled\":true,\"max_attempts\":15,\"end_after_days\":60}," + + "\"downtime\":{\"enabled\":true}," + + "\"max_attempts\":2,\"end_after_days\":3}", json); + assertEquals(original, serializer.fromJson(json, PaymentRetryRequest.class)); } @Test void shouldHandleAbsentOptionalFields() { - final String json = "{}"; - - final PaymentRetryRequest request = serializer.fromJson(json, PaymentRetryRequest.class); + final PaymentRetryRequest request = serializer.fromJson("{}", PaymentRetryRequest.class); assertNotNull(request); - assertDoesNotThrow(() -> serializer.toJson(request)); + assertNull(request.getEnabled()); assertNull(request.getDunning()); assertNull(request.getDowntime()); + assertEquals("{}", serializer.toJson(request)); } } diff --git a/src/test/java/com/checkout/payments/response/PaymentRetryResponseSerializationTest.java b/src/test/java/com/checkout/payments/response/PaymentRetryResponseSerializationTest.java new file mode 100644 index 000000000..df90cf10f --- /dev/null +++ b/src/test/java/com/checkout/payments/response/PaymentRetryResponseSerializationTest.java @@ -0,0 +1,60 @@ +package com.checkout.payments.response; + +import com.checkout.GsonSerializer; +import org.junit.jupiter.api.Test; + +import java.time.Instant; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class PaymentRetryResponseSerializationTest { + + private final GsonSerializer serializer = new GsonSerializer(); + + @Test + void shouldDeserializeGetPaymentRetry() { + final String json = "{\"enabled\":true,\"attempts_made\":1,\"max_attempts\":6," + + "\"ends_on\":\"2019-08-24T14:15:22Z\",\"next_attempt_on\":\"2019-08-25T14:15:22Z\"}"; + + final PaymentRetryResponse retry = serializer.fromJson(json, PaymentRetryResponse.class); + + assertTrue(retry.getEnabled()); + assertEquals(1, retry.getAttemptsMade()); + assertEquals(6, retry.getMaxAttempts()); + assertEquals(Instant.parse("2019-08-24T14:15:22Z"), retry.getEndsOn()); + assertEquals(Instant.parse("2019-08-25T14:15:22Z"), retry.getNextAttemptOn()); + } + + @Test + void shouldDeserializePostPaymentRetryWithoutAttemptsMade() { + final PaymentRetryResponse retry = serializer.fromJson("{\"enabled\":false}", PaymentRetryResponse.class); + + assertFalse(retry.getEnabled()); + assertNull(retry.getAttemptsMade()); + assertNull(retry.getMaxAttempts()); + } + + @Test + void shouldRoundTrip() { + final PaymentRetryResponse original = PaymentRetryResponse.builder() + .enabled(true) + .attemptsMade(0) + .maxAttempts(15) + .endsOn(Instant.parse("2019-08-24T14:15:22Z")) + .nextAttemptOn(Instant.parse("2019-08-25T14:15:22Z")) + .build(); + + assertEquals(original, serializer.fromJson(serializer.toJson(original), PaymentRetryResponse.class)); + } + + @Test + void shouldDeserializeRetryInsidePaymentResponses() { + final String retry = "{\"retry\":{\"enabled\":true,\"attempts_made\":2,\"max_attempts\":6}}"; + + assertEquals(2, serializer.fromJson(retry, GetPaymentResponse.class).getRetry().getAttemptsMade()); + assertEquals(6, serializer.fromJson(retry, PaymentResponse.class).getRetry().getMaxAttempts()); + } +} From b9f31e3aa1889ca8f2412d6184c5a641ca83b792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20Rodr=C3=ADguez?= <127134616+armando-rodriguez-cko@users.noreply.github.com> Date: Wed, 28 Oct 2026 21:23:19 +0100 Subject: [PATCH 2/4] fix(payments): keep customer retry overload and document responses --- .../payments/hosted/HostedPaymentRequest.java | 42 +++++ .../payments/links/PaymentLinkRequest.java | 42 +++++ .../payments/request/PaymentRetryRequest.java | 7 +- .../payments/response/GetPaymentResponse.java | 165 +++++++++++++++++- .../payments/response/PaymentResponse.java | 131 +++++++++++++- ...HostedPaymentRequestSerializationTest.java | 51 ++++++ .../PaymentLinkRequestSerializationTest.java | 51 ++++++ .../PaymentRetryRequestSerializationTest.java | 24 +-- 8 files changed, 490 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java b/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java index 469356686..281a50d18 100644 --- a/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java +++ b/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java @@ -18,6 +18,7 @@ import com.checkout.payments.RiskRequest; import com.checkout.payments.ShippingDetails; import com.checkout.payments.ThreeDSRequest; +import com.checkout.payments.request.PaymentRetryRequest; import com.checkout.payments.sender.Sender; import com.checkout.payments.PaymentMethodConfiguration; import com.google.gson.annotations.SerializedName; @@ -245,4 +246,45 @@ public final class HostedPaymentRequest { * Default: "Final" */ private AuthorizationType authorizationType; + + /** + * Builder for {@link HostedPaymentRequest}. Only the customer retry methods are written by hand; every other + * method is generated by Lombok. + */ + public static class HostedPaymentRequestBuilder { + + /** + * Configures the parameters for customer retries. + * + * @param customerRetry the customer retry configuration + * @return this builder + */ + public HostedPaymentRequestBuilder customerRetry(final CustomerRetry customerRetry) { + this.customerRetry = customerRetry; + return this; + } + + /** + * Configures customer retries from a {@link PaymentRetryRequest}. Only its max attempts value is kept, + * because customer_retry only accepts max_attempts. A null request clears the customer retry; a request + * without max attempts sends the {@link CustomerRetry} default. + * + * @param customerRetry the retry configuration to convert + * @return this builder + * @deprecated Use {@link #customerRetry(CustomerRetry)} instead. + * This method will be removed in the next major version. + */ + @Deprecated + @SuppressWarnings("deprecation") + public HostedPaymentRequestBuilder customerRetry(final PaymentRetryRequest customerRetry) { + if (customerRetry == null) { + this.customerRetry = null; + } else if (customerRetry.getMaxAttempts() == null) { + this.customerRetry = CustomerRetry.builder().build(); + } else { + this.customerRetry = CustomerRetry.builder().maxAttempts(customerRetry.getMaxAttempts()).build(); + } + return this; + } + } } diff --git a/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java b/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java index ee689f43d..7fb4273fc 100644 --- a/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java +++ b/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java @@ -18,6 +18,7 @@ import com.checkout.payments.RiskRequest; import com.checkout.payments.ShippingDetails; import com.checkout.payments.ThreeDSRequest; +import com.checkout.payments.request.PaymentRetryRequest; import com.checkout.payments.PaymentInstruction; import com.checkout.payments.sender.PaymentSender; import com.google.gson.annotations.SerializedName; @@ -232,4 +233,45 @@ public final class PaymentLinkRequest { * Default: "Final" */ private AuthorizationType authorizationType; + + /** + * Builder for {@link PaymentLinkRequest}. Only the customer retry methods are written by hand; every other + * method is generated by Lombok. + */ + public static class PaymentLinkRequestBuilder { + + /** + * Configures the parameters for customer retries. + * + * @param customerRetry the customer retry configuration + * @return this builder + */ + public PaymentLinkRequestBuilder customerRetry(final CustomerRetry customerRetry) { + this.customerRetry = customerRetry; + return this; + } + + /** + * Configures customer retries from a {@link PaymentRetryRequest}. Only its max attempts value is kept, + * because customer_retry only accepts max_attempts. A null request clears the customer retry; a request + * without max attempts sends the {@link CustomerRetry} default. + * + * @param customerRetry the retry configuration to convert + * @return this builder + * @deprecated Use {@link #customerRetry(CustomerRetry)} instead. + * This method will be removed in the next major version. + */ + @Deprecated + @SuppressWarnings("deprecation") + public PaymentLinkRequestBuilder customerRetry(final PaymentRetryRequest customerRetry) { + if (customerRetry == null) { + this.customerRetry = null; + } else if (customerRetry.getMaxAttempts() == null) { + this.customerRetry = CustomerRetry.builder().build(); + } else { + this.customerRetry = CustomerRetry.builder().maxAttempts(customerRetry.getMaxAttempts()).build(); + } + return this; + } + } } diff --git a/src/main/java/com/checkout/payments/request/PaymentRetryRequest.java b/src/main/java/com/checkout/payments/request/PaymentRetryRequest.java index 8ef213368..22b9b5d6e 100644 --- a/src/main/java/com/checkout/payments/request/PaymentRetryRequest.java +++ b/src/main/java/com/checkout/payments/request/PaymentRetryRequest.java @@ -37,7 +37,9 @@ public final class PaymentRetryRequest { * where the API does not read it. * [Optional] * - * @deprecated Use {@link DunningRetryRequest#getMaxAttempts()} via {@link #dunning} instead. + * @deprecated For customer_retry on hosted payments and payment links, use + * {@link com.checkout.handlepaymentsandpayouts.flow.entities.CustomerRetry#getMaxAttempts()} instead. + * For retry on payments, use {@link DunningRetryRequest#getMaxAttempts()} via {@link #dunning} instead. * This property will be removed in the next major version. */ @Deprecated @@ -48,7 +50,8 @@ public final class PaymentRetryRequest { * where the API does not read it. * [Optional] * - * @deprecated Use {@link DunningRetryRequest#getEndAfterDays()} via {@link #dunning} instead. + * @deprecated For retry on payments, use {@link DunningRetryRequest#getEndAfterDays()} via {@link #dunning} + * instead. * This property will be removed in the next major version. */ @Deprecated diff --git a/src/main/java/com/checkout/payments/response/GetPaymentResponse.java b/src/main/java/com/checkout/payments/response/GetPaymentResponse.java index 193aeba55..7df74592a 100644 --- a/src/main/java/com/checkout/payments/response/GetPaymentResponse.java +++ b/src/main/java/com/checkout/payments/response/GetPaymentResponse.java @@ -29,91 +29,234 @@ import java.util.List; import java.util.Map; +/** + * Response of get payment details (GET /payments/{id}). + */ @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public final class GetPaymentResponse extends Resource { + /** + * Payment unique identifier. + * [Required] + * ^(pay)_(\w{26})$ + * 30 characters + */ private String id; + /** + * Not part of the get payment details schema in the API reference; kept for backward compatibility. + * [Optional] + */ private String authenticationId; + /** + * Not part of the get payment details schema in the API reference; kept for backward compatibility. + * [Optional] + */ private String processingChannelId; + /** + * The date/time the payment was requested. Read-only UTC timestamp, automatically assigned by Checkout.com. + * [Required] + * Format: date-time (RFC 3339) + */ private Instant requestedOn; + /** + * The source of the payment. + * [Optional] + */ private ResponseSource source; + /** + * The destination of the payment. + * [Optional] + */ private PaymentResponseDestination destination; + /** + * Information about the sender of the payment's funds. + * [Optional] + */ private Sender sender; + /** + * The original payment amount. + * [Required] + */ private Long amount; + /** + * The full amount from the original authorization, if a partial authorization was requested. + * [Optional] + */ private Long amountRequested; + /** + * The three-letter ISO currency code of the payment. + * [Required] + * 3 characters + */ private Currency currency; + /** + * This must be specified for card payments where the cardholder is not present + * (for example, recurring or mail order / telephone order). + * [Optional] + */ @SerializedName("payment_type") private PaymentType type; + /** + * The details of a recurring subscription or installment. + * [Optional] + */ private PaymentPlan paymentPlan; + /** + * Your reference for the payment. + * [Optional] + */ private String reference; + /** + * A description of the payment. + * [Optional] + */ private String description; + /** + * Whether the payment was successful. + * [Required] + */ private Boolean approved; + /** + * The timestamp (ISO 8601 code) for when the authorization's validity period expires. + * [Optional] + */ private Instant expiresOn; + /** + * The status of the payment. + * [Required] + */ private PaymentStatus status; + /** + * The payment balances. + * [Optional] + */ private PaymentResponseBalances balances; + /** + * Provides information relating to the processing of 3D Secure payments. + * [Optional] + */ @SerializedName("3ds") private ThreeDSData threeDSData; /** * Provides information relating to the authentication of the payment. - *

* [Optional] - *

*/ private PaymentResponseAuthentication authentication; + /** + * Returns the payments risk assessment results. + * [Optional] + */ private RiskAssessment risk; + /** + * The customer to which this payment is linked. + * [Optional] + */ private CustomerResponse customer; + /** + * An optional description that is displayed on the customer's statement identifying a purchase. + * [Optional] + */ @SerializedName("billing_descriptor") private BillingDescriptor billing; + /** + * The payment shipping details. + * [Optional] + */ private ShippingDetails shipping; + /** + * The IP address used to make the payment. Used by Checkout.com's risk engine to check the customer's + * IP address. Only accepts IPv4 and IPv6 addresses. + * [Optional] + * Format: ipv4 + * max 45 characters + */ private String paymentIp; /** + * Not part of the get payment details schema in the API reference. + * [Optional] + * * @deprecated This property will be removed in the future, and should be used * {@link GetPaymentResponse#amountAllocations} instead */ @Deprecated private MarketplaceData marketplace; + /** + * The sub-entities that the payment is being processed on behalf of. + * [Optional] + */ private List amountAllocations; + /** + * Information about the recipient of the payment's funds. Relevant for Account Funding Transactions + * and VISA or Mastercard domestic UK transactions processed by financial institutions. + * [Optional] + */ private PaymentRecipient recipient; + /** + * Returns information related to the processing of the payment. + * [Optional] + */ private ProcessingData processing; + /** + * The order's line items. + * [Optional] + */ private List items; + /** + * A set of key-value pairs that you can attach to a payment. It can be useful for storing additional + * information in a structured format. + * [Optional] + */ private Map metadata; + /** + * The final Electronic Commerce Indicator (ECI) security level used to authorize the payment. + * Applicable for 3D Secure and network token payments. + * [Optional] + */ private String eci; + /** + * The scheme transaction identifier. + * [Optional] + */ private String schemeId; + /** + * A summary of the payment's actions, returned when a session ID is used to get the payment details. + * [Optional] + */ private List actions; /** @@ -122,12 +265,30 @@ public final class GetPaymentResponse extends Resource { */ private PaymentRetryResponse retry; + /** + * Not part of the get payment details schema in the API reference; kept for backward compatibility. + * [Optional] + */ private PanProcessedType panTypeProcessed; + /** + * The flag indicating if Checkout Network Token was available for the payment. + * [Optional] + */ private Boolean ckoNetworkTokenAvailable; + /** + * Card payouts only: if the scheme has finished processing the payout request, the UTC date and time + * the payout was approved or declined. + * [Optional] + * Format: date-time (RFC 3339) + */ private String processedOn; + /** + * Details about the payment instruction. + * [Optional] + */ private PaymentInstruction instruction; } diff --git a/src/main/java/com/checkout/payments/response/PaymentResponse.java b/src/main/java/com/checkout/payments/response/PaymentResponse.java index 1d63dcfa1..b10dc20bb 100644 --- a/src/main/java/com/checkout/payments/response/PaymentResponse.java +++ b/src/main/java/com/checkout/payments/response/PaymentResponse.java @@ -6,6 +6,7 @@ import com.checkout.payments.PaymentProcessing; import com.checkout.payments.PaymentRecipient; import com.checkout.payments.PaymentStatus; +import com.checkout.payments.PaymentSubscription; import com.checkout.payments.PaymentType; import com.checkout.payments.RiskAssessment; import com.checkout.payments.ShippingDetails; @@ -22,72 +23,200 @@ import java.util.HashMap; import java.util.Map; +/** + * Response of request a payment or payout (POST /payments). + */ @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public final class PaymentResponse extends Resource implements Serializable { + /** + * The source of the payment. + * [Optional] + */ private ResponseSource source; + /** + * The payment's unique identifier. + * [Required] + * ^(pay)_(\w{26})$ + * 30 characters + */ private String id; + /** + * Not part of the PaymentResponse schema in the API reference; kept for backward compatibility. + * [Optional] + */ private PaymentType paymentType; + /** + * Not part of the PaymentResponse schema in the API reference; kept for backward compatibility. + * [Optional] + */ private PaymentPlan paymentPlan; + /** + * The unique identifier for the action performed against this payment. + * [Required] + * ^(act)_(\w{26})$ + * 30 characters + */ private String actionId; + /** + * The payment amount. + * [Required] + */ private Long amount; + /** + * The full amount from the original authorization, if a partial authorization was requested and approved. + * [Optional] + */ private Long amountRequested; + /** + * The three-letter ISO currency code of the payment. + * [Required] + * 3 characters + */ private Currency currency; + /** + * Whether or not the authorization or capture was successful. + * [Required] + */ private boolean approved; + /** + * The status of the payment. + * [Required] + */ private PaymentStatus status; + /** + * The acquirer authorization code if the payment was authorized. + * [Optional] + */ private String authCode; + /** + * The Gateway response code. + * [Required] + */ private String responseCode; + /** + * The Gateway response summary. + * [Optional] + */ private String responseSummary; + /** + * The timestamp (ISO 8601 code) for when the authorization's validity period expires. + * [Optional] + */ private Instant expiresOn; + /** + * Provides 3D Secure enrollment status if the payment was downgraded to non-3D Secure. + * [Optional] + */ @SerializedName("3ds") private ThreeDSEnrollment threeDSEnrollment; + /** + * Returns the payment's risk assessment results. + * [Optional] + */ private RiskAssessment risk; + /** + * The customer associated with the payment, if provided in the request. + * [Optional] + */ private CustomerResponse customer; + /** + * The payment balances. + * [Optional] + */ private PaymentResponseBalances balances; + /** + * The date/time the payment was processed. Read-only UTC timestamp, automatically assigned by Checkout.com. + * [Required] + * Format: date-time (RFC 3339) + */ private Instant processedOn; + /** + * Your reference for the payment. + * [Optional] + */ private String reference; + /** + * Returns information related to the processing of the payment. + * [Optional] + */ private PaymentProcessing processing; + /** + * The final Electronic Commerce Indicator (ECI) security level used to authorize the payment. + * Applicable for 3D Secure and network token payments. + * [Optional] + */ private String eci; + /** + * The scheme transaction identifier. + * [Optional] + */ private String schemeId; /** - * Configuration relating to asynchronous retries. + * The details of the subscription. + * [Optional] + */ + private PaymentSubscription subscription; + + /** + * Configuration relating to asynchronous retries (Beta). * [Optional] */ private PaymentRetryResponse retry; + /** + * Not part of the PaymentResponse schema in the API reference; kept for backward compatibility. + * [Optional] + */ private String paymentIp; + /** + * Not part of the PaymentResponse schema in the API reference; kept for backward compatibility. + * [Optional] + */ private PaymentRecipient recipient; + /** + * Not part of the PaymentResponse schema in the API reference; kept for backward compatibility. + * [Optional] + */ private ShippingDetails shipping; + /** + * Not part of the PaymentResponse schema in the API reference; kept for backward compatibility. + * [Optional] + */ private String description; + /** + * Not part of the PaymentResponse schema in the API reference; kept for backward compatibility. + * [Optional] + */ private Map metadata = new HashMap<>(); } \ No newline at end of file diff --git a/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java b/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java index 99ecd10c5..98ab99d3d 100644 --- a/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java +++ b/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java @@ -9,6 +9,10 @@ import com.checkout.payments.BillingInformation; import com.checkout.payments.PaymentPlan; import com.checkout.payments.PaymentType; +import com.checkout.payments.request.PaymentRetryRequest; +import com.checkout.handlepaymentsandpayouts.flow.entities.CustomerRetry; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.junit.jupiter.api.Test; import java.time.Instant; @@ -281,4 +285,51 @@ void shouldDeserializePaymentPlanAndAuthorizationType() { assertEquals(12, request.getPaymentPlan().getTotalNumberOfPayments()); assertEquals("Plan A", request.getPaymentPlan().getName()); } + + // ------------------------------------------------------------------------ + // customer_retry: the CustomerRetry builder method and the deprecated + // PaymentRetryRequest overload must send the same customer_retry object. + // ------------------------------------------------------------------------ + + @Test + void shouldSerializeCustomerRetryForHostedPaymentRequest() { + final HostedPaymentRequest request = HostedPaymentRequest.builder() + .customerRetry(CustomerRetry.builder().maxAttempts(3).build()) + .build(); + + assertEquals("{\"max_attempts\":3}", customerRetryJson(request)); + assertEquals(3, serializer.fromJson(serializer.toJson(request), HostedPaymentRequest.class) + .getCustomerRetry().getMaxAttempts()); + } + + // The overload under test is deprecated on purpose (kept for compatibility), so calling it is the test. + // The PaymentRetryRequest argument is built from JSON to avoid its deprecated builder methods. + @Test + @SuppressWarnings("deprecation") + void shouldSerializeDeprecatedCustomerRetryOverloadLikeCustomerRetryForHostedPaymentRequest() { + final PaymentRetryRequest legacy = serializer.fromJson("{\"max_attempts\":3}", PaymentRetryRequest.class); + + final HostedPaymentRequest fromLegacy = HostedPaymentRequest.builder().customerRetry(legacy).build(); + final HostedPaymentRequest fromCustomerRetry = HostedPaymentRequest.builder() + .customerRetry(CustomerRetry.builder().maxAttempts(3).build()) + .build(); + + assertEquals(customerRetryJson(fromCustomerRetry), customerRetryJson(fromLegacy)); + assertEquals("{\"max_attempts\":3}", customerRetryJson(fromLegacy)); + } + + @Test + @SuppressWarnings("deprecation") + void shouldConvertDeprecatedCustomerRetryOverloadEdgeCasesForHostedPaymentRequest() { + final PaymentRetryRequest withoutMaxAttempts = serializer.fromJson("{\"enabled\":true}", PaymentRetryRequest.class); + + assertEquals("{\"max_attempts\":5}", + customerRetryJson(HostedPaymentRequest.builder().customerRetry(withoutMaxAttempts).build())); + assertNull(HostedPaymentRequest.builder().customerRetry((PaymentRetryRequest) null).build().getCustomerRetry()); + } + + private String customerRetryJson(final HostedPaymentRequest request) { + final JsonObject json = JsonParser.parseString(serializer.toJson(request)).getAsJsonObject(); + return json.get("customer_retry").toString(); + } } diff --git a/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java b/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java index 38d24a77d..0134831a1 100644 --- a/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java +++ b/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java @@ -9,6 +9,10 @@ import com.checkout.payments.BillingInformation; import com.checkout.payments.PaymentPlan; import com.checkout.payments.PaymentType; +import com.checkout.payments.request.PaymentRetryRequest; +import com.checkout.handlepaymentsandpayouts.flow.entities.CustomerRetry; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.junit.jupiter.api.Test; import java.time.Instant; @@ -278,4 +282,51 @@ void shouldDeserializePaymentPlanAndAuthorizationType() { assertEquals(12, request.getPaymentPlan().getTotalNumberOfPayments()); assertEquals("Plan A", request.getPaymentPlan().getName()); } + + // ------------------------------------------------------------------------ + // customer_retry: the CustomerRetry builder method and the deprecated + // PaymentRetryRequest overload must send the same customer_retry object. + // ------------------------------------------------------------------------ + + @Test + void shouldSerializeCustomerRetryForPaymentLinkRequest() { + final PaymentLinkRequest request = PaymentLinkRequest.builder() + .customerRetry(CustomerRetry.builder().maxAttempts(3).build()) + .build(); + + assertEquals("{\"max_attempts\":3}", customerRetryJson(request)); + assertEquals(3, serializer.fromJson(serializer.toJson(request), PaymentLinkRequest.class) + .getCustomerRetry().getMaxAttempts()); + } + + // The overload under test is deprecated on purpose (kept for compatibility), so calling it is the test. + // The PaymentRetryRequest argument is built from JSON to avoid its deprecated builder methods. + @Test + @SuppressWarnings("deprecation") + void shouldSerializeDeprecatedCustomerRetryOverloadLikeCustomerRetryForPaymentLinkRequest() { + final PaymentRetryRequest legacy = serializer.fromJson("{\"max_attempts\":3}", PaymentRetryRequest.class); + + final PaymentLinkRequest fromLegacy = PaymentLinkRequest.builder().customerRetry(legacy).build(); + final PaymentLinkRequest fromCustomerRetry = PaymentLinkRequest.builder() + .customerRetry(CustomerRetry.builder().maxAttempts(3).build()) + .build(); + + assertEquals(customerRetryJson(fromCustomerRetry), customerRetryJson(fromLegacy)); + assertEquals("{\"max_attempts\":3}", customerRetryJson(fromLegacy)); + } + + @Test + @SuppressWarnings("deprecation") + void shouldConvertDeprecatedCustomerRetryOverloadEdgeCasesForPaymentLinkRequest() { + final PaymentRetryRequest withoutMaxAttempts = serializer.fromJson("{\"enabled\":true}", PaymentRetryRequest.class); + + assertEquals("{\"max_attempts\":5}", + customerRetryJson(PaymentLinkRequest.builder().customerRetry(withoutMaxAttempts).build())); + assertNull(PaymentLinkRequest.builder().customerRetry((PaymentRetryRequest) null).build().getCustomerRetry()); + } + + private String customerRetryJson(final PaymentLinkRequest request) { + final JsonObject json = JsonParser.parseString(serializer.toJson(request)).getAsJsonObject(); + return json.get("customer_retry").toString(); + } } diff --git a/src/test/java/com/checkout/payments/request/PaymentRetryRequestSerializationTest.java b/src/test/java/com/checkout/payments/request/PaymentRetryRequestSerializationTest.java index 9e59b0451..f4a4a5d11 100644 --- a/src/test/java/com/checkout/payments/request/PaymentRetryRequestSerializationTest.java +++ b/src/test/java/com/checkout/payments/request/PaymentRetryRequestSerializationTest.java @@ -69,13 +69,9 @@ void shouldSerializeEnabledFalseEverywhere() { } @Test - @SuppressWarnings("deprecation") void shouldStillSendDeprecatedTopLevelFields() { - final PaymentRetryRequest request = PaymentRetryRequest.builder() - .enabled(true) - .maxAttempts(4) - .endAfterDays(10) - .build(); + final PaymentRetryRequest request = serializer.fromJson( + "{\"enabled\":true,\"max_attempts\":4,\"end_after_days\":10}", PaymentRetryRequest.class); assertEquals("{\"enabled\":true,\"max_attempts\":4,\"end_after_days\":10}", serializer.toJson(request)); } @@ -96,19 +92,11 @@ void shouldDeserializeFromJson() { } @Test - @SuppressWarnings("deprecation") void shouldRoundTripAllProperties() { - final PaymentRetryRequest original = PaymentRetryRequest.builder() - .enabled(true) - .maxAttempts(2) - .endAfterDays(3) - .dunning(DunningRetryRequest.builder() - .enabled(true) - .maxAttempts(15) - .endAfterDays(60) - .build()) - .downtime(DowntimeRetryRequest.builder().enabled(true).build()) - .build(); + final PaymentRetryRequest original = serializer.fromJson("{\"enabled\":true," + + "\"max_attempts\":2,\"end_after_days\":3," + + "\"dunning\":{\"enabled\":true,\"max_attempts\":15,\"end_after_days\":60}," + + "\"downtime\":{\"enabled\":true}}", PaymentRetryRequest.class); final String json = serializer.toJson(original); From fe2b0261c220230aa21b9bc6e269245e7cb41a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20Rodr=C3=ADguez?= <127134616+armando-rodriguez-cko@users.noreply.github.com> Date: Wed, 28 Oct 2026 21:27:55 +0100 Subject: [PATCH 3/4] fix(payments): add deprecated customer retry setter and subscription tests --- .../payments/hosted/HostedPaymentRequest.java | 45 +++++++++++++++---- .../payments/links/PaymentLinkRequest.java | 45 +++++++++++++++---- ...HostedPaymentRequestSerializationTest.java | 19 ++++++++ .../PaymentLinkRequestSerializationTest.java | 19 ++++++++ ...PaymentRetryResponseSerializationTest.java | 26 +++++++++++ 5 files changed, 138 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java b/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java index 281a50d18..25eccb97e 100644 --- a/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java +++ b/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java @@ -247,6 +247,42 @@ public final class HostedPaymentRequest { */ private AuthorizationType authorizationType; + + /** + * Configures the parameters for customer retries. Written by hand because Lombok does not generate a + * setter when another method with the same name exists. + * + * @param customerRetry the customer retry configuration + */ + public void setCustomerRetry(final CustomerRetry customerRetry) { + this.customerRetry = customerRetry; + } + + /** + * Configures customer retries from a {@link PaymentRetryRequest}. Only its max attempts value is kept, + * because customer_retry only accepts max_attempts. A null request clears the customer retry; a request + * without max attempts sets the {@link CustomerRetry} default. + * + * @param customerRetry the retry configuration to convert + * @deprecated Use {@link #setCustomerRetry(CustomerRetry)} instead. + * This method will be removed in the next major version. + */ + @Deprecated + public void setCustomerRetry(final PaymentRetryRequest customerRetry) { + this.customerRetry = toCustomerRetry(customerRetry); + } + + @SuppressWarnings("deprecation") + private static CustomerRetry toCustomerRetry(final PaymentRetryRequest customerRetry) { + if (customerRetry == null) { + return null; + } + if (customerRetry.getMaxAttempts() == null) { + return CustomerRetry.builder().build(); + } + return CustomerRetry.builder().maxAttempts(customerRetry.getMaxAttempts()).build(); + } + /** * Builder for {@link HostedPaymentRequest}. Only the customer retry methods are written by hand; every other * method is generated by Lombok. @@ -275,15 +311,8 @@ public HostedPaymentRequestBuilder customerRetry(final CustomerRetry customerRet * This method will be removed in the next major version. */ @Deprecated - @SuppressWarnings("deprecation") public HostedPaymentRequestBuilder customerRetry(final PaymentRetryRequest customerRetry) { - if (customerRetry == null) { - this.customerRetry = null; - } else if (customerRetry.getMaxAttempts() == null) { - this.customerRetry = CustomerRetry.builder().build(); - } else { - this.customerRetry = CustomerRetry.builder().maxAttempts(customerRetry.getMaxAttempts()).build(); - } + this.customerRetry = toCustomerRetry(customerRetry); return this; } } diff --git a/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java b/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java index 7fb4273fc..95e8b47a1 100644 --- a/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java +++ b/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java @@ -234,6 +234,42 @@ public final class PaymentLinkRequest { */ private AuthorizationType authorizationType; + + /** + * Configures the parameters for customer retries. Written by hand because Lombok does not generate a + * setter when another method with the same name exists. + * + * @param customerRetry the customer retry configuration + */ + public void setCustomerRetry(final CustomerRetry customerRetry) { + this.customerRetry = customerRetry; + } + + /** + * Configures customer retries from a {@link PaymentRetryRequest}. Only its max attempts value is kept, + * because customer_retry only accepts max_attempts. A null request clears the customer retry; a request + * without max attempts sets the {@link CustomerRetry} default. + * + * @param customerRetry the retry configuration to convert + * @deprecated Use {@link #setCustomerRetry(CustomerRetry)} instead. + * This method will be removed in the next major version. + */ + @Deprecated + public void setCustomerRetry(final PaymentRetryRequest customerRetry) { + this.customerRetry = toCustomerRetry(customerRetry); + } + + @SuppressWarnings("deprecation") + private static CustomerRetry toCustomerRetry(final PaymentRetryRequest customerRetry) { + if (customerRetry == null) { + return null; + } + if (customerRetry.getMaxAttempts() == null) { + return CustomerRetry.builder().build(); + } + return CustomerRetry.builder().maxAttempts(customerRetry.getMaxAttempts()).build(); + } + /** * Builder for {@link PaymentLinkRequest}. Only the customer retry methods are written by hand; every other * method is generated by Lombok. @@ -262,15 +298,8 @@ public PaymentLinkRequestBuilder customerRetry(final CustomerRetry customerRetry * This method will be removed in the next major version. */ @Deprecated - @SuppressWarnings("deprecation") public PaymentLinkRequestBuilder customerRetry(final PaymentRetryRequest customerRetry) { - if (customerRetry == null) { - this.customerRetry = null; - } else if (customerRetry.getMaxAttempts() == null) { - this.customerRetry = CustomerRetry.builder().build(); - } else { - this.customerRetry = CustomerRetry.builder().maxAttempts(customerRetry.getMaxAttempts()).build(); - } + this.customerRetry = toCustomerRetry(customerRetry); return this; } } diff --git a/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java b/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java index 98ab99d3d..3c62ccf3d 100644 --- a/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java +++ b/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java @@ -328,6 +328,25 @@ void shouldConvertDeprecatedCustomerRetryOverloadEdgeCasesForHostedPaymentReques assertNull(HostedPaymentRequest.builder().customerRetry((PaymentRetryRequest) null).build().getCustomerRetry()); } + @Test + @SuppressWarnings("deprecation") + void shouldSetCustomerRetryThroughBothSettersForHostedPaymentRequest() { + final PaymentRetryRequest legacy = serializer.fromJson("{\"max_attempts\":2}", PaymentRetryRequest.class); + + final HostedPaymentRequest fromLegacy = HostedPaymentRequest.builder().build(); + fromLegacy.setCustomerRetry(legacy); + final HostedPaymentRequest fromCustomerRetry = HostedPaymentRequest.builder().build(); + fromCustomerRetry.setCustomerRetry(CustomerRetry.builder().maxAttempts(2).build()); + + assertEquals("{\"max_attempts\":2}", customerRetryJson(fromLegacy)); + assertEquals(customerRetryJson(fromCustomerRetry), customerRetryJson(fromLegacy)); + + fromLegacy.setCustomerRetry(serializer.fromJson("{}", PaymentRetryRequest.class)); + assertEquals("{\"max_attempts\":5}", customerRetryJson(fromLegacy)); + fromLegacy.setCustomerRetry((PaymentRetryRequest) null); + assertNull(fromLegacy.getCustomerRetry()); + } + private String customerRetryJson(final HostedPaymentRequest request) { final JsonObject json = JsonParser.parseString(serializer.toJson(request)).getAsJsonObject(); return json.get("customer_retry").toString(); diff --git a/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java b/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java index 0134831a1..5250191f2 100644 --- a/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java +++ b/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java @@ -325,6 +325,25 @@ void shouldConvertDeprecatedCustomerRetryOverloadEdgeCasesForPaymentLinkRequest( assertNull(PaymentLinkRequest.builder().customerRetry((PaymentRetryRequest) null).build().getCustomerRetry()); } + @Test + @SuppressWarnings("deprecation") + void shouldSetCustomerRetryThroughBothSettersForPaymentLinkRequest() { + final PaymentRetryRequest legacy = serializer.fromJson("{\"max_attempts\":2}", PaymentRetryRequest.class); + + final PaymentLinkRequest fromLegacy = PaymentLinkRequest.builder().build(); + fromLegacy.setCustomerRetry(legacy); + final PaymentLinkRequest fromCustomerRetry = PaymentLinkRequest.builder().build(); + fromCustomerRetry.setCustomerRetry(CustomerRetry.builder().maxAttempts(2).build()); + + assertEquals("{\"max_attempts\":2}", customerRetryJson(fromLegacy)); + assertEquals(customerRetryJson(fromCustomerRetry), customerRetryJson(fromLegacy)); + + fromLegacy.setCustomerRetry(serializer.fromJson("{}", PaymentRetryRequest.class)); + assertEquals("{\"max_attempts\":5}", customerRetryJson(fromLegacy)); + fromLegacy.setCustomerRetry((PaymentRetryRequest) null); + assertNull(fromLegacy.getCustomerRetry()); + } + private String customerRetryJson(final PaymentLinkRequest request) { final JsonObject json = JsonParser.parseString(serializer.toJson(request)).getAsJsonObject(); return json.get("customer_retry").toString(); diff --git a/src/test/java/com/checkout/payments/response/PaymentRetryResponseSerializationTest.java b/src/test/java/com/checkout/payments/response/PaymentRetryResponseSerializationTest.java index df90cf10f..35620b944 100644 --- a/src/test/java/com/checkout/payments/response/PaymentRetryResponseSerializationTest.java +++ b/src/test/java/com/checkout/payments/response/PaymentRetryResponseSerializationTest.java @@ -57,4 +57,30 @@ void shouldDeserializeRetryInsidePaymentResponses() { assertEquals(2, serializer.fromJson(retry, GetPaymentResponse.class).getRetry().getAttemptsMade()); assertEquals(6, serializer.fromJson(retry, PaymentResponse.class).getRetry().getMaxAttempts()); } + + // ------------------------------------------------------------------------ + // PaymentResponse.subscription + // The spec PaymentResponse schema returns subscription (Subscription: id, max 50 characters). + // The spec has no example value, so the id below is illustrative. + // ------------------------------------------------------------------------ + + @Test + void shouldDeserializePaymentResponseSubscription() { + final PaymentResponse response = serializer.fromJson( + "{\"id\":\"pay_mbabizu24mvu3mela5njyhpit4\",\"subscription\":{\"id\":\"sub_reference_123\"}}", + PaymentResponse.class); + + assertEquals("sub_reference_123", response.getSubscription().getId()); + } + + @Test + void shouldRoundTripPaymentResponseSubscription() { + final PaymentResponse original = serializer.fromJson( + "{\"subscription\":{\"id\":\"sub_reference_123\"}}", PaymentResponse.class); + + final String json = serializer.toJson(original); + + assertTrue(json.contains("\"subscription\":{\"id\":\"sub_reference_123\"}")); + assertEquals(original.getSubscription(), serializer.fromJson(json, PaymentResponse.class).getSubscription()); + } } From 48b757ff80a449bd133fc1ac9a5f6ed432a7179f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20Rodr=C3=ADguez?= <127134616+armando-rodriguez-cko@users.noreply.github.com> Date: Mon, 2 Nov 2026 12:53:39 +0100 Subject: [PATCH 4/4] fix(payments): mark customer retry converter and tests deprecated Code scanning flags calls to deprecated members from non-deprecated code. The private converter only serves the deprecated PaymentRetryRequest overloads, and the tests exercise those overloads on purpose, so both are marked deprecated instead of suppressing the warning. --- .../checkout/payments/hosted/HostedPaymentRequest.java | 8 +++++++- .../com/checkout/payments/links/PaymentLinkRequest.java | 8 +++++++- .../hosted/HostedPaymentRequestSerializationTest.java | 6 +++--- .../links/PaymentLinkRequestSerializationTest.java | 6 +++--- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java b/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java index 25eccb97e..ac0ec1805 100644 --- a/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java +++ b/src/main/java/com/checkout/payments/hosted/HostedPaymentRequest.java @@ -272,7 +272,13 @@ public void setCustomerRetry(final PaymentRetryRequest customerRetry) { this.customerRetry = toCustomerRetry(customerRetry); } - @SuppressWarnings("deprecation") + /** + * Converts the deprecated {@link PaymentRetryRequest} overloads to {@link CustomerRetry}. + * + * @deprecated Only used by the deprecated {@link PaymentRetryRequest} overloads; removed with them in the next + * major version. + */ + @Deprecated private static CustomerRetry toCustomerRetry(final PaymentRetryRequest customerRetry) { if (customerRetry == null) { return null; diff --git a/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java b/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java index 95e8b47a1..6991a2be2 100644 --- a/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java +++ b/src/main/java/com/checkout/payments/links/PaymentLinkRequest.java @@ -259,7 +259,13 @@ public void setCustomerRetry(final PaymentRetryRequest customerRetry) { this.customerRetry = toCustomerRetry(customerRetry); } - @SuppressWarnings("deprecation") + /** + * Converts the deprecated {@link PaymentRetryRequest} overloads to {@link CustomerRetry}. + * + * @deprecated Only used by the deprecated {@link PaymentRetryRequest} overloads; removed with them in the next + * major version. + */ + @Deprecated private static CustomerRetry toCustomerRetry(final PaymentRetryRequest customerRetry) { if (customerRetry == null) { return null; diff --git a/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java b/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java index 3c62ccf3d..74e8358e4 100644 --- a/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java +++ b/src/test/java/com/checkout/payments/hosted/HostedPaymentRequestSerializationTest.java @@ -305,7 +305,7 @@ void shouldSerializeCustomerRetryForHostedPaymentRequest() { // The overload under test is deprecated on purpose (kept for compatibility), so calling it is the test. // The PaymentRetryRequest argument is built from JSON to avoid its deprecated builder methods. @Test - @SuppressWarnings("deprecation") + @Deprecated void shouldSerializeDeprecatedCustomerRetryOverloadLikeCustomerRetryForHostedPaymentRequest() { final PaymentRetryRequest legacy = serializer.fromJson("{\"max_attempts\":3}", PaymentRetryRequest.class); @@ -319,7 +319,7 @@ void shouldSerializeDeprecatedCustomerRetryOverloadLikeCustomerRetryForHostedPay } @Test - @SuppressWarnings("deprecation") + @Deprecated void shouldConvertDeprecatedCustomerRetryOverloadEdgeCasesForHostedPaymentRequest() { final PaymentRetryRequest withoutMaxAttempts = serializer.fromJson("{\"enabled\":true}", PaymentRetryRequest.class); @@ -329,7 +329,7 @@ void shouldConvertDeprecatedCustomerRetryOverloadEdgeCasesForHostedPaymentReques } @Test - @SuppressWarnings("deprecation") + @Deprecated void shouldSetCustomerRetryThroughBothSettersForHostedPaymentRequest() { final PaymentRetryRequest legacy = serializer.fromJson("{\"max_attempts\":2}", PaymentRetryRequest.class); diff --git a/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java b/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java index 5250191f2..f7b8fec96 100644 --- a/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java +++ b/src/test/java/com/checkout/payments/links/PaymentLinkRequestSerializationTest.java @@ -302,7 +302,7 @@ void shouldSerializeCustomerRetryForPaymentLinkRequest() { // The overload under test is deprecated on purpose (kept for compatibility), so calling it is the test. // The PaymentRetryRequest argument is built from JSON to avoid its deprecated builder methods. @Test - @SuppressWarnings("deprecation") + @Deprecated void shouldSerializeDeprecatedCustomerRetryOverloadLikeCustomerRetryForPaymentLinkRequest() { final PaymentRetryRequest legacy = serializer.fromJson("{\"max_attempts\":3}", PaymentRetryRequest.class); @@ -316,7 +316,7 @@ void shouldSerializeDeprecatedCustomerRetryOverloadLikeCustomerRetryForPaymentLi } @Test - @SuppressWarnings("deprecation") + @Deprecated void shouldConvertDeprecatedCustomerRetryOverloadEdgeCasesForPaymentLinkRequest() { final PaymentRetryRequest withoutMaxAttempts = serializer.fromJson("{\"enabled\":true}", PaymentRetryRequest.class); @@ -326,7 +326,7 @@ void shouldConvertDeprecatedCustomerRetryOverloadEdgeCasesForPaymentLinkRequest( } @Test - @SuppressWarnings("deprecation") + @Deprecated void shouldSetCustomerRetryThroughBothSettersForPaymentLinkRequest() { final PaymentRetryRequest legacy = serializer.fromJson("{\"max_attempts\":2}", PaymentRetryRequest.class);