From 048725333bc902dcf90a4669e9cec7affcdf17ad Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:22:34 +0200 Subject: [PATCH 01/29] tests: reuse global test config --- .../PaymentExecutionApiClientTest.java | 67 ++++++++++++------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClientTest.java b/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClientTest.java index 922c2dc..197f0a7 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClientTest.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClientTest.java @@ -17,7 +17,6 @@ import com.payone.commerce.platform.lib.errors.ApiErrorResponseException; import com.payone.commerce.platform.lib.errors.ApiException; import com.payone.commerce.platform.lib.errors.ApiResponseRetrievalException; -import com.payone.commerce.platform.lib.CommunicatorConfiguration; import com.payone.commerce.platform.lib.models.PaymentExecutionRequest; import com.payone.commerce.platform.lib.models.RefundPaymentResponse; import com.payone.commerce.platform.lib.models.RefundRequest; @@ -29,15 +28,11 @@ import com.payone.commerce.platform.lib.models.CompletePaymentResponse; import com.payone.commerce.platform.lib.models.CreatePaymentResponse; import com.payone.commerce.platform.lib.testutils.ApiResponseMocks; +import com.payone.commerce.platform.lib.testutils.TestConfig; import okhttp3.Response; public class PaymentExecutionApiClientTest { - private final String TEST_KEY = "KEY"; - private final String TEST_SECRET = "Super duper Ethan Hunt level secret"; - private final CommunicatorConfiguration CONFIG = new CommunicatorConfiguration(TEST_KEY, TEST_SECRET, - "awesome-api.com"); - @Nested @DisplayName("createPaymentRequest") class createPayment { @@ -45,7 +40,8 @@ class createPayment { @DisplayName("given request was successful, then return response") void createPaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CreatePaymentResponse expected = new CreatePaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new CreatePaymentResponse()); @@ -62,7 +58,8 @@ void createPaymentRequestSuccessful() throws InvalidKeyException, ApiException, @DisplayName("given request was unsuccessful (400), then throw exception") void createPaymentRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -80,7 +77,8 @@ void createPaymentRequestUnsuccessful() throws InvalidKeyException, ApiException @DisplayName("given request was unsuccessful (500) with empty body, then throw exception") void createPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -98,7 +96,8 @@ void createPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExcept @DisplayName("Given required params are null, then throw exception") void createPaymentRequestNullParams() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); PaymentExecutionRequest payload = new PaymentExecutionRequest(); IllegalArgumentException e; @@ -137,7 +136,8 @@ class CapturePayment { @DisplayName("given request was successful, then return response") void capturePaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CapturePaymentResponse expected = new CapturePaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new CapturePaymentResponse()); @@ -154,7 +154,8 @@ void capturePaymentRequestSuccessful() throws InvalidKeyException, ApiException, @DisplayName("given request unsuccessful (400), then throw exception") void capturePaymentRequestUnsuccessful400() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -172,7 +173,8 @@ void capturePaymentRequestUnsuccessful400() throws InvalidKeyException, ApiExcep @DisplayName("given request unsuccessful (500) with empty body, then throw exception") void capturePaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -190,7 +192,8 @@ void capturePaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExcep @DisplayName("Given required params are null, then throw exception") void capturePaymentRequestParamsNull() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CapturePaymentRequest payload = new CapturePaymentRequest(); IllegalArgumentException e; @@ -235,7 +238,8 @@ class CancelPayment { @DisplayName("given request was successful, then return response") void cancelPaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CancelPaymentResponse expected = new CancelPaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new CancelPayment()); @@ -252,7 +256,8 @@ void cancelPaymentRequestSuccessful() throws InvalidKeyException, ApiException, @DisplayName("given request unsuccessful (400), then throw exception") void cancelPaymentRequestUnsuccessful400() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -270,7 +275,8 @@ void cancelPaymentRequestUnsuccessful400() throws InvalidKeyException, ApiExcept @DisplayName("given request unsuccessful (500) with empty body, then throw exception") void cancelPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -288,7 +294,8 @@ void cancelPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExcept @DisplayName("Given required params are null, then throw exception") void cancelPaymentRequestParamsNull() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CancelPaymentRequest payload = new CancelPaymentRequest(); IllegalArgumentException e; @@ -333,7 +340,8 @@ class CompletePayment { @DisplayName("given request was successful, then return response") void completePaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CompletePaymentResponse expected = new CompletePaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new CompletePaymentResponse()); @@ -350,7 +358,8 @@ void completePaymentRequestSuccessful() throws InvalidKeyException, ApiException @DisplayName("given request unsuccessful (400), then throw exception") void completePaymentRequestUnsuccessful400() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -368,7 +377,8 @@ void completePaymentRequestUnsuccessful400() throws InvalidKeyException, ApiExce @DisplayName("given request unsuccessful (500) with empty body, then throw exception") void completePaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -386,7 +396,8 @@ void completePaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExce @DisplayName("Given required params are null, then throw exception") void completePaymentRequestParamsNull() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CompletePaymentRequest payload = new CompletePaymentRequest(); IllegalArgumentException e; @@ -431,7 +442,8 @@ class PaymentRefund { @DisplayName("given request was successful, then return response") void refundPaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); RefundPaymentResponse expected = new RefundPaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new RefundPaymentResponse()); @@ -448,7 +460,8 @@ void refundPaymentRequestSuccessful() throws InvalidKeyException, ApiException, @DisplayName("given request unsuccessful (400), then throw exception") void refundPaymentRequestUnsuccessful400() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -466,7 +479,8 @@ void refundPaymentRequestUnsuccessful400() throws InvalidKeyException, ApiExcept @DisplayName("given request unsuccessful (500) with empty body, then throw exception") void refundPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -484,7 +498,8 @@ void refundPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExcept @DisplayName("Given required params are null, then throw exception") void refundPaymentRequestParamsNull() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); RefundRequest payload = new RefundRequest(); IllegalArgumentException e; From 7a7a5bc58cc8380701a668b78245c36ca6e63256 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:23:04 +0200 Subject: [PATCH 02/29] feature: add integrator field to be send as part of the ServerMetaInfo --- .../com/payone/commerce/platform/app/App.java | 596 +++++++++--------- .../lib/CommunicatorConfiguration.java | 8 +- .../platform/lib/RequestHeaderGenerator.java | 2 +- .../platform/lib/utils/ServerMetaInfo.java | 11 +- .../lib/RequestHeaderGeneratorTest.java | 4 +- .../platform/lib/testutils/TestConfig.java | 2 +- 6 files changed, 330 insertions(+), 293 deletions(-) diff --git a/app/src/main/java/com/payone/commerce/platform/app/App.java b/app/src/main/java/com/payone/commerce/platform/app/App.java index e9990f4..0f2cf01 100644 --- a/app/src/main/java/com/payone/commerce/platform/app/App.java +++ b/app/src/main/java/com/payone/commerce/platform/app/App.java @@ -52,321 +52,343 @@ import com.payone.commerce.platform.lib.models.ShoppingCartInput; public class App { - private final String MERCHANT_ID; - private final CommunicatorConfiguration config; - private final CommerceCaseApiClient commerceCaseClient; - private final CheckoutApiClient checkoutClient; - private final OrderManagementCheckoutActionsApiClient orderManagementCheckoutClient; - private final PaymentExecutionApiClient paymentExecutionClient; + private final String MERCHANT_ID; + private final CommunicatorConfiguration config; + private final CommerceCaseApiClient commerceCaseClient; + private final CheckoutApiClient checkoutClient; + private final OrderManagementCheckoutActionsApiClient orderManagementCheckoutClient; + private final PaymentExecutionApiClient paymentExecutionClient; - public App(String API_KEY, String API_SECRET, String MERCHANT_ID) { - this.MERCHANT_ID = MERCHANT_ID; - this.config = new CommunicatorConfiguration(API_KEY, API_SECRET, "preprod.commerce-api.payone.com"); - try { - this.commerceCaseClient = new CommerceCaseApiClient(config); - this.checkoutClient = new CheckoutApiClient(config); - this.orderManagementCheckoutClient = new OrderManagementCheckoutActionsApiClient(config); - this.paymentExecutionClient = new PaymentExecutionApiClient(config); - } catch (InvalidKeyException e) { - throw new RuntimeException("Expected key to be valid", e); + public App(String API_KEY, String API_SECRET, String MERCHANT_ID) { + this.MERCHANT_ID = MERCHANT_ID; + this.config = new CommunicatorConfiguration(API_KEY, API_SECRET, "preprod.commerce-api.payone.com", + "YOUR_SHOP_NAME"); + try { + this.commerceCaseClient = new CommerceCaseApiClient(config); + this.checkoutClient = new CheckoutApiClient(config); + this.orderManagementCheckoutClient = new OrderManagementCheckoutActionsApiClient(config); + this.paymentExecutionClient = new PaymentExecutionApiClient(config); + } catch (InvalidKeyException e) { + throw new RuntimeException("Expected key to be valid", e); + } } - } - private static App initFromEnv() { - String apiKey = System.getenv("API_KEY"); - String apiSecret = System.getenv("API_SECRET"); - String merchantId = System.getenv("MERCHANT_ID"); + private static App initFromEnv() { + String apiKey = System.getenv("API_KEY"); + String apiSecret = System.getenv("API_SECRET"); + String merchantId = System.getenv("MERCHANT_ID"); - if (apiKey == null) { - throw new RuntimeException("required environment variable API_KEY is not set"); - } - if (apiSecret == null) { - throw new RuntimeException("required environment variable API_SECRET is not set"); - } - if (merchantId == null) { - throw new RuntimeException("required environment variable MERCHANT_ID is not set"); - } - - return new App(apiKey, apiSecret, merchantId); - } - - private void runCheckoutWithPaymentExecution(String commerceCaseMerchantReference) - throws IOException, ApiException { - // Create a commerce case, add customer data, put something into the shopping - // cart - CreateCommerceCaseRequest createCommerceCaseRequest = new CreateCommerceCaseRequest(); - - Customer customer = new Customer(); - PersonalInformation personalInformation = new PersonalInformation() - .dateOfBirth("19991112") - .name(new PersonalName().firstName("Ryan").surname("Carniato")); - ContactDetails contactDetails = new ContactDetails().emailAddress("mail@mail.com"); - Address address = new Address() - .countryCode("DE") - .zip("24937") - .city("Flensburg") - .street("Rathausplatz") - .houseNumber("1"); - customer.setPersonalInformation(personalInformation); - customer.setContactDetails(contactDetails); - customer.billingAddress(address); - - CreateCheckoutRequest checkoutRequest = new CreateCheckoutRequest(); - AmountOfMoney amountOfMoney = new AmountOfMoney() - .amount(3599L) - .currencyCode("EUR"); - Shipping shipping = new Shipping() - .address(new AddressPersonal() - .countryCode("DE") - .zip("24937") - .city("Flensburg") - .street("Rathausplatz").houseNumber("1")); - ShoppingCartInput shoppingCart = new ShoppingCartInput(); - CartItemInput cartItem = new CartItemInput() - .invoiceData(new CartItemInvoiceData() - .description("T-Shirt - Scaleshape Logo - S")) - .orderLineDetails(new OrderLineDetailsInput() - .productPrice(3599L) - .quantity(1L) - .productType(ProductType.GOODS)); - shoppingCart.addItemsItem(cartItem); + if (apiKey == null) { + throw new RuntimeException("required environment variable API_KEY is not set"); + } + if (apiSecret == null) { + throw new RuntimeException("required environment variable API_SECRET is not set"); + } + if (merchantId == null) { + throw new RuntimeException("required environment variable MERCHANT_ID is not set"); + } - checkoutRequest.amountOfMoney(amountOfMoney) - .shoppingCart(shoppingCart) - .shipping(shipping); + return new App(apiKey, apiSecret, merchantId); + } - createCommerceCaseRequest - .merchantReference(commerceCaseMerchantReference) - .customer(customer) - .checkout(checkoutRequest); + private void runCheckoutWithPaymentExecution(String commerceCaseMerchantReference) + throws IOException, ApiException { + // Create a commerce case, add customer data, put something into the shopping + // cart + CreateCommerceCaseRequest createCommerceCaseRequest = new CreateCommerceCaseRequest(); - CreateCommerceCaseResponse commerceCase = commerceCaseClient.createCommerceCaseRequest( - MERCHANT_ID, - createCommerceCaseRequest); + Customer customer = new Customer(); + PersonalInformation personalInformation = new PersonalInformation() + .dateOfBirth("19991112") + .name(new PersonalName().firstName("Ryan").surname("Carniato")); + ContactDetails contactDetails = new ContactDetails().emailAddress("mail@mail.com"); + Address address = new Address() + .countryCode("DE") + .zip("24937") + .city("Flensburg") + .street("Rathausplatz") + .houseNumber("1"); + customer.setPersonalInformation(personalInformation); + customer.setContactDetails(contactDetails); + customer.billingAddress(address); - PaymentExecutionRequest paymentExecutionRequest = new PaymentExecutionRequest() - .paymentExecutionSpecificInput(new PaymentExecutionSpecificInput() - .paymentReferences(new References().merchantReference("p-" + commerceCaseMerchantReference)) - .amountOfMoney(new AmountOfMoney() + CreateCheckoutRequest checkoutRequest = new CreateCheckoutRequest(); + AmountOfMoney amountOfMoney = new AmountOfMoney() .amount(3599L) - .currencyCode("EUR"))) - .paymentMethodSpecificInput(new PaymentMethodSpecificInput() - .sepaDirectDebitPaymentMethodSpecificInput(new SepaDirectDebitPaymentMethodSpecificInput() - .paymentProductId(771) - .paymentProduct771SpecificInput(new SepaDirectDebitPaymentProduct771SpecificInput() - .mandate(new ProcessingMandateInformation() - .bankAccountIban(new BankAccountInformation() - .iban("DE75512108001245126199") - .accountHolder("Ryan Carniato")) - .dateOfSignature("20240730") - .recurrenceType(MandateRecurrenceType.UNIQUE) - .uniqueMandateReference("m-" + commerceCaseMerchantReference) - .creditorId("DE98ZZZ09999999999"))))); - CreatePaymentResponse paymentResponse = this.paymentExecutionClient.createPayment(MERCHANT_ID, - commerceCase.getCommerceCaseId().toString(), - commerceCase.getCheckout().getCheckoutId().toString(), paymentExecutionRequest); - System.out.println(paymentResponse); - - CheckoutResponse finalCheckout = this.checkoutClient.getCheckoutRequest( - MERCHANT_ID, - commerceCase.getCommerceCaseId().toString(), - commerceCase.getCheckout().getCheckoutId().toString()); - System.out.println(finalCheckout); - } - - private void runSingleStepCheckout(String commerceCaseMerchantReference) - throws IOException, ApiException { - CreateCommerceCaseRequest payload = new CreateCommerceCaseRequest(); - - Customer customer = new Customer(); - PersonalInformation personalInformation = new PersonalInformation() - .dateOfBirth("19840505") - .name(new PersonalName().firstName("Rich").surname("Harris")); - ContactDetails contactDetails = new ContactDetails().emailAddress("mail@mail.com"); - Address address = new Address() - .countryCode("DE") - .zip("40474") - .city("Düsseldorf") - .street("Cecilienallee") - .houseNumber("2"); - customer.setPersonalInformation(personalInformation); - customer.setContactDetails(contactDetails); - customer.billingAddress(address); + .currencyCode("EUR"); + Shipping shipping = new Shipping() + .address(new AddressPersonal() + .countryCode("DE") + .zip("24937") + .city("Flensburg") + .street("Rathausplatz").houseNumber("1")); + ShoppingCartInput shoppingCart = new ShoppingCartInput(); + CartItemInput cartItem = new CartItemInput() + .invoiceData(new CartItemInvoiceData() + .description("T-Shirt - Scaleshape Logo - S")) + .orderLineDetails(new OrderLineDetailsInput() + .productPrice(3599L) + .quantity(1L) + .productType(ProductType.GOODS)); + shoppingCart.addItemsItem(cartItem); - CreateCheckoutRequest checkout = new CreateCheckoutRequest(); + checkoutRequest.amountOfMoney(amountOfMoney) + .shoppingCart(shoppingCart) + .shipping(shipping); - CheckoutReferences checkoutReferences = new CheckoutReferences() - .merchantReference("c-" + commerceCaseMerchantReference); - AmountOfMoney amountOfMoney = new AmountOfMoney() - .amount(5199L) - .currencyCode("EUR"); - Shipping shipping = new Shipping() - .address(new AddressPersonal() - .countryCode("DE") - .zip("40474") - .city("Düsseldorf") - .street("Cecilienallee").houseNumber("2")); - ShoppingCartInput shoppingCart = new ShoppingCartInput(); - CartItemInput cartItem = new CartItemInput() - .invoiceData(new CartItemInvoiceData() - .description("Hoodie - Scaleshape Logo - L")) - .orderLineDetails(new OrderLineDetailsInput() - .productPrice(5199L) - .quantity(1L) - .productType(ProductType.GOODS)); - shoppingCart.addItemsItem(cartItem); + createCommerceCaseRequest + .merchantReference(commerceCaseMerchantReference) + .customer(customer) + .checkout(checkoutRequest); - OrderRequest orderRequest = new OrderRequest() - .orderReferences(new References().merchantReference("o-" + commerceCaseMerchantReference)) - .paymentMethodSpecificInput(new PaymentMethodSpecificInput() - .sepaDirectDebitPaymentMethodSpecificInput(new SepaDirectDebitPaymentMethodSpecificInput() - .paymentProductId(771) - .paymentProduct771SpecificInput(new SepaDirectDebitPaymentProduct771SpecificInput() - .mandate(new ProcessingMandateInformation() - .bankAccountIban(new BankAccountInformation() - .iban("DE75512108001245126199") - .accountHolder("Rich Harris")) - .dateOfSignature("20240730") - .recurrenceType(MandateRecurrenceType.UNIQUE) - .uniqueMandateReference("m-" + commerceCaseMerchantReference) - .creditorId("DE98ZZZ09999999999"))))); + CreateCommerceCaseResponse commerceCase = commerceCaseClient.createCommerceCaseRequest( + MERCHANT_ID, + createCommerceCaseRequest); - checkout - .references(checkoutReferences) - .amountOfMoney(amountOfMoney) - .shipping(shipping) - .shoppingCart(shoppingCart) - .orderRequest(orderRequest); + PaymentExecutionRequest paymentExecutionRequest = new PaymentExecutionRequest() + .paymentExecutionSpecificInput(new PaymentExecutionSpecificInput() + .paymentReferences(new References().merchantReference( + "p-" + commerceCaseMerchantReference)) + .amountOfMoney(new AmountOfMoney() + .amount(3599L) + .currencyCode("EUR"))) + .paymentMethodSpecificInput(new PaymentMethodSpecificInput() + .sepaDirectDebitPaymentMethodSpecificInput( + new SepaDirectDebitPaymentMethodSpecificInput() + .paymentProductId(771) + .paymentProduct771SpecificInput( + new SepaDirectDebitPaymentProduct771SpecificInput() + .mandate(new ProcessingMandateInformation() + .bankAccountIban( + new BankAccountInformation() + .iban("DE75512108001245126199") + .accountHolder("Ryan Carniato")) + .dateOfSignature( + "20240730") + .recurrenceType(MandateRecurrenceType.UNIQUE) + .uniqueMandateReference( + "m-" + commerceCaseMerchantReference) + .creditorId("DE98ZZZ09999999999"))))); + CreatePaymentResponse paymentResponse = this.paymentExecutionClient.createPayment(MERCHANT_ID, + commerceCase.getCommerceCaseId().toString(), + commerceCase.getCheckout().getCheckoutId().toString(), paymentExecutionRequest); + System.out.println(paymentResponse); - payload.setMerchantReference(commerceCaseMerchantReference); - payload.checkout(checkout); - payload.customer(customer); + CheckoutResponse finalCheckout = this.checkoutClient.getCheckoutRequest( + MERCHANT_ID, + commerceCase.getCommerceCaseId().toString(), + commerceCase.getCheckout().getCheckoutId().toString()); + System.out.println(finalCheckout); + } - CreateCommerceCaseResponse commerceCase = commerceCaseClient.createCommerceCaseRequest(MERCHANT_ID, - payload); - System.out.println(commerceCase); - } + private void runSingleStepCheckout(String commerceCaseMerchantReference) + throws IOException, ApiException { + CreateCommerceCaseRequest payload = new CreateCommerceCaseRequest(); - private void runMultiStepCheckout(String commerceCaseMerchantReference) - throws IOException, ApiException { - // create the commercase - CreateCommerceCaseRequest createCommerceCaseRequest = new CreateCommerceCaseRequest() - .customer(new Customer() - .businessRelation("B2C") - .locale("de") - .personalInformation(new PersonalInformation().dateOfBirth("19840604") - .name(new PersonalName().firstName("Rich").surname("Harris"))) - .contactDetails(new ContactDetails().emailAddress("mail@mail.com")) - .billingAddress(new Address() + Customer customer = new Customer(); + PersonalInformation personalInformation = new PersonalInformation() + .dateOfBirth("19840505") + .name(new PersonalName().firstName("Rich").surname("Harris")); + ContactDetails contactDetails = new ContactDetails().emailAddress("mail@mail.com"); + Address address = new Address() .countryCode("DE") .zip("40474") .city("Düsseldorf") .street("Cecilienallee") - .houseNumber("2"))) - .checkout(new CreateCheckoutRequest() - .shoppingCart(new ShoppingCartInput() - .items(Arrays.asList(new CartItemInput() - .invoiceData(new CartItemInvoiceData() - .description("Frankenstein - Mary Shelley - Hardcover")) - .orderLineDetails(new OrderLineDetailsInput() - .productCode("shelley-42") - .productPrice(1999L) - .quantity(1L) - .productType(ProductType.GOODS) - .taxAmount(19L)))))); - CreateCommerceCaseResponse initialCommerceCase = this.commerceCaseClient.createCommerceCaseRequest(MERCHANT_ID, - createCommerceCaseRequest); - // add shipping information - PatchCheckoutRequest patchCheckoutRequest = new PatchCheckoutRequest() - .shipping(new Shipping() - .address(new AddressPersonal() - .countryCode("DE") - .zip("40474") - .city("Düsseldorf") - .street("Cecilienallee") - .houseNumber("2"))); - this.checkoutClient.updateCheckoutRequest( - MERCHANT_ID, - initialCommerceCase.getCommerceCaseId().toString(), - initialCommerceCase.getCheckout().getCheckoutId().toString(), - patchCheckoutRequest); + .houseNumber("2"); + customer.setPersonalInformation(personalInformation); + customer.setContactDetails(contactDetails); + customer.billingAddress(address); + + CreateCheckoutRequest checkout = new CreateCheckoutRequest(); - // confirm the order - OrderRequest orderRequest = new OrderRequest() - .orderType(OrderType.FULL) - .orderReferences(new References().merchantReference("o-" + commerceCaseMerchantReference)) - .paymentMethodSpecificInput(new PaymentMethodSpecificInput() - .paymentChannel(PaymentChannel.ECOMMERCE) - .sepaDirectDebitPaymentMethodSpecificInput(new SepaDirectDebitPaymentMethodSpecificInput() - .paymentProductId(771) - .paymentProduct771SpecificInput(new SepaDirectDebitPaymentProduct771SpecificInput() - .mandate(new ProcessingMandateInformation() - .bankAccountIban(new BankAccountInformation() - .iban("DE75512108001245126199") - .accountHolder("Rich Harris")) - .dateOfSignature("20240730") - .recurrenceType(MandateRecurrenceType.UNIQUE) - .uniqueMandateReference("m-" + commerceCaseMerchantReference) - .creditorId("DE98ZZZ09999999999"))))); - this.orderManagementCheckoutClient.createOrder( - MERCHANT_ID, - initialCommerceCase.getCommerceCaseId().toString(), - initialCommerceCase.getCheckout().getCheckoutId().toString(), - orderRequest); + CheckoutReferences checkoutReferences = new CheckoutReferences() + .merchantReference("c-" + commerceCaseMerchantReference); + AmountOfMoney amountOfMoney = new AmountOfMoney() + .amount(5199L) + .currencyCode("EUR"); + Shipping shipping = new Shipping() + .address(new AddressPersonal() + .countryCode("DE") + .zip("40474") + .city("Düsseldorf") + .street("Cecilienallee").houseNumber("2")); + ShoppingCartInput shoppingCart = new ShoppingCartInput(); + CartItemInput cartItem = new CartItemInput() + .invoiceData(new CartItemInvoiceData() + .description("Hoodie - Scaleshape Logo - L")) + .orderLineDetails(new OrderLineDetailsInput() + .productPrice(5199L) + .quantity(1L) + .productType(ProductType.GOODS)); + shoppingCart.addItemsItem(cartItem); - CheckoutResponse finalCheckout = this.checkoutClient.getCheckoutRequest( - MERCHANT_ID, - initialCommerceCase.getCommerceCaseId().toString(), - initialCommerceCase.getCheckout().getCheckoutId().toString()); - System.out.println(finalCheckout); + OrderRequest orderRequest = new OrderRequest() + .orderReferences(new References() + .merchantReference("o-" + commerceCaseMerchantReference)) + .paymentMethodSpecificInput(new PaymentMethodSpecificInput() + .sepaDirectDebitPaymentMethodSpecificInput( + new SepaDirectDebitPaymentMethodSpecificInput() + .paymentProductId(771) + .paymentProduct771SpecificInput( + new SepaDirectDebitPaymentProduct771SpecificInput() + .mandate(new ProcessingMandateInformation() + .bankAccountIban( + new BankAccountInformation() + .iban("DE75512108001245126199") + .accountHolder("Rich Harris")) + .dateOfSignature( + "20240730") + .recurrenceType(MandateRecurrenceType.UNIQUE) + .uniqueMandateReference( + "m-" + commerceCaseMerchantReference) + .creditorId("DE98ZZZ09999999999"))))); - // items are ready for shipment, the delivery can be performed to capture the - // money from the reservation - DeliverResponse delivery = this.orderManagementCheckoutClient.deliverOrder( - MERCHANT_ID, - initialCommerceCase.getCommerceCaseId().toString(), - initialCommerceCase.getCheckout().getCheckoutId().toString(), - new DeliverRequest().deliverType(DeliverType.FULL).isFinal(true)); - System.out.println(delivery); - } + checkout + .references(checkoutReferences) + .amountOfMoney(amountOfMoney) + .shipping(shipping) + .shoppingCart(shoppingCart) + .orderRequest(orderRequest); - public static void main(String[] args) { - App app = initFromEnv(); + payload.setMerchantReference(commerceCaseMerchantReference); + payload.checkout(checkout); + payload.customer(customer); - // creates a checkout and executes the payment in one go - try { - app.runCheckoutWithPaymentExecution("comc1a5"); - } catch (ApiErrorResponseException e) { - for (APIError error : e.getErrors()) { - System.err.println(error.getMessage()); - } - System.exit(1); - } catch (Exception e) { - throw new RuntimeException(e); + CreateCommerceCaseResponse commerceCase = commerceCaseClient.createCommerceCaseRequest(MERCHANT_ID, + payload); + System.out.println(commerceCase); } - // see: https://docs.payone.com/pcp/checkout-flows/step-by-step-checkout - // not that the given reference must be unique and has to renewed after each run - try { - app.runMultiStepCheckout("comc1a1"); - } catch (ApiErrorResponseException e) { - for (APIError error : e.getErrors()) { - System.err.println(error.getMessage()); - } - } catch (Exception e) { - throw new RuntimeException(e); + private void runMultiStepCheckout(String commerceCaseMerchantReference) + throws IOException, ApiException { + // create the commercase + CreateCommerceCaseRequest createCommerceCaseRequest = new CreateCommerceCaseRequest() + .customer(new Customer() + .businessRelation("B2C") + .locale("de") + .personalInformation(new PersonalInformation().dateOfBirth("19840604") + .name(new PersonalName().firstName("Rich") + .surname("Harris"))) + .contactDetails(new ContactDetails().emailAddress("mail@mail.com")) + .billingAddress(new Address() + .countryCode("DE") + .zip("40474") + .city("Düsseldorf") + .street("Cecilienallee") + .houseNumber("2"))) + .checkout(new CreateCheckoutRequest() + .shoppingCart(new ShoppingCartInput() + .items(Arrays.asList(new CartItemInput() + .invoiceData(new CartItemInvoiceData() + .description("Frankenstein - Mary Shelley - Hardcover")) + .orderLineDetails( + new OrderLineDetailsInput() + .productCode("shelley-42") + .productPrice(1999L) + .quantity(1L) + .productType(ProductType.GOODS) + .taxAmount(19L)))))); + CreateCommerceCaseResponse initialCommerceCase = this.commerceCaseClient.createCommerceCaseRequest( + MERCHANT_ID, + createCommerceCaseRequest); + // add shipping information + PatchCheckoutRequest patchCheckoutRequest = new PatchCheckoutRequest() + .shipping(new Shipping() + .address(new AddressPersonal() + .countryCode("DE") + .zip("40474") + .city("Düsseldorf") + .street("Cecilienallee") + .houseNumber("2"))); + this.checkoutClient.updateCheckoutRequest( + MERCHANT_ID, + initialCommerceCase.getCommerceCaseId().toString(), + initialCommerceCase.getCheckout().getCheckoutId().toString(), + patchCheckoutRequest); + + // confirm the order + OrderRequest orderRequest = new OrderRequest() + .orderType(OrderType.FULL) + .orderReferences(new References() + .merchantReference("o-" + commerceCaseMerchantReference)) + .paymentMethodSpecificInput(new PaymentMethodSpecificInput() + .paymentChannel(PaymentChannel.ECOMMERCE) + .sepaDirectDebitPaymentMethodSpecificInput( + new SepaDirectDebitPaymentMethodSpecificInput() + .paymentProductId(771) + .paymentProduct771SpecificInput( + new SepaDirectDebitPaymentProduct771SpecificInput() + .mandate(new ProcessingMandateInformation() + .bankAccountIban( + new BankAccountInformation() + .iban("DE75512108001245126199") + .accountHolder("Rich Harris")) + .dateOfSignature( + "20240730") + .recurrenceType(MandateRecurrenceType.UNIQUE) + .uniqueMandateReference( + "m-" + commerceCaseMerchantReference) + .creditorId("DE98ZZZ09999999999"))))); + this.orderManagementCheckoutClient.createOrder( + MERCHANT_ID, + initialCommerceCase.getCommerceCaseId().toString(), + initialCommerceCase.getCheckout().getCheckoutId().toString(), + orderRequest); + + CheckoutResponse finalCheckout = this.checkoutClient.getCheckoutRequest( + MERCHANT_ID, + initialCommerceCase.getCommerceCaseId().toString(), + initialCommerceCase.getCheckout().getCheckoutId().toString()); + System.out.println(finalCheckout); + + // items are ready for shipment, the delivery can be performed to capture the + // money from the reservation + DeliverResponse delivery = this.orderManagementCheckoutClient.deliverOrder( + MERCHANT_ID, + initialCommerceCase.getCommerceCaseId().toString(), + initialCommerceCase.getCheckout().getCheckoutId().toString(), + new DeliverRequest().deliverType(DeliverType.FULL).isFinal(true)); + System.out.println(delivery); } - // see: https://docs.payone.com/pcp/checkout-flows/one-step-checkout - // not that the given reference must be unique and has to renewed after each run - try { - app.runSingleStepCheckout("comc1a1"); - } catch (ApiErrorResponseException e) { - for (APIError error : e.getErrors()) { - System.err.println(error.getMessage()); - } - } catch (Exception e) { - throw new RuntimeException(e); + public static void main(String[] args) { + App app = initFromEnv(); + + // creates a checkout and executes the payment in one go + try { + app.runCheckoutWithPaymentExecution("comc1a5"); + } catch (ApiErrorResponseException e) { + for (APIError error : e.getErrors()) { + System.err.println(error.getMessage()); + } + System.exit(1); + } catch (Exception e) { + throw new RuntimeException(e); + } + + // see: https://docs.payone.com/pcp/checkout-flows/step-by-step-checkout + // not that the given reference must be unique and has to renewed after each run + try { + app.runMultiStepCheckout("comc1a1"); + } catch (ApiErrorResponseException e) { + for (APIError error : e.getErrors()) { + System.err.println(error.getMessage()); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + + // see: https://docs.payone.com/pcp/checkout-flows/one-step-checkout + // not that the given reference must be unique and has to renewed after each run + try { + app.runSingleStepCheckout("comc1a1"); + } catch (ApiErrorResponseException e) { + for (APIError error : e.getErrors()) { + System.err.println(error.getMessage()); + } + } catch (Exception e) { + throw new RuntimeException(e); + } } - } } diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/CommunicatorConfiguration.java b/lib/src/main/java/com/payone/commerce/platform/lib/CommunicatorConfiguration.java index 9bbcfed..a6fb90d 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/CommunicatorConfiguration.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/CommunicatorConfiguration.java @@ -4,11 +4,13 @@ public class CommunicatorConfiguration { private final String apiKey; private final String apiSecret; private final String host; + private final String integrator; - public CommunicatorConfiguration(String apiKey, String apiSecret, String host) { + public CommunicatorConfiguration(String apiKey, String apiSecret, String host, String integrator) { this.apiKey = apiKey; this.apiSecret = apiSecret; this.host = host; + this.integrator = integrator; } public String getApiKey() { @@ -22,4 +24,8 @@ public String getApiSecret() { public String getHost() { return host; } + + public String getIntegrator() { + return integrator; + } } diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java index b8bdf90..da65628 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java @@ -106,7 +106,7 @@ private String sign(String target) { } private String getServerMetaInfo() { - ServerMetaInfo meta = new ServerMetaInfo(); + ServerMetaInfo meta = new ServerMetaInfo(this.config.getIntegrator()); String jsonString; try { diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/utils/ServerMetaInfo.java b/lib/src/main/java/com/payone/commerce/platform/lib/utils/ServerMetaInfo.java index 82687b8..f7683b8 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/utils/ServerMetaInfo.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/utils/ServerMetaInfo.java @@ -6,6 +6,7 @@ public class ServerMetaInfo { public String platformIdentifier; public String sdkIdentifier; public String sdkCreator; + public String integrator; public ServerMetaInfo() { this.platformIdentifier = String.format("%s, java version is: %s", System.getProperty("os.name"), @@ -13,8 +14,16 @@ public ServerMetaInfo() { // version gets updated with the prepare-release.sh script this.sdkIdentifier = "JavaServerSDK/v0.0.2"; this.sdkCreator = "PAYONE GmbH"; + this.integrator = null; + } - // TODO: what about integrator? + public ServerMetaInfo(String integrator) { + this.platformIdentifier = String.format("%s, java version is: %s", System.getProperty("os.name"), + System.getProperty("java.version")); + // version gets updated with the prepare-release.sh script + this.sdkIdentifier = "JavaServerSDK/v0.0.2"; + this.sdkCreator = "PAYONE GmbH"; + this.integrator = integrator; } @Override diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java b/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java index 812bc7c..42bb376 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java @@ -25,7 +25,7 @@ public class RequestHeaderGeneratorTest { private static final String TEST_KEY = "KEY"; private static final String TEST_SECRET = "Super duper Ethan Hunt level secret"; private static final CommunicatorConfiguration CONFIG = new CommunicatorConfiguration(TEST_KEY, TEST_SECRET, - "awesome-api.com"); + "awesome-api.com", null); private static final RequestHeaderGenerator HEADER_GENERATOR; static { try { @@ -119,7 +119,7 @@ void addServerMetaInfoIfMissingTest() { serverMetaInfoAsJson = new String(Base64.getDecoder().decode(serverMetaInfoBase64), StandardCharsets.UTF_8); ServerMetaInfo serverMetaInfo = objectMapper.readValue(serverMetaInfoAsJson, ServerMetaInfo.class); - assertEquals(serverMetaInfo, new ServerMetaInfo()); + assertEquals(serverMetaInfo, new ServerMetaInfo(null)); } catch (JsonProcessingException e) { fail(String.format("Decoded meta info '%s', should have been valid json", serverMetaInfoAsJson), e); } catch (Exception e) { diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/testutils/TestConfig.java b/lib/src/test/java/com/payone/commerce/platform/lib/testutils/TestConfig.java index c903ced..5ac6c6e 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/testutils/TestConfig.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/testutils/TestConfig.java @@ -6,5 +6,5 @@ public abstract class TestConfig { public static final CommunicatorConfiguration COMMUNICATOR_CONFIGURATION = new CommunicatorConfiguration("KEY", "Super duper Ethan Hunt level secret", - "awesome-api.com"); + "awesome-api.com", null); } From 4a39a0cf4714cabfbc60622d05e6bb430da63287 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:24:29 +0200 Subject: [PATCH 03/29] chore: use single expression for initializing and assigning json string when serializing --- .../commerce/platform/lib/endpoints/CheckoutApiClient.java | 4 +--- .../platform/lib/endpoints/CommerceCaseApiClient.java | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java index 26d5d10..02299e2 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java @@ -157,9 +157,7 @@ public void updateCheckoutRequest(String merchantId, String commerceCaseId, Stri .addPathSegment(checkoutId) .build(); - String jsonString = null; - - jsonString = JsonSerializer.serializeToJson(payload); + String jsonString = JsonSerializer.serializeToJson(payload); Request request = new Request.Builder() .url(url) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java index 81be14a..c2d0cce 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java @@ -145,9 +145,7 @@ public void updateCommerceCaseRequest(String merchantId, String commerceCaseId, .addPathSegment(commerceCaseId) .build(); - String jsonString = null; - - jsonString = JsonSerializer.serializeToJson(payload); + String jsonString = JsonSerializer.serializeToJson(payload); RequestBody formBody = RequestBody.create("{\"customer\":" + jsonString + "}", JSON); From a98a1e87089a7b5717bd9d8969a2b7f19a02a93b Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:30:06 +0200 Subject: [PATCH 04/29] refactor: use constant for http header name 'Content-Type' --- .../platform/lib/RequestHeaderGenerator.java | 12 ++++++------ .../platform/lib/endpoints/BaseApiClient.java | 6 ++++-- .../platform/lib/endpoints/CheckoutApiClient.java | 4 ++-- .../lib/endpoints/CommerceCaseApiClient.java | 4 ++-- .../OrderManagementCheckoutActionsApiClient.java | 8 ++++---- .../lib/endpoints/PaymentExecutionApiClient.java | 10 +++++----- .../lib/endpoints/PaymentInformationApiClient.java | 2 +- 7 files changed, 24 insertions(+), 22 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java index da65628..e94e5a6 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java @@ -17,14 +17,14 @@ import okhttp3.Request; public class RequestHeaderGenerator { - - public static final String SERVER_META_INFO_HEADER_NAME = "X-GCS-ServerMetaInfo"; + private static final String AUTHORIZATION_HEADER_NAME = "Authorization"; + private static final String CONTENT_TYPE_HEADER_NAME = "Content-Type"; + private static final String DATE_HEADER_NAME = "Date"; public static final String CLIENT_META_INFO_HEADER_NAME = "X-GCS-ClientMetaInfo"; + public static final String SERVER_META_INFO_HEADER_NAME = "X-GCS-ServerMetaInfo"; private static final String ALGORITHM = "HmacSHA256"; private static final String WHITESPACE_REGEX = "\\r?\\n[\\h]*"; - private final String DATE_HEADER_NAME = "Date"; - private final String AUTHORIZATION_HEADER_NAME = "Authorization"; private final CommunicatorConfiguration config; private final Mac mac; @@ -69,8 +69,8 @@ private String getAuthHeader(Request request, Builder headersBuilder) { StringBuilder stringToSign = new StringBuilder(request.method()); stringToSign.append("\n"); // 2. Content-Type - if (headersBuilder.get("Content-Type") != null) { - stringToSign.append(headersBuilder.get("Content-Type")); + if (headersBuilder.get(CONTENT_TYPE_HEADER_NAME) != null) { + stringToSign.append(headersBuilder.get(CONTENT_TYPE_HEADER_NAME)); } stringToSign.append("\n"); // 3. Date diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java index 9f94df5..35765f9 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java @@ -19,9 +19,11 @@ import okhttp3.Response; public class BaseApiClient { + private static final String JSON_PARSE_ERROR = "Excepted valid JSON response, but failed to parse"; + protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + protected static final String CONTENT_TYPE_HEADER_NAME = "Content-Type"; + private final OkHttpClient client = new OkHttpClient(); - private final String JSON_PARSE_ERROR = "Excepted valid JSON response, but failed to parse"; - protected final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); private final RequestHeaderGenerator requestHeaderGenerator; private final CommunicatorConfiguration config; diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java index 02299e2..c6c839b 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java @@ -58,7 +58,7 @@ public CreateCheckoutResponse createCheckoutRequest(String merchantId, String co Request request = new Request.Builder() .url(url) .post(RequestBody.create(jsonString, JSON)) - .header("Content-Type", JSON.toString()) + .header(CONTENT_TYPE_HEADER_NAME, JSON.toString()) .build(); return this.makeApiCall(request, CreateCheckoutResponse.class); @@ -162,7 +162,7 @@ public void updateCheckoutRequest(String merchantId, String commerceCaseId, Stri Request request = new Request.Builder() .url(url) .patch(RequestBody.create(jsonString, JSON)) - .header("Content-Type", JSON.toString()) + .header(CONTENT_TYPE_HEADER_NAME, JSON.toString()) .build(); this.makeApiCall(request); diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java index c2d0cce..7509c77 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java @@ -53,7 +53,7 @@ public CreateCommerceCaseResponse createCommerceCaseRequest(String merchantId, C Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CreateCommerceCaseResponse.class); @@ -152,7 +152,7 @@ public void updateCommerceCaseRequest(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .patch(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); this.makeApiCall(request); diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java index ba38dfd..fdc70b9 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java @@ -64,7 +64,7 @@ public OrderResponse createOrder(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, OrderResponse.class); @@ -106,7 +106,7 @@ public DeliverResponse deliverOrder(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, DeliverResponse.class); @@ -148,7 +148,7 @@ public ReturnResponse returnOrder(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, ReturnResponse.class); @@ -190,7 +190,7 @@ public CancelResponse cancelOrder(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CancelResponse.class); diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java index 4dfbf98..1a396e9 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java @@ -63,7 +63,7 @@ public CreatePaymentResponse createPayment(String merchantId, String commerceCas Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CreatePaymentResponse.class); @@ -110,7 +110,7 @@ public CapturePaymentResponse capturePayment(String merchantId, String commerceC Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CapturePaymentResponse.class); @@ -157,7 +157,7 @@ public CancelPaymentResponse cancelPayment(String merchantId, String commerceCas Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CancelPaymentResponse.class); @@ -204,7 +204,7 @@ public RefundPaymentResponse refundPayment(String merchantId, String commerceCas Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, RefundPaymentResponse.class); @@ -251,7 +251,7 @@ public CompletePaymentResponse completePayment(String merchantId, String commerc Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CompletePaymentResponse.class); diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java index 0c3d511..4cf4a60 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java @@ -54,7 +54,7 @@ public PaymentInformationResponse createPaymentInformation(String merchantId, St Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, PaymentInformationResponse.class); From fed58c83818fdd9c7f3dc003177220bef1e91fb1 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:34:12 +0200 Subject: [PATCH 05/29] chore: fix typo of 'gradle' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf3e835..b3e3b80 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ class App { This repo contains a demo app that showcases how to implement common use cases, like a [Step-by-Step Checkout](https://docs.payone.com/pcp/checkout-flows/step-by-step-checkout) and an [One-Stop-Checkout](https://docs.payone.com/pcp/checkout-flows/one-step-checkout). For each use case the demo app contains a private method in the top level class `App`. You can run the app to execute the code within in the sandbox API. This is a good way to test, if your setup is correct. -If you're using grald can run it within the demo app directory via: +If you're using gradle can run it within the demo app directory via: ```sh API_KEY=api_key API_SECRET=api_secret MERCHANT_ID=123 COMMERCE_CASE_ID=234 CHECKOUT_ID=345 ./gradlew :app:run From 4e070b288206579d1d51e5cacc50f2b31a3ca7bf Mon Sep 17 00:00:00 2001 From: Dirk Ehrhardt Date: Wed, 7 Aug 2024 15:42:12 +0200 Subject: [PATCH 06/29] chore: add sonarcloud scanner --- .github/workflows/test.yml | 6 +++++- lib/build.gradle | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 14b837c..c704639 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Run Tests +name: Run Tests and SonarCloud Scan on: push: @@ -33,3 +33,7 @@ jobs: - name: Test run: | ./gradlew :lib:test + - name: Run SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/lib/build.gradle b/lib/build.gradle index 75c874d..5904463 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -15,6 +15,7 @@ plugins { id 'jacoco' id 'checkstyle' id "io.github.kmbisset89.changelog.plugin" version "1.0.4" + id "org.sonarqube" version "5.1.0.4882" } if (JavaVersion.current().majorVersion != "8") { @@ -62,6 +63,21 @@ tasks.jacocoTestReport { } } +tasks["sonar"].dependsOn "jacocoTestReport" + +sonar { + properties { + property "sonar.projectKey", "PAYONE-GmbH_PCP-ServerSDK-java" + property "sonar.projectName", "PCP-ServerSDK-java" + property "sonar.organization", "payone-gmbh" + property "sonar.host.url", "https://sonarcloud.io" + property "sonar.sources", "src/main" + property "sonar.tests", "src/test" + property "sonar.coverage.exclusions", "**/models/*" + property "sonar.exclusions", "**/models/*" + } +} + if (JavaVersion.current().majorVersion != "8") { mavenPublishing { publishToMavenCentral("CENTRAL_PORTAL") From dd4a1d8778f2005e9efe78a06a207c5b697510fd Mon Sep 17 00:00:00 2001 From: Dirk Ehrhardt Date: Wed, 7 Aug 2024 15:54:25 +0200 Subject: [PATCH 07/29] chore: adjust sonar scanner --- .github/workflows/test.yml | 8 +--- .github/workflows/test_and_build.yml | 24 +++++++++- lib/build.gradle | 70 ++++++++++++++-------------- 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c704639..a24c736 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Run Tests and SonarCloud Scan +name: Run Tests on: push: @@ -29,11 +29,7 @@ jobs: - name: Setup Gradle 8.8 uses: gradle/actions/setup-gradle@v3 with: - gradle-version: 8.8 + gradle-version: 8.9 - name: Test run: | ./gradlew :lib:test - - name: Run SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@master - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.github/workflows/test_and_build.yml b/.github/workflows/test_and_build.yml index b23022d..878fa67 100644 --- a/.github/workflows/test_and_build.yml +++ b/.github/workflows/test_and_build.yml @@ -10,7 +10,7 @@ jobs: test: uses: ./.github/workflows/test.yml - build-and-publish: + sonar-scan: needs: [test] runs-on: ubuntu-20.04 steps: @@ -24,7 +24,27 @@ jobs: - name: Setup Gradle 8.8 uses: gradle/actions/setup-gradle@v3 with: - gradle-version: 8.8 + gradle-version: 8.9 + - name: Run SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + build-and-publish: + needs: [test, sonar-scan] + runs-on: ubuntu-20.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'adopt' + - name: Setup Gradle 8.8 + uses: gradle/actions/setup-gradle@v3 + with: + gradle-version: 8.9 - name: Build Lib run: ./gradlew :lib:build - name: Publish package diff --git a/lib/build.gradle b/lib/build.gradle index 5904463..426640d 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -4,7 +4,7 @@ buildscript { gradlePluginPortal() } dependencies { - if (JavaVersion.current().majorVersion != "8") { + if (JavaVersion.current().majorVersion != '8') { classpath 'com.vanniktech:gradle-maven-publish-plugin:0.29.0' } } @@ -14,15 +14,14 @@ plugins { id 'java-library' id 'jacoco' id 'checkstyle' - id "io.github.kmbisset89.changelog.plugin" version "1.0.4" - id "org.sonarqube" version "5.1.0.4882" + id 'io.github.kmbisset89.changelog.plugin' version '1.0.4' } -if (JavaVersion.current().majorVersion != "8") { +if (JavaVersion.current().majorVersion != '8') { apply plugin: 'com.vanniktech.maven.publish' + apply plugin: 'org.sonarqube' version '5.1.0.4882' } - version = '0.0.2' repositories { @@ -40,7 +39,7 @@ dependencies { } jacoco { - toolVersion = "0.8.8" // Specify the version of JaCoCo you want to use + toolVersion = '0.8.8' // Specify the version of JaCoCo you want to use } tasks.test { @@ -57,57 +56,58 @@ tasks.jacocoTestReport { afterEvaluate { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(dir: it, exclude: [ - "com/payone/**/models/*" + 'com/payone/**/models/*' ]) })) } } -tasks["sonar"].dependsOn "jacocoTestReport" - -sonar { - properties { - property "sonar.projectKey", "PAYONE-GmbH_PCP-ServerSDK-java" - property "sonar.projectName", "PCP-ServerSDK-java" - property "sonar.organization", "payone-gmbh" - property "sonar.host.url", "https://sonarcloud.io" - property "sonar.sources", "src/main" - property "sonar.tests", "src/test" - property "sonar.coverage.exclusions", "**/models/*" - property "sonar.exclusions", "**/models/*" - } -} -if (JavaVersion.current().majorVersion != "8") { +if (JavaVersion.current().majorVersion != '8') { mavenPublishing { - publishToMavenCentral("CENTRAL_PORTAL") + publishToMavenCentral('CENTRAL_PORTAL') signAllPublications() - coordinates("io.github.payone-gmbh", "pcp-serversdk-java", version) + coordinates('io.github.payone-gmbh', 'pcp-serversdk-java', version) pom { - name = "PCP-SERVERSDK-JAVA" - description = "The PayOne PCP Java SDK." - inceptionYear = "2024" - url = "https://github.com/PAYONE-GmbH/PCP-ServerSDK-java" + name = 'PCP-SERVERSDK-JAVA' + description = 'The PayOne PCP Java SDK.' + inceptionYear = '2024' + url = 'https://github.com/PAYONE-GmbH/PCP-ServerSDK-java' licenses { license { - name = "MIT" + name = 'MIT' } } developers { developer { - id = "username" - name = "PayOne-GmbH" - url = "https://github.com/PAYONE-GmbH" + id = 'username' + name = 'PayOne-GmbH' + url = 'https://github.com/PAYONE-GmbH' } } scm { - url = "https://github.com/PAYONE-GmbH/PCP-ServerSDK-java" - connection = "scm:git:git://github.com/PAYONE-GmbH/PCP-ServerSDK-java.git" - developerConnection = "scm:git:ssh://git@github.com/PAYONE-GmbH/PCP-ServerSDK-java.git" + url = 'https://github.com/PAYONE-GmbH/PCP-ServerSDK-java' + connection = 'scm:git:git://github.com/PAYONE-GmbH/PCP-ServerSDK-java.git' + developerConnection = 'scm:git:ssh://git@github.com/PAYONE-GmbH/PCP-ServerSDK-java.git' } } } + + tasks['sonar'].dependsOn 'jacocoTestReport' + + sonar { + properties { + property 'sonar.projectKey', 'PAYONE-GmbH_PCP-ServerSDK-java' + property 'sonar.projectName', 'PCP-ServerSDK-java' + property 'sonar.organization', 'payone-gmbh' + property 'sonar.host.url', 'https://sonarcloud.io' + property 'sonar.sources', 'src/main' + property 'sonar.tests', 'src/test' + property 'sonar.coverage.exclusions', '**/models/*' + property 'sonar.exclusions', '**/models/*' + } + } } \ No newline at end of file From 8fb0599badb58a0ff82fcc89f6cf95da3e18ecf7 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:51:37 +0200 Subject: [PATCH 08/29] refactor(NoSuchAlgorithm): Use meaningful AssertionError instead of RuntimeException --- .../commerce/platform/lib/RequestHeaderGenerator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java index e94e5a6..873a070 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java @@ -38,7 +38,7 @@ public RequestHeaderGenerator(CommunicatorConfiguration config) throws InvalidKe ALGORITHM); this.mac.init(secretKeySpec); } catch (NoSuchAlgorithmException e) { - throw new RuntimeException("HmacSHA256 must be available to use the PCP Java SDK", e); + throw new AssertionError("HmacSHA256 must be available to use the PCP Java SDK", e); } } @@ -90,7 +90,7 @@ private String getAuthHeader(Request request, Builder headersBuilder) { .append("\n"); } // 5. Canonicalized Resource (has to include query parameters) - stringToSign.append(request.url().encodedPath().toString()); + stringToSign.append(request.url().encodedPath()); if (request.url().encodedQuery() != null) { stringToSign.append("?") .append(request.url().encodedQuery()); @@ -113,7 +113,7 @@ private String getServerMetaInfo() { jsonString = JsonSerializer.serializeToJson(meta); return Base64.getEncoder().encodeToString(jsonString.getBytes(StandardCharsets.UTF_8)); } catch (JsonProcessingException e) { - throw new RuntimeException( + throw new AssertionError( "Server Meta Info must be encodable as JSON, this is likely an internal bug of the java PCP SDK", e); } From ae33d6e9d82e3647ab50f8179c8c220a417a4f10 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:55:19 +0200 Subject: [PATCH 09/29] refactor(handleError): avoid unneccessary null check for responseBody --- .../payone/commerce/platform/lib/endpoints/BaseApiClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java index 35765f9..ae79c87 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java @@ -88,7 +88,7 @@ private void handleError(Response response) } String responseBody = response.body().string(); - if (responseBody == null || responseBody.isEmpty()) { + if (responseBody.isEmpty()) { throw new ApiResponseRetrievalException(response.code(), responseBody); } try { From e9c77ad412b0aa2cbb5cb3f251f83934ca50e2f3 Mon Sep 17 00:00:00 2001 From: Dirk Ehrhardt Date: Wed, 7 Aug 2024 16:00:57 +0200 Subject: [PATCH 10/29] chore: add classpath to sonarcloud in build gradle --- lib/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/build.gradle b/lib/build.gradle index 426640d..c974975 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -6,6 +6,7 @@ buildscript { dependencies { if (JavaVersion.current().majorVersion != '8') { classpath 'com.vanniktech:gradle-maven-publish-plugin:0.29.0' + classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:5.1.0.4882' } } } @@ -19,7 +20,7 @@ plugins { if (JavaVersion.current().majorVersion != '8') { apply plugin: 'com.vanniktech.maven.publish' - apply plugin: 'org.sonarqube' version '5.1.0.4882' + apply plugin: 'org.sonarqube' } version = '0.0.2' From 3ed231ec6c7b789dbf206be5bd659282e46bea5d Mon Sep 17 00:00:00 2001 From: Dirk Ehrhardt Date: Wed, 7 Aug 2024 16:08:22 +0200 Subject: [PATCH 11/29] chore: update sonar scanner --- .github/workflows/sonar_scanner.yml | 25 +++++++++++++++++++++++++ .github/workflows/test.yml | 2 +- .github/workflows/test_and_build.yml | 20 ++------------------ 3 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/sonar_scanner.yml diff --git a/.github/workflows/sonar_scanner.yml b/.github/workflows/sonar_scanner.yml new file mode 100644 index 0000000..1b60340 --- /dev/null +++ b/.github/workflows/sonar_scanner.yml @@ -0,0 +1,25 @@ +name: Run Tests + +on: + workflow_call: + workflow_dispatch: + +jobs: + sonar-scan: + runs-on: ubuntu-20.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'adopt' + - name: Setup Gradle 8.9 + uses: gradle/actions/setup-gradle@v3 + with: + gradle-version: 8.9 + - name: Run SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a24c736..e69e644 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: with: java-version: ${{ matrix.java }} distribution: 'adopt' - - name: Setup Gradle 8.8 + - name: Setup Gradle 8.9 uses: gradle/actions/setup-gradle@v3 with: gradle-version: 8.9 diff --git a/.github/workflows/test_and_build.yml b/.github/workflows/test_and_build.yml index 878fa67..7295452 100644 --- a/.github/workflows/test_and_build.yml +++ b/.github/workflows/test_and_build.yml @@ -12,23 +12,7 @@ jobs: sonar-scan: needs: [test] - runs-on: ubuntu-20.04 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up JDK - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'adopt' - - name: Setup Gradle 8.8 - uses: gradle/actions/setup-gradle@v3 - with: - gradle-version: 8.9 - - name: Run SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@master - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + uses: ./.github/workflows/sonar_scanner.yml build-and-publish: needs: [test, sonar-scan] @@ -41,7 +25,7 @@ jobs: with: java-version: '17' distribution: 'adopt' - - name: Setup Gradle 8.8 + - name: Setup Gradle 8.9 uses: gradle/actions/setup-gradle@v3 with: gradle-version: 8.9 From bc297e6c943a3282b4cea606286979ae8dee1a42 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 16:11:35 +0200 Subject: [PATCH 12/29] refactor(illegal-argument-messages): use constants for errors on required arguments --- .../platform/lib/endpoints/BaseApiClient.java | 4 +++ .../lib/endpoints/CheckoutApiClient.java | 28 ++++++++--------- .../lib/endpoints/CommerceCaseApiClient.java | 8 ++--- ...derManagementCheckoutActionsApiClient.java | 24 +++++++-------- .../endpoints/PaymentExecutionApiClient.java | 30 +++++++++---------- .../PaymentInformationApiClient.java | 10 +++---- 6 files changed, 54 insertions(+), 50 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java index ae79c87..f7f3928 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java @@ -20,6 +20,10 @@ public class BaseApiClient { private static final String JSON_PARSE_ERROR = "Excepted valid JSON response, but failed to parse"; + protected static final String MERCHANT_ID_REQUIRED_ERROR = "Merchant ID is required"; + protected static final String COMMERCE_CASE_ID_REQUIRED_ERROR = "Commerce Case ID is required"; + protected static final String CHECKOUT_ID_REQUIRED_ERROR = "Checkout ID is required"; + protected static final String PAYLOAD_REQUIRED_ERROR = "Payload is required"; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); protected static final String CONTENT_TYPE_HEADER_NAME = "Content-Type"; diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java index c6c839b..ce51e95 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java @@ -32,13 +32,13 @@ public CreateCheckoutResponse createCheckoutRequest(String merchantId, String co CreateCheckoutRequest payload) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -68,13 +68,13 @@ public CreateCheckoutResponse createCheckoutRequest(String merchantId, String co public CheckoutResponse getCheckoutRequest(String merchantId, String commerceCaseId, String checkoutId) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -105,7 +105,7 @@ public CheckoutsResponse getCheckoutsRequest(String merchantID) public CheckoutsResponse getCheckoutsRequest(String merchantId, GetCheckoutsQuery queryParams) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } HttpUrl.Builder urlBuilder = new HttpUrl.Builder() @@ -134,16 +134,16 @@ public void updateCheckoutRequest(String merchantId, String commerceCaseId, Stri PatchCheckoutRequest payload) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -172,13 +172,13 @@ public void updateCheckoutRequest(String merchantId, String commerceCaseId, Stri public void removeCheckoutRequest(String merchantId, String commerceCaseId, String checkoutId) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java index 7509c77..9e8b096 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java @@ -35,7 +35,7 @@ public CreateCommerceCaseResponse createCommerceCaseRequest(String merchantId, C throw new IllegalArgumentException("Merchant ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -66,7 +66,7 @@ public CommerceCaseResponse getCommerceCaseRequest(String merchantId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } HttpUrl.Builder urlBuilder = new HttpUrl.Builder() @@ -130,10 +130,10 @@ public void updateCommerceCaseRequest(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java index fdc70b9..deab21b 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java @@ -36,13 +36,13 @@ public OrderResponse createOrder(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -78,13 +78,13 @@ public DeliverResponse deliverOrder(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -120,13 +120,13 @@ public ReturnResponse returnOrder(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -162,13 +162,13 @@ public CancelResponse cancelOrder(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java index 1a396e9..4440e8d 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java @@ -35,13 +35,13 @@ public CreatePaymentResponse createPayment(String merchantId, String commerceCas throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -77,16 +77,16 @@ public CapturePaymentResponse capturePayment(String merchantId, String commerceC throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentExecutionId == null) { throw new IllegalArgumentException("Payment Execution ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -124,16 +124,16 @@ public CancelPaymentResponse cancelPayment(String merchantId, String commerceCas throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentExecutionId == null) { throw new IllegalArgumentException("Payment Execution ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -171,16 +171,16 @@ public RefundPaymentResponse refundPayment(String merchantId, String commerceCas throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentExecutionId == null) { throw new IllegalArgumentException("Payment Execution ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -218,16 +218,16 @@ public CompletePaymentResponse completePayment(String merchantId, String commerc throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentExecutionId == null) { throw new IllegalArgumentException("Payment Execution ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java index 4cf4a60..a4dc715 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java @@ -26,13 +26,13 @@ public PaymentInformationResponse createPaymentInformation(String merchantId, St throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -68,10 +68,10 @@ public PaymentInformationResponse getPaymentInformation(String merchantId, Strin throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentInformationId == null) { throw new IllegalArgumentException("Payment Information ID is required"); From 274361b03ce09eb30670cc447ae439fc0bb0a023 Mon Sep 17 00:00:00 2001 From: Dirk Ehrhardt Date: Wed, 7 Aug 2024 16:17:02 +0200 Subject: [PATCH 13/29] chore: udpate gradle version to 8.9 --- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43504 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 5 ++++- gradlew.bat | 2 ++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..2c3521197d7c4586c843d1d3e9090525f1898cde 100644 GIT binary patch delta 8703 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 Ojj7^59?Sdh$^Qpp*~F>< delta 8662 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a441313..09523c0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf1..f5feea6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30d..9d21a21 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## From c7912ce4c459b50f672a81143ad85384c427f3ee Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 16:18:26 +0200 Subject: [PATCH 14/29] refactor: hide constructor, remove unneccessary exception declaration --- .../commerce/platform/lib/serializer/JsonSerializer.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/serializer/JsonSerializer.java b/lib/src/main/java/com/payone/commerce/platform/lib/serializer/JsonSerializer.java index f78b6e7..e6705bc 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/serializer/JsonSerializer.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/serializer/JsonSerializer.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @@ -18,17 +17,20 @@ public class JsonSerializer { JSON_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } + private JsonSerializer() { + } + public static String serializeToJson(Object object) throws JsonProcessingException { return JSON_MAPPER.writeValueAsString(object); } public static T deserializeFromJson(String json, Class clazz) - throws JsonMappingException, JsonProcessingException { + throws JsonProcessingException { return JSON_MAPPER.readValue(json, clazz); } public static T deserializeFromJson(String json, TypeReference valueTypeRef) - throws JsonMappingException, JsonProcessingException { + throws JsonProcessingException { return JSON_MAPPER.readValue(json, valueTypeRef); } } From 07a59430b54cf65e1b2b8049667a7418e18226b0 Mon Sep 17 00:00:00 2001 From: Dirk Ehrhardt Date: Wed, 7 Aug 2024 16:19:31 +0200 Subject: [PATCH 15/29] chore: adjust name of sonar scanner workflow --- .github/workflows/sonar_scanner.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sonar_scanner.yml b/.github/workflows/sonar_scanner.yml index 1b60340..ffdff23 100644 --- a/.github/workflows/sonar_scanner.yml +++ b/.github/workflows/sonar_scanner.yml @@ -1,4 +1,4 @@ -name: Run Tests +name: Run SonarCloud Scan on: workflow_call: From edb085bfbe0b59cb1de8a64519fac5330a924ddb Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 16:23:50 +0200 Subject: [PATCH 16/29] tests: only declare possible exceptions --- .../lib/endpoints/CheckoutApiClientTest.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClientTest.java b/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClientTest.java index c37396b..d3db66e 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClientTest.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClientTest.java @@ -35,7 +35,7 @@ public class CheckoutApiClientTest { class CreateCheckoutRequestTests { @Test @DisplayName("given request was successful, then return response") - void createCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void createCheckoutRequestSuccessful() throws InvalidKeyException, IOException, ApiException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -54,7 +54,7 @@ void createCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void createCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void createCheckoutRequestUnsuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); @@ -70,7 +70,7 @@ void createCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiExceptio @Test @DisplayName("given request was unsuccessful (500) with an empty body, then throw exception") - void createCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void createCheckoutRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); @@ -86,7 +86,7 @@ void createCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiExcep @Test @DisplayName("given some params are null, then throw exception") - void createCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void createCheckoutRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CreateCheckoutRequest payload = new CreateCheckoutRequest(); @@ -114,7 +114,7 @@ void createCheckoutRequestNullParams() throws InvalidKeyException, ApiException, class GetCheckoutRequestTests { @Test @DisplayName("given request was successful, then return response") - void getCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void getCheckoutRequestSuccessful() throws InvalidKeyException, IOException, ApiException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CheckoutResponse expected = new CheckoutResponse(); @@ -131,7 +131,7 @@ void getCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IO @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void getCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void getCheckoutRequestUnsuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); @@ -146,7 +146,7 @@ void getCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (500), then throw exception") - void getCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void getCheckoutRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); @@ -162,7 +162,7 @@ void getCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiExceptio @Test @DisplayName("given some params are null, then throw exception") - void getCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void getCheckoutRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -191,7 +191,7 @@ void getCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IO class getCheckoutsRequestTests { @Test @DisplayName("given request was successful, then return response") - void getCheckoutsRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void getCheckoutsRequestSuccessful() throws InvalidKeyException, IOException, ApiException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -209,7 +209,7 @@ void getCheckoutsRequestSuccessful() throws InvalidKeyException, ApiException, I @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void getCheckoutsRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void getCheckoutsRequestUnsuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -227,7 +227,7 @@ void getCheckoutsRequestUnsuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (500) with empty body, then throw exception") - void getCommerceCaseRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void getCommerceCaseRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -244,7 +244,7 @@ void getCommerceCaseRequestUnsuccessful500() throws InvalidKeyException, ApiExce @Test @DisplayName("given some params are null, then throw exception") - void getCheckoutsRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void getCheckoutsRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -263,7 +263,7 @@ void getCheckoutsRequestNullParams() throws InvalidKeyException, ApiException, I class UpdateCheckoutRequestTests { @Test @DisplayName("given request was successful, then throw no exception") - void updateCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void updateCheckoutRequestSuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createResponse(200); @@ -279,7 +279,7 @@ void updateCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void updateCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void updateCheckoutRequestUnsuccessful() throws InvalidKeyException, IOException { Response response = ApiResponseMocks.createErrorResponse(400); CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); doReturn(response).when(checkoutApiClient).getResponse(any()); @@ -293,7 +293,7 @@ void updateCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiExceptio @Test @DisplayName("given request was unsuccessful (500), then throw exception") - void updateCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void updateCheckoutRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(500); @@ -310,7 +310,7 @@ void updateCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiExcep @Test @DisplayName("given some params are null, then throw exception") - void updateCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void updateCheckoutRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -351,7 +351,7 @@ void updateCheckoutRequestNullParams() throws InvalidKeyException, ApiException, class RemoveCheckoutRequestTests { @Test @DisplayName("given request was successful, then throw no exception") - void removeCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void removeCheckoutRequestSuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createResponse(200); @@ -365,7 +365,7 @@ void removeCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void removeCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void removeCheckoutRequestUnsuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); @@ -381,7 +381,7 @@ void removeCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiExceptio @Test @DisplayName("given request was unsuccessful (500), then throw exception") - void removeCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void removeCheckoutRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); @@ -397,7 +397,7 @@ void removeCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiExcep @Test @DisplayName("given some params are null, then throw exception") - void removeCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void removeCheckoutRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); From 406428dde1150068102f12e759ca791f579ac823 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 16:24:50 +0200 Subject: [PATCH 17/29] tests: remove visibilty modifier from class, use idiomatic order of arguments in assert calls --- .../platform/lib/RequestHeaderGeneratorTest.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java b/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java index 42bb376..a9cbe2f 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java @@ -21,7 +21,7 @@ import java.util.Base64; import java.util.Date; -public class RequestHeaderGeneratorTest { +class RequestHeaderGeneratorTest { private static final String TEST_KEY = "KEY"; private static final String TEST_SECRET = "Super duper Ethan Hunt level secret"; private static final CommunicatorConfiguration CONFIG = new CommunicatorConfiguration(TEST_KEY, TEST_SECRET, @@ -51,8 +51,9 @@ void testSignatureGenerationForGet() { try { Request updatedRequest = HEADER_GENERATOR.generateAdditionalRequestHeaders(request); - assertEquals(updatedRequest.header("Authorization"), - "GCS v1HMAC:KEY:ZSq7H19dyhyNGSPY5UgyPwITc5n4QG+zHnNDExIa6A8="); + assertEquals( + "GCS v1HMAC:KEY:ZSq7H19dyhyNGSPY5UgyPwITc5n4QG+zHnNDExIa6A8=", + updatedRequest.header("Authorization")); } catch (Exception e) { fail(e); } @@ -78,8 +79,8 @@ void testSignatureGenerationWithContentType() { try { Request updatedRequest = HEADER_GENERATOR.generateAdditionalRequestHeaders(request); - assertEquals(updatedRequest.header("Authorization"), - "GCS v1HMAC:KEY:c5aNDw4AUxRChugRyN0OmTCs38YLA9E/tR+k0bOQzyk="); + assertEquals("GCS v1HMAC:KEY:c5aNDw4AUxRChugRyN0OmTCs38YLA9E/tR+k0bOQzyk=", + updatedRequest.header("Authorization")); } catch (Exception e) { fail(e); } @@ -96,7 +97,7 @@ void addADateHeaderIfMissingTest() { Request updatedRequest = HEADER_GENERATOR.generateAdditionalRequestHeaders(request); assertNotNull(updatedRequest.headers().get("Date")); - assertNotEquals(updatedRequest.headers().get("Date"), ""); + assertNotEquals("", updatedRequest.headers().get("Date")); } catch (Exception e) { fail(e); } @@ -140,7 +141,7 @@ void addServerClientInfoIfMissingTest() { assertNotNull(clientMetaInfo); String metaInfoAsJson = new String(Base64.getDecoder().decode(clientMetaInfo), StandardCharsets.UTF_8); - assertEquals(metaInfoAsJson, "\"[]\""); + assertEquals("\"[]\"", metaInfoAsJson); } catch (Exception e) { fail(e); } From c40584df880ea18233682e4b9a99e1efccb2af76 Mon Sep 17 00:00:00 2001 From: Dirk Ehrhardt Date: Wed, 7 Aug 2024 16:35:07 +0200 Subject: [PATCH 18/29] chore: update sonar scanner workflow --- .github/workflows/sonar_scanner.yml | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/sonar_scanner.yml b/.github/workflows/sonar_scanner.yml index ffdff23..ead990e 100644 --- a/.github/workflows/sonar_scanner.yml +++ b/.github/workflows/sonar_scanner.yml @@ -10,16 +10,30 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + with: + # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - name: Set up JDK uses: actions/setup-java@v4 with: java-version: '17' distribution: 'adopt' - - name: Setup Gradle 8.9 - uses: gradle/actions/setup-gradle@v3 + - name: Cache Gradle packages + uses: actions/cache@v4 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: ${{ runner.os }}-gradle + - name: Cache SonarCloud packages + uses: actions/cache@v4 with: - gradle-version: 8.9 - - name: Run SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@master + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Build and analyze + run: ./gradlew build jacocoTestReport sonarqube --info env: + # Needed to get some information about the pull request, if any + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # SonarCloud access token should be generated from https://sonarcloud.io/account/security/ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From e1063ff6bdca8d519b7680b9d74069327775f769 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:22:34 +0200 Subject: [PATCH 19/29] tests: reuse global test config --- .../PaymentExecutionApiClientTest.java | 67 ++++++++++++------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClientTest.java b/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClientTest.java index 922c2dc..197f0a7 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClientTest.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClientTest.java @@ -17,7 +17,6 @@ import com.payone.commerce.platform.lib.errors.ApiErrorResponseException; import com.payone.commerce.platform.lib.errors.ApiException; import com.payone.commerce.platform.lib.errors.ApiResponseRetrievalException; -import com.payone.commerce.platform.lib.CommunicatorConfiguration; import com.payone.commerce.platform.lib.models.PaymentExecutionRequest; import com.payone.commerce.platform.lib.models.RefundPaymentResponse; import com.payone.commerce.platform.lib.models.RefundRequest; @@ -29,15 +28,11 @@ import com.payone.commerce.platform.lib.models.CompletePaymentResponse; import com.payone.commerce.platform.lib.models.CreatePaymentResponse; import com.payone.commerce.platform.lib.testutils.ApiResponseMocks; +import com.payone.commerce.platform.lib.testutils.TestConfig; import okhttp3.Response; public class PaymentExecutionApiClientTest { - private final String TEST_KEY = "KEY"; - private final String TEST_SECRET = "Super duper Ethan Hunt level secret"; - private final CommunicatorConfiguration CONFIG = new CommunicatorConfiguration(TEST_KEY, TEST_SECRET, - "awesome-api.com"); - @Nested @DisplayName("createPaymentRequest") class createPayment { @@ -45,7 +40,8 @@ class createPayment { @DisplayName("given request was successful, then return response") void createPaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CreatePaymentResponse expected = new CreatePaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new CreatePaymentResponse()); @@ -62,7 +58,8 @@ void createPaymentRequestSuccessful() throws InvalidKeyException, ApiException, @DisplayName("given request was unsuccessful (400), then throw exception") void createPaymentRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -80,7 +77,8 @@ void createPaymentRequestUnsuccessful() throws InvalidKeyException, ApiException @DisplayName("given request was unsuccessful (500) with empty body, then throw exception") void createPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -98,7 +96,8 @@ void createPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExcept @DisplayName("Given required params are null, then throw exception") void createPaymentRequestNullParams() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); PaymentExecutionRequest payload = new PaymentExecutionRequest(); IllegalArgumentException e; @@ -137,7 +136,8 @@ class CapturePayment { @DisplayName("given request was successful, then return response") void capturePaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CapturePaymentResponse expected = new CapturePaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new CapturePaymentResponse()); @@ -154,7 +154,8 @@ void capturePaymentRequestSuccessful() throws InvalidKeyException, ApiException, @DisplayName("given request unsuccessful (400), then throw exception") void capturePaymentRequestUnsuccessful400() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -172,7 +173,8 @@ void capturePaymentRequestUnsuccessful400() throws InvalidKeyException, ApiExcep @DisplayName("given request unsuccessful (500) with empty body, then throw exception") void capturePaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -190,7 +192,8 @@ void capturePaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExcep @DisplayName("Given required params are null, then throw exception") void capturePaymentRequestParamsNull() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CapturePaymentRequest payload = new CapturePaymentRequest(); IllegalArgumentException e; @@ -235,7 +238,8 @@ class CancelPayment { @DisplayName("given request was successful, then return response") void cancelPaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CancelPaymentResponse expected = new CancelPaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new CancelPayment()); @@ -252,7 +256,8 @@ void cancelPaymentRequestSuccessful() throws InvalidKeyException, ApiException, @DisplayName("given request unsuccessful (400), then throw exception") void cancelPaymentRequestUnsuccessful400() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -270,7 +275,8 @@ void cancelPaymentRequestUnsuccessful400() throws InvalidKeyException, ApiExcept @DisplayName("given request unsuccessful (500) with empty body, then throw exception") void cancelPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -288,7 +294,8 @@ void cancelPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExcept @DisplayName("Given required params are null, then throw exception") void cancelPaymentRequestParamsNull() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CancelPaymentRequest payload = new CancelPaymentRequest(); IllegalArgumentException e; @@ -333,7 +340,8 @@ class CompletePayment { @DisplayName("given request was successful, then return response") void completePaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CompletePaymentResponse expected = new CompletePaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new CompletePaymentResponse()); @@ -350,7 +358,8 @@ void completePaymentRequestSuccessful() throws InvalidKeyException, ApiException @DisplayName("given request unsuccessful (400), then throw exception") void completePaymentRequestUnsuccessful400() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -368,7 +377,8 @@ void completePaymentRequestUnsuccessful400() throws InvalidKeyException, ApiExce @DisplayName("given request unsuccessful (500) with empty body, then throw exception") void completePaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -386,7 +396,8 @@ void completePaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExce @DisplayName("Given required params are null, then throw exception") void completePaymentRequestParamsNull() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CompletePaymentRequest payload = new CompletePaymentRequest(); IllegalArgumentException e; @@ -431,7 +442,8 @@ class PaymentRefund { @DisplayName("given request was successful, then return response") void refundPaymentRequestSuccessful() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); RefundPaymentResponse expected = new RefundPaymentResponse(); Response response = ApiResponseMocks.createResponse(200, new RefundPaymentResponse()); @@ -448,7 +460,8 @@ void refundPaymentRequestSuccessful() throws InvalidKeyException, ApiException, @DisplayName("given request unsuccessful (400), then throw exception") void refundPaymentRequestUnsuccessful400() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -466,7 +479,8 @@ void refundPaymentRequestUnsuccessful400() throws InvalidKeyException, ApiExcept @DisplayName("given request unsuccessful (500) with empty body, then throw exception") void refundPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); doReturn(response).when(paymentExecutionApiClient).getResponse(any()); @@ -484,7 +498,8 @@ void refundPaymentRequestUnsuccessful500() throws InvalidKeyException, ApiExcept @DisplayName("Given required params are null, then throw exception") void refundPaymentRequestParamsNull() throws InvalidKeyException, ApiException, IOException { - PaymentExecutionApiClient paymentExecutionApiClient = spy(new PaymentExecutionApiClient(CONFIG)); + PaymentExecutionApiClient paymentExecutionApiClient = spy( + new PaymentExecutionApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); RefundRequest payload = new RefundRequest(); IllegalArgumentException e; From 134ece12447633561ac08116c76a4872db7029dc Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:23:04 +0200 Subject: [PATCH 20/29] feature: add integrator field to be send as part of the ServerMetaInfo --- .../com/payone/commerce/platform/app/App.java | 596 +++++++++--------- .../lib/CommunicatorConfiguration.java | 8 +- .../platform/lib/RequestHeaderGenerator.java | 2 +- .../platform/lib/utils/ServerMetaInfo.java | 11 +- .../lib/RequestHeaderGeneratorTest.java | 4 +- .../platform/lib/testutils/TestConfig.java | 2 +- 6 files changed, 330 insertions(+), 293 deletions(-) diff --git a/app/src/main/java/com/payone/commerce/platform/app/App.java b/app/src/main/java/com/payone/commerce/platform/app/App.java index e9990f4..0f2cf01 100644 --- a/app/src/main/java/com/payone/commerce/platform/app/App.java +++ b/app/src/main/java/com/payone/commerce/platform/app/App.java @@ -52,321 +52,343 @@ import com.payone.commerce.platform.lib.models.ShoppingCartInput; public class App { - private final String MERCHANT_ID; - private final CommunicatorConfiguration config; - private final CommerceCaseApiClient commerceCaseClient; - private final CheckoutApiClient checkoutClient; - private final OrderManagementCheckoutActionsApiClient orderManagementCheckoutClient; - private final PaymentExecutionApiClient paymentExecutionClient; + private final String MERCHANT_ID; + private final CommunicatorConfiguration config; + private final CommerceCaseApiClient commerceCaseClient; + private final CheckoutApiClient checkoutClient; + private final OrderManagementCheckoutActionsApiClient orderManagementCheckoutClient; + private final PaymentExecutionApiClient paymentExecutionClient; - public App(String API_KEY, String API_SECRET, String MERCHANT_ID) { - this.MERCHANT_ID = MERCHANT_ID; - this.config = new CommunicatorConfiguration(API_KEY, API_SECRET, "preprod.commerce-api.payone.com"); - try { - this.commerceCaseClient = new CommerceCaseApiClient(config); - this.checkoutClient = new CheckoutApiClient(config); - this.orderManagementCheckoutClient = new OrderManagementCheckoutActionsApiClient(config); - this.paymentExecutionClient = new PaymentExecutionApiClient(config); - } catch (InvalidKeyException e) { - throw new RuntimeException("Expected key to be valid", e); + public App(String API_KEY, String API_SECRET, String MERCHANT_ID) { + this.MERCHANT_ID = MERCHANT_ID; + this.config = new CommunicatorConfiguration(API_KEY, API_SECRET, "preprod.commerce-api.payone.com", + "YOUR_SHOP_NAME"); + try { + this.commerceCaseClient = new CommerceCaseApiClient(config); + this.checkoutClient = new CheckoutApiClient(config); + this.orderManagementCheckoutClient = new OrderManagementCheckoutActionsApiClient(config); + this.paymentExecutionClient = new PaymentExecutionApiClient(config); + } catch (InvalidKeyException e) { + throw new RuntimeException("Expected key to be valid", e); + } } - } - private static App initFromEnv() { - String apiKey = System.getenv("API_KEY"); - String apiSecret = System.getenv("API_SECRET"); - String merchantId = System.getenv("MERCHANT_ID"); + private static App initFromEnv() { + String apiKey = System.getenv("API_KEY"); + String apiSecret = System.getenv("API_SECRET"); + String merchantId = System.getenv("MERCHANT_ID"); - if (apiKey == null) { - throw new RuntimeException("required environment variable API_KEY is not set"); - } - if (apiSecret == null) { - throw new RuntimeException("required environment variable API_SECRET is not set"); - } - if (merchantId == null) { - throw new RuntimeException("required environment variable MERCHANT_ID is not set"); - } - - return new App(apiKey, apiSecret, merchantId); - } - - private void runCheckoutWithPaymentExecution(String commerceCaseMerchantReference) - throws IOException, ApiException { - // Create a commerce case, add customer data, put something into the shopping - // cart - CreateCommerceCaseRequest createCommerceCaseRequest = new CreateCommerceCaseRequest(); - - Customer customer = new Customer(); - PersonalInformation personalInformation = new PersonalInformation() - .dateOfBirth("19991112") - .name(new PersonalName().firstName("Ryan").surname("Carniato")); - ContactDetails contactDetails = new ContactDetails().emailAddress("mail@mail.com"); - Address address = new Address() - .countryCode("DE") - .zip("24937") - .city("Flensburg") - .street("Rathausplatz") - .houseNumber("1"); - customer.setPersonalInformation(personalInformation); - customer.setContactDetails(contactDetails); - customer.billingAddress(address); - - CreateCheckoutRequest checkoutRequest = new CreateCheckoutRequest(); - AmountOfMoney amountOfMoney = new AmountOfMoney() - .amount(3599L) - .currencyCode("EUR"); - Shipping shipping = new Shipping() - .address(new AddressPersonal() - .countryCode("DE") - .zip("24937") - .city("Flensburg") - .street("Rathausplatz").houseNumber("1")); - ShoppingCartInput shoppingCart = new ShoppingCartInput(); - CartItemInput cartItem = new CartItemInput() - .invoiceData(new CartItemInvoiceData() - .description("T-Shirt - Scaleshape Logo - S")) - .orderLineDetails(new OrderLineDetailsInput() - .productPrice(3599L) - .quantity(1L) - .productType(ProductType.GOODS)); - shoppingCart.addItemsItem(cartItem); + if (apiKey == null) { + throw new RuntimeException("required environment variable API_KEY is not set"); + } + if (apiSecret == null) { + throw new RuntimeException("required environment variable API_SECRET is not set"); + } + if (merchantId == null) { + throw new RuntimeException("required environment variable MERCHANT_ID is not set"); + } - checkoutRequest.amountOfMoney(amountOfMoney) - .shoppingCart(shoppingCart) - .shipping(shipping); + return new App(apiKey, apiSecret, merchantId); + } - createCommerceCaseRequest - .merchantReference(commerceCaseMerchantReference) - .customer(customer) - .checkout(checkoutRequest); + private void runCheckoutWithPaymentExecution(String commerceCaseMerchantReference) + throws IOException, ApiException { + // Create a commerce case, add customer data, put something into the shopping + // cart + CreateCommerceCaseRequest createCommerceCaseRequest = new CreateCommerceCaseRequest(); - CreateCommerceCaseResponse commerceCase = commerceCaseClient.createCommerceCaseRequest( - MERCHANT_ID, - createCommerceCaseRequest); + Customer customer = new Customer(); + PersonalInformation personalInformation = new PersonalInformation() + .dateOfBirth("19991112") + .name(new PersonalName().firstName("Ryan").surname("Carniato")); + ContactDetails contactDetails = new ContactDetails().emailAddress("mail@mail.com"); + Address address = new Address() + .countryCode("DE") + .zip("24937") + .city("Flensburg") + .street("Rathausplatz") + .houseNumber("1"); + customer.setPersonalInformation(personalInformation); + customer.setContactDetails(contactDetails); + customer.billingAddress(address); - PaymentExecutionRequest paymentExecutionRequest = new PaymentExecutionRequest() - .paymentExecutionSpecificInput(new PaymentExecutionSpecificInput() - .paymentReferences(new References().merchantReference("p-" + commerceCaseMerchantReference)) - .amountOfMoney(new AmountOfMoney() + CreateCheckoutRequest checkoutRequest = new CreateCheckoutRequest(); + AmountOfMoney amountOfMoney = new AmountOfMoney() .amount(3599L) - .currencyCode("EUR"))) - .paymentMethodSpecificInput(new PaymentMethodSpecificInput() - .sepaDirectDebitPaymentMethodSpecificInput(new SepaDirectDebitPaymentMethodSpecificInput() - .paymentProductId(771) - .paymentProduct771SpecificInput(new SepaDirectDebitPaymentProduct771SpecificInput() - .mandate(new ProcessingMandateInformation() - .bankAccountIban(new BankAccountInformation() - .iban("DE75512108001245126199") - .accountHolder("Ryan Carniato")) - .dateOfSignature("20240730") - .recurrenceType(MandateRecurrenceType.UNIQUE) - .uniqueMandateReference("m-" + commerceCaseMerchantReference) - .creditorId("DE98ZZZ09999999999"))))); - CreatePaymentResponse paymentResponse = this.paymentExecutionClient.createPayment(MERCHANT_ID, - commerceCase.getCommerceCaseId().toString(), - commerceCase.getCheckout().getCheckoutId().toString(), paymentExecutionRequest); - System.out.println(paymentResponse); - - CheckoutResponse finalCheckout = this.checkoutClient.getCheckoutRequest( - MERCHANT_ID, - commerceCase.getCommerceCaseId().toString(), - commerceCase.getCheckout().getCheckoutId().toString()); - System.out.println(finalCheckout); - } - - private void runSingleStepCheckout(String commerceCaseMerchantReference) - throws IOException, ApiException { - CreateCommerceCaseRequest payload = new CreateCommerceCaseRequest(); - - Customer customer = new Customer(); - PersonalInformation personalInformation = new PersonalInformation() - .dateOfBirth("19840505") - .name(new PersonalName().firstName("Rich").surname("Harris")); - ContactDetails contactDetails = new ContactDetails().emailAddress("mail@mail.com"); - Address address = new Address() - .countryCode("DE") - .zip("40474") - .city("Düsseldorf") - .street("Cecilienallee") - .houseNumber("2"); - customer.setPersonalInformation(personalInformation); - customer.setContactDetails(contactDetails); - customer.billingAddress(address); + .currencyCode("EUR"); + Shipping shipping = new Shipping() + .address(new AddressPersonal() + .countryCode("DE") + .zip("24937") + .city("Flensburg") + .street("Rathausplatz").houseNumber("1")); + ShoppingCartInput shoppingCart = new ShoppingCartInput(); + CartItemInput cartItem = new CartItemInput() + .invoiceData(new CartItemInvoiceData() + .description("T-Shirt - Scaleshape Logo - S")) + .orderLineDetails(new OrderLineDetailsInput() + .productPrice(3599L) + .quantity(1L) + .productType(ProductType.GOODS)); + shoppingCart.addItemsItem(cartItem); - CreateCheckoutRequest checkout = new CreateCheckoutRequest(); + checkoutRequest.amountOfMoney(amountOfMoney) + .shoppingCart(shoppingCart) + .shipping(shipping); - CheckoutReferences checkoutReferences = new CheckoutReferences() - .merchantReference("c-" + commerceCaseMerchantReference); - AmountOfMoney amountOfMoney = new AmountOfMoney() - .amount(5199L) - .currencyCode("EUR"); - Shipping shipping = new Shipping() - .address(new AddressPersonal() - .countryCode("DE") - .zip("40474") - .city("Düsseldorf") - .street("Cecilienallee").houseNumber("2")); - ShoppingCartInput shoppingCart = new ShoppingCartInput(); - CartItemInput cartItem = new CartItemInput() - .invoiceData(new CartItemInvoiceData() - .description("Hoodie - Scaleshape Logo - L")) - .orderLineDetails(new OrderLineDetailsInput() - .productPrice(5199L) - .quantity(1L) - .productType(ProductType.GOODS)); - shoppingCart.addItemsItem(cartItem); + createCommerceCaseRequest + .merchantReference(commerceCaseMerchantReference) + .customer(customer) + .checkout(checkoutRequest); - OrderRequest orderRequest = new OrderRequest() - .orderReferences(new References().merchantReference("o-" + commerceCaseMerchantReference)) - .paymentMethodSpecificInput(new PaymentMethodSpecificInput() - .sepaDirectDebitPaymentMethodSpecificInput(new SepaDirectDebitPaymentMethodSpecificInput() - .paymentProductId(771) - .paymentProduct771SpecificInput(new SepaDirectDebitPaymentProduct771SpecificInput() - .mandate(new ProcessingMandateInformation() - .bankAccountIban(new BankAccountInformation() - .iban("DE75512108001245126199") - .accountHolder("Rich Harris")) - .dateOfSignature("20240730") - .recurrenceType(MandateRecurrenceType.UNIQUE) - .uniqueMandateReference("m-" + commerceCaseMerchantReference) - .creditorId("DE98ZZZ09999999999"))))); + CreateCommerceCaseResponse commerceCase = commerceCaseClient.createCommerceCaseRequest( + MERCHANT_ID, + createCommerceCaseRequest); - checkout - .references(checkoutReferences) - .amountOfMoney(amountOfMoney) - .shipping(shipping) - .shoppingCart(shoppingCart) - .orderRequest(orderRequest); + PaymentExecutionRequest paymentExecutionRequest = new PaymentExecutionRequest() + .paymentExecutionSpecificInput(new PaymentExecutionSpecificInput() + .paymentReferences(new References().merchantReference( + "p-" + commerceCaseMerchantReference)) + .amountOfMoney(new AmountOfMoney() + .amount(3599L) + .currencyCode("EUR"))) + .paymentMethodSpecificInput(new PaymentMethodSpecificInput() + .sepaDirectDebitPaymentMethodSpecificInput( + new SepaDirectDebitPaymentMethodSpecificInput() + .paymentProductId(771) + .paymentProduct771SpecificInput( + new SepaDirectDebitPaymentProduct771SpecificInput() + .mandate(new ProcessingMandateInformation() + .bankAccountIban( + new BankAccountInformation() + .iban("DE75512108001245126199") + .accountHolder("Ryan Carniato")) + .dateOfSignature( + "20240730") + .recurrenceType(MandateRecurrenceType.UNIQUE) + .uniqueMandateReference( + "m-" + commerceCaseMerchantReference) + .creditorId("DE98ZZZ09999999999"))))); + CreatePaymentResponse paymentResponse = this.paymentExecutionClient.createPayment(MERCHANT_ID, + commerceCase.getCommerceCaseId().toString(), + commerceCase.getCheckout().getCheckoutId().toString(), paymentExecutionRequest); + System.out.println(paymentResponse); - payload.setMerchantReference(commerceCaseMerchantReference); - payload.checkout(checkout); - payload.customer(customer); + CheckoutResponse finalCheckout = this.checkoutClient.getCheckoutRequest( + MERCHANT_ID, + commerceCase.getCommerceCaseId().toString(), + commerceCase.getCheckout().getCheckoutId().toString()); + System.out.println(finalCheckout); + } - CreateCommerceCaseResponse commerceCase = commerceCaseClient.createCommerceCaseRequest(MERCHANT_ID, - payload); - System.out.println(commerceCase); - } + private void runSingleStepCheckout(String commerceCaseMerchantReference) + throws IOException, ApiException { + CreateCommerceCaseRequest payload = new CreateCommerceCaseRequest(); - private void runMultiStepCheckout(String commerceCaseMerchantReference) - throws IOException, ApiException { - // create the commercase - CreateCommerceCaseRequest createCommerceCaseRequest = new CreateCommerceCaseRequest() - .customer(new Customer() - .businessRelation("B2C") - .locale("de") - .personalInformation(new PersonalInformation().dateOfBirth("19840604") - .name(new PersonalName().firstName("Rich").surname("Harris"))) - .contactDetails(new ContactDetails().emailAddress("mail@mail.com")) - .billingAddress(new Address() + Customer customer = new Customer(); + PersonalInformation personalInformation = new PersonalInformation() + .dateOfBirth("19840505") + .name(new PersonalName().firstName("Rich").surname("Harris")); + ContactDetails contactDetails = new ContactDetails().emailAddress("mail@mail.com"); + Address address = new Address() .countryCode("DE") .zip("40474") .city("Düsseldorf") .street("Cecilienallee") - .houseNumber("2"))) - .checkout(new CreateCheckoutRequest() - .shoppingCart(new ShoppingCartInput() - .items(Arrays.asList(new CartItemInput() - .invoiceData(new CartItemInvoiceData() - .description("Frankenstein - Mary Shelley - Hardcover")) - .orderLineDetails(new OrderLineDetailsInput() - .productCode("shelley-42") - .productPrice(1999L) - .quantity(1L) - .productType(ProductType.GOODS) - .taxAmount(19L)))))); - CreateCommerceCaseResponse initialCommerceCase = this.commerceCaseClient.createCommerceCaseRequest(MERCHANT_ID, - createCommerceCaseRequest); - // add shipping information - PatchCheckoutRequest patchCheckoutRequest = new PatchCheckoutRequest() - .shipping(new Shipping() - .address(new AddressPersonal() - .countryCode("DE") - .zip("40474") - .city("Düsseldorf") - .street("Cecilienallee") - .houseNumber("2"))); - this.checkoutClient.updateCheckoutRequest( - MERCHANT_ID, - initialCommerceCase.getCommerceCaseId().toString(), - initialCommerceCase.getCheckout().getCheckoutId().toString(), - patchCheckoutRequest); + .houseNumber("2"); + customer.setPersonalInformation(personalInformation); + customer.setContactDetails(contactDetails); + customer.billingAddress(address); + + CreateCheckoutRequest checkout = new CreateCheckoutRequest(); - // confirm the order - OrderRequest orderRequest = new OrderRequest() - .orderType(OrderType.FULL) - .orderReferences(new References().merchantReference("o-" + commerceCaseMerchantReference)) - .paymentMethodSpecificInput(new PaymentMethodSpecificInput() - .paymentChannel(PaymentChannel.ECOMMERCE) - .sepaDirectDebitPaymentMethodSpecificInput(new SepaDirectDebitPaymentMethodSpecificInput() - .paymentProductId(771) - .paymentProduct771SpecificInput(new SepaDirectDebitPaymentProduct771SpecificInput() - .mandate(new ProcessingMandateInformation() - .bankAccountIban(new BankAccountInformation() - .iban("DE75512108001245126199") - .accountHolder("Rich Harris")) - .dateOfSignature("20240730") - .recurrenceType(MandateRecurrenceType.UNIQUE) - .uniqueMandateReference("m-" + commerceCaseMerchantReference) - .creditorId("DE98ZZZ09999999999"))))); - this.orderManagementCheckoutClient.createOrder( - MERCHANT_ID, - initialCommerceCase.getCommerceCaseId().toString(), - initialCommerceCase.getCheckout().getCheckoutId().toString(), - orderRequest); + CheckoutReferences checkoutReferences = new CheckoutReferences() + .merchantReference("c-" + commerceCaseMerchantReference); + AmountOfMoney amountOfMoney = new AmountOfMoney() + .amount(5199L) + .currencyCode("EUR"); + Shipping shipping = new Shipping() + .address(new AddressPersonal() + .countryCode("DE") + .zip("40474") + .city("Düsseldorf") + .street("Cecilienallee").houseNumber("2")); + ShoppingCartInput shoppingCart = new ShoppingCartInput(); + CartItemInput cartItem = new CartItemInput() + .invoiceData(new CartItemInvoiceData() + .description("Hoodie - Scaleshape Logo - L")) + .orderLineDetails(new OrderLineDetailsInput() + .productPrice(5199L) + .quantity(1L) + .productType(ProductType.GOODS)); + shoppingCart.addItemsItem(cartItem); - CheckoutResponse finalCheckout = this.checkoutClient.getCheckoutRequest( - MERCHANT_ID, - initialCommerceCase.getCommerceCaseId().toString(), - initialCommerceCase.getCheckout().getCheckoutId().toString()); - System.out.println(finalCheckout); + OrderRequest orderRequest = new OrderRequest() + .orderReferences(new References() + .merchantReference("o-" + commerceCaseMerchantReference)) + .paymentMethodSpecificInput(new PaymentMethodSpecificInput() + .sepaDirectDebitPaymentMethodSpecificInput( + new SepaDirectDebitPaymentMethodSpecificInput() + .paymentProductId(771) + .paymentProduct771SpecificInput( + new SepaDirectDebitPaymentProduct771SpecificInput() + .mandate(new ProcessingMandateInformation() + .bankAccountIban( + new BankAccountInformation() + .iban("DE75512108001245126199") + .accountHolder("Rich Harris")) + .dateOfSignature( + "20240730") + .recurrenceType(MandateRecurrenceType.UNIQUE) + .uniqueMandateReference( + "m-" + commerceCaseMerchantReference) + .creditorId("DE98ZZZ09999999999"))))); - // items are ready for shipment, the delivery can be performed to capture the - // money from the reservation - DeliverResponse delivery = this.orderManagementCheckoutClient.deliverOrder( - MERCHANT_ID, - initialCommerceCase.getCommerceCaseId().toString(), - initialCommerceCase.getCheckout().getCheckoutId().toString(), - new DeliverRequest().deliverType(DeliverType.FULL).isFinal(true)); - System.out.println(delivery); - } + checkout + .references(checkoutReferences) + .amountOfMoney(amountOfMoney) + .shipping(shipping) + .shoppingCart(shoppingCart) + .orderRequest(orderRequest); - public static void main(String[] args) { - App app = initFromEnv(); + payload.setMerchantReference(commerceCaseMerchantReference); + payload.checkout(checkout); + payload.customer(customer); - // creates a checkout and executes the payment in one go - try { - app.runCheckoutWithPaymentExecution("comc1a5"); - } catch (ApiErrorResponseException e) { - for (APIError error : e.getErrors()) { - System.err.println(error.getMessage()); - } - System.exit(1); - } catch (Exception e) { - throw new RuntimeException(e); + CreateCommerceCaseResponse commerceCase = commerceCaseClient.createCommerceCaseRequest(MERCHANT_ID, + payload); + System.out.println(commerceCase); } - // see: https://docs.payone.com/pcp/checkout-flows/step-by-step-checkout - // not that the given reference must be unique and has to renewed after each run - try { - app.runMultiStepCheckout("comc1a1"); - } catch (ApiErrorResponseException e) { - for (APIError error : e.getErrors()) { - System.err.println(error.getMessage()); - } - } catch (Exception e) { - throw new RuntimeException(e); + private void runMultiStepCheckout(String commerceCaseMerchantReference) + throws IOException, ApiException { + // create the commercase + CreateCommerceCaseRequest createCommerceCaseRequest = new CreateCommerceCaseRequest() + .customer(new Customer() + .businessRelation("B2C") + .locale("de") + .personalInformation(new PersonalInformation().dateOfBirth("19840604") + .name(new PersonalName().firstName("Rich") + .surname("Harris"))) + .contactDetails(new ContactDetails().emailAddress("mail@mail.com")) + .billingAddress(new Address() + .countryCode("DE") + .zip("40474") + .city("Düsseldorf") + .street("Cecilienallee") + .houseNumber("2"))) + .checkout(new CreateCheckoutRequest() + .shoppingCart(new ShoppingCartInput() + .items(Arrays.asList(new CartItemInput() + .invoiceData(new CartItemInvoiceData() + .description("Frankenstein - Mary Shelley - Hardcover")) + .orderLineDetails( + new OrderLineDetailsInput() + .productCode("shelley-42") + .productPrice(1999L) + .quantity(1L) + .productType(ProductType.GOODS) + .taxAmount(19L)))))); + CreateCommerceCaseResponse initialCommerceCase = this.commerceCaseClient.createCommerceCaseRequest( + MERCHANT_ID, + createCommerceCaseRequest); + // add shipping information + PatchCheckoutRequest patchCheckoutRequest = new PatchCheckoutRequest() + .shipping(new Shipping() + .address(new AddressPersonal() + .countryCode("DE") + .zip("40474") + .city("Düsseldorf") + .street("Cecilienallee") + .houseNumber("2"))); + this.checkoutClient.updateCheckoutRequest( + MERCHANT_ID, + initialCommerceCase.getCommerceCaseId().toString(), + initialCommerceCase.getCheckout().getCheckoutId().toString(), + patchCheckoutRequest); + + // confirm the order + OrderRequest orderRequest = new OrderRequest() + .orderType(OrderType.FULL) + .orderReferences(new References() + .merchantReference("o-" + commerceCaseMerchantReference)) + .paymentMethodSpecificInput(new PaymentMethodSpecificInput() + .paymentChannel(PaymentChannel.ECOMMERCE) + .sepaDirectDebitPaymentMethodSpecificInput( + new SepaDirectDebitPaymentMethodSpecificInput() + .paymentProductId(771) + .paymentProduct771SpecificInput( + new SepaDirectDebitPaymentProduct771SpecificInput() + .mandate(new ProcessingMandateInformation() + .bankAccountIban( + new BankAccountInformation() + .iban("DE75512108001245126199") + .accountHolder("Rich Harris")) + .dateOfSignature( + "20240730") + .recurrenceType(MandateRecurrenceType.UNIQUE) + .uniqueMandateReference( + "m-" + commerceCaseMerchantReference) + .creditorId("DE98ZZZ09999999999"))))); + this.orderManagementCheckoutClient.createOrder( + MERCHANT_ID, + initialCommerceCase.getCommerceCaseId().toString(), + initialCommerceCase.getCheckout().getCheckoutId().toString(), + orderRequest); + + CheckoutResponse finalCheckout = this.checkoutClient.getCheckoutRequest( + MERCHANT_ID, + initialCommerceCase.getCommerceCaseId().toString(), + initialCommerceCase.getCheckout().getCheckoutId().toString()); + System.out.println(finalCheckout); + + // items are ready for shipment, the delivery can be performed to capture the + // money from the reservation + DeliverResponse delivery = this.orderManagementCheckoutClient.deliverOrder( + MERCHANT_ID, + initialCommerceCase.getCommerceCaseId().toString(), + initialCommerceCase.getCheckout().getCheckoutId().toString(), + new DeliverRequest().deliverType(DeliverType.FULL).isFinal(true)); + System.out.println(delivery); } - // see: https://docs.payone.com/pcp/checkout-flows/one-step-checkout - // not that the given reference must be unique and has to renewed after each run - try { - app.runSingleStepCheckout("comc1a1"); - } catch (ApiErrorResponseException e) { - for (APIError error : e.getErrors()) { - System.err.println(error.getMessage()); - } - } catch (Exception e) { - throw new RuntimeException(e); + public static void main(String[] args) { + App app = initFromEnv(); + + // creates a checkout and executes the payment in one go + try { + app.runCheckoutWithPaymentExecution("comc1a5"); + } catch (ApiErrorResponseException e) { + for (APIError error : e.getErrors()) { + System.err.println(error.getMessage()); + } + System.exit(1); + } catch (Exception e) { + throw new RuntimeException(e); + } + + // see: https://docs.payone.com/pcp/checkout-flows/step-by-step-checkout + // not that the given reference must be unique and has to renewed after each run + try { + app.runMultiStepCheckout("comc1a1"); + } catch (ApiErrorResponseException e) { + for (APIError error : e.getErrors()) { + System.err.println(error.getMessage()); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + + // see: https://docs.payone.com/pcp/checkout-flows/one-step-checkout + // not that the given reference must be unique and has to renewed after each run + try { + app.runSingleStepCheckout("comc1a1"); + } catch (ApiErrorResponseException e) { + for (APIError error : e.getErrors()) { + System.err.println(error.getMessage()); + } + } catch (Exception e) { + throw new RuntimeException(e); + } } - } } diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/CommunicatorConfiguration.java b/lib/src/main/java/com/payone/commerce/platform/lib/CommunicatorConfiguration.java index 9bbcfed..a6fb90d 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/CommunicatorConfiguration.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/CommunicatorConfiguration.java @@ -4,11 +4,13 @@ public class CommunicatorConfiguration { private final String apiKey; private final String apiSecret; private final String host; + private final String integrator; - public CommunicatorConfiguration(String apiKey, String apiSecret, String host) { + public CommunicatorConfiguration(String apiKey, String apiSecret, String host, String integrator) { this.apiKey = apiKey; this.apiSecret = apiSecret; this.host = host; + this.integrator = integrator; } public String getApiKey() { @@ -22,4 +24,8 @@ public String getApiSecret() { public String getHost() { return host; } + + public String getIntegrator() { + return integrator; + } } diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java index b8bdf90..da65628 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java @@ -106,7 +106,7 @@ private String sign(String target) { } private String getServerMetaInfo() { - ServerMetaInfo meta = new ServerMetaInfo(); + ServerMetaInfo meta = new ServerMetaInfo(this.config.getIntegrator()); String jsonString; try { diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/utils/ServerMetaInfo.java b/lib/src/main/java/com/payone/commerce/platform/lib/utils/ServerMetaInfo.java index 82687b8..f7683b8 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/utils/ServerMetaInfo.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/utils/ServerMetaInfo.java @@ -6,6 +6,7 @@ public class ServerMetaInfo { public String platformIdentifier; public String sdkIdentifier; public String sdkCreator; + public String integrator; public ServerMetaInfo() { this.platformIdentifier = String.format("%s, java version is: %s", System.getProperty("os.name"), @@ -13,8 +14,16 @@ public ServerMetaInfo() { // version gets updated with the prepare-release.sh script this.sdkIdentifier = "JavaServerSDK/v0.0.2"; this.sdkCreator = "PAYONE GmbH"; + this.integrator = null; + } - // TODO: what about integrator? + public ServerMetaInfo(String integrator) { + this.platformIdentifier = String.format("%s, java version is: %s", System.getProperty("os.name"), + System.getProperty("java.version")); + // version gets updated with the prepare-release.sh script + this.sdkIdentifier = "JavaServerSDK/v0.0.2"; + this.sdkCreator = "PAYONE GmbH"; + this.integrator = integrator; } @Override diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java b/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java index 812bc7c..42bb376 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java @@ -25,7 +25,7 @@ public class RequestHeaderGeneratorTest { private static final String TEST_KEY = "KEY"; private static final String TEST_SECRET = "Super duper Ethan Hunt level secret"; private static final CommunicatorConfiguration CONFIG = new CommunicatorConfiguration(TEST_KEY, TEST_SECRET, - "awesome-api.com"); + "awesome-api.com", null); private static final RequestHeaderGenerator HEADER_GENERATOR; static { try { @@ -119,7 +119,7 @@ void addServerMetaInfoIfMissingTest() { serverMetaInfoAsJson = new String(Base64.getDecoder().decode(serverMetaInfoBase64), StandardCharsets.UTF_8); ServerMetaInfo serverMetaInfo = objectMapper.readValue(serverMetaInfoAsJson, ServerMetaInfo.class); - assertEquals(serverMetaInfo, new ServerMetaInfo()); + assertEquals(serverMetaInfo, new ServerMetaInfo(null)); } catch (JsonProcessingException e) { fail(String.format("Decoded meta info '%s', should have been valid json", serverMetaInfoAsJson), e); } catch (Exception e) { diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/testutils/TestConfig.java b/lib/src/test/java/com/payone/commerce/platform/lib/testutils/TestConfig.java index c903ced..5ac6c6e 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/testutils/TestConfig.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/testutils/TestConfig.java @@ -6,5 +6,5 @@ public abstract class TestConfig { public static final CommunicatorConfiguration COMMUNICATOR_CONFIGURATION = new CommunicatorConfiguration("KEY", "Super duper Ethan Hunt level secret", - "awesome-api.com"); + "awesome-api.com", null); } From 61d315da56d777b6864510acfbc04bd39a95e621 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:24:29 +0200 Subject: [PATCH 21/29] chore: use single expression for initializing and assigning json string when serializing --- .../commerce/platform/lib/endpoints/CheckoutApiClient.java | 4 +--- .../platform/lib/endpoints/CommerceCaseApiClient.java | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java index 26d5d10..02299e2 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java @@ -157,9 +157,7 @@ public void updateCheckoutRequest(String merchantId, String commerceCaseId, Stri .addPathSegment(checkoutId) .build(); - String jsonString = null; - - jsonString = JsonSerializer.serializeToJson(payload); + String jsonString = JsonSerializer.serializeToJson(payload); Request request = new Request.Builder() .url(url) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java index 81be14a..c2d0cce 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java @@ -145,9 +145,7 @@ public void updateCommerceCaseRequest(String merchantId, String commerceCaseId, .addPathSegment(commerceCaseId) .build(); - String jsonString = null; - - jsonString = JsonSerializer.serializeToJson(payload); + String jsonString = JsonSerializer.serializeToJson(payload); RequestBody formBody = RequestBody.create("{\"customer\":" + jsonString + "}", JSON); From 68922e5d669fa0b6eafb7c76a755f42164bc575f Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:30:06 +0200 Subject: [PATCH 22/29] refactor: use constant for http header name 'Content-Type' --- .../platform/lib/RequestHeaderGenerator.java | 12 ++++++------ .../platform/lib/endpoints/BaseApiClient.java | 6 ++++-- .../platform/lib/endpoints/CheckoutApiClient.java | 4 ++-- .../lib/endpoints/CommerceCaseApiClient.java | 4 ++-- .../OrderManagementCheckoutActionsApiClient.java | 8 ++++---- .../lib/endpoints/PaymentExecutionApiClient.java | 10 +++++----- .../lib/endpoints/PaymentInformationApiClient.java | 2 +- 7 files changed, 24 insertions(+), 22 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java index da65628..e94e5a6 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java @@ -17,14 +17,14 @@ import okhttp3.Request; public class RequestHeaderGenerator { - - public static final String SERVER_META_INFO_HEADER_NAME = "X-GCS-ServerMetaInfo"; + private static final String AUTHORIZATION_HEADER_NAME = "Authorization"; + private static final String CONTENT_TYPE_HEADER_NAME = "Content-Type"; + private static final String DATE_HEADER_NAME = "Date"; public static final String CLIENT_META_INFO_HEADER_NAME = "X-GCS-ClientMetaInfo"; + public static final String SERVER_META_INFO_HEADER_NAME = "X-GCS-ServerMetaInfo"; private static final String ALGORITHM = "HmacSHA256"; private static final String WHITESPACE_REGEX = "\\r?\\n[\\h]*"; - private final String DATE_HEADER_NAME = "Date"; - private final String AUTHORIZATION_HEADER_NAME = "Authorization"; private final CommunicatorConfiguration config; private final Mac mac; @@ -69,8 +69,8 @@ private String getAuthHeader(Request request, Builder headersBuilder) { StringBuilder stringToSign = new StringBuilder(request.method()); stringToSign.append("\n"); // 2. Content-Type - if (headersBuilder.get("Content-Type") != null) { - stringToSign.append(headersBuilder.get("Content-Type")); + if (headersBuilder.get(CONTENT_TYPE_HEADER_NAME) != null) { + stringToSign.append(headersBuilder.get(CONTENT_TYPE_HEADER_NAME)); } stringToSign.append("\n"); // 3. Date diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java index 9f94df5..35765f9 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java @@ -19,9 +19,11 @@ import okhttp3.Response; public class BaseApiClient { + private static final String JSON_PARSE_ERROR = "Excepted valid JSON response, but failed to parse"; + protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + protected static final String CONTENT_TYPE_HEADER_NAME = "Content-Type"; + private final OkHttpClient client = new OkHttpClient(); - private final String JSON_PARSE_ERROR = "Excepted valid JSON response, but failed to parse"; - protected final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); private final RequestHeaderGenerator requestHeaderGenerator; private final CommunicatorConfiguration config; diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java index 02299e2..c6c839b 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java @@ -58,7 +58,7 @@ public CreateCheckoutResponse createCheckoutRequest(String merchantId, String co Request request = new Request.Builder() .url(url) .post(RequestBody.create(jsonString, JSON)) - .header("Content-Type", JSON.toString()) + .header(CONTENT_TYPE_HEADER_NAME, JSON.toString()) .build(); return this.makeApiCall(request, CreateCheckoutResponse.class); @@ -162,7 +162,7 @@ public void updateCheckoutRequest(String merchantId, String commerceCaseId, Stri Request request = new Request.Builder() .url(url) .patch(RequestBody.create(jsonString, JSON)) - .header("Content-Type", JSON.toString()) + .header(CONTENT_TYPE_HEADER_NAME, JSON.toString()) .build(); this.makeApiCall(request); diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java index c2d0cce..7509c77 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java @@ -53,7 +53,7 @@ public CreateCommerceCaseResponse createCommerceCaseRequest(String merchantId, C Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CreateCommerceCaseResponse.class); @@ -152,7 +152,7 @@ public void updateCommerceCaseRequest(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .patch(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); this.makeApiCall(request); diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java index ba38dfd..fdc70b9 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java @@ -64,7 +64,7 @@ public OrderResponse createOrder(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, OrderResponse.class); @@ -106,7 +106,7 @@ public DeliverResponse deliverOrder(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, DeliverResponse.class); @@ -148,7 +148,7 @@ public ReturnResponse returnOrder(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, ReturnResponse.class); @@ -190,7 +190,7 @@ public CancelResponse cancelOrder(String merchantId, String commerceCaseId, Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CancelResponse.class); diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java index 4dfbf98..1a396e9 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java @@ -63,7 +63,7 @@ public CreatePaymentResponse createPayment(String merchantId, String commerceCas Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CreatePaymentResponse.class); @@ -110,7 +110,7 @@ public CapturePaymentResponse capturePayment(String merchantId, String commerceC Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CapturePaymentResponse.class); @@ -157,7 +157,7 @@ public CancelPaymentResponse cancelPayment(String merchantId, String commerceCas Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CancelPaymentResponse.class); @@ -204,7 +204,7 @@ public RefundPaymentResponse refundPayment(String merchantId, String commerceCas Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, RefundPaymentResponse.class); @@ -251,7 +251,7 @@ public CompletePaymentResponse completePayment(String merchantId, String commerc Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, CompletePaymentResponse.class); diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java index 0c3d511..4cf4a60 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java @@ -54,7 +54,7 @@ public PaymentInformationResponse createPaymentInformation(String merchantId, St Request request = new Request.Builder() .url(url) .post(formBody) - .header("Content-Type", formBody.contentType().toString()) + .header(CONTENT_TYPE_HEADER_NAME, formBody.contentType().toString()) .build(); return this.makeApiCall(request, PaymentInformationResponse.class); From e01a355ccc27cc33705c89ac7473544675dbfe00 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:34:12 +0200 Subject: [PATCH 23/29] chore: fix typo of 'gradle' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf3e835..b3e3b80 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ class App { This repo contains a demo app that showcases how to implement common use cases, like a [Step-by-Step Checkout](https://docs.payone.com/pcp/checkout-flows/step-by-step-checkout) and an [One-Stop-Checkout](https://docs.payone.com/pcp/checkout-flows/one-step-checkout). For each use case the demo app contains a private method in the top level class `App`. You can run the app to execute the code within in the sandbox API. This is a good way to test, if your setup is correct. -If you're using grald can run it within the demo app directory via: +If you're using gradle can run it within the demo app directory via: ```sh API_KEY=api_key API_SECRET=api_secret MERCHANT_ID=123 COMMERCE_CASE_ID=234 CHECKOUT_ID=345 ./gradlew :app:run From 1ef3a029e93452268329dee5781d8d80ab09fc38 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:51:37 +0200 Subject: [PATCH 24/29] refactor(NoSuchAlgorithm): Use meaningful AssertionError instead of RuntimeException --- .../commerce/platform/lib/RequestHeaderGenerator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java index e94e5a6..873a070 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/RequestHeaderGenerator.java @@ -38,7 +38,7 @@ public RequestHeaderGenerator(CommunicatorConfiguration config) throws InvalidKe ALGORITHM); this.mac.init(secretKeySpec); } catch (NoSuchAlgorithmException e) { - throw new RuntimeException("HmacSHA256 must be available to use the PCP Java SDK", e); + throw new AssertionError("HmacSHA256 must be available to use the PCP Java SDK", e); } } @@ -90,7 +90,7 @@ private String getAuthHeader(Request request, Builder headersBuilder) { .append("\n"); } // 5. Canonicalized Resource (has to include query parameters) - stringToSign.append(request.url().encodedPath().toString()); + stringToSign.append(request.url().encodedPath()); if (request.url().encodedQuery() != null) { stringToSign.append("?") .append(request.url().encodedQuery()); @@ -113,7 +113,7 @@ private String getServerMetaInfo() { jsonString = JsonSerializer.serializeToJson(meta); return Base64.getEncoder().encodeToString(jsonString.getBytes(StandardCharsets.UTF_8)); } catch (JsonProcessingException e) { - throw new RuntimeException( + throw new AssertionError( "Server Meta Info must be encodable as JSON, this is likely an internal bug of the java PCP SDK", e); } From c242ec23f3c3d6395165d5b6a993775de4a217a6 Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 15:55:19 +0200 Subject: [PATCH 25/29] refactor(handleError): avoid unneccessary null check for responseBody --- .../payone/commerce/platform/lib/endpoints/BaseApiClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java index 35765f9..ae79c87 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java @@ -88,7 +88,7 @@ private void handleError(Response response) } String responseBody = response.body().string(); - if (responseBody == null || responseBody.isEmpty()) { + if (responseBody.isEmpty()) { throw new ApiResponseRetrievalException(response.code(), responseBody); } try { From 50339ed34d836d7c9c1304db9e3ede158599db6d Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 16:11:35 +0200 Subject: [PATCH 26/29] refactor(illegal-argument-messages): use constants for errors on required arguments --- .../platform/lib/endpoints/BaseApiClient.java | 4 +++ .../lib/endpoints/CheckoutApiClient.java | 28 ++++++++--------- .../lib/endpoints/CommerceCaseApiClient.java | 8 ++--- ...derManagementCheckoutActionsApiClient.java | 24 +++++++-------- .../endpoints/PaymentExecutionApiClient.java | 30 +++++++++---------- .../PaymentInformationApiClient.java | 10 +++---- 6 files changed, 54 insertions(+), 50 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java index ae79c87..f7f3928 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/BaseApiClient.java @@ -20,6 +20,10 @@ public class BaseApiClient { private static final String JSON_PARSE_ERROR = "Excepted valid JSON response, but failed to parse"; + protected static final String MERCHANT_ID_REQUIRED_ERROR = "Merchant ID is required"; + protected static final String COMMERCE_CASE_ID_REQUIRED_ERROR = "Commerce Case ID is required"; + protected static final String CHECKOUT_ID_REQUIRED_ERROR = "Checkout ID is required"; + protected static final String PAYLOAD_REQUIRED_ERROR = "Payload is required"; protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); protected static final String CONTENT_TYPE_HEADER_NAME = "Content-Type"; diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java index c6c839b..ce51e95 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClient.java @@ -32,13 +32,13 @@ public CreateCheckoutResponse createCheckoutRequest(String merchantId, String co CreateCheckoutRequest payload) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -68,13 +68,13 @@ public CreateCheckoutResponse createCheckoutRequest(String merchantId, String co public CheckoutResponse getCheckoutRequest(String merchantId, String commerceCaseId, String checkoutId) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -105,7 +105,7 @@ public CheckoutsResponse getCheckoutsRequest(String merchantID) public CheckoutsResponse getCheckoutsRequest(String merchantId, GetCheckoutsQuery queryParams) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } HttpUrl.Builder urlBuilder = new HttpUrl.Builder() @@ -134,16 +134,16 @@ public void updateCheckoutRequest(String merchantId, String commerceCaseId, Stri PatchCheckoutRequest payload) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -172,13 +172,13 @@ public void updateCheckoutRequest(String merchantId, String commerceCaseId, Stri public void removeCheckoutRequest(String merchantId, String commerceCaseId, String checkoutId) throws ApiErrorResponseException, ApiResponseRetrievalException, IOException { if (merchantId == null) { - throw new IllegalArgumentException("Merchant ID is required"); + throw new IllegalArgumentException(MERCHANT_ID_REQUIRED_ERROR); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java index 7509c77..9e8b096 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/CommerceCaseApiClient.java @@ -35,7 +35,7 @@ public CreateCommerceCaseResponse createCommerceCaseRequest(String merchantId, C throw new IllegalArgumentException("Merchant ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -66,7 +66,7 @@ public CommerceCaseResponse getCommerceCaseRequest(String merchantId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } HttpUrl.Builder urlBuilder = new HttpUrl.Builder() @@ -130,10 +130,10 @@ public void updateCommerceCaseRequest(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java index fdc70b9..deab21b 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/OrderManagementCheckoutActionsApiClient.java @@ -36,13 +36,13 @@ public OrderResponse createOrder(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -78,13 +78,13 @@ public DeliverResponse deliverOrder(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -120,13 +120,13 @@ public ReturnResponse returnOrder(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -162,13 +162,13 @@ public CancelResponse cancelOrder(String merchantId, String commerceCaseId, throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java index 1a396e9..4440e8d 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentExecutionApiClient.java @@ -35,13 +35,13 @@ public CreatePaymentResponse createPayment(String merchantId, String commerceCas throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -77,16 +77,16 @@ public CapturePaymentResponse capturePayment(String merchantId, String commerceC throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentExecutionId == null) { throw new IllegalArgumentException("Payment Execution ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -124,16 +124,16 @@ public CancelPaymentResponse cancelPayment(String merchantId, String commerceCas throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentExecutionId == null) { throw new IllegalArgumentException("Payment Execution ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -171,16 +171,16 @@ public RefundPaymentResponse refundPayment(String merchantId, String commerceCas throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentExecutionId == null) { throw new IllegalArgumentException("Payment Execution ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -218,16 +218,16 @@ public CompletePaymentResponse completePayment(String merchantId, String commerc throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentExecutionId == null) { throw new IllegalArgumentException("Payment Execution ID is required"); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java index 4cf4a60..a4dc715 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/endpoints/PaymentInformationApiClient.java @@ -26,13 +26,13 @@ public PaymentInformationResponse createPaymentInformation(String merchantId, St throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (payload == null) { - throw new IllegalArgumentException("Payload is required"); + throw new IllegalArgumentException(PAYLOAD_REQUIRED_ERROR); } HttpUrl url = new HttpUrl.Builder() @@ -68,10 +68,10 @@ public PaymentInformationResponse getPaymentInformation(String merchantId, Strin throw new IllegalArgumentException("Merchant ID is required"); } if (commerceCaseId == null) { - throw new IllegalArgumentException("Commerce Case ID is required"); + throw new IllegalArgumentException(COMMERCE_CASE_ID_REQUIRED_ERROR); } if (checkoutId == null) { - throw new IllegalArgumentException("Checkout ID is required"); + throw new IllegalArgumentException(CHECKOUT_ID_REQUIRED_ERROR); } if (paymentInformationId == null) { throw new IllegalArgumentException("Payment Information ID is required"); From 850acccf6f03b6ce0693193ca67534b821b67dba Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 16:18:26 +0200 Subject: [PATCH 27/29] refactor: hide constructor, remove unneccessary exception declaration --- .../commerce/platform/lib/serializer/JsonSerializer.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/com/payone/commerce/platform/lib/serializer/JsonSerializer.java b/lib/src/main/java/com/payone/commerce/platform/lib/serializer/JsonSerializer.java index f78b6e7..e6705bc 100644 --- a/lib/src/main/java/com/payone/commerce/platform/lib/serializer/JsonSerializer.java +++ b/lib/src/main/java/com/payone/commerce/platform/lib/serializer/JsonSerializer.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @@ -18,17 +17,20 @@ public class JsonSerializer { JSON_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } + private JsonSerializer() { + } + public static String serializeToJson(Object object) throws JsonProcessingException { return JSON_MAPPER.writeValueAsString(object); } public static T deserializeFromJson(String json, Class clazz) - throws JsonMappingException, JsonProcessingException { + throws JsonProcessingException { return JSON_MAPPER.readValue(json, clazz); } public static T deserializeFromJson(String json, TypeReference valueTypeRef) - throws JsonMappingException, JsonProcessingException { + throws JsonProcessingException { return JSON_MAPPER.readValue(json, valueTypeRef); } } From 500af5200ffa8c0075bc557a2f268a0b7c8e345f Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 16:23:50 +0200 Subject: [PATCH 28/29] tests: only declare possible exceptions --- .../lib/endpoints/CheckoutApiClientTest.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClientTest.java b/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClientTest.java index c37396b..d3db66e 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClientTest.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/endpoints/CheckoutApiClientTest.java @@ -35,7 +35,7 @@ public class CheckoutApiClientTest { class CreateCheckoutRequestTests { @Test @DisplayName("given request was successful, then return response") - void createCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void createCheckoutRequestSuccessful() throws InvalidKeyException, IOException, ApiException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -54,7 +54,7 @@ void createCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void createCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void createCheckoutRequestUnsuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); @@ -70,7 +70,7 @@ void createCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiExceptio @Test @DisplayName("given request was unsuccessful (500) with an empty body, then throw exception") - void createCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void createCheckoutRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); @@ -86,7 +86,7 @@ void createCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiExcep @Test @DisplayName("given some params are null, then throw exception") - void createCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void createCheckoutRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CreateCheckoutRequest payload = new CreateCheckoutRequest(); @@ -114,7 +114,7 @@ void createCheckoutRequestNullParams() throws InvalidKeyException, ApiException, class GetCheckoutRequestTests { @Test @DisplayName("given request was successful, then return response") - void getCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void getCheckoutRequestSuccessful() throws InvalidKeyException, IOException, ApiException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); CheckoutResponse expected = new CheckoutResponse(); @@ -131,7 +131,7 @@ void getCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IO @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void getCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void getCheckoutRequestUnsuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); @@ -146,7 +146,7 @@ void getCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (500), then throw exception") - void getCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void getCheckoutRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); @@ -162,7 +162,7 @@ void getCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiExceptio @Test @DisplayName("given some params are null, then throw exception") - void getCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void getCheckoutRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -191,7 +191,7 @@ void getCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IO class getCheckoutsRequestTests { @Test @DisplayName("given request was successful, then return response") - void getCheckoutsRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void getCheckoutsRequestSuccessful() throws InvalidKeyException, IOException, ApiException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -209,7 +209,7 @@ void getCheckoutsRequestSuccessful() throws InvalidKeyException, ApiException, I @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void getCheckoutsRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void getCheckoutsRequestUnsuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -227,7 +227,7 @@ void getCheckoutsRequestUnsuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (500) with empty body, then throw exception") - void getCommerceCaseRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void getCommerceCaseRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -244,7 +244,7 @@ void getCommerceCaseRequestUnsuccessful500() throws InvalidKeyException, ApiExce @Test @DisplayName("given some params are null, then throw exception") - void getCheckoutsRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void getCheckoutsRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy( new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -263,7 +263,7 @@ void getCheckoutsRequestNullParams() throws InvalidKeyException, ApiException, I class UpdateCheckoutRequestTests { @Test @DisplayName("given request was successful, then throw no exception") - void updateCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void updateCheckoutRequestSuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createResponse(200); @@ -279,7 +279,7 @@ void updateCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void updateCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void updateCheckoutRequestUnsuccessful() throws InvalidKeyException, IOException { Response response = ApiResponseMocks.createErrorResponse(400); CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); doReturn(response).when(checkoutApiClient).getResponse(any()); @@ -293,7 +293,7 @@ void updateCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiExceptio @Test @DisplayName("given request was unsuccessful (500), then throw exception") - void updateCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void updateCheckoutRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(500); @@ -310,7 +310,7 @@ void updateCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiExcep @Test @DisplayName("given some params are null, then throw exception") - void updateCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void updateCheckoutRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); @@ -351,7 +351,7 @@ void updateCheckoutRequestNullParams() throws InvalidKeyException, ApiException, class RemoveCheckoutRequestTests { @Test @DisplayName("given request was successful, then throw no exception") - void removeCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, IOException { + void removeCheckoutRequestSuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createResponse(200); @@ -365,7 +365,7 @@ void removeCheckoutRequestSuccessful() throws InvalidKeyException, ApiException, @Test @DisplayName("given request was unsuccessful (400), then throw exception") - void removeCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiException, IOException { + void removeCheckoutRequestUnsuccessful() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createErrorResponse(400); @@ -381,7 +381,7 @@ void removeCheckoutRequestUnsuccessful() throws InvalidKeyException, ApiExceptio @Test @DisplayName("given request was unsuccessful (500), then throw exception") - void removeCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiException, IOException { + void removeCheckoutRequestUnsuccessful500() throws InvalidKeyException, IOException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); Response response = ApiResponseMocks.createEmptyErrorResponse(500); @@ -397,7 +397,7 @@ void removeCheckoutRequestUnsuccessful500() throws InvalidKeyException, ApiExcep @Test @DisplayName("given some params are null, then throw exception") - void removeCheckoutRequestNullParams() throws InvalidKeyException, ApiException, IOException { + void removeCheckoutRequestNullParams() throws InvalidKeyException { CheckoutApiClient checkoutApiClient = spy(new CheckoutApiClient(TestConfig.COMMUNICATOR_CONFIGURATION)); From cdf39284ed32d9702061ba329d25a3f8b43e8fcb Mon Sep 17 00:00:00 2001 From: Lukas Rosenfeldt Date: Wed, 7 Aug 2024 16:24:50 +0200 Subject: [PATCH 29/29] tests: remove visibilty modifier from class, use idiomatic order of arguments in assert calls --- .../platform/lib/RequestHeaderGeneratorTest.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java b/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java index 42bb376..a9cbe2f 100644 --- a/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java +++ b/lib/src/test/java/com/payone/commerce/platform/lib/RequestHeaderGeneratorTest.java @@ -21,7 +21,7 @@ import java.util.Base64; import java.util.Date; -public class RequestHeaderGeneratorTest { +class RequestHeaderGeneratorTest { private static final String TEST_KEY = "KEY"; private static final String TEST_SECRET = "Super duper Ethan Hunt level secret"; private static final CommunicatorConfiguration CONFIG = new CommunicatorConfiguration(TEST_KEY, TEST_SECRET, @@ -51,8 +51,9 @@ void testSignatureGenerationForGet() { try { Request updatedRequest = HEADER_GENERATOR.generateAdditionalRequestHeaders(request); - assertEquals(updatedRequest.header("Authorization"), - "GCS v1HMAC:KEY:ZSq7H19dyhyNGSPY5UgyPwITc5n4QG+zHnNDExIa6A8="); + assertEquals( + "GCS v1HMAC:KEY:ZSq7H19dyhyNGSPY5UgyPwITc5n4QG+zHnNDExIa6A8=", + updatedRequest.header("Authorization")); } catch (Exception e) { fail(e); } @@ -78,8 +79,8 @@ void testSignatureGenerationWithContentType() { try { Request updatedRequest = HEADER_GENERATOR.generateAdditionalRequestHeaders(request); - assertEquals(updatedRequest.header("Authorization"), - "GCS v1HMAC:KEY:c5aNDw4AUxRChugRyN0OmTCs38YLA9E/tR+k0bOQzyk="); + assertEquals("GCS v1HMAC:KEY:c5aNDw4AUxRChugRyN0OmTCs38YLA9E/tR+k0bOQzyk=", + updatedRequest.header("Authorization")); } catch (Exception e) { fail(e); } @@ -96,7 +97,7 @@ void addADateHeaderIfMissingTest() { Request updatedRequest = HEADER_GENERATOR.generateAdditionalRequestHeaders(request); assertNotNull(updatedRequest.headers().get("Date")); - assertNotEquals(updatedRequest.headers().get("Date"), ""); + assertNotEquals("", updatedRequest.headers().get("Date")); } catch (Exception e) { fail(e); } @@ -140,7 +141,7 @@ void addServerClientInfoIfMissingTest() { assertNotNull(clientMetaInfo); String metaInfoAsJson = new String(Base64.getDecoder().decode(clientMetaInfo), StandardCharsets.UTF_8); - assertEquals(metaInfoAsJson, "\"[]\""); + assertEquals("\"[]\"", metaInfoAsJson); } catch (Exception e) { fail(e); }