From b357b140d4108b815f9ba6eb9b8b7c097a5d8fe9 Mon Sep 17 00:00:00 2001 From: "david.owusu" Date: Tue, 18 Feb 2025 17:01:47 +0100 Subject: [PATCH 1/6] [CC-2018] Add customer v2. --- .../java/com/unzer/payment/CustomerV2.java | 24 +++ .../AbstractUnzerRestCommunication.java | 12 +- .../communication/UnzerRestCommunication.java | 13 ++ .../payment/communication/api/ApiConfigs.java | 1 + .../unzer/payment/service/PaymentService.java | 146 ++++++++++++++++-- .../payment/business/CustomerV2Test.java | 67 ++++++++ .../payment/communication/HttpClientMock.java | 12 +- 7 files changed, 260 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/unzer/payment/CustomerV2.java create mode 100644 src/test/java/com/unzer/payment/business/CustomerV2Test.java diff --git a/src/main/java/com/unzer/payment/CustomerV2.java b/src/main/java/com/unzer/payment/CustomerV2.java new file mode 100644 index 00000000..ba7572b3 --- /dev/null +++ b/src/main/java/com/unzer/payment/CustomerV2.java @@ -0,0 +1,24 @@ +package com.unzer.payment; + +/** + * Business object for Customer together with billingAddress. + *

+ * firstname and lastname are mandatory to create a new Customer. + * + * @author Unzer E-Com GmbH + */ +public class CustomerV2 extends Customer { + + public CustomerV2(String firstname, String lastname) { + super(firstname, lastname); + } + + public CustomerV2(String company) { + super(company); + } + + @Override + public String getResourceUrl() { + return "/v2/customers/"; + } +} diff --git a/src/main/java/com/unzer/payment/communication/AbstractUnzerRestCommunication.java b/src/main/java/com/unzer/payment/communication/AbstractUnzerRestCommunication.java index eaec160b..00880c0e 100644 --- a/src/main/java/com/unzer/payment/communication/AbstractUnzerRestCommunication.java +++ b/src/main/java/com/unzer/payment/communication/AbstractUnzerRestCommunication.java @@ -17,7 +17,10 @@ import java.util.Locale; import java.util.Objects; -import static org.apache.hc.core5.http.HttpHeaders.*; +import static org.apache.hc.core5.http.HttpHeaders.ACCEPT_LANGUAGE; +import static org.apache.hc.core5.http.HttpHeaders.AUTHORIZATION; +import static org.apache.hc.core5.http.HttpHeaders.CONTENT_TYPE; +import static org.apache.hc.core5.http.HttpHeaders.USER_AGENT; /** * Template implementation of the {@code UnzerRestCommunication}. You should @@ -117,6 +120,13 @@ public String httpPut(String url, String privateKey, Object data) return sendRequestWithBody(createRequest(url, UnzerHttpMethod.PUT), privateKey, data); } + public String httpPut(String url, String privateKey, Object data, ApiConfig apiClientConfig) + throws HttpCommunicationException { + Objects.requireNonNull(url); + Objects.requireNonNull(data); + return sendRequestWithBody(createRequest(url, UnzerHttpMethod.PUT), privateKey, data, apiClientConfig); + } + public String httpDelete(String url, String privateKey) throws HttpCommunicationException { Objects.requireNonNull(url); return this.execute(createRequest(url, UnzerHttpMethod.DELETE), privateKey, EMPTY_JSON); diff --git a/src/main/java/com/unzer/payment/communication/UnzerRestCommunication.java b/src/main/java/com/unzer/payment/communication/UnzerRestCommunication.java index b56d0008..4f500578 100644 --- a/src/main/java/com/unzer/payment/communication/UnzerRestCommunication.java +++ b/src/main/java/com/unzer/payment/communication/UnzerRestCommunication.java @@ -68,6 +68,19 @@ public interface UnzerRestCommunication { */ String httpPut(String url, String privateKey, Object data) throws HttpCommunicationException; + /** + * Executes a PUT Request to the given {@code url} authenticated with the given + * {@code privateKey}. + * + * @param url - the url to be called + * @param privateKey - the private key of the key-pair to used + * @param data - any data object as defined in the com.unzer.payment package + * @param apiClientConfig - API config to use. + * @return - the Response as application/json, UTF-8 + * @throws HttpCommunicationException - thrown for any problems occurring in http-communication + */ + String httpPut(String url, String privateKey, Object data, ApiConfig apiClientConfig) throws HttpCommunicationException; + /** * Executes a DELETE Request to the given {@code url} authenticated with the given * {@code privateKey}. diff --git a/src/main/java/com/unzer/payment/communication/api/ApiConfigs.java b/src/main/java/com/unzer/payment/communication/api/ApiConfigs.java index 2b1134a5..44ddaa77 100644 --- a/src/main/java/com/unzer/payment/communication/api/ApiConfigs.java +++ b/src/main/java/com/unzer/payment/communication/api/ApiConfigs.java @@ -3,6 +3,7 @@ public class ApiConfigs { public static final ApiConfig PAYMENT_API = new ApiConfig("https://api.unzer.com", "https://sbx-api.unzer.com"); + public static final ApiConfig PAYMENT_API_BEARER_AUTH = new ApiConfig("https://api.unzer.com", "https://sbx-api.unzer.com", ApiConfig.AuthMethod.BEARER); public static final ApiConfig TOKEN_SERVICE_API = new ApiConfig("https://token.upcgw.com", "https://token.test.upcgw.com"); public static final ApiConfig PAYPAGE_API = new ApiConfig("https://paypage.unzer.com", "https://paypage.test.unzer.io", ApiConfig.AuthMethod.BEARER); } diff --git a/src/main/java/com/unzer/payment/service/PaymentService.java b/src/main/java/com/unzer/payment/service/PaymentService.java index 4b618bc1..d0f0b990 100644 --- a/src/main/java/com/unzer/payment/service/PaymentService.java +++ b/src/main/java/com/unzer/payment/service/PaymentService.java @@ -1,21 +1,101 @@ package com.unzer.payment.service; -import com.unzer.payment.*; -import com.unzer.payment.business.paymenttypes.*; +import com.unzer.payment.Authorization; +import com.unzer.payment.BasePayment; +import com.unzer.payment.Basket; +import com.unzer.payment.Cancel; +import com.unzer.payment.Charge; +import com.unzer.payment.Chargeback; +import com.unzer.payment.Customer; +import com.unzer.payment.CustomerV2; +import com.unzer.payment.Metadata; +import com.unzer.payment.PaylaterInstallmentPlans; +import com.unzer.payment.Payment; +import com.unzer.payment.PaymentException; +import com.unzer.payment.Payout; +import com.unzer.payment.Preauthorization; +import com.unzer.payment.Recurring; +import com.unzer.payment.Shipment; +import com.unzer.payment.Unzer; +import com.unzer.payment.business.paymenttypes.HirePurchaseDirectDebit; +import com.unzer.payment.business.paymenttypes.InstallmentSecuredRatePlan; +import com.unzer.payment.business.paymenttypes.InvoiceFactoring; +import com.unzer.payment.business.paymenttypes.InvoiceGuaranteed; +import com.unzer.payment.business.paymenttypes.SepaDirectDebitGuaranteed; import com.unzer.payment.communication.HttpCommunicationException; import com.unzer.payment.communication.JsonParser; import com.unzer.payment.communication.UnzerRestCommunication; -import com.unzer.payment.communication.json.*; +import com.unzer.payment.communication.api.ApiConfig; +import com.unzer.payment.communication.api.ApiConfigs; +import com.unzer.payment.communication.json.ApiApplepayResponse; +import com.unzer.payment.communication.json.ApiAuthorization; +import com.unzer.payment.communication.json.ApiBancontact; +import com.unzer.payment.communication.json.ApiCancel; +import com.unzer.payment.communication.json.ApiCard; +import com.unzer.payment.communication.json.ApiCharge; +import com.unzer.payment.communication.json.ApiChargeback; +import com.unzer.payment.communication.json.ApiCustomer; +import com.unzer.payment.communication.json.ApiIdObject; +import com.unzer.payment.communication.json.ApiIdeal; +import com.unzer.payment.communication.json.ApiInstallmentSecuredRatePlan; +import com.unzer.payment.communication.json.ApiObject; +import com.unzer.payment.communication.json.ApiOpenBanking; +import com.unzer.payment.communication.json.ApiPaylaterInstallment; +import com.unzer.payment.communication.json.ApiPayment; +import com.unzer.payment.communication.json.ApiPayout; +import com.unzer.payment.communication.json.ApiPaypal; +import com.unzer.payment.communication.json.ApiPis; +import com.unzer.payment.communication.json.ApiRecurring; +import com.unzer.payment.communication.json.ApiSepaDirectDebit; +import com.unzer.payment.communication.json.ApiShipment; +import com.unzer.payment.communication.json.ApiTransaction; +import com.unzer.payment.communication.json.JsonInstallmentSecuredRatePlanList; import com.unzer.payment.communication.json.paylater.ApiInstallmentPlans; import com.unzer.payment.communication.mapper.ApiToSdkConverter; import com.unzer.payment.models.PaylaterInvoiceConfig; import com.unzer.payment.models.PaylaterInvoiceConfigRequest; import com.unzer.payment.models.paylater.InstallmentPlansRequest; -import com.unzer.payment.paymenttypes.*; +import com.unzer.payment.paymenttypes.Alipay; +import com.unzer.payment.paymenttypes.Applepay; +import com.unzer.payment.paymenttypes.Bancontact; +import com.unzer.payment.paymenttypes.BasePaymentType; +import com.unzer.payment.paymenttypes.Card; +import com.unzer.payment.paymenttypes.ClickToPay; +import com.unzer.payment.paymenttypes.Eps; +import com.unzer.payment.paymenttypes.Giropay; +import com.unzer.payment.paymenttypes.GooglePay; +import com.unzer.payment.paymenttypes.Ideal; +import com.unzer.payment.paymenttypes.Invoice; +import com.unzer.payment.paymenttypes.InvoiceSecured; +import com.unzer.payment.paymenttypes.Klarna; +import com.unzer.payment.paymenttypes.OpenBanking; +import com.unzer.payment.paymenttypes.PayU; +import com.unzer.payment.paymenttypes.PaylaterDirectDebit; +import com.unzer.payment.paymenttypes.PaylaterInstallment; +import com.unzer.payment.paymenttypes.PaylaterInvoice; +import com.unzer.payment.paymenttypes.PaymentType; +import com.unzer.payment.paymenttypes.PaymentTypeEnum; +import com.unzer.payment.paymenttypes.Paypal; +import com.unzer.payment.paymenttypes.Pis; +import com.unzer.payment.paymenttypes.PostFinanceCard; +import com.unzer.payment.paymenttypes.PostFinanceEFinance; +import com.unzer.payment.paymenttypes.Prepayment; +import com.unzer.payment.paymenttypes.Przelewy24; +import com.unzer.payment.paymenttypes.SepaDirectDebit; +import com.unzer.payment.paymenttypes.SepaDirectDebitSecured; +import com.unzer.payment.paymenttypes.Sofort; +import com.unzer.payment.paymenttypes.Twint; +import com.unzer.payment.paymenttypes.Wechatpay; import java.math.BigDecimal; import java.net.URL; -import java.util.*; +import java.util.ArrayList; +import java.util.Currency; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -243,29 +323,64 @@ public T updatePaymentType(T paymentType) } public Customer createCustomer(Customer customer) throws HttpCommunicationException { + ApiConfig apiConfig = customer instanceof CustomerV2 ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; + String authentication = unzer.getPrivateKey(); + if (apiConfig.getAuthMethod() == ApiConfig.AuthMethod.BEARER) { + unzer.prepareJwtToken(); + authentication = unzer.getJwtToken(); + } String response = - restCommunication.httpPost(urlUtil.getUrl(customer), unzer.getPrivateKey(), - apiToSdkMapper.map(customer)); + restCommunication.httpPost( + urlUtil.getUrl(customer), + authentication, + apiToSdkMapper.map(customer), + apiConfig + ); ApiIdObject jsonId = jsonParser.fromJson(response, ApiIdObject.class); return fetchCustomer(jsonId.getId()); } public Customer fetchCustomer(String customerId) throws HttpCommunicationException, PaymentException { - Customer customer = new Customer("", ""); + boolean isV2Id = isUUIDResource(customerId); + ApiConfig apiConfig = isV2Id ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; + Customer customer = isV2Id ? new CustomerV2("", "") : new Customer("", ""); + customer.setId(customerId); + + String authentication = unzer.getPrivateKey(); + if (isV2Id) { + unzer.prepareJwtToken(); + authentication = unzer.getJwtToken(); + } String response = restCommunication.httpGet( urlUtil.getUrl(customer), - unzer.getPrivateKey() + authentication, + apiConfig ); ApiCustomer json = jsonParser.fromJson(response, ApiCustomer.class); return apiToSdkMapper.mapToBusinessObject(json, new Customer("", "")); } + private static boolean isUUIDResource(String customerId) { + String uuidPattern = "^[sp]-([a-z]{3}|p24)-[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"; + return Pattern.matches(uuidPattern, customerId); + } + public Customer updateCustomer(String id, Customer customer) throws HttpCommunicationException { + ApiConfig apiConfig = customer instanceof CustomerV2 ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; + String authentication = unzer.getPrivateKey(); + if (apiConfig.getAuthMethod() == ApiConfig.AuthMethod.BEARER) { + unzer.prepareJwtToken(); + authentication = unzer.getJwtToken(); + } customer.setId(id); - restCommunication.httpPut(urlUtil.getUrl(customer), unzer.getPrivateKey(), - apiToSdkMapper.map(customer)); + restCommunication.httpPut( + urlUtil.getUrl(customer), + authentication, + apiToSdkMapper.map(customer), + apiConfig + ); return fetchCustomer(id); } @@ -777,13 +892,18 @@ public Recurring recurring(Recurring recurring) throws HttpCommunicationExceptio } public String deleteCustomer(String customerId) throws HttpCommunicationException { - Customer customer = new Customer("a", "b"); + boolean isV2Id = isUUIDResource(customerId); + ApiConfig apiConfig = isV2Id ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; + Customer customer = isV2Id ? new CustomerV2("", "") : new Customer("", ""); + String authentication = isV2Id ? unzer.getJwtToken() : unzer.getPrivateKey(); + customer.setId(customerId); customer.setCustomerId(customerId); String response = restCommunication.httpDelete( urlUtil.getUrl(customer), - unzer.getPrivateKey() + authentication, + apiConfig ); if (response == null || response.isEmpty()) { throw new PaymentException("Customer '" + customerId + "' cannot be deleted"); diff --git a/src/test/java/com/unzer/payment/business/CustomerV2Test.java b/src/test/java/com/unzer/payment/business/CustomerV2Test.java new file mode 100644 index 00000000..e0798ea7 --- /dev/null +++ b/src/test/java/com/unzer/payment/business/CustomerV2Test.java @@ -0,0 +1,67 @@ +package com.unzer.payment.business; + + +import com.unzer.payment.Customer; +import com.unzer.payment.CustomerV2; +import com.unzer.payment.PaymentException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class CustomerV2Test extends AbstractPaymentTest { + @Test + void testCreateMinimumCustomer() { + Customer customer = getUnzer().createCustomer(new CustomerV2("firstname", "lastname")); + assertNotNull(customer); + assertNotNull(customer.getId()); + assertEquals(getMinimumCustomer().getFirstname(), customer.getFirstname()); + assertEquals(getMinimumCustomer().getLastname(), customer.getLastname()); + } + + @Test + void testFetchCustomerMinimum() { + Customer customer = getUnzer().createCustomer(new CustomerV2("firstname", "lastname")); + assertNotNull(customer); + assertNotNull(customer.getId()); + + Customer fetchedCustomer = getUnzer().fetchCustomer(customer.getId()); + assertCustomerEquals(customer, fetchedCustomer); + } + + + @Test + void testUpdateCustomer() { + Customer customer = getUnzer().createCustomer(new CustomerV2("firstname", "lastname")); + assertNotNull(customer); + assertNotNull(customer.getId()); + Customer customerToUpdate = new Customer(customer.getFirstname(), customer.getLastname()); + customerToUpdate.setFirstname("Max"); + Customer updatedCustomer = getUnzer().updateCustomer(customer.getId(), customerToUpdate); + assertEquals("Max", updatedCustomer.getFirstname()); + Customer fetchedCustomer = getUnzer().fetchCustomer(customer.getId()); + assertEquals("Max", fetchedCustomer.getFirstname()); + } + + @Test + void testDeleteCustomer() { + Customer customer = getUnzer().createCustomer(new CustomerV2("firstname", "lastname")); + assertNotNull(customer); + assertNotNull(customer.getId()); + String deletedCustomerId = getUnzer().deleteCustomer(customer.getId()); + assertEquals(customer.getId(), deletedCustomerId); + } + + @Test + void testCreateCustomerWithException() { + assertThrows(IllegalArgumentException.class, () -> { + getUnzer().createCustomer(null); + }); + assertThrows(PaymentException.class, () -> { + Customer customerRequest = new CustomerV2("User", "Test"); + customerRequest.setId("s-cst-abcdef"); + getUnzer().createCustomer(customerRequest); + }); + } +} diff --git a/src/test/java/com/unzer/payment/communication/HttpClientMock.java b/src/test/java/com/unzer/payment/communication/HttpClientMock.java index 2847b400..c1edfb25 100644 --- a/src/test/java/com/unzer/payment/communication/HttpClientMock.java +++ b/src/test/java/com/unzer/payment/communication/HttpClientMock.java @@ -1,7 +1,12 @@ package com.unzer.payment.communication; import com.unzer.payment.communication.api.ApiConfig; -import org.apache.hc.client5.http.classic.methods.*; +import org.apache.hc.client5.http.classic.methods.HttpDelete; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPatch; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.classic.methods.HttpPut; +import org.apache.hc.client5.http.classic.methods.HttpUriRequest; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.core5.http.ContentType; @@ -41,6 +46,11 @@ public String httpPut(String url, String privateKey, Object data) { return execute(new HttpPut(proxyUrl(url)), data); } + @Override + public String httpPut(String url, String privateKey, Object data, ApiConfig apiClientConfig) throws HttpCommunicationException { + return execute(new HttpPut(proxyUrl(url)), data); + } + @Override public String httpDelete(String url, String privateKey) { return execute(new HttpDelete(proxyUrl(url)), null); From 69ae5a45db768ec8f13be86086aec3df445fc8d8 Mon Sep 17 00:00:00 2001 From: "david.owusu" Date: Wed, 19 Feb 2025 09:49:23 +0100 Subject: [PATCH 2/6] [CC-2018] Add customer v2. --- src/main/java/com/unzer/payment/CustomerV2.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/unzer/payment/CustomerV2.java b/src/main/java/com/unzer/payment/CustomerV2.java index ba7572b3..3a205538 100644 --- a/src/main/java/com/unzer/payment/CustomerV2.java +++ b/src/main/java/com/unzer/payment/CustomerV2.java @@ -2,10 +2,7 @@ /** * Business object for Customer together with billingAddress. - *

* firstname and lastname are mandatory to create a new Customer. - * - * @author Unzer E-Com GmbH */ public class CustomerV2 extends Customer { From 902add42f1b1d19fbb79fad1f9ada3cf6c6d7e8b Mon Sep 17 00:00:00 2001 From: "david.owusu" Date: Wed, 19 Feb 2025 16:48:19 +0100 Subject: [PATCH 3/6] [CC-2019] Add basket v3. --- src/main/java/com/unzer/payment/BasketV3.java | 8 ++ .../unzer/payment/service/PaymentService.java | 31 +++-- .../unzer/payment/business/BasketV3Test.java | 111 ++++++++++++++++++ .../payment/business/BasketV3TestData.java | 79 +++++++++++++ 4 files changed, 222 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/unzer/payment/BasketV3.java create mode 100644 src/test/java/com/unzer/payment/business/BasketV3Test.java create mode 100644 src/test/java/com/unzer/payment/business/BasketV3TestData.java diff --git a/src/main/java/com/unzer/payment/BasketV3.java b/src/main/java/com/unzer/payment/BasketV3.java new file mode 100644 index 00000000..becf565e --- /dev/null +++ b/src/main/java/com/unzer/payment/BasketV3.java @@ -0,0 +1,8 @@ +package com.unzer.payment; + +public class BasketV3 extends Basket { + @Override + protected String getResourceUrl() { + return "/v3/baskets/"; + } +} diff --git a/src/main/java/com/unzer/payment/service/PaymentService.java b/src/main/java/com/unzer/payment/service/PaymentService.java index d0f0b990..90c136c1 100644 --- a/src/main/java/com/unzer/payment/service/PaymentService.java +++ b/src/main/java/com/unzer/payment/service/PaymentService.java @@ -3,6 +3,7 @@ import com.unzer.payment.Authorization; import com.unzer.payment.BasePayment; import com.unzer.payment.Basket; +import com.unzer.payment.BasketV3; import com.unzer.payment.Cancel; import com.unzer.payment.Charge; import com.unzer.payment.Chargeback; @@ -385,27 +386,36 @@ public Customer updateCustomer(String id, Customer customer) throws HttpCommunic } public Basket updateBasket(Basket basket) throws HttpCommunicationException { - restCommunication.httpPut(urlUtil.getUrl(basket), unzer.getPrivateKey(), basket); + ApiConfig apiConfig = basket instanceof BasketV3 ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; + String authentication = unzer.getPrivateKey(); + if (apiConfig.getAuthMethod() == ApiConfig.AuthMethod.BEARER) { + unzer.prepareJwtToken(); + authentication = unzer.getJwtToken(); + } + restCommunication.httpPut(urlUtil.getUrl(basket), authentication, basket, apiConfig); return fetchBasket(basket.getId()); } public Basket fetchBasket(String id) throws HttpCommunicationException { String response; + boolean isUUID = isUUIDResource(id); + ApiConfig apiConfig = isUUID ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; try { // Try fetch Basket version 2 // basket v2 has totalvaluegross. this object is not sent to api - Basket basket = new Basket() - .setId(id) + Basket basket = isUUID ? new BasketV3() : new Basket(); + basket.setId(id) .setTotalValueGross(BigDecimal.ONE); response = restCommunication.httpGet( urlUtil.getUrl(basket), - unzer.getPrivateKey() + unzer.getPrivateKey(), + apiConfig ); } catch (PaymentException ex) { // ... or Basket version 1 - if (ex.getStatusCode() == 404) { // not found + if (ex.getStatusCode() == 404 && !isUUID) { // not found response = restCommunication.httpGet( urlUtil.getUrl(new Basket().setId(id)), unzer.getPrivateKey() @@ -445,10 +455,17 @@ public Metadata fetchMetadata(String id) throws HttpCommunicationException { } public Basket createBasket(Basket basket) throws HttpCommunicationException { + ApiConfig apiConfig = basket instanceof BasketV3 ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; + String authentication = unzer.getPrivateKey(); + if (apiConfig.getAuthMethod() == ApiConfig.AuthMethod.BEARER) { + unzer.prepareJwtToken(); + authentication = unzer.getJwtToken(); + } String response = restCommunication.httpPost( urlUtil.getUrl(basket), - unzer.getPrivateKey(), - basket + authentication, + basket, + apiConfig ); Basket jsonBasket = jsonParser.fromJson(response, Basket.class); basket.setId(jsonBasket.getId()); diff --git a/src/test/java/com/unzer/payment/business/BasketV3Test.java b/src/test/java/com/unzer/payment/business/BasketV3Test.java new file mode 100644 index 00000000..a06c1e40 --- /dev/null +++ b/src/test/java/com/unzer/payment/business/BasketV3Test.java @@ -0,0 +1,111 @@ +package com.unzer.payment.business; + + +import com.unzer.payment.Authorization; +import com.unzer.payment.Basket; +import com.unzer.payment.Charge; +import com.unzer.payment.Payment; +import com.unzer.payment.Unzer; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; + +import static com.unzer.payment.business.BasketV3TestData.getMaxTestBasketV3; +import static com.unzer.payment.business.BasketV3TestData.getMinTestBasketV3; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class BasketV3Test extends AbstractPaymentTest { + @Test + void testCreateFetchBasket() { + Basket maxBasket = getMaxTestBasketV3(); + Basket basket = getUnzer().createBasket(maxBasket); + Basket basketFetched = getUnzer().fetchBasket(basket.getId()); + assertNotNull(basketFetched); + assertNotNull(basketFetched.getId()); + assertBasketEquals(maxBasket, basketFetched); + } + + private void assertBasketEquals(Basket expected, Basket actual) { + assertThat(expected) + .usingComparatorForType(BigDecimal::compareTo, BigDecimal.class) + .usingRecursiveComparison() + .isEqualTo(actual); + } + + @Test + void testCreateFetchMinBasket() { + Basket minBasket = getMinTestBasketV3(); + Basket basket = getUnzer().createBasket(minBasket); + Basket basketFetched = getUnzer().fetchBasket(basket.getId()); + assertNotNull(basketFetched); + assertNotNull(basketFetched.getId()); + assertBasketEquals(minBasket, basketFetched); + } + + @Test + void testUpdateBasket() { + Basket minBasket = getMinTestBasketV3(); + Basket basket = getUnzer().createBasket(minBasket); + Basket basketFetched = getUnzer().fetchBasket(basket.getId()); + Basket maxBasket = getMaxTestBasketV3(); + maxBasket.setOrderId(basket.getOrderId()); + Basket updatedBasket = getUnzer().updateBasket(maxBasket, basket.getId()); + assertNotNull(basketFetched); + assertNotNull(basketFetched.getId()); + + maxBasket.setId(basket.getId()); + assertBasketEquals(maxBasket, updatedBasket); + } + + @Test + void testUpdateBasketWithFetched() { + Basket minBasket = getMinTestBasketV3(); + Basket basket = getUnzer().createBasket(minBasket); + Basket basketFetched = getUnzer().fetchBasket(basket.getId()); + Basket updatedBasket = getUnzer().updateBasket(basketFetched, basket.getId()); + assertNotNull(basketFetched); + assertNotNull(basketFetched.getId()); + assertBasketEquals(basketFetched, updatedBasket); + } + + @Test + void testAuthorizationWithBasket() { + Unzer unzer = getUnzer(); + Basket basket = unzer.createBasket(getMaxTestBasketV3()); + Authorization authorization = getAuthorization( + createPaymentTypeCard(unzer, "4711100000000000").getId(), + null, + null, + null, + basket.getId() + ); + authorization.setAmount(BigDecimal.valueOf(684.47)); + Authorization authorize = unzer.authorize(authorization); + Payment payment = unzer.fetchPayment(authorize.getPayment().getId()); + assertNotNull(payment); + assertNotNull(payment.getId()); + assertNotNull(payment.getAuthorization()); + assertNotNull(payment.getAuthorization().getId()); + assertEquals(basket.getId(), payment.getBasketId()); + assertEquals(basket.getId(), payment.getAuthorization().getBasketId()); + } + + @Test + void testChargeWithBasket() { + Basket basket = getUnzer().createBasket(getMaxTestBasketV3()); + Charge chargeReq = + getCharge(createPaymentTypeCard(getUnzer(), "4711100000000000").getId(), null, null, null, + basket.getId(), null); + chargeReq.setAmount(BigDecimal.valueOf(684.47)); + Charge charge = getUnzer().charge(chargeReq); + Payment payment = getUnzer().fetchPayment(charge.getPayment().getId()); + assertNotNull(payment); + assertNotNull(payment.getId()); + assertNotNull(payment.getCharge(0)); + assertNotNull(payment.getCharge(0).getId()); + assertEquals(basket.getId(), payment.getBasketId()); + assertEquals(basket.getId(), payment.getCharge(0).getBasketId()); + } +} diff --git a/src/test/java/com/unzer/payment/business/BasketV3TestData.java b/src/test/java/com/unzer/payment/business/BasketV3TestData.java new file mode 100644 index 00000000..3f4e8108 --- /dev/null +++ b/src/test/java/com/unzer/payment/business/BasketV3TestData.java @@ -0,0 +1,79 @@ +package com.unzer.payment.business; + +import com.unzer.payment.Basket; +import com.unzer.payment.BasketItem; +import com.unzer.payment.BasketV3; + +import java.math.BigDecimal; +import java.util.Currency; + +import static com.unzer.payment.util.Types.unsafeUrl; +import static com.unzer.payment.util.Uuid.generateUuid; + +public class BasketV3TestData { + public static Basket getMaxTestBasketV3() { + return new BasketV3() + .setTotalValueGross(new BigDecimal("380.48")) + .setCurrencyCode(Currency.getInstance("EUR")) + .setOrderId(generateUuid()) + .addBasketItem(getMaxTestBasketItem1V2()) // 14.48 - 1.0 + .addBasketItem(getMaxTestBasketItem2V2()); // 366 // 122 * 3 + } + + public static BasketItem getMaxTestBasketItem2V2() { + return new BasketItem() + .setBasketItemReferenceId("Artikelnummer4712") + .setAmountPerUnitGross(new BigDecimal("122")) + .setQuantity(3) + .setTitle("Apple iPad Air") + .setUnit("Pc.") + .setAmountDiscountPerUnitGross(BigDecimal.ZERO) + .setVat(BigDecimal.valueOf(20)) + .setSubTitle("Nicht nur Pros brauchen Power.") + .setType(BasketItem.Type.GOODS) + .setImageUrl(unsafeUrl("https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-12-pro-family-hero")); + } + + + public static BasketItem getMaxTestBasketItem1V2() { + return new BasketItem() + .setBasketItemReferenceId("Artikelnummer4711") + .setAmountPerUnitGross(new BigDecimal("24.48")) + .setAmountDiscountPerUnitGross(BigDecimal.TEN) + .setQuantity(1) + .setTitle("Apple iPhone") + .setUnit("Pc.") + .setVat(BigDecimal.valueOf(19)) + .setSubTitle("XS in Red").setType(BasketItem.Type.GOODS) + .setImageUrl(unsafeUrl("https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-12-pro-family-hero")); + } + + public static Basket getMaxTestBasketV3(BigDecimal amount) { + return new BasketV3() + .setTotalValueGross(amount) + .setCurrencyCode(Currency.getInstance("EUR")) + .setOrderId(generateUuid()) + .addBasketItem(getMaxTestBasketItem1V2()) + .addBasketItem(getMaxTestBasketItem2V2()); + } + + + public static BasketItem getMinTestBasketItemV2() { + return new BasketItem() + .setBasketItemReferenceId("Artikelnummer4711") + .setQuantity(5) + .setVat(BigDecimal.ZERO) + .setAmountDiscountPerUnitGross(BigDecimal.ZERO) + .setAmountPerUnitGross(new BigDecimal("100.1")) + .setTitle("Apple iPhone"); + } + + + public static Basket getMinTestBasketV3() { + return new BasketV3() + .setTotalValueGross(new BigDecimal("500.5")) + .setCurrencyCode(Currency.getInstance("EUR")) + .setOrderId(generateUuid()) + .addBasketItem(getMinTestBasketItemV2()); + } +} From 27dfe08c0d5a500e5cf03778b9d58086631a4507 Mon Sep 17 00:00:00 2001 From: "david.owusu" Date: Tue, 25 Feb 2025 15:14:53 +0100 Subject: [PATCH 4/6] [CC-2019] [CC-2019] cleanup redundant tests --- src/main/java/com/unzer/payment/Basket.java | 4 ++ .../unzer/payment/business/BasketV3Test.java | 55 +++---------------- 2 files changed, 11 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/unzer/payment/Basket.java b/src/main/java/com/unzer/payment/Basket.java index 889ecd78..47dfec0a 100644 --- a/src/main/java/com/unzer/payment/Basket.java +++ b/src/main/java/com/unzer/payment/Basket.java @@ -1,11 +1,14 @@ package com.unzer.payment; +import lombok.EqualsAndHashCode; + import java.math.BigDecimal; import java.util.ArrayList; import java.util.Currency; import java.util.List; import java.util.Objects; +@EqualsAndHashCode(callSuper = false) public class Basket extends BaseResource implements Resource { private String id; @@ -147,6 +150,7 @@ public Basket setAmountTotalGross(BigDecimal amountTotalGross) { } @Override + @EqualsAndHashCode.Include protected String getResourceUrl() { return Objects.isNull(this.totalValueGross) ? "/v1/baskets/" diff --git a/src/test/java/com/unzer/payment/business/BasketV3Test.java b/src/test/java/com/unzer/payment/business/BasketV3Test.java index a06c1e40..34b69be9 100644 --- a/src/test/java/com/unzer/payment/business/BasketV3Test.java +++ b/src/test/java/com/unzer/payment/business/BasketV3Test.java @@ -1,11 +1,8 @@ package com.unzer.payment.business; - -import com.unzer.payment.Authorization; import com.unzer.payment.Basket; import com.unzer.payment.Charge; import com.unzer.payment.Payment; -import com.unzer.payment.Unzer; import org.junit.jupiter.api.Test; import java.math.BigDecimal; @@ -27,20 +24,11 @@ void testCreateFetchBasket() { assertBasketEquals(maxBasket, basketFetched); } - private void assertBasketEquals(Basket expected, Basket actual) { - assertThat(expected) - .usingComparatorForType(BigDecimal::compareTo, BigDecimal.class) - .usingRecursiveComparison() - .isEqualTo(actual); - } - @Test void testCreateFetchMinBasket() { Basket minBasket = getMinTestBasketV3(); Basket basket = getUnzer().createBasket(minBasket); Basket basketFetched = getUnzer().fetchBasket(basket.getId()); - assertNotNull(basketFetched); - assertNotNull(basketFetched.getId()); assertBasketEquals(minBasket, basketFetched); } @@ -48,50 +36,14 @@ void testCreateFetchMinBasket() { void testUpdateBasket() { Basket minBasket = getMinTestBasketV3(); Basket basket = getUnzer().createBasket(minBasket); - Basket basketFetched = getUnzer().fetchBasket(basket.getId()); Basket maxBasket = getMaxTestBasketV3(); maxBasket.setOrderId(basket.getOrderId()); Basket updatedBasket = getUnzer().updateBasket(maxBasket, basket.getId()); - assertNotNull(basketFetched); - assertNotNull(basketFetched.getId()); maxBasket.setId(basket.getId()); assertBasketEquals(maxBasket, updatedBasket); } - @Test - void testUpdateBasketWithFetched() { - Basket minBasket = getMinTestBasketV3(); - Basket basket = getUnzer().createBasket(minBasket); - Basket basketFetched = getUnzer().fetchBasket(basket.getId()); - Basket updatedBasket = getUnzer().updateBasket(basketFetched, basket.getId()); - assertNotNull(basketFetched); - assertNotNull(basketFetched.getId()); - assertBasketEquals(basketFetched, updatedBasket); - } - - @Test - void testAuthorizationWithBasket() { - Unzer unzer = getUnzer(); - Basket basket = unzer.createBasket(getMaxTestBasketV3()); - Authorization authorization = getAuthorization( - createPaymentTypeCard(unzer, "4711100000000000").getId(), - null, - null, - null, - basket.getId() - ); - authorization.setAmount(BigDecimal.valueOf(684.47)); - Authorization authorize = unzer.authorize(authorization); - Payment payment = unzer.fetchPayment(authorize.getPayment().getId()); - assertNotNull(payment); - assertNotNull(payment.getId()); - assertNotNull(payment.getAuthorization()); - assertNotNull(payment.getAuthorization().getId()); - assertEquals(basket.getId(), payment.getBasketId()); - assertEquals(basket.getId(), payment.getAuthorization().getBasketId()); - } - @Test void testChargeWithBasket() { Basket basket = getUnzer().createBasket(getMaxTestBasketV3()); @@ -108,4 +60,11 @@ void testChargeWithBasket() { assertEquals(basket.getId(), payment.getBasketId()); assertEquals(basket.getId(), payment.getCharge(0).getBasketId()); } + + private void assertBasketEquals(Basket expected, Basket actual) { + assertThat(expected) + .usingComparatorForType(BigDecimal::compareTo, BigDecimal.class) + .usingRecursiveComparison() + .isEqualTo(actual); + } } From 07628a29e45ee70ed5cb38296de5b5d5cda7d783 Mon Sep 17 00:00:00 2001 From: "david.owusu" Date: Tue, 1 Apr 2025 16:19:28 +0200 Subject: [PATCH 5/6] [CC-2019] Fix authentication for new resources. --- .../unzer/payment/service/PaymentService.java | 125 +++--------------- .../unzer/payment/business/BasketV3Test.java | 3 +- .../payment/business/CustomerV2Test.java | 25 ++-- ...2BaseTest.java => BearerAuthBaseTest.java} | 2 +- .../integration/resources/LinkpayV2Test.java | 2 +- .../integration/resources/PaypageV2Test.java | 2 +- 6 files changed, 39 insertions(+), 120 deletions(-) rename src/test/java/com/unzer/payment/integration/resources/{PaypageV2BaseTest.java => BearerAuthBaseTest.java} (94%) diff --git a/src/main/java/com/unzer/payment/service/PaymentService.java b/src/main/java/com/unzer/payment/service/PaymentService.java index 73f5763d..d18a9351 100644 --- a/src/main/java/com/unzer/payment/service/PaymentService.java +++ b/src/main/java/com/unzer/payment/service/PaymentService.java @@ -1,101 +1,23 @@ package com.unzer.payment.service; -import com.unzer.payment.Authorization; -import com.unzer.payment.BasePayment; -import com.unzer.payment.Basket; -import com.unzer.payment.BasketV3; -import com.unzer.payment.Cancel; -import com.unzer.payment.Charge; -import com.unzer.payment.Chargeback; -import com.unzer.payment.Customer; -import com.unzer.payment.CustomerV2; -import com.unzer.payment.Metadata; -import com.unzer.payment.PaylaterInstallmentPlans; -import com.unzer.payment.Payment; -import com.unzer.payment.PaymentException; -import com.unzer.payment.Payout; -import com.unzer.payment.Preauthorization; -import com.unzer.payment.Recurring; -import com.unzer.payment.Shipment; -import com.unzer.payment.Unzer; -import com.unzer.payment.business.paymenttypes.HirePurchaseDirectDebit; -import com.unzer.payment.business.paymenttypes.InstallmentSecuredRatePlan; -import com.unzer.payment.business.paymenttypes.InvoiceFactoring; -import com.unzer.payment.business.paymenttypes.InvoiceGuaranteed; -import com.unzer.payment.business.paymenttypes.SepaDirectDebitGuaranteed; +import com.unzer.payment.*; +import com.unzer.payment.business.paymenttypes.*; import com.unzer.payment.communication.HttpCommunicationException; import com.unzer.payment.communication.JsonParser; import com.unzer.payment.communication.UnzerRestCommunication; import com.unzer.payment.communication.api.ApiConfig; import com.unzer.payment.communication.api.ApiConfigs; -import com.unzer.payment.communication.json.ApiApplepayResponse; -import com.unzer.payment.communication.json.ApiAuthorization; -import com.unzer.payment.communication.json.ApiBancontact; -import com.unzer.payment.communication.json.ApiCancel; -import com.unzer.payment.communication.json.ApiCard; -import com.unzer.payment.communication.json.ApiCharge; -import com.unzer.payment.communication.json.ApiChargeback; -import com.unzer.payment.communication.json.ApiCustomer; -import com.unzer.payment.communication.json.ApiIdObject; -import com.unzer.payment.communication.json.ApiIdeal; -import com.unzer.payment.communication.json.ApiInstallmentSecuredRatePlan; -import com.unzer.payment.communication.json.ApiObject; -import com.unzer.payment.communication.json.ApiOpenBanking; -import com.unzer.payment.communication.json.ApiPaylaterInstallment; -import com.unzer.payment.communication.json.ApiPayment; -import com.unzer.payment.communication.json.ApiPayout; -import com.unzer.payment.communication.json.ApiPaypal; -import com.unzer.payment.communication.json.ApiPis; -import com.unzer.payment.communication.json.ApiRecurring; -import com.unzer.payment.communication.json.ApiSepaDirectDebit; -import com.unzer.payment.communication.json.ApiShipment; -import com.unzer.payment.communication.json.ApiTransaction; -import com.unzer.payment.communication.json.JsonInstallmentSecuredRatePlanList; +import com.unzer.payment.communication.json.*; import com.unzer.payment.communication.json.paylater.ApiInstallmentPlans; import com.unzer.payment.communication.mapper.ApiToSdkConverter; import com.unzer.payment.models.PaylaterInvoiceConfig; import com.unzer.payment.models.PaylaterInvoiceConfigRequest; import com.unzer.payment.models.paylater.InstallmentPlansRequest; -import com.unzer.payment.paymenttypes.Alipay; -import com.unzer.payment.paymenttypes.Applepay; -import com.unzer.payment.paymenttypes.Bancontact; -import com.unzer.payment.paymenttypes.BasePaymentType; -import com.unzer.payment.paymenttypes.Card; -import com.unzer.payment.paymenttypes.ClickToPay; -import com.unzer.payment.paymenttypes.Eps; -import com.unzer.payment.paymenttypes.Giropay; -import com.unzer.payment.paymenttypes.GooglePay; -import com.unzer.payment.paymenttypes.Ideal; -import com.unzer.payment.paymenttypes.Invoice; -import com.unzer.payment.paymenttypes.InvoiceSecured; -import com.unzer.payment.paymenttypes.Klarna; -import com.unzer.payment.paymenttypes.OpenBanking; -import com.unzer.payment.paymenttypes.PayU; -import com.unzer.payment.paymenttypes.PaylaterDirectDebit; -import com.unzer.payment.paymenttypes.PaylaterInstallment; -import com.unzer.payment.paymenttypes.PaylaterInvoice; -import com.unzer.payment.paymenttypes.PaymentType; -import com.unzer.payment.paymenttypes.PaymentTypeEnum; -import com.unzer.payment.paymenttypes.Paypal; -import com.unzer.payment.paymenttypes.Pis; -import com.unzer.payment.paymenttypes.PostFinanceCard; -import com.unzer.payment.paymenttypes.PostFinanceEFinance; -import com.unzer.payment.paymenttypes.Prepayment; -import com.unzer.payment.paymenttypes.Przelewy24; -import com.unzer.payment.paymenttypes.SepaDirectDebit; -import com.unzer.payment.paymenttypes.SepaDirectDebitSecured; -import com.unzer.payment.paymenttypes.Sofort; -import com.unzer.payment.paymenttypes.Twint; -import com.unzer.payment.paymenttypes.Wechatpay; +import com.unzer.payment.paymenttypes.*; import java.math.BigDecimal; import java.net.URL; -import java.util.ArrayList; -import java.util.Currency; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -327,15 +249,11 @@ public T updatePaymentType(T paymentType) public Customer createCustomer(Customer customer) throws HttpCommunicationException { ApiConfig apiConfig = customer instanceof CustomerV2 ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; - String authentication = unzer.getPrivateKey(); - if (apiConfig.getAuthMethod() == ApiConfig.AuthMethod.BEARER) { - unzer.prepareJwtToken(); - authentication = unzer.getJwtToken(); - } + String response = restCommunication.httpPost( urlUtil.getUrl(customer), - authentication, + getAuthentication(apiConfig), apiToSdkMapper.map(customer), apiConfig ); @@ -371,11 +289,7 @@ private static boolean isUUIDResource(String customerId) { public Customer updateCustomer(String id, Customer customer) throws HttpCommunicationException { ApiConfig apiConfig = customer instanceof CustomerV2 ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; - String authentication = unzer.getPrivateKey(); - if (apiConfig.getAuthMethod() == ApiConfig.AuthMethod.BEARER) { - unzer.prepareJwtToken(); - authentication = unzer.getJwtToken(); - } + String authentication = getAuthentication(apiConfig); customer.setId(id); restCommunication.httpPut( urlUtil.getUrl(customer), @@ -388,12 +302,7 @@ public Customer updateCustomer(String id, Customer customer) throws HttpCommunic public Basket updateBasket(Basket basket) throws HttpCommunicationException { ApiConfig apiConfig = basket instanceof BasketV3 ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; - String authentication = unzer.getPrivateKey(); - if (apiConfig.getAuthMethod() == ApiConfig.AuthMethod.BEARER) { - unzer.prepareJwtToken(); - authentication = unzer.getJwtToken(); - } - restCommunication.httpPut(urlUtil.getUrl(basket), authentication, basket, apiConfig); + restCommunication.httpPut(urlUtil.getUrl(basket), getAuthentication(apiConfig), basket, apiConfig); return fetchBasket(basket.getId()); } @@ -411,7 +320,7 @@ public Basket fetchBasket(String id) throws HttpCommunicationException { .setTotalValueGross(BigDecimal.ONE); response = restCommunication.httpGet( urlUtil.getUrl(basket), - unzer.getPrivateKey(), + getAuthentication(apiConfig), apiConfig ); } catch (PaymentException ex) { @@ -913,14 +822,13 @@ public String deleteCustomer(String customerId) throws HttpCommunicationExceptio boolean isV2Id = isUUIDResource(customerId); ApiConfig apiConfig = isV2Id ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; Customer customer = isV2Id ? new CustomerV2("", "") : new Customer("", ""); - String authentication = isV2Id ? unzer.getJwtToken() : unzer.getPrivateKey(); - customer.setId(customerId); customer.setCustomerId(customerId); + String response = restCommunication.httpDelete( urlUtil.getUrl(customer), - authentication, + getAuthentication(apiConfig), apiConfig ); if (response == null || response.isEmpty()) { @@ -930,6 +838,15 @@ public String deleteCustomer(String customerId) throws HttpCommunicationExceptio return idResponse.getId(); } + private String getAuthentication(ApiConfig apiConfig) { + String authentication = unzer.getPrivateKey(); + if (apiConfig.getAuthMethod() == ApiConfig.AuthMethod.BEARER) { + unzer.prepareJwtToken(); + authentication = unzer.getJwtToken(); + } + return authentication; + } + public Authorization fetchAuthorization(String paymentId) throws HttpCommunicationException { return fetchPayment(paymentId).getAuthorization(); } diff --git a/src/test/java/com/unzer/payment/business/BasketV3Test.java b/src/test/java/com/unzer/payment/business/BasketV3Test.java index 34b69be9..e05df424 100644 --- a/src/test/java/com/unzer/payment/business/BasketV3Test.java +++ b/src/test/java/com/unzer/payment/business/BasketV3Test.java @@ -3,6 +3,7 @@ import com.unzer.payment.Basket; import com.unzer.payment.Charge; import com.unzer.payment.Payment; +import com.unzer.payment.integration.resources.BearerAuthBaseTest; import org.junit.jupiter.api.Test; import java.math.BigDecimal; @@ -13,7 +14,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -public class BasketV3Test extends AbstractPaymentTest { +class BasketV3Test extends BearerAuthBaseTest { @Test void testCreateFetchBasket() { Basket maxBasket = getMaxTestBasketV3(); diff --git a/src/test/java/com/unzer/payment/business/CustomerV2Test.java b/src/test/java/com/unzer/payment/business/CustomerV2Test.java index cafd7192..59becf9e 100644 --- a/src/test/java/com/unzer/payment/business/CustomerV2Test.java +++ b/src/test/java/com/unzer/payment/business/CustomerV2Test.java @@ -4,17 +4,16 @@ import com.unzer.payment.Customer; import com.unzer.payment.CustomerV2; import com.unzer.payment.PaymentException; +import com.unzer.payment.Unzer; +import com.unzer.payment.integration.resources.BearerAuthBaseTest; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; -class CustomerV2Test extends AbstractPaymentTest { +class CustomerV2Test extends BearerAuthBaseTest { @Test void testCreateMinimumCustomer() { - Customer customer = getUnzer().createCustomer(new CustomerV2("firstname", "lastname")); + Customer customer = getUnzer().createCustomer(new CustomerV2("Max", "Mustermann")); assertNotNull(customer); assertNotNull(customer.getId()); assertEquals(getMinimumCustomer().getFirstname(), customer.getFirstname()); @@ -58,21 +57,23 @@ void testUpdateCustomer() { @Test void testDeleteCustomer() { - Customer customer = getUnzer().createCustomer(initV2Customer()); - String deletedCustomerId = getUnzer().deleteCustomer(customer.getId()); + Unzer unzer = getUnzer(); + Customer customer = unzer.createCustomer(initV2Customer()); + String deletedCustomerId = unzer.deleteCustomer(customer.getId()); assertEquals(customer.getId(), deletedCustomerId); assertThrows(PaymentException.class, () -> { - getUnzer().fetchCustomer(deletedCustomerId); + unzer.fetchCustomer(deletedCustomerId); }, "Fetching deleted customer should cause PaymentException"); } @Test void testCreateCustomerWithException() { + Customer customerRequest = new CustomerV2("User", "Test"); + customerRequest.setId("s-cst-abcdef"); + Unzer unzer = getUnzer(); assertThrows(PaymentException.class, () -> { - Customer customerRequest = new CustomerV2("User", "Test"); - customerRequest.setId("s-cst-abcdef"); - getUnzer().createCustomer(customerRequest); + unzer.createCustomer(customerRequest); }); } } diff --git a/src/test/java/com/unzer/payment/integration/resources/PaypageV2BaseTest.java b/src/test/java/com/unzer/payment/integration/resources/BearerAuthBaseTest.java similarity index 94% rename from src/test/java/com/unzer/payment/integration/resources/PaypageV2BaseTest.java rename to src/test/java/com/unzer/payment/integration/resources/BearerAuthBaseTest.java index f49b56e1..dd45585e 100644 --- a/src/test/java/com/unzer/payment/integration/resources/PaypageV2BaseTest.java +++ b/src/test/java/com/unzer/payment/integration/resources/BearerAuthBaseTest.java @@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @TestInstance(TestInstance.Lifecycle.PER_CLASS) -abstract class PaypageV2BaseTest extends AbstractPaymentTest { +public abstract class BearerAuthBaseTest extends AbstractPaymentTest { protected Unzer unzer; @BeforeAll diff --git a/src/test/java/com/unzer/payment/integration/resources/LinkpayV2Test.java b/src/test/java/com/unzer/payment/integration/resources/LinkpayV2Test.java index f03b423c..52390583 100644 --- a/src/test/java/com/unzer/payment/integration/resources/LinkpayV2Test.java +++ b/src/test/java/com/unzer/payment/integration/resources/LinkpayV2Test.java @@ -14,7 +14,7 @@ /** * Paypage V2 Test for linkpay specific features. */ -class LinkpayV2Test extends PaypageV2BaseTest { +class LinkpayV2Test extends BearerAuthBaseTest { @Test void minimumLinkpayCreation() { diff --git a/src/test/java/com/unzer/payment/integration/resources/PaypageV2Test.java b/src/test/java/com/unzer/payment/integration/resources/PaypageV2Test.java index 7ebe82ef..444a355b 100644 --- a/src/test/java/com/unzer/payment/integration/resources/PaypageV2Test.java +++ b/src/test/java/com/unzer/payment/integration/resources/PaypageV2Test.java @@ -20,7 +20,7 @@ import static org.junit.jupiter.api.Assertions.*; -class PaypageV2Test extends PaypageV2BaseTest { +class PaypageV2Test extends BearerAuthBaseTest { @Test void minimumPaypageCreation() { From 1364b9efbef00135695fb7eaa36ad8bc3f671750 Mon Sep 17 00:00:00 2001 From: "david.owusu" Date: Mon, 7 Apr 2025 17:48:17 +0200 Subject: [PATCH 6/6] [CC-2019] Fix Review comments. --- .../unzer/payment/service/PaymentService.java | 100 +++++++++++++++--- .../unzer/payment/business/BasketV3Test.java | 16 ++- 2 files changed, 101 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/unzer/payment/service/PaymentService.java b/src/main/java/com/unzer/payment/service/PaymentService.java index d18a9351..29f64956 100644 --- a/src/main/java/com/unzer/payment/service/PaymentService.java +++ b/src/main/java/com/unzer/payment/service/PaymentService.java @@ -1,23 +1,101 @@ package com.unzer.payment.service; -import com.unzer.payment.*; -import com.unzer.payment.business.paymenttypes.*; +import com.unzer.payment.Authorization; +import com.unzer.payment.BasePayment; +import com.unzer.payment.Basket; +import com.unzer.payment.BasketV3; +import com.unzer.payment.Cancel; +import com.unzer.payment.Charge; +import com.unzer.payment.Chargeback; +import com.unzer.payment.Customer; +import com.unzer.payment.CustomerV2; +import com.unzer.payment.Metadata; +import com.unzer.payment.PaylaterInstallmentPlans; +import com.unzer.payment.Payment; +import com.unzer.payment.PaymentException; +import com.unzer.payment.Payout; +import com.unzer.payment.Preauthorization; +import com.unzer.payment.Recurring; +import com.unzer.payment.Shipment; +import com.unzer.payment.Unzer; +import com.unzer.payment.business.paymenttypes.HirePurchaseDirectDebit; +import com.unzer.payment.business.paymenttypes.InstallmentSecuredRatePlan; +import com.unzer.payment.business.paymenttypes.InvoiceFactoring; +import com.unzer.payment.business.paymenttypes.InvoiceGuaranteed; +import com.unzer.payment.business.paymenttypes.SepaDirectDebitGuaranteed; import com.unzer.payment.communication.HttpCommunicationException; import com.unzer.payment.communication.JsonParser; import com.unzer.payment.communication.UnzerRestCommunication; import com.unzer.payment.communication.api.ApiConfig; import com.unzer.payment.communication.api.ApiConfigs; -import com.unzer.payment.communication.json.*; +import com.unzer.payment.communication.json.ApiApplepayResponse; +import com.unzer.payment.communication.json.ApiAuthorization; +import com.unzer.payment.communication.json.ApiBancontact; +import com.unzer.payment.communication.json.ApiCancel; +import com.unzer.payment.communication.json.ApiCard; +import com.unzer.payment.communication.json.ApiCharge; +import com.unzer.payment.communication.json.ApiChargeback; +import com.unzer.payment.communication.json.ApiCustomer; +import com.unzer.payment.communication.json.ApiIdObject; +import com.unzer.payment.communication.json.ApiIdeal; +import com.unzer.payment.communication.json.ApiInstallmentSecuredRatePlan; +import com.unzer.payment.communication.json.ApiObject; +import com.unzer.payment.communication.json.ApiOpenBanking; +import com.unzer.payment.communication.json.ApiPaylaterInstallment; +import com.unzer.payment.communication.json.ApiPayment; +import com.unzer.payment.communication.json.ApiPayout; +import com.unzer.payment.communication.json.ApiPaypal; +import com.unzer.payment.communication.json.ApiPis; +import com.unzer.payment.communication.json.ApiRecurring; +import com.unzer.payment.communication.json.ApiSepaDirectDebit; +import com.unzer.payment.communication.json.ApiShipment; +import com.unzer.payment.communication.json.ApiTransaction; +import com.unzer.payment.communication.json.JsonInstallmentSecuredRatePlanList; import com.unzer.payment.communication.json.paylater.ApiInstallmentPlans; import com.unzer.payment.communication.mapper.ApiToSdkConverter; import com.unzer.payment.models.PaylaterInvoiceConfig; import com.unzer.payment.models.PaylaterInvoiceConfigRequest; import com.unzer.payment.models.paylater.InstallmentPlansRequest; -import com.unzer.payment.paymenttypes.*; +import com.unzer.payment.paymenttypes.Alipay; +import com.unzer.payment.paymenttypes.Applepay; +import com.unzer.payment.paymenttypes.Bancontact; +import com.unzer.payment.paymenttypes.BasePaymentType; +import com.unzer.payment.paymenttypes.Card; +import com.unzer.payment.paymenttypes.ClickToPay; +import com.unzer.payment.paymenttypes.Eps; +import com.unzer.payment.paymenttypes.Giropay; +import com.unzer.payment.paymenttypes.GooglePay; +import com.unzer.payment.paymenttypes.Ideal; +import com.unzer.payment.paymenttypes.Invoice; +import com.unzer.payment.paymenttypes.InvoiceSecured; +import com.unzer.payment.paymenttypes.Klarna; +import com.unzer.payment.paymenttypes.OpenBanking; +import com.unzer.payment.paymenttypes.PayU; +import com.unzer.payment.paymenttypes.PaylaterDirectDebit; +import com.unzer.payment.paymenttypes.PaylaterInstallment; +import com.unzer.payment.paymenttypes.PaylaterInvoice; +import com.unzer.payment.paymenttypes.PaymentType; +import com.unzer.payment.paymenttypes.PaymentTypeEnum; +import com.unzer.payment.paymenttypes.Paypal; +import com.unzer.payment.paymenttypes.Pis; +import com.unzer.payment.paymenttypes.PostFinanceCard; +import com.unzer.payment.paymenttypes.PostFinanceEFinance; +import com.unzer.payment.paymenttypes.Prepayment; +import com.unzer.payment.paymenttypes.Przelewy24; +import com.unzer.payment.paymenttypes.SepaDirectDebit; +import com.unzer.payment.paymenttypes.SepaDirectDebitSecured; +import com.unzer.payment.paymenttypes.Sofort; +import com.unzer.payment.paymenttypes.Twint; +import com.unzer.payment.paymenttypes.Wechatpay; import java.math.BigDecimal; import java.net.URL; -import java.util.*; +import java.util.ArrayList; +import java.util.Currency; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -312,10 +390,9 @@ public Basket fetchBasket(String id) throws HttpCommunicationException { ApiConfig apiConfig = isUUID ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; try { - // Try fetch Basket version 2 - - // basket v2 has totalvaluegross. this object is not sent to api + // Try fetch Basket version 2 or 3 Basket basket = isUUID ? new BasketV3() : new Basket(); + // basket v2 has totalvaluegross. this object is not sent to api basket.setId(id) .setTotalValueGross(BigDecimal.ONE); response = restCommunication.httpGet( @@ -366,14 +443,9 @@ public Metadata fetchMetadata(String id) throws HttpCommunicationException { public Basket createBasket(Basket basket) throws HttpCommunicationException { ApiConfig apiConfig = basket instanceof BasketV3 ? ApiConfigs.PAYMENT_API_BEARER_AUTH : ApiConfigs.PAYMENT_API; - String authentication = unzer.getPrivateKey(); - if (apiConfig.getAuthMethod() == ApiConfig.AuthMethod.BEARER) { - unzer.prepareJwtToken(); - authentication = unzer.getJwtToken(); - } String response = restCommunication.httpPost( urlUtil.getUrl(basket), - authentication, + getAuthentication(apiConfig), basket, apiConfig ); diff --git a/src/test/java/com/unzer/payment/business/BasketV3Test.java b/src/test/java/com/unzer/payment/business/BasketV3Test.java index e05df424..80a6b4fb 100644 --- a/src/test/java/com/unzer/payment/business/BasketV3Test.java +++ b/src/test/java/com/unzer/payment/business/BasketV3Test.java @@ -19,7 +19,11 @@ class BasketV3Test extends BearerAuthBaseTest { void testCreateFetchBasket() { Basket maxBasket = getMaxTestBasketV3(); Basket basket = getUnzer().createBasket(maxBasket); + + // when Basket basketFetched = getUnzer().fetchBasket(basket.getId()); + + // then assertNotNull(basketFetched); assertNotNull(basketFetched.getId()); assertBasketEquals(maxBasket, basketFetched); @@ -29,7 +33,11 @@ void testCreateFetchBasket() { void testCreateFetchMinBasket() { Basket minBasket = getMinTestBasketV3(); Basket basket = getUnzer().createBasket(minBasket); + + // when Basket basketFetched = getUnzer().fetchBasket(basket.getId()); + + // then assertBasketEquals(minBasket, basketFetched); } @@ -39,9 +47,11 @@ void testUpdateBasket() { Basket basket = getUnzer().createBasket(minBasket); Basket maxBasket = getMaxTestBasketV3(); maxBasket.setOrderId(basket.getOrderId()); + + // when Basket updatedBasket = getUnzer().updateBasket(maxBasket, basket.getId()); - maxBasket.setId(basket.getId()); + //then assertBasketEquals(maxBasket, updatedBasket); } @@ -53,7 +63,11 @@ void testChargeWithBasket() { basket.getId(), null); chargeReq.setAmount(BigDecimal.valueOf(684.47)); Charge charge = getUnzer().charge(chargeReq); + + //when Payment payment = getUnzer().fetchPayment(charge.getPayment().getId()); + + //then assertNotNull(payment); assertNotNull(payment.getId()); assertNotNull(payment.getCharge(0));