From 6ebbefbcdbd6e2baa305fee5c7c18a0b3a618d6c Mon Sep 17 00:00:00 2001 From: Simon Gabriel <15432768+sixer1182@users.noreply.github.com> Date: Tue, 8 Sep 2026 08:58:47 +0200 Subject: [PATCH 1/3] [CC-4065] Deprecate the Pis (unzer-bank-transfer) payment type PIS / Unzer Bank Transfer (FlexiPay Direct) has been retired: PAPI's PISController is @Hidden and POST /v1/types/pis is being removed. The SDK still offered the type as if supported, so merchants got a runtime failure with no compile-time warning. @Deprecated surfaces that in consumer builds. Deprecation only - nothing is removed from src/main. * Pis: class-level @Deprecated + @deprecated javadoc, worded like Giropay. Also fixes the class javadoc, which read "Paypal business object". * PaymentTypeEnum.PIS: @Deprecated, matching the other deprecated constants. * PisTest.java: deleted. These are integration tests against the endpoint being removed, so they test a dead endpoint. * CHANGELOG: new [Unreleased] / Deprecated entry. No version bump, no existing release header touched. Deliberately left unannotated: PaymentService's two `case PIS:` factory branches are internal dispatch that must keep working for deprecated types; the same switch statements already handle @Deprecated constants such as SEPA_DIRECT_DEBIT_SECURED without suppression. ApiPis and ApiToSdkConverter are internal serialisation, not public API. The separate Open Banking type (openbanking-pis / PaymentTypeEnum.OPEN_BANKING) is untouched and remains fully supported. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 9 +++ .../payment/paymenttypes/PaymentTypeEnum.java | 1 + .../com/unzer/payment/paymenttypes/Pis.java | 4 +- .../integration/paymenttypes/PisTest.java | 73 ------------------- 4 files changed, 13 insertions(+), 74 deletions(-) delete mode 100644 src/test/java/com/unzer/payment/integration/paymenttypes/PisTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 60b496dc..26f03214 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Deprecated + +* Deprecated PIS / Unzer Bank Transfer payment type (`com.unzer.payment.paymenttypes.Pis`) + and the corresponding `PaymentTypeEnum.PIS` constant. This does **not** affect the separate + Open Banking payment type (`com.unzer.payment.paymenttypes.OpenBanking` / + `PaymentTypeEnum.OPEN_BANKING`), which remains fully supported. + ## [5.9.0](https://github.com/unzerdev/java-sdk/compare/5.8.2..5.9.0) ### Added diff --git a/src/main/java/com/unzer/payment/paymenttypes/PaymentTypeEnum.java b/src/main/java/com/unzer/payment/paymenttypes/PaymentTypeEnum.java index 641eaf86..504a1769 100644 --- a/src/main/java/com/unzer/payment/paymenttypes/PaymentTypeEnum.java +++ b/src/main/java/com/unzer/payment/paymenttypes/PaymentTypeEnum.java @@ -26,6 +26,7 @@ public enum PaymentTypeEnum { @Deprecated SEPA_DIRECT_DEBIT_SECURED("dds"), SOFORT("sft"), + @Deprecated PIS("pis"), ALIPAY("ali"), WECHATPAY("wcp"), diff --git a/src/main/java/com/unzer/payment/paymenttypes/Pis.java b/src/main/java/com/unzer/payment/paymenttypes/Pis.java index 710afeab..3f6e15ec 100644 --- a/src/main/java/com/unzer/payment/paymenttypes/Pis.java +++ b/src/main/java/com/unzer/payment/paymenttypes/Pis.java @@ -12,10 +12,12 @@ import java.util.Currency; /** - * Paypal business object + * Pis business object * * @author Unzer E-Com GmbH + * @deprecated PIS (Unzer Bank Transfer) payment type is no longer supported and will be removed in a future version. */ +@Deprecated public class Pis extends BasePaymentType { private String iban; diff --git a/src/test/java/com/unzer/payment/integration/paymenttypes/PisTest.java b/src/test/java/com/unzer/payment/integration/paymenttypes/PisTest.java deleted file mode 100644 index 5271461c..00000000 --- a/src/test/java/com/unzer/payment/integration/paymenttypes/PisTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.unzer.payment.integration.paymenttypes; - - -import com.unzer.payment.Charge; -import com.unzer.payment.Unzer; -import com.unzer.payment.business.AbstractPaymentTest; -import com.unzer.payment.paymenttypes.Pis; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import java.math.BigDecimal; -import java.util.Currency; - -import static com.unzer.payment.util.Types.unsafeUrl; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -class PisTest extends AbstractPaymentTest { - - @Test - void testCreatePis() { - Pis pis = new Pis(); - pis = getUnzer().createPaymentType(pis); - assertNotNull(pis.getId()); - } - - @Test - void testCreatePisWithIbanBic() { - Pis pis = new Pis("DE69545100670661762678", "SPFKAT2BXXX"); - pis = getUnzer().createPaymentType(pis); - assertNotNull(pis.getId()); - assertNotNull(pis.getIban()); - assertNotNull(pis.getBic()); - - Pis fetchedPis = (Pis) getUnzer().fetchPaymentType(pis.getId()); - assertNotNull(fetchedPis.getId()); - assertNotNull(fetchedPis.getIban()); - assertNotNull(fetchedPis.getBic()); - } - - @Test - @Disabled("Unspecified (Technical)") - public void testAuthorizeType() { - Unzer unzer = getUnzer(); - Pis pis = unzer.createPaymentType(new Pis()); - Charge charge = unzer.charge( - BigDecimal.ONE, - Currency.getInstance("EUR"), - pis.getId(), - unsafeUrl("https://www.meinShop.de") - ); - assertNotNull(charge); - assertNotNull(charge.getId()); - assertNotNull(charge.getRedirectUrl()); - } - - @Test - void testFetchPisType() { - Pis pis = getUnzer().createPaymentType(new Pis()); - assertNotNull(pis.getId()); - Pis fetchedPis = (Pis) getUnzer().fetchPaymentType(pis.getId()); - assertNotNull(fetchedPis.getId()); - } - - @Test - @Disabled("AHC-3615 PIS holder not in response when doing a POST/GET") - public void testFetchPisTypeWithHolderBicIban() { - Pis fetchedPis = (Pis) getUnzer().fetchPaymentType("s-pis-ivt4ibypi0zk"); - assertNotNull(fetchedPis.getId()); - assertNotNull(fetchedPis.getIban()); - assertNotNull(fetchedPis.getBic()); - assertNotNull(fetchedPis.getHolder()); - } -} From f0077b06576b3fc6c2efc7b999ffd67998a7ab03 Mon Sep 17 00:00:00 2001 From: Simon Gabriel <15432768+sixer1182@users.noreply.github.com> Date: Tue, 8 Sep 2026 11:26:27 +0200 Subject: [PATCH 2/3] [CC-4065] Run test classes in same_thread to fix WireMock port race Twelve test classes declare @WireMockTest(httpPort = 8080), all binding the same fixed port. junit-platform.properties set parallel.mode.default=concurrent, so those classes started concurrently and raced to bind 8080; every class but the first died in beforeAll with: FatalStartupException: java.io.IOException: Failed to bind to /0.0.0.0:8080 In CI this took out ClickToPayTest, CardTest, GooglePayTest, PaylaterInstallmentTest, PayUTest, PaypalExpressTest and OpenBankingTest. Switching mode.default to same_thread serialises test classes, so only one WireMock server exists at a time. Tests themselves are untouched. Pre-existing and unrelated to the Pis deprecation: reproduced on unmodified origin/main (6adfc23), and the Unit tests workflow has failed on every run in the visible history, main included. Measured on the same local run, non-credentialed subset: before (concurrent): 231 run, 134 failures, 13 errors after (same_thread): 246 run, 134 failures, 2 errors Errors drop from 13 to 2 and 15 more tests get to run; failure count is unchanged, and the 2 remaining errors are "privateKey is null" from absent local UNZER_* credentials, which CI injects. No "Failed to bind" remains. Trade-off: the suite no longer runs test classes in parallel, so it is slower. The alternative fixes are per-class @Isolated (12 files) or dynamic ports (rewiring each client base URL); both are larger and belong in their own change. Co-Authored-By: Claude Opus 5 (1M context) --- src/test/resources/junit-platform.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/resources/junit-platform.properties b/src/test/resources/junit-platform.properties index 07bf940e..b1329fb9 100644 --- a/src/test/resources/junit-platform.properties +++ b/src/test/resources/junit-platform.properties @@ -1,2 +1,5 @@ junit.jupiter.execution.parallel.enabled=true -junit.jupiter.execution.parallel.mode.default=concurrent \ No newline at end of file +# Test classes must not run concurrently: 12 of them share a WireMock server on the +# fixed port 8080 (@WireMockTest(httpPort = 8080)), so concurrent classes race to bind +# it and all but the first fail with "Failed to bind to /0.0.0.0:8080". +junit.jupiter.execution.parallel.mode.default=same_thread From 0b7d7c89c007330974659dacfb6f81dfc22365bf Mon Sep 17 00:00:00 2001 From: Simon Gabriel <15432768+sixer1182@users.noreply.github.com> Date: Wed, 9 Sep 2026 10:13:34 +0200 Subject: [PATCH 3/3] [CC-4065] Remove SofortTest, which exercises a discontinued endpoint SofortTest.testCreateSofortManatoryType and testFetchSofortType fail in CI: POST /v1/types/sofort/ now answers HTTP 410 with 'Sofort payment method has been discontinued.', so the two remaining enabled tests in the class can never pass again. The third test was already @Disabled('does not work on PAPI'). Same situation this PR already handled for PisTest, and the same treatment GiropayTest received in #187 (CC-1085). Nothing under src/main is touched - Sofort stays in the SDK until the next major release. The two other Sofort references, ChargeTest.testChargeSofort and testMarketplaceChargeWithSofort, are already @Disabled and are left as they are. The remaining CI failures on this PR (CardTest, IdealTest, InstallmentSecuredTest, PaypalExpressTest) are pre-existing sandbox issues unrelated to CC-4065 - CardTest#97 already failed on the 5.9.0 release PR in February. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_011GTcoUbc5ziRDHgWV3hgzQ --- .../integration/paymenttypes/SofortTest.java | 42 ------------------- 1 file changed, 42 deletions(-) delete mode 100644 src/test/java/com/unzer/payment/integration/paymenttypes/SofortTest.java diff --git a/src/test/java/com/unzer/payment/integration/paymenttypes/SofortTest.java b/src/test/java/com/unzer/payment/integration/paymenttypes/SofortTest.java deleted file mode 100644 index f1e3d809..00000000 --- a/src/test/java/com/unzer/payment/integration/paymenttypes/SofortTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.unzer.payment.integration.paymenttypes; - - -import com.unzer.payment.Charge; -import com.unzer.payment.business.AbstractPaymentTest; -import com.unzer.payment.paymenttypes.Sofort; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import java.math.BigDecimal; -import java.util.Currency; - -import static com.unzer.payment.util.Types.unsafeUrl; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -class SofortTest extends AbstractPaymentTest { - - @Test - void testCreateSofortManatoryType() { - Sofort sofort = new Sofort(); - sofort = getUnzer().createPaymentType(sofort); - assertNotNull(sofort.getId()); - } - - @Test - @Disabled("does not work on PAPI") - public void testChargeSofortType() { - Sofort sofort = getUnzer().createPaymentType(new Sofort()); - Charge charge = sofort.charge(BigDecimal.ONE, Currency.getInstance("EUR"), unsafeUrl("https://www.unzer.com")); - assertNotNull(charge); - assertNotNull(charge.getId()); - assertNotNull(charge.getRedirectUrl()); - } - - @Test - void testFetchSofortType() { - Sofort sofort = getUnzer().createPaymentType(new Sofort()); - assertNotNull(sofort.getId()); - Sofort fetchedSofort = (Sofort) getUnzer().fetchPaymentType(sofort.getId()); - assertNotNull(fetchedSofort.getId()); - } -}