diff --git a/.github/workflows/CI_test.yml b/.github/workflows/CI_test.yml new file mode 100644 index 0000000..5ed13d1 --- /dev/null +++ b/.github/workflows/CI_test.yml @@ -0,0 +1,41 @@ +name: Lint and Test + +on: + pull_request: + branches: + - develop + - main + +jobs: + lint-and-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + java-version: [8,11,17,18,19,20,21,22,23] + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK ${{ matrix.java-version }} + uses: actions/setup-java@v3 + with: + java-version: ${{ matrix.java-version }} + distribution: temurin + - name: Check current Java version + run: java -version + + # Step 3: Validate Maven dependencies + - name: Validate Maven dependencies with Java ${{ matrix.java-version }} + working-directory: ./paytrailpayment-sdk + run: mvn dependency:resolve + + # Step 4: Run Maven lint checks (Checkstyle, SpotBugs, etc.) + - name: Run Maven lint checks with Java ${{ matrix.java-version }} + working-directory: ./paytrailpayment-sdk + run: mvn checkstyle:check + + # Step 5: Run Maven tests + - name: Run Maven tests with Java ${{ matrix.java-version }} + working-directory: ./paytrailpayment-sdk + run: mvn test \ No newline at end of file diff --git a/paytrailpayment-app/pom.xml b/paytrailpayment-app/pom.xml index dbe8884..a522b24 100644 --- a/paytrailpayment-app/pom.xml +++ b/paytrailpayment-app/pom.xml @@ -16,7 +16,8 @@ org.projectlombok lombok - 1.18.26 + 1.18.36 + provided org.junit.jupiter @@ -34,6 +35,12 @@ jackson-databind 2.14.0 + + io.paytrailpayment + paytrailpayment-sdk + 1.0-SNAPSHOT + compile + diff --git a/paytrailpayment-app/src/main/java/io/paytrailpayment/Main.java b/paytrailpayment-app/src/main/java/io/paytrailpayment/Main.java index 2a643c2..e6492bd 100644 --- a/paytrailpayment-app/src/main/java/io/paytrailpayment/Main.java +++ b/paytrailpayment-app/src/main/java/io/paytrailpayment/Main.java @@ -1,12 +1,11 @@ package io.paytrailpayment; import io.paytrailpayment.dto.request.CreatePaymentRequest; -import io.paytrailpayment.dto.request.model.CallbackUrl; -import io.paytrailpayment.dto.request.model.Customer; -import io.paytrailpayment.dto.request.model.Item; +import io.paytrailpayment.dto.request.model.*; import io.paytrailpayment.dto.response.CreatePaymentResponse; import io.paytrailpayment.utilites.ResponseMessage; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -19,8 +18,8 @@ public static void main(String[] args) { req.setStamp(UUID.randomUUID().toString()); req.setReference("9187445"); - req.setCurrency("EUR"); - req.setLanguage("FI"); + req.setCurrency(PaytrailCurrency.EUR); + req.setLanguage(PaytrailLanguage.FI); req.setOrderId("12335"); req.setAmount(1590); @@ -28,7 +27,7 @@ public static void main(String[] args) { Item item = new Item(); item.setUnitPrice(1590); item.setUnits(1); - item.setVatPercentage(24); + item.setVatPercentage(new BigDecimal(24)); item.setProductCode("#927502759"); items.add(item); diff --git a/paytrailpayment-sdk/pom.xml b/paytrailpayment-sdk/pom.xml index eb0a084..943cd67 100644 --- a/paytrailpayment-sdk/pom.xml +++ b/paytrailpayment-sdk/pom.xml @@ -15,7 +15,8 @@ org.projectlombok lombok - 1.18.26 + 1.18.36 + provided org.junit.jupiter @@ -55,11 +56,63 @@ commons-lang3 3.12.0 + + com.squareup.okhttp3 + okhttp + 4.12.0 + 8 8 UTF-8 + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${maven.compiler.source} + ${maven.compiler.target} + + + org.projectlombok + lombok + 1.18.36 + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.2 + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.6.0 + + + verify + + check + + + + + google_checks.xml + true + + + + + \ No newline at end of file diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/IPaytrail.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/IPaytrail.java index 18b6e2f..a811f48 100644 --- a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/IPaytrail.java +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/IPaytrail.java @@ -1,10 +1,7 @@ package io.paytrailpayment; -import io.paytrailpayment.dto.request.CreatePaymentRequest; -import io.paytrailpayment.dto.request.CreateRefundRequest; -import io.paytrailpayment.dto.response.CreatePaymentResponse; -import io.paytrailpayment.dto.response.CreateRefundResponse; -import io.paytrailpayment.dto.response.GetPaymentResponse; +import io.paytrailpayment.dto.request.*; +import io.paytrailpayment.dto.response.*; /** * Defines methods for interacting with the Paytrail payment system. @@ -27,6 +24,7 @@ public interface IPaytrail { * Note! The transaction id needs to be sent on checkout-transaction-id header as well. * * @param transactionId The unique identifier for the transaction. + * @return GetPaymentResponse * @see Paytrail Documentation - Get Payment */ GetPaymentResponse getPaymentInfo(String transactionId); @@ -36,7 +34,82 @@ public interface IPaytrail { * * @param refundRequest The request object containing refund details. * @param transactionId The unique identifier for the transaction to refund. + * @return CreateRefundResponse * @see Paytrail Documentation - Create Refund Request */ CreateRefundResponse createRefundRequest(CreateRefundRequest refundRequest, String transactionId); + + /** + * HTTP POST /tokenization/addcard-form add card form. + * + * @param req The request object containing add card request + * @return AddCardFormResponse + * @see Paytrail Documentation - Create Refund Request + */ + AddCardFormResponse createAddCardFormRequest(AddCardFormRequest req); + + /** + * HTTP POST /payments/token/mit/charge creates a new MIT payment charge. + * @param req + * @return CreateMitPaymentChargeResponse + * @see Paytrail Documentation - Create authorization hold or charge + */ + CreateMitOrCitPaymentResponse createMitPaymentCharge(CreateMitOrCitPaymentRequest req); + /** + * HTTP POST /payments/token/mit/authorization-hold creates a new MIT authorization hold. + * @param createMitPaymentAuthorizationHold + * @return CreateMitPaymentChargeResponse + * @see Paytrail Documentation - Create authorization hold or charge + */ + CreateMitOrCitPaymentResponse createMitPaymentAuthorizationHold(CreateMitOrCitPaymentRequest createMitPaymentAuthorizationHold); + + /** + * HTTP POST /payments/{transactionId}/token/commit commits a MIT payment. + * @param req + * @param transactionId + * @return CreateMitOrCitPaymentResponse + * @see Paytrail Documentation - Create MIT payment commit + */ + CreateMitOrCitPaymentResponse createMitPaymentCommit(CreateMitOrCitPaymentRequest req, String transactionId); + + /** + * HTTP POST /payments/token/cit/charge creates a new CIT payment charge. + * @param req + * @return CreateMitOrCitPaymentResponse + * @see Paytrail Documentation - Create authorization hold or charge + */ + CreateMitOrCitPaymentResponse createCitPaymentCharge(CreateMitOrCitPaymentRequest req); + + + /** + * HTTP POST /payments/token/cit/authorization-hold creates a new CIT authorization hold. + * @param req + * @return CreateMitOrCitPaymentResponse + * @see Paytrail Documentation - Create CIT authorization hold + */ + CreateMitOrCitPaymentResponse createCitPaymentAuthorizationHold(CreateMitOrCitPaymentRequest req); + + /** + * HTTP POST /payments/{transactionId}/token/commit commits a CIT payment. + * @param req + * @param transactionId + * @return CreateMitOrCitPaymentResponse + * @see Paytrail Documentation - Create CIT payment commit + */ + CreateMitOrCitPaymentResponse createCitPaymentCommit(CreateMitOrCitPaymentRequest req, String transactionId); + + /** + * HTTP POST /tokenization/pay-and-add-card pay and add card. + * @param req + * @return + */ + PayAddCardResponse payAndAddCard(PayAddCardRequest req); + + /** + * + * HTTP POST /tokenization/get-token get token. + * @param req + * @return the actual card token which can then be used to make payments on the card + */ + GetTokenResponse createGetTokenRequest(GetTokenRequest req); } diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/Paytrail.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/Paytrail.java index 3d84627..bbc7461 100644 --- a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/Paytrail.java +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/Paytrail.java @@ -6,16 +6,11 @@ import io.paytrailpayment.utilites.Constants; import io.paytrailpayment.utilites.ResponseMessage; import io.paytrailpayment.utilites.Signature; -import org.apache.hc.client5.http.classic.HttpClient; -import org.apache.hc.client5.http.classic.methods.HttpGet; -import org.apache.hc.client5.http.classic.methods.HttpPost; -import org.apache.hc.client5.http.entity.EntityBuilder; -import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; -import org.apache.hc.core5.http.HttpEntity; -import org.apache.hc.core5.http.io.HttpClientResponseHandler; -import org.apache.hc.core5.http.io.entity.EntityUtils; +import okhttp3.OkHttpClient; +import okhttp3.RequestBody; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.*; @@ -34,8 +29,8 @@ protected Map getHeaders(String method, String transactionId, St headers.put(Constants.CHECKOUT_METHOD_HEADER, method.toUpperCase()); headers.put(Constants.CHECKOUT_NONCE_HEADER, UUID.randomUUID().toString()); headers.put(Constants.CHECKOUT_TIMESTAMP_HEADER, String.format("%tFT% hdparams, String body) throws return Signature.calculateHmac(this.secretKey, hdparams, body, Constants.SHA256_ALGORITHM); } - protected DataResponse handleRequest(String method, String url, String body, String transactionId, String checkoutTokenizationId) throws PaytrailClientException, PaytrailCommunicationException{ + protected DataResponse handleRequest(String method, String url, String body, String transactionId, String checkoutTokenizationId) throws PaytrailClientException, PaytrailCommunicationException { + return handleRequest(method, url, body, transactionId, checkoutTokenizationId, false); + } + + protected DataResponse handleRequest(String method, String url, String body, + String transactionId, String checkoutTokenizationId, boolean skipAuthHeaders) + throws PaytrailClientException, PaytrailCommunicationException { DataResponse res = new DataResponse(); try { - Map hdparams = getHeaders(method, transactionId, checkoutTokenizationId); - - String signature = calculateHmac(hdparams, body); - - if (signature.isEmpty()) { - res.setStatusCode(ResponseMessage.BAD_REQUEST.getCode()); - res.setData(ResponseMessage.BAD_REQUEST.getDescription()); - return res; - } - - hdparams = getHeaders(hdparams, Constants.SIGNATURE_HEADER, signature); + Map hdparams = null; - // Create new request - HttpClient httpClient = HttpClientBuilder.create().build(); + if (!skipAuthHeaders) { + hdparams = getHeaders(method, transactionId, checkoutTokenizationId); + String signature = calculateHmac(hdparams, body); - HttpPost httpPost = new HttpPost(url); - HttpGet httpGet = new HttpGet(url); + if (signature.isEmpty()) { + res.setStatusCode(ResponseMessage.BAD_REQUEST.getCode()); + res.setData(ResponseMessage.BAD_REQUEST.getDescription()); + return res; + } - if (Objects.equals(method, Constants.POST_METHOD)) { - EntityBuilder builder = EntityBuilder - .create() - .setText(body); - httpPost.setEntity(builder.build()); + hdparams = getHeaders(hdparams, Constants.SIGNATURE_HEADER, signature); + } else { + Map headers = new HashMap<>(); + hdparams = getHeaders(headers, Constants.CONTENT_TYPE_HEADER, Constants.CONTENT_TYPE); + hdparams = getHeaders(hdparams, Constants.PLATFORM_NAME_HEADER, this.platformName); + } + // Build the OkHttpClient instance (add interceptors if needed for logging) + OkHttpClient client = new OkHttpClient.Builder().build(); + // Build the request, adding headers if available + okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder().url(url); + if (hdparams != null) { for (Map.Entry entry : hdparams.entrySet()) { - httpPost.setHeader(entry.getKey(), entry.getValue()); - } - } else if (Objects.equals(method, Constants.GET_METHOD)) { - for (Map.Entry entry : hdparams.entrySet()) { - httpGet.setHeader(entry.getKey(), entry.getValue()); + requestBuilder.addHeader(entry.getKey(), entry.getValue()); } } + if (Constants.POST_METHOD.equals(method)) { + RequestBody requestBody = RequestBody.create(body.getBytes(StandardCharsets.UTF_8)); + requestBuilder.post(requestBody); + } else if (Constants.GET_METHOD.equals(method)) { + requestBuilder.get(); + } - // Send request - HttpClientResponseHandler handler = response -> { - int status = response.getCode(); - HttpEntity entity = response.getEntity(); - String getResponseString = entity != null ? EntityUtils.toString(entity) : null; - if (entity != null) { - EntityUtils.consume(entity); - } - + okhttp3.Request request = requestBuilder.build(); + // Execute the request + try (okhttp3.Response response = client.newCall(request).execute()) { + int status = response.code(); + String responseString = response.body() != null ? response.body().string() : null; res.setStatusCode(status); - res.setData(getResponseString); - - return getResponseString; - }; - - // Execute - if (Objects.equals(method, Constants.POST_METHOD)) { - httpClient.execute(httpPost, handler); - } else if (Objects.equals(method, Constants.GET_METHOD)) { - httpClient.execute(httpGet, handler); + res.setData(responseString); } return res; } catch (NoSuchAlgorithmException | InvalidKeyException e) { - // throw the exception related to the client. + // Exception related to the client (e.g., HMAC calculation) throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.toString(), e); } catch (IOException e) { - // throw the exception related to the communication with the server. + // Exception related to communication issues throw new PaytrailCommunicationException(ResponseMessage.EXCEPTION.getCode(), e.getMessage(), e); } } diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/PaytrailClient.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/PaytrailClient.java index 46691dd..d6c0db6 100644 --- a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/PaytrailClient.java +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/PaytrailClient.java @@ -2,16 +2,10 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import io.paytrailpayment.dto.request.CreatePaymentRequest; -import io.paytrailpayment.dto.request.CreateRefundRequest; -import io.paytrailpayment.dto.request.ValidationResult; -import io.paytrailpayment.dto.response.CreatePaymentResponse; -import io.paytrailpayment.dto.response.CreateRefundResponse; -import io.paytrailpayment.dto.response.GetPaymentResponse; -import io.paytrailpayment.dto.response.data.CreateRefundData; -import io.paytrailpayment.dto.response.data.DataResponse; -import io.paytrailpayment.dto.response.data.CreatePaymentData; -import io.paytrailpayment.dto.response.data.GetPaymentData; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import io.paytrailpayment.dto.request.*; +import io.paytrailpayment.dto.response.*; +import io.paytrailpayment.dto.response.data.*; import io.paytrailpayment.exception.PaytrailClientException; import io.paytrailpayment.exception.PaytrailCommunicationException; import io.paytrailpayment.utilites.Constants; @@ -22,8 +16,6 @@ import java.util.HashMap; import java.util.Map; -import static io.paytrailpayment.utilites.Constants.GET_METHOD; - @NoArgsConstructor @Getter @Setter @@ -66,12 +58,12 @@ private CreatePaymentResponse executeCreatePayment(CreatePaymentRequest req) thr String targetURL = Constants.API_ENDPOINT + "/payments"; DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, jsonRequest, null, null); - if (data.getStatusCode() != ResponseMessage.CREATED.getCode()) { + if (data.getStatusCode() != ResponseMessage.CREATED.getCode() && data.getStatusCode() != ResponseMessage.OK.getCode()) { return new CreatePaymentResponse(data.getStatusCode(), data.getData(), null); } else { // Successfully created the payment and parse the result CreatePaymentData dataMapper = mapper.readValue(data.getData(), CreatePaymentData.class); - return new CreatePaymentResponse(data.getStatusCode(), ResponseMessage.OK.getDescription(), dataMapper); + return new CreatePaymentResponse(ResponseMessage.OK.getCode(), ResponseMessage.OK.getDescription(), dataMapper); } } catch (JsonProcessingException e) { @@ -157,12 +149,12 @@ private CreateRefundResponse executeCreateRefund(CreateRefundRequest req, String String targetURL = Constants.API_ENDPOINT + "/payments/" + transactionId + "/refund"; DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, jsonRequest, transactionId, null); - if (data.getStatusCode() != ResponseMessage.CREATED.getCode()) { + if (data.getStatusCode() != ResponseMessage.CREATED.getCode() && data.getStatusCode() != ResponseMessage.OK.getCode()) { res.setReturnCode(data.getStatusCode()); res.setReturnMessage(data.getData()); } else { CreateRefundData dataMapper = mapper.readValue(data.getData(), CreateRefundData.class); - res.setReturnCode(data.getStatusCode()); + res.setReturnCode(ResponseMessage.OK.getCode()); res.setReturnMessage(ResponseMessage.OK.getDescription()); res.setData(dataMapper); } @@ -171,6 +163,373 @@ private CreateRefundResponse executeCreateRefund(CreateRefundRequest req, String throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.getMessage(), e); } } + @Override + public AddCardFormResponse createAddCardFormRequest(AddCardFormRequest req) { + try { + ValidationResult validationResult = validateAddCardFormRequest(req); + if (!validationResult.isValid()) { + AddCardFormResponse response = new AddCardFormResponse(); + response.setReturnCode(ResponseMessage.BAD_REQUEST.getCode()); + response.setReturnMessage(validationResult.getMessagesAsJson()); + return response; + } + return executeCreateAddCardForm(req); + } catch (PaytrailClientException | PaytrailCommunicationException e) { + return new AddCardFormResponse(e.getErrorCode(), e.getMessage(), null); + } + } + + private ValidationResult validateAddCardFormRequest(AddCardFormRequest req) { + if (req == null) { + Map error = new HashMap<>(); + error.put("error", ResponseMessage.BAD_REQUEST.getDescription()); + return new ValidationResult(false, error); + } + return req.validate(); + } + + private AddCardFormResponse executeCreateAddCardForm(AddCardFormRequest req) throws PaytrailCommunicationException, PaytrailClientException { + try { + ObjectMapper mapper = new ObjectMapper(); + String jsonRequest = mapper.writeValueAsString(req); + String targetURL = Constants.API_ENDPOINT + "/tokenization/addcard-form"; + // Send request without signature in header. + DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, jsonRequest, null, null, true); + + if (data.getStatusCode() != ResponseMessage.CREATED.getCode()) { + return new AddCardFormResponse(data.getStatusCode(), data.getData(), null); + } else { + // Successfully created the add card form and parse the result + AddCardFormData dataMapper = mapper.readValue(data.getData(), AddCardFormData.class); + return new AddCardFormResponse(data.getStatusCode(), ResponseMessage.OK.getDescription(), dataMapper); + } + } catch (JsonProcessingException e) { + throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.getMessage(), e); + } + } + + @Override + public CreateMitOrCitPaymentResponse createMitPaymentCharge(CreateMitOrCitPaymentRequest req) { + CreateMitOrCitPaymentResponse res = new CreateMitOrCitPaymentResponse(); + try { + ValidationResult validationResult = validateCreateMitOrCitPaymentRequest(req); + if (!validationResult.isValid()) { + res.setReturnCode(ResponseMessage.BAD_REQUEST.getCode()); + res.setReturnMessage(validationResult.getMessagesAsJson()); + return res; + } + return executeCreateMitPaymentCharge(req); + } catch (PaytrailClientException | PaytrailCommunicationException e) { + res.setReturnCode(ResponseMessage.EXCEPTION.getCode()); + res.setReturnMessage(e.getMessage()); + return res; + } + } + + private ValidationResult validateCreateMitOrCitPaymentRequest(CreateMitOrCitPaymentRequest req) { + if (req == null) { + Map error = new HashMap<>(); + error.put("error", ResponseMessage.BAD_REQUEST.getDescription()); + return new ValidationResult(false, error); + } + return req.validate(); + } + + private CreateMitOrCitPaymentResponse executeCreateMitPaymentCharge(CreateMitOrCitPaymentRequest req) throws PaytrailClientException, PaytrailCommunicationException { + try { + ObjectMapper mapper = new ObjectMapper(); + String jsonRequest = mapper.writeValueAsString(req); + String targetURL = Constants.API_ENDPOINT + "/payments/token/mit/charge"; + + DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, jsonRequest, null, null); + + if (data.getStatusCode() != ResponseMessage.OK.getCode() && data.getStatusCode() != ResponseMessage.CREATED.getCode()) { + return new CreateMitOrCitPaymentResponse(data.getStatusCode(), data.getData(), null); + } else { + CreateMitPaymentChargeData dataMapper = mapper.readValue(data.getData(), CreateMitPaymentChargeData.class); + return new CreateMitOrCitPaymentResponse(ResponseMessage.OK.getCode(), ResponseMessage.OK.getDescription(), dataMapper); + } + } catch (JsonProcessingException e) { + throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.getMessage(), e); + } + } + + public CreateMitOrCitPaymentResponse createMitPaymentAuthorizationHold(CreateMitOrCitPaymentRequest createMitPaymentAuthorizationHold) { + CreateMitOrCitPaymentResponse res = new CreateMitOrCitPaymentResponse(); + try { + // Validate create mit payment authorization hold + ValidationResult validationResult = validateCreateMitOrCitPaymentRequest(createMitPaymentAuthorizationHold); + if (!validationResult.isValid()) { + res.setReturnCode(ResponseMessage.BAD_REQUEST.getCode()); + res.setReturnMessage(validationResult.getMessagesAsJson()); + return res; + } + return executeCreateMitPaymentAuthorizationHold(createMitPaymentAuthorizationHold); + } catch (Exception ex) { + res.setReturnCode(ResponseMessage.EXCEPTION.getCode()); + res.setReturnMessage(ex.toString()); + return res; + } + } + private CreateMitOrCitPaymentResponse executeCreateMitPaymentAuthorizationHold(CreateMitOrCitPaymentRequest req) throws PaytrailCommunicationException, PaytrailClientException { + try { + ObjectMapper mapper = new ObjectMapper(); + String jsonRequest = mapper.writeValueAsString(req); + String targetURL = Constants.API_ENDPOINT + "/payments/token/mit/authorization-hold"; + DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, jsonRequest, null, null); + + if (data.getStatusCode() != ResponseMessage.OK.getCode() && data.getStatusCode() != ResponseMessage.CREATED.getCode()) { + return new CreateMitOrCitPaymentResponse(data.getStatusCode(), data.getData(), null); + } else { + // Successfully created the MIT payment authorization hold and parse the result + CreateMitPaymentChargeData dataMapper = mapper.readValue(data.getData(), CreateMitPaymentChargeData.class); + return new CreateMitOrCitPaymentResponse(ResponseMessage.OK.getCode(), ResponseMessage.OK.getDescription(), dataMapper); + } + } catch (JsonProcessingException e) { + throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.getMessage(), e); + } + } + + @Override + public CreateMitOrCitPaymentResponse createMitPaymentCommit(CreateMitOrCitPaymentRequest req, String transactionId) { + CreateMitOrCitPaymentResponse res = new CreateMitOrCitPaymentResponse(); + try { + ValidationResult validationResult = validateCreateMitOrCitPaymentRequest(req); + if (!validationResult.isValid()) { + res.setReturnCode(ResponseMessage.BAD_REQUEST.getCode()); + res.setReturnMessage(validationResult.getMessagesAsJson()); + return res; + } + + if (transactionId == null || transactionId.isEmpty()) { + res.setReturnCode(ResponseMessage.RESPONSE_NULL.getCode()); + res.setReturnMessage("transactionId cannot be null"); + return res; + } + + return executeCreateMitOrCitPaymentCommit(req, transactionId); + } catch (Exception ex) { + res.setReturnCode(ResponseMessage.EXCEPTION.getCode()); + res.setReturnMessage(ex.toString()); + return res; + } + } + + private CreateMitOrCitPaymentResponse executeCreateMitOrCitPaymentCommit(CreateMitOrCitPaymentRequest req, String transactionId) throws PaytrailCommunicationException, PaytrailClientException { + try { + ObjectMapper mapper = new ObjectMapper(); + String jsonRequest = mapper.writeValueAsString(req); + String targetURL = Constants.API_ENDPOINT + "/payments/" + transactionId + "/token/commit/"; + + DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, jsonRequest, transactionId, null); + + if (data.getStatusCode() != ResponseMessage.OK.getCode()) { + return new CreateMitOrCitPaymentResponse(data.getStatusCode(), data.getData(), null); + } else { + CreateMitPaymentChargeData dataMapper = mapper.readValue(data.getData(), CreateMitPaymentChargeData.class); + return new CreateMitOrCitPaymentResponse(ResponseMessage.OK.getCode(), ResponseMessage.OK.getDescription(), dataMapper); + } + } catch (JsonProcessingException e) { + throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.getMessage(), e); + } + } + + @Override + public CreateMitOrCitPaymentResponse createCitPaymentCharge(CreateMitOrCitPaymentRequest req) { + CreateMitOrCitPaymentResponse res = new CreateMitOrCitPaymentResponse(); + try { + ValidationResult validationResult = validateCreateMitOrCitPaymentRequest(req); + if (!validationResult.isValid()) { + res.setReturnCode(ResponseMessage.BAD_REQUEST.getCode()); + res.setReturnMessage(validationResult.getMessagesAsJson()); + return res; + } + return executeCreateCitPaymentCharge(req); + } catch (PaytrailClientException | PaytrailCommunicationException e) { + res.setReturnCode(ResponseMessage.EXCEPTION.getCode()); + res.setReturnMessage(e.getMessage()); + return res; + } + } + + private CreateMitOrCitPaymentResponse executeCreateCitPaymentCharge(CreateMitOrCitPaymentRequest req) throws PaytrailClientException, PaytrailCommunicationException { + try { + ObjectMapper mapper = new ObjectMapper(); + String jsonRequest = mapper.writeValueAsString(req); + String targetURL = Constants.API_ENDPOINT + "/payments/token/cit/charge"; + + DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, jsonRequest, null, null); + + if (data.getStatusCode() != ResponseMessage.OK.getCode() && data.getStatusCode() != ResponseMessage.CREATED.getCode()) { + return new CreateMitOrCitPaymentResponse(data.getStatusCode(), data.getData(), null); + } else { + CreateMitPaymentChargeData dataMapper = mapper.readValue(data.getData(), CreateMitPaymentChargeData.class); + return new CreateMitOrCitPaymentResponse(ResponseMessage.OK.getCode(), ResponseMessage.OK.getDescription(), dataMapper); + } + } catch (JsonProcessingException e) { + throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.getMessage(), e); + } + } + + @Override + public CreateMitOrCitPaymentResponse createCitPaymentAuthorizationHold(CreateMitOrCitPaymentRequest req) { + CreateMitOrCitPaymentResponse res = new CreateMitOrCitPaymentResponse(); + try { + ValidationResult validationResult = validateCreateMitOrCitPaymentRequest(req); + if (!validationResult.isValid()) { + res.setReturnCode(ResponseMessage.BAD_REQUEST.getCode()); + res.setReturnMessage(validationResult.getMessagesAsJson()); + return res; + } + return executeCreateCitPaymentAuthorizationHold(req); + } catch (PaytrailClientException | PaytrailCommunicationException e) { + res.setReturnCode(ResponseMessage.EXCEPTION.getCode()); + res.setReturnMessage(e.getMessage()); + return res; + } + } + + private CreateMitOrCitPaymentResponse executeCreateCitPaymentAuthorizationHold(CreateMitOrCitPaymentRequest req) throws PaytrailClientException, PaytrailCommunicationException { + try { + ObjectMapper mapper = new ObjectMapper(); + String jsonRequest = mapper.writeValueAsString(req); + String targetURL = Constants.API_ENDPOINT + "/payments/token/cit/authorization-hold"; + + DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, jsonRequest, null, null); + + if (data.getStatusCode() != ResponseMessage.OK.getCode() && data.getStatusCode() != ResponseMessage.CREATED.getCode()) { + return new CreateMitOrCitPaymentResponse(data.getStatusCode(), data.getData(), null); + } else { + CreateMitPaymentChargeData dataMapper = mapper.readValue(data.getData(), CreateMitPaymentChargeData.class); + return new CreateMitOrCitPaymentResponse(ResponseMessage.OK.getCode(), ResponseMessage.OK.getDescription(), dataMapper); + } + } catch (JsonProcessingException e) { + throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.getMessage(), e); + } + } + + @Override + public CreateMitOrCitPaymentResponse createCitPaymentCommit(CreateMitOrCitPaymentRequest req, String transactionId) { + CreateMitOrCitPaymentResponse res = new CreateMitOrCitPaymentResponse(); + try { + ValidationResult validationResult = validateCreateMitOrCitPaymentRequest(req); + if (!validationResult.isValid()) { + res.setReturnCode(ResponseMessage.BAD_REQUEST.getCode()); + res.setReturnMessage(validationResult.getMessagesAsJson()); + return res; + } + + if (transactionId == null || transactionId.isEmpty()) { + res.setReturnCode(ResponseMessage.RESPONSE_NULL.getCode()); + res.setReturnMessage("transactionId cannot be null"); + return res; + } + + return executeCreateMitOrCitPaymentCommit(req, transactionId); + } catch (Exception ex) { + res.setReturnCode(ResponseMessage.EXCEPTION.getCode()); + res.setReturnMessage(ex.toString()); + return res; + } + } + + @Override + public PayAddCardResponse payAndAddCard(PayAddCardRequest req) { + PayAddCardResponse res = new PayAddCardResponse(); + try { + ValidationResult validationResult = validatePayAndAddCardRequest(req); + if (!validationResult.isValid()) { + res.setReturnCode(ResponseMessage.BAD_REQUEST.getCode()); + res.setReturnMessage(validationResult.getMessagesAsJson()); + return res; + } + return executePayAndAddCard(req); + } catch (Exception ex) { + res.setReturnCode(ResponseMessage.EXCEPTION.getCode()); + res.setReturnMessage(ex.toString()); + return res; + } + } + + private ValidationResult validatePayAndAddCardRequest(PayAddCardRequest req) { + if (req == null) { + Map error = new HashMap<>(); + error.put("error", ResponseMessage.BAD_REQUEST.getDescription()); + return new ValidationResult(false, error); + } + return req.validate(); + } + + private PayAddCardResponse executePayAndAddCard(PayAddCardRequest req) throws PaytrailClientException, PaytrailCommunicationException { + try { + ObjectMapper mapper = new ObjectMapper(); + String jsonRequest = mapper.writeValueAsString(req); + String targetURL = Constants.API_ENDPOINT + "/tokenization/pay-and-add-card"; + + DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, jsonRequest, null, null); + + if (data.getStatusCode() != ResponseMessage.OK.getCode()) { + return new PayAddCardResponse(data.getStatusCode(), data.getData(), null); + } else { + PayAddCardData dataMapper = mapper.readValue(data.getData(), PayAddCardData.class); + return new PayAddCardResponse(ResponseMessage.OK.getCode(), ResponseMessage.OK.getDescription(), dataMapper); + } + } catch (JsonProcessingException e) { + throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.getMessage(), e); + } + } + + @Override + public GetTokenResponse createGetTokenRequest(GetTokenRequest req) { + GetTokenResponse res = new GetTokenResponse(); + try { + // Validate request before processing + ValidationResult validationResult = validateGetTokenRequest(req); + if (!validationResult.isValid()) { + res.setReturnCode(ResponseMessage.BAD_REQUEST.getCode()); + res.setReturnMessage(validationResult.getMessagesAsJson()); + return res; + } + return executeCreateGetTokenRequest(req); + } catch (PaytrailClientException | PaytrailCommunicationException e) { + res.setReturnCode(ResponseMessage.EXCEPTION.getCode()); + res.setReturnMessage(e.getMessage()); + return res; + } + } + + private GetTokenResponse executeCreateGetTokenRequest(GetTokenRequest req) throws PaytrailClientException, PaytrailCommunicationException { + try { + ObjectMapper mapper = new ObjectMapper(); + String jsonRequest = mapper.writeValueAsString(req); + + // Construct the URL dynamically using checkoutTokenizationId from TokenRequest + String targetURL = Constants.API_ENDPOINT + "/tokenization/" + req.getCheckoutTokenizationId(); + + // Handle HTTP request + DataResponse data = this.handleRequest(Constants.POST_METHOD, targetURL, "{}", null, req.getCheckoutTokenizationId()); + + // Process API response + if (data.getStatusCode() != ResponseMessage.OK.getCode()) { + return new GetTokenResponse(data.getStatusCode(), data.getData(), null); + } else { + mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); + GetTokenData dataMapper = mapper.readValue(data.getData(), GetTokenData.class); + return new GetTokenResponse(ResponseMessage.OK.getCode(), ResponseMessage.OK.getDescription(), dataMapper); + } + } catch (JsonProcessingException e) { + throw new PaytrailClientException(ResponseMessage.RESPONSE_ERROR.getCode(), e.getMessage(), e); + } + } + + private ValidationResult validateGetTokenRequest(GetTokenRequest req) { + if (req == null) { + Map error = new HashMap<>(); + error.put("error", ResponseMessage.BAD_REQUEST.getDescription()); + return new ValidationResult(false, error); + } + return req.validate(); + } } diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/AddCardFormRequest.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/AddCardFormRequest.java new file mode 100644 index 0000000..71e8b8d --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/AddCardFormRequest.java @@ -0,0 +1,84 @@ +package io.paytrailpayment.dto.request; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.Arrays; + +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_DEFAULT) +public class AddCardFormRequest extends Request { + @JsonProperty("checkout-account") + private Integer checkoutAccount; + + @JsonProperty("checkout-algorithm") + private String checkoutAlgorithm; + + @JsonProperty("checkout-method") + private String checkoutMethod; + + @JsonProperty("checkout-nonce") + private String checkoutNonce; + + @JsonProperty("checkout-timestamp") + private String checkoutTimestamp; + + @JsonProperty("checkout-redirect-success-url") + private String checkoutRedirectSuccessUrl; + + @JsonProperty("checkout-redirect-cancel-url") + private String checkoutRedirectCancelUrl; + + @JsonProperty("signature") + private String signature; + + @JsonProperty("checkout-callback-success-url") + private String checkoutCallbackSuccessUrl; + + @JsonProperty("checkout-callback-cancel-url") + private String checkoutCallbackCancelUrl; + + @JsonProperty("language") + private String language; + + @Override + protected void specificValidate() { + String[] supportedLanguages = {"FI", "SV", "EN"}; + String[] supportedMethods = {"GET", "POST"}; + + if (checkoutAccount == null) { + addValidationError("checkout-account", "checkout-account is empty."); + } + + if (checkoutAlgorithm == null || checkoutAlgorithm.isEmpty()) { + addValidationError("checkout-algorithm", "checkout-algorithm is empty."); + } + + if (!Arrays.asList(supportedMethods).contains(checkoutMethod)) { + addValidationError("checkout-method", "unsupported method chosen."); + } + + if (checkoutTimestamp == null || checkoutTimestamp.isEmpty()) { + addValidationError("checkout-timestamp", "checkout-timestamp is empty."); + } + + if (checkoutRedirectSuccessUrl == null || checkoutRedirectSuccessUrl.isEmpty()) { + addValidationError("checkout-redirect-success-url", "checkout-redirect success url is empty."); + } + + if (checkoutRedirectCancelUrl == null || checkoutRedirectCancelUrl.isEmpty()) { + addValidationError("checkout-redirect-cancel-url", "checkout-redirect cancel url is empty."); + } + + if (!Arrays.asList(supportedLanguages).contains(language)) { + addValidationError("language", "unsupported language chosen."); + } + } +} \ No newline at end of file diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/CreateMitOrCitPaymentRequest.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/CreateMitOrCitPaymentRequest.java new file mode 100644 index 0000000..53a0891 --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/CreateMitOrCitPaymentRequest.java @@ -0,0 +1,23 @@ +package io.paytrailpayment.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CreateMitOrCitPaymentRequest extends CreatePaymentRequest { + private String token; + + @Override + protected void specificValidate() { + super.specificValidate(); + + if (token == null || token.isEmpty()) { + addValidationError("token", "token can't be null."); + } + } +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/CreatePaymentRequest.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/CreatePaymentRequest.java index 417b0b1..61ee034 100644 --- a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/CreatePaymentRequest.java +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/CreatePaymentRequest.java @@ -112,11 +112,11 @@ protected void specificValidate() { addValidationError("amount", "Amount must be less than 99999999."); } - if (orderId == null || orderId.isEmpty()) { - if (reference == null || reference.isEmpty()) { - addValidationError("orderId", "OrderId is not provided, then reference must be provided. "); - } - } +// if (orderId == null || orderId.isEmpty()) { +// if (reference == null || reference.isEmpty()) { +// addValidationError("orderId", "OrderId is not provided, then reference must be provided. "); +// } +// } if (items != null) { for (Item item : items) { diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/GetTokenRequest.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/GetTokenRequest.java new file mode 100644 index 0000000..9c37b3c --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/GetTokenRequest.java @@ -0,0 +1,24 @@ +package io.paytrailpayment.dto.request; + + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_DEFAULT) +public class GetTokenRequest extends Request { + private String checkoutTokenizationId; + + @Override + protected void specificValidate() { + if (checkoutTokenizationId == null || checkoutTokenizationId.isEmpty()) { + addValidationError("checkoutTokenizationId", "checkoutTokenizationId can't be null."); + } + } +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/PayAddCardRequest.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/PayAddCardRequest.java new file mode 100644 index 0000000..666deda --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/PayAddCardRequest.java @@ -0,0 +1,122 @@ +package io.paytrailpayment.dto.request; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.paytrailpayment.dto.request.model.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_DEFAULT) +public class PayAddCardRequest extends Request { + private String stamp; + private String reference; + private int amount; + private PaytrailCurrency currency; + private PaytrailLanguage language; + private String orderId; + private List items; + private Customer customer; + private Address deliveryAddress; + private Address invoicingAddress; + private boolean manualInvoiceActivation; + private CallbackUrl redirectUrls; + private CallbackUrl callbackUrls; + private int callbackDelay; + private List groups; + private boolean usePricesWithoutVat; + + @Override + protected void specificValidate() { + StringBuilder message = new StringBuilder(); + + if (stamp == null || stamp.isEmpty()) { + addValidationError("stamp", "Stamp can't be null or empty."); + } else if (stamp.length() > 200) { + addValidationError("stamp", "Stamp is more than 200 characters."); + } + + if (reference == null || reference.isEmpty()) { + addValidationError("reference", "Reference can't be null or empty."); + } else if (reference.length() > 200) { + addValidationError("reference", "Reference is more than 200 characters."); + } + + if (amount < 0) { + addValidationError("amount", "Amount can't be less than zero."); + } else if (amount > 99999999) { + addValidationError("amount", "Amount can't be more than 99999999."); + } + + if (customer == null) { + addValidationError("customer", "Customer can't be null."); + } else { + ValidationResult customerValidationResult = customer.validate(); + if (!customerValidationResult.isValid()) { + addValidationError("customer", customerValidationResult.getMessagesAsJson()); + } + } + + if (items != null) { + for (Item item : items) { + ValidationResult itemValidationResult = item.validate(); + if (!itemValidationResult.isValid()) { + addValidationError("item", itemValidationResult.getMessagesAsJson()); + break; + } + } + } + + if (deliveryAddress != null) { + ValidationResult deliveryAddressValidationResult = deliveryAddress.validate(); + if (!deliveryAddressValidationResult.isValid()) { + addValidationError("deliveryAddress", deliveryAddressValidationResult.getMessagesAsJson()); + } + } + + if (invoicingAddress != null) { + ValidationResult invoicingAddressValidationResult = invoicingAddress.validate(); + if (!invoicingAddressValidationResult.isValid()) { + addValidationError("invoicingAddress", invoicingAddressValidationResult.getMessagesAsJson()); + } + } + + if (redirectUrls == null) { + addValidationError("redirectUrls", "Object redirectUrls can't be null."); + } else { + ValidationResult redirectUrlsValidationResult = redirectUrls.validate(); + if (!redirectUrlsValidationResult.isValid()) { + addValidationError("redirectUrls", redirectUrlsValidationResult.getMessagesAsJson()); + } + } + + if (callbackUrls == null) { + addValidationError("callbackUrls", "Object callbackUrls can't be null."); + } else { + ValidationResult callbackUrlsValidationResult = callbackUrls.validate(); + if (!callbackUrlsValidationResult.isValid()) { + addValidationError("callbackUrls", callbackUrlsValidationResult.getMessagesAsJson()); + } + } + + if (groups != null) { + Set allowedGroups = EnumSet.allOf(PaytrailPaymentMethodGroup.class).stream() + .map(Enum::toString) + .collect(Collectors.toSet()); + for (String group : groups) { + if (!allowedGroups.contains(group)) { + addValidationError("groups", "Value '" + group + "' is not in the list of allowed payment methods."); + } + } + } + } +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/model/Item.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/model/Item.java index 2f4239f..7c6e52e 100644 --- a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/model/Item.java +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/model/Item.java @@ -7,6 +7,8 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.math.BigDecimal; + @Data @NoArgsConstructor @AllArgsConstructor @@ -23,9 +25,9 @@ public class Item extends Request { private int units; /** - * VAT percentage + * VAT percentage, with one decimal precision. */ - private int vatPercentage; + private BigDecimal vatPercentage; /** * Merchant product code. May appear on invoices of certain payment methods. Maximum of 100 characters @@ -42,10 +44,10 @@ public class Item extends Request { */ private String category; - /** - * Item level order ID (suborder ID). Mainly useful for Shop-in-Shop purchases. - */ - private String orderId; +// /** +// * Item level order ID (suborder ID). Mainly useful for Shop-in-Shop purchases. +// */ +// private String orderId; /** * Unique identifier for this item. Required for Shop-in-Shop payments. Required for item refunds. @@ -57,15 +59,15 @@ public class Item extends Request { */ private String reference; - /** - * Merchant ID for the item. Required for Shop-in-Shop payments, do not use for normal payments. - */ - private String merchant; - - /** - * Shop-in-Shop commission. Do not use for normal payments. - */ - private Commission commission; +// /** +// * Merchant ID for the item. Required for Shop-in-Shop payments, do not use for normal payments. +// */ +// private String merchant; +// +// /** +// * Shop-in-Shop commission. Do not use for normal payments. +// */ +// private Commission commission; @Override() protected void specificValidate() { @@ -77,8 +79,14 @@ protected void specificValidate() { addValidationError("units", "Item's units are invalid. "); } - if (vatPercentage < 0) { - addValidationError("vatPercentage", "Item's vat Percentage can't be a negative number."); + if (vatPercentage == null || vatPercentage.compareTo(BigDecimal.ZERO) < 0) { + addValidationError("vatPercentage", "Item's vat Percentage can't be null or a negative number."); + } else { + // Check if vatPercentage has more than one decimal place + int scale = vatPercentage.stripTrailingZeros().scale(); + if (scale > 1) { + addValidationError("vatPercentage", "Item's vat Percentage can't have more than one decimal place."); + } } if (productCode == null) { @@ -96,5 +104,13 @@ protected void specificValidate() { } } + public Item(int unitPrice, int units, BigDecimal vatPercentage, String productCode, String category, String description) { + this.unitPrice = unitPrice; + this.units = units; + this.vatPercentage = vatPercentage; + this.productCode = productCode; + this.category = category; + this.description = description; + } } diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/model/ShopInShopItem.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/model/ShopInShopItem.java new file mode 100644 index 0000000..5839425 --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/request/model/ShopInShopItem.java @@ -0,0 +1,71 @@ +package io.paytrailpayment.dto.request.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.paytrailpayment.dto.request.ValidationResult; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_DEFAULT) +public class ShopInShopItem extends Item { + /** + * Item level order ID (suborder ID). Mainly useful for Shop-in-Shop purchases. + */ + private String orderId; + + /** + * Merchant ID for the item. Required for Shop-in-Shop payments, do not use for normal payments. + */ + private String merchant; + + /** + * Shop-in-Shop commission. Do not use for normal payments. + */ + private Commission commission; + + public ShopInShopItem(int unitPrice, int units, BigDecimal vatPercentage, String productCode, String category, String description, String stamp, String reference, String orderId, String merchant, Commission commission) { + super(unitPrice, units, vatPercentage, productCode, description, category, stamp, reference); + this.orderId = orderId; + this.merchant = merchant; + this.commission = commission; + } + + public ShopInShopItem(int unitPrice, int units, BigDecimal vatPercentage, String productCode, String category, String description, String stamp, String reference) { + super(unitPrice, units, vatPercentage, productCode, description, category, stamp, reference); + } + + public ShopInShopItem(int unitPrice, int units, BigDecimal vatPercentage, String productCode, String category, + String description, String merchant, String stamp, String reference, String orderId) { + super(unitPrice, units, vatPercentage, productCode, description, category, stamp, reference); + this.merchant = merchant; + this.orderId = orderId; + } + + @Override + protected void specificValidate() { + super.specificValidate(); + +// if (orderId == null) { +// addValidationError("orderId", "Item's orderId can't be null."); +// } + + + if (merchant == null || merchant.isEmpty()) { + addValidationError("merchant", "Item's merchant can't be null or empty."); + } + + if (commission != null) { + ValidationResult commissionValidationResult = commission.validate(); + if (!commissionValidationResult.isValid()) { + addValidationError("commission", commissionValidationResult.getMessagesAsJson()); + } + } + } +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/AddCardFormResponse.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/AddCardFormResponse.java new file mode 100644 index 0000000..49eda6c --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/AddCardFormResponse.java @@ -0,0 +1,18 @@ +package io.paytrailpayment.dto.response; + +import io.paytrailpayment.dto.response.data.AddCardFormData; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class AddCardFormResponse extends Response { + private AddCardFormData data; + + public AddCardFormResponse(int statusCode, String description, AddCardFormData dataMapper) { + super(statusCode, description); + this.data = dataMapper; + } +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/CreateMitOrCitPaymentResponse.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/CreateMitOrCitPaymentResponse.java new file mode 100644 index 0000000..49d7f3b --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/CreateMitOrCitPaymentResponse.java @@ -0,0 +1,20 @@ +package io.paytrailpayment.dto.response; + +import io.paytrailpayment.dto.response.data.CreateMitPaymentChargeData; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CreateMitOrCitPaymentResponse extends Response { + private CreateMitPaymentChargeData data; + + public CreateMitOrCitPaymentResponse(int statusCode, String description, CreateMitPaymentChargeData dataMapper) { + super(statusCode, description); + this.data = dataMapper; + } +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/GetTokenResponse.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/GetTokenResponse.java new file mode 100644 index 0000000..86f1138 --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/GetTokenResponse.java @@ -0,0 +1,21 @@ +package io.paytrailpayment.dto.response; + +import io.paytrailpayment.dto.response.data.GetTokenData; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GetTokenResponse extends Response { + private GetTokenData data; + + public GetTokenResponse(int statusCode, String description, GetTokenData dataMapper) { + super(statusCode, description); + this.data = dataMapper; + + } +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/PayAddCardResponse.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/PayAddCardResponse.java new file mode 100644 index 0000000..d1c2735 --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/PayAddCardResponse.java @@ -0,0 +1,20 @@ +package io.paytrailpayment.dto.response; + +import io.paytrailpayment.dto.response.data.PayAddCardData; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PayAddCardResponse extends Response { + private PayAddCardData data; + + public PayAddCardResponse(int returnCode, String returnMessage, PayAddCardData data) { + super(returnCode, returnMessage); + this.data = data; + } +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/AddCardFormData.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/AddCardFormData.java new file mode 100644 index 0000000..5fe68e6 --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/AddCardFormData.java @@ -0,0 +1,12 @@ +package io.paytrailpayment.dto.response.data; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class AddCardFormData { + private String content; +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/Card.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/Card.java new file mode 100644 index 0000000..75dec63 --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/Card.java @@ -0,0 +1,73 @@ +package io.paytrailpayment.dto.response.data; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Represents a Card with its details. + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Card { + + /** + * Card type, for example "Visa". + */ + private String type; + + /** + * First 2 or 6 digits of the card number (6 for MC/VISA, 2 for Amex/Diners). + */ + private String bin; + + /** + * Last four digits of the card. + */ + private String partialPan; + + /** + * Card expiration year. + */ + private String expireYear; + + /** + * Card expiration month. + */ + private String expireMonth; + + /** + * Whether the CVC is required for paying with this card. + * Can be one of "yes", "no" or "not_tested". + */ + private String cvcRequired; + + /** + * The card funding type: credit, debit, or unknown. + */ + private String funding; + + /** + * Card category: business, prepaid, or unknown. + */ + private String category; + + /** + * Country code, e.g. "FI". + */ + private String countryCode; + + /** + * Identifies a specific card number. + * Cards with the same PAN but different expiry dates will have the same PAN fingerprint. + * Hex string of length 64. + */ + private String panFingerprint; + + /** + * Identifies a specific card including the expiry date. + * Hex string of length 64. + */ + private String cardFingerprint; +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/CreateMitPaymentChargeData.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/CreateMitPaymentChargeData.java new file mode 100644 index 0000000..d679a93 --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/CreateMitPaymentChargeData.java @@ -0,0 +1,13 @@ +package io.paytrailpayment.dto.response.data; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CreateMitPaymentChargeData { + private String transactionId; + private String threeDSecureUrl; +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/CustomerDetail.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/CustomerDetail.java new file mode 100644 index 0000000..e856b8b --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/CustomerDetail.java @@ -0,0 +1,21 @@ +package io.paytrailpayment.dto.response.data; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CustomerDetail { + /** + * Customer's network address. + */ + private String networkAddress; + + /** + * Country code. + */ + private String countryCode; + +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/GetTokenData.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/GetTokenData.java new file mode 100644 index 0000000..33d2b2b --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/GetTokenData.java @@ -0,0 +1,23 @@ +package io.paytrailpayment.dto.response.data; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class GetTokenData { + /** + * Payment card token. + */ + private String token; + /** + * Masked card details. Present if verification was successful. + */ + private Card card; + /** + * Customer details. + */ + private CustomerDetail customer; +} diff --git a/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/PayAddCardData.java b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/PayAddCardData.java new file mode 100644 index 0000000..214d7c3 --- /dev/null +++ b/paytrailpayment-sdk/src/main/java/io/paytrailpayment/dto/response/data/PayAddCardData.java @@ -0,0 +1,13 @@ +package io.paytrailpayment.dto.response.data; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PayAddCardData { + private String transactionId; + private String redirectUrl; +} diff --git a/paytrailpayment-sdk/src/test/java/CreatePaymentUnitTest.java b/paytrailpayment-sdk/src/test/java/CreatePaymentUnitTest.java deleted file mode 100644 index de8359e..0000000 --- a/paytrailpayment-sdk/src/test/java/CreatePaymentUnitTest.java +++ /dev/null @@ -1,189 +0,0 @@ -import io.paytrailpayment.PaytrailClient; -import io.paytrailpayment.dto.request.CreatePaymentRequest; -import io.paytrailpayment.dto.request.model.*; -import io.paytrailpayment.dto.request.model.PaytrailCurrency; -import io.paytrailpayment.dto.response.CreatePaymentResponse; - -import io.paytrailpayment.utilites.ResponseMessage; -import org.junit.Before; -import org.junit.Test; - -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; - -public class CreatePaymentUnitTest extends TestCase { - private PaytrailClient client; - - @Before - public void setUp() { - // Initialize your PaytrailClient here with default values for all tests or any other setup. - client = new PaytrailClient(this.merchantId, this.secretKey, this.platformName); - } - - @Test() - public void createPaymentReturnStatusCode400WithPayloadNull() { - CreatePaymentResponse res = client.createPayment(null); - - assertNotNull(res); - assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); - assertNull(res.getData()); - } - - @Test() - public void createPaymentReturnStatusCode400WithFieldRequiredNotFilled() { - String messageExpect = "{\"reference\":\"Reference can't be null or empty.\",\"amount\":\"Amount doesn't match total of items.\",\"stamp\":\"Stamp can't be null or empty.\",\"currency\":\"Currency can't be null.\",\"language\":\"Language can't be null.\"}"; - CreatePaymentRequest req = new CreatePaymentRequest(); - - req.setOrderId("12335"); - - List items = new ArrayList<>(); - Item item = new Item(); - item.setUnitPrice(1590); - item.setUnits(1); - item.setVatPercentage(24); - item.setProductCode("#927502759"); - items.add(item); - - req.setItems(items); - - Customer customer = new Customer(); - customer.setEmail("erja.esimerkki@example.org"); - customer.setFirstName("TEST"); - customer.setLastName("test"); - customer.setPhone("0369874566"); - customer.setVatId("156988"); - customer.setCompanyName("ttest"); - req.setCustomer(customer); - - CallbackUrl redirectUrls = new CallbackUrl(); - redirectUrls.setSuccess("https://ecom.example.org/success"); - redirectUrls.setCancel("https://ecom.example.org/cancel"); - req.setRedirectUrls(redirectUrls); - - CallbackUrl callbackUrls = new CallbackUrl(); - callbackUrls.setSuccess("https://ecom.example.org/success"); - callbackUrls.setCancel("https://ecom.example.org/cancel"); - req.setCallbackUrls(callbackUrls); - - CreatePaymentResponse res = client.createPayment(req); - - assertNotNull(res); - assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); - assertEquals(messageExpect, res.getReturnMessage()); - assertNull(res.getData()); - } - - @Test() - public void createPaymentReturnStatusCode400WithPayloadValidateFail() { - CreatePaymentRequest req = new CreatePaymentRequest(); - - req.setStamp(UUID.randomUUID().toString()); - req.setReference("9187445"); - req.setCurrency(PaytrailCurrency.EUR); - req.setLanguage(PaytrailLanguage.EN); - req.setAmount(-1590); - - CreatePaymentResponse res = client.createPayment(req); - - assertNotNull(res); - assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); - assertNull(res.getData()); - } - - @Test() - public void createPaymentReturnStatusCode201() { - CreatePaymentRequest req = new CreatePaymentRequest(); - - req.setStamp(UUID.randomUUID().toString()); - req.setReference("9187445"); - req.setCurrency(PaytrailCurrency.EUR); - req.setLanguage(PaytrailLanguage.EN); - req.setOrderId("12335"); - req.setAmount(1590); - - List items = new ArrayList<>(); - Item item = new Item(); - item.setUnitPrice(1590); - item.setUnits(1); - item.setVatPercentage(24); - item.setProductCode("#927502759"); - items.add(item); - - req.setItems(items); - - Customer customer = new Customer(); - customer.setEmail("erja.esimerkki@example.org"); - customer.setFirstName("TEST"); - customer.setLastName("test"); - customer.setPhone("0369874566"); - customer.setVatId("156988"); - customer.setCompanyName("ttest"); - req.setCustomer(customer); - - CallbackUrl redirectUrls = new CallbackUrl(); - redirectUrls.setSuccess("https://ecom.example.org/success"); - redirectUrls.setCancel("https://ecom.example.org/cancel"); - req.setRedirectUrls(redirectUrls); - - CallbackUrl callbackUrls = new CallbackUrl(); - callbackUrls.setSuccess("https://ecom.example.org/success"); - callbackUrls.setCancel("https://ecom.example.org/cancel"); - req.setCallbackUrls(callbackUrls); - - CreatePaymentResponse res = client.createPayment(req); - - assertNotNull(res); - assertEquals(ResponseMessage.CREATED.getCode(), res.getReturnCode()); - assertEquals(ResponseMessage.CREATED.getDescription(), res.getReturnMessage()); - assertNotNull(res.getData()); - } - - @Test() - public void createPaymentReturnStatusCode401WithFalseAuthenticationInformation() { - client = new PaytrailClient("375918", "SAIPPUAKAUPPIAS", "test"); - - CreatePaymentRequest req = new CreatePaymentRequest(); - - req.setStamp(UUID.randomUUID().toString()); - req.setReference("9187445"); - req.setCurrency(PaytrailCurrency.EUR); - req.setLanguage(PaytrailLanguage.EN); - req.setOrderId("12335"); - req.setAmount(1590); - - List items = new ArrayList<>(); - Item item = new Item(); - item.setUnitPrice(1590); - item.setUnits(1); - item.setVatPercentage(24); - item.setProductCode("#927502759"); - items.add(item); - - req.setItems(items); - - Customer customer = new Customer(); - customer.setEmail("erja.esimerkki@example.org"); - customer.setFirstName("TEST"); - customer.setLastName("test"); - customer.setPhone("0369874566"); - customer.setVatId("156988"); - customer.setCompanyName("ttest"); - req.setCustomer(customer); - - CallbackUrl redirectUrls = new CallbackUrl(); - redirectUrls.setSuccess("https://ecom.example.org/success"); - redirectUrls.setCancel("https://ecom.example.org/cancel"); - req.setRedirectUrls(redirectUrls); - - CallbackUrl callbackUrls = new CallbackUrl(); - callbackUrls.setSuccess("https://ecom.example.org/success"); - callbackUrls.setCancel("https://ecom.example.org/cancel"); - req.setCallbackUrls(callbackUrls); - - CreatePaymentResponse res = client.createPayment(req); - - assertNotNull(res); - assertEquals(ResponseMessage.UNAUTHORIZED.getCode(), res.getReturnCode()); - } -} diff --git a/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateAddCardFormRequestTests.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateAddCardFormRequestTests.java new file mode 100644 index 0000000..6de588b --- /dev/null +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateAddCardFormRequestTests.java @@ -0,0 +1,84 @@ +package io.paytrailpayment; + +import com.fasterxml.jackson.core.JsonProcessingException; +import io.paytrailpayment.dto.request.AddCardFormRequest; +import io.paytrailpayment.dto.response.AddCardFormResponse; +import io.paytrailpayment.utilites.ResponseMessage; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import static org.junit.jupiter.api.Assertions.*; + +public class CreateAddCardFormRequestTests extends TestCase { + private static final String MERCHANTIDSIS = "695861"; + private static final String SECRETKEYSIS = "MONISAIPPUAKAUPPIAS"; + private PaytrailClient payTrail; + + @BeforeEach + public void init() { + payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + } + + @Test + public void createAddCardFormRequest_RequestNull_ReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + AddCardFormRequest request = null; + AddCardFormResponse res = payTrail.createAddCardFormRequest(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createAddCardFormRequest_ValidateFalse_ReturnCode401() { + // Arrange + int expected = ResponseMessage.UNAUTHORIZED.getCode(); + + // Act + AddCardFormRequest request = new AddCardFormRequest(); + request.setCheckoutAccount(375917); + request.setCheckoutAlgorithm("sha256"); + request.setCheckoutMethod("POST"); + request.setCheckoutNonce("6501220b16b7"); + request.setCheckoutTimestamp("2023-08-22T04:05:20.253Z"); + request.setCheckoutRedirectSuccessUrl("https://somedomain.com/success"); + request.setCheckoutRedirectCancelUrl("https://somedomain.com/cancel"); + request.setLanguage("EN"); + request.setSignature("542e780c253761ed64333d5485391ddd4f55d5e00b7bdc7f60f0f0d15516f888"); + AddCardFormResponse res = payTrail.createAddCardFormRequest(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createAddCardFormRequest_Success_ReturnCode200() throws NoSuchAlgorithmException, InvalidKeyException, JsonProcessingException { + // Arrange + int expected = ResponseMessage.OK.getCode(); + + // Act + AddCardFormRequest request = new AddCardFormRequest(); + request.setCheckoutAccount(375917); + request.setCheckoutAlgorithm("sha256"); + request.setCheckoutMethod("POST"); + request.setCheckoutNonce("6501220b16b7"); + request.setCheckoutTimestamp("2023-08-22T04:05:20.253Z"); + request.setCheckoutRedirectSuccessUrl("https://somedomain.com/success"); + request.setCheckoutRedirectCancelUrl("https://somedomain.com/cancel"); + request.setLanguage("EN"); + request.setSignature("542e780c253761ed64333d5485391ddd4f55d5e00b7bdc7f60f0f0d15516f889"); + AddCardFormResponse res = payTrail.createAddCardFormRequest(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } +} diff --git a/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateCitPaymentAuthorizationHoldTests.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateCitPaymentAuthorizationHoldTests.java new file mode 100644 index 0000000..ee52828 --- /dev/null +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateCitPaymentAuthorizationHoldTests.java @@ -0,0 +1,160 @@ +package io.paytrailpayment; + +import io.paytrailpayment.dto.request.*; +import io.paytrailpayment.dto.request.model.*; +import io.paytrailpayment.dto.response.CreateMitOrCitPaymentResponse; +import io.paytrailpayment.dto.response.GetTokenResponse; +import io.paytrailpayment.utilites.ResponseMessage; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class CreateCitPaymentAuthorizationHoldTests { + private static final String MERCHANTIDN = "375917"; + private static final String MERCHANTIDSIS = "695861"; + private static final String SECRETKEYSIS = "MONISAIPPUAKAUPPIAS"; + + @Test + public void createCitPaymentAuthorizationHold_RequestNull_ReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = null; + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentAuthorizationHold(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createCitPaymentAuthorizationHold_ValidateFalse_ReturnCode401() { + // Arrange + int expected = ResponseMessage.UNAUTHORIZED.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = createValidPayload(); + // set wrong token + request.setToken("1d0a51f6-a60c-477b-94e2-403a0ed37199"); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCharge(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createCitPaymentAuthorizationHold_Success_ReturnCode200() { + // Arrange + int expected = ResponseMessage.OK.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentAuthorizationHold(payload); + int actual = res.getReturnCode(); + // Assert + assertEquals(expected, actual); + } + + @Test + public void createCitPaymentAuthorizationHold_CallPaytrailReturnFail_ReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCharge(payload); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + private CreateMitOrCitPaymentRequest createValidPayload() { + CreateMitOrCitPaymentRequest payload = new CreateMitOrCitPaymentRequest(); + payload.setToken("c7441208-c2a1-4a10-8eb6-458bd8eaa64f"); + payload.setStamp(UUID.randomUUID().toString()); + payload.setReference("9187445"); + payload.setAmount(1590); + payload.setCurrency(PaytrailCurrency.EUR); + payload.setLanguage(PaytrailLanguage.FI); + payload.setOrderId("12335"); + + ShopInShopItem item = new ShopInShopItem(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(BigDecimal.valueOf(24)); + item.setProductCode("#927502759"); + item.setCategory("Pet supplies"); + item.setDescription("Cat ladder"); + item.setStamp(UUID.randomUUID().toString()); + item.setReference("9187445"); + item.setOrderId("12335"); + item.setMerchant("375917"); + payload.setItems(Arrays.asList(item)); + + Customer customer = new Customer(); + customer.setEmail("erja.esimerkki@example.org"); + customer.setFirstName("Erja"); + customer.setVatId("FI12345671"); + customer.setCompanyName("nothing"); + customer.setLastName("+358501234567"); + customer.setPhone("123"); + payload.setCustomer(customer); + + CallbackUrl redirectUrls = new CallbackUrl(); + redirectUrls.setSuccess("https://ecom.example.org/success"); + redirectUrls.setCancel("https://ecom.example.org/cancel"); + payload.setRedirectUrls(redirectUrls); + + CallbackUrl callbackUrls = new CallbackUrl(); + callbackUrls.setSuccess("https://ecom.example.org/success"); + callbackUrls.setCancel("https://ecom.example.org/cancel"); + payload.setCallbackUrls(callbackUrls); + + Address deliveryAddress = new Address(); + deliveryAddress.setCity("Tampere"); + deliveryAddress.setCountry("FI"); + deliveryAddress.setCounty("Pirkanmaa"); + deliveryAddress.setPostalCode("33100"); + deliveryAddress.setStreetAddress("Hämeenkatu 6 B"); + payload.setDeliveryAddress(deliveryAddress); + + Address invoicingAddress = new Address(); + invoicingAddress.setCity("Helsinki"); + invoicingAddress.setCountry("FI"); + invoicingAddress.setCounty("Uusimaa"); + invoicingAddress.setPostalCode("00510"); + invoicingAddress.setStreetAddress("Testikatu 1"); + payload.setInvoicingAddress(invoicingAddress); + + payload.setGroups(Arrays.asList(PaytrailPaymentMethodGroup.mobile.toString())); + payload.setToken(this.getToken()); + return payload; + } + + /** + * Get token + * + * @return + */ + private String getToken() { + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + GetTokenRequest getTokenRequest = new GetTokenRequest(); + getTokenRequest.setCheckoutTokenizationId("1d0a51f6-a60c-477b-94e2-403a0ed37199"); + GetTokenResponse getTokenResponse = payTrail.createGetTokenRequest(getTokenRequest); + if (getTokenResponse == null || getTokenResponse.getReturnCode() != ResponseMessage.OK.getCode()) { + return null; + } + return getTokenResponse.getData().getToken(); + } +} diff --git a/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateCitPaymentChargeTests.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateCitPaymentChargeTests.java new file mode 100644 index 0000000..9832d40 --- /dev/null +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateCitPaymentChargeTests.java @@ -0,0 +1,177 @@ +package io.paytrailpayment; + +import io.paytrailpayment.dto.request.*; +import io.paytrailpayment.dto.request.model.*; +import io.paytrailpayment.dto.response.CreateMitOrCitPaymentResponse; +import io.paytrailpayment.dto.response.GetTokenResponse; +import io.paytrailpayment.utilites.ResponseMessage; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class CreateCitPaymentChargeTests { + private static final String MERCHANTIDN = "695874"; + private static final String MERCHANTIDSIS = "695861"; + private static final String SECRETKEYSIS = "MONISAIPPUAKAUPPIAS"; + private static final String SECRETKEYSIS_BAD = "MONISAIPPUAKAUPPIASS"; + + @Test + public void createCitPaymentCharge_RequestNull_ReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = null; + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCharge(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createCitPaymentCharge_ValidateFalse_ReturnCode400_With_Validate_Request() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = new CreateMitOrCitPaymentRequest(); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCharge(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createCitPaymentCharge_Success_ReturnCode200() { + // Arrange + int expected = ResponseMessage.OK.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCharge(payload); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createCitPaymentCharge_CallPaytrailReturnFail_ReturnCode400_With_Failed_Create_Token_Payment() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + // Set wrong token + payload.setToken("1d0a51f6-a60c-477b-94e2-403a0ed37199"); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCharge(payload); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createCitPaymentCharge_CallPaytrailReturnFail_ReturnCode401() { + // Arrange + int expected = ResponseMessage.UNAUTHORIZED.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS_BAD, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCharge(payload); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + private CreateMitOrCitPaymentRequest createValidPayload() { + CreateMitOrCitPaymentRequest payload = new CreateMitOrCitPaymentRequest(); + payload.setToken("c7441208-c2a1-4a10-8eb6-458bd8eaa64f"); + payload.setStamp(UUID.randomUUID().toString()); + payload.setReference("9187445"); + payload.setAmount(1590); + payload.setCurrency(PaytrailCurrency.EUR); + payload.setLanguage(PaytrailLanguage.FI); + payload.setOrderId("12335"); + + ShopInShopItem item = new ShopInShopItem(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(BigDecimal.valueOf(24)); + item.setProductCode("#927502759"); + item.setCategory("Pet supplies"); + item.setDescription("Cat ladder"); + item.setStamp(UUID.randomUUID().toString()); + item.setReference("9187445"); + item.setOrderId("12335"); + item.setMerchant("695874"); + payload.setItems(Arrays.asList(item)); + + Customer customer = new Customer(); + customer.setEmail("erja.esimerkki@example.org"); + customer.setFirstName("Erja"); + customer.setVatId("FI12345671"); + customer.setCompanyName("nothing"); + customer.setLastName("+358501234567"); + customer.setPhone("123"); + payload.setCustomer(customer); + + CallbackUrl redirectUrls = new CallbackUrl(); + redirectUrls.setSuccess("https://ecom.example.org/success"); + redirectUrls.setCancel("https://ecom.example.org/cancel"); + payload.setRedirectUrls(redirectUrls); + + CallbackUrl callbackUrls = new CallbackUrl(); + callbackUrls.setSuccess("https://ecom.example.org/success"); + callbackUrls.setCancel("https://ecom.example.org/cancel"); + payload.setCallbackUrls(callbackUrls); + + Address deliveryAddress = new Address(); + deliveryAddress.setCity("Tampere"); + deliveryAddress.setCountry("FI"); + deliveryAddress.setCounty("Pirkanmaa"); + deliveryAddress.setPostalCode("33100"); + deliveryAddress.setStreetAddress("Hämeenkatu 6 B"); + payload.setDeliveryAddress(deliveryAddress); + + Address invoicingAddress = new Address(); + invoicingAddress.setCity("Helsinki"); + invoicingAddress.setCountry("FI"); + invoicingAddress.setCounty("Uusimaa"); + invoicingAddress.setPostalCode("00510"); + invoicingAddress.setStreetAddress("Testikatu 1"); + payload.setInvoicingAddress(invoicingAddress); + + payload.setGroups(Arrays.asList(PaytrailPaymentMethodGroup.mobile.toString())); + payload.setToken(this.getToken()); + return payload; + } + + /** + * Get token + * + * @return + */ + private String getToken() { + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + GetTokenRequest getTokenRequest = new GetTokenRequest(); + getTokenRequest.setCheckoutTokenizationId("1d0a51f6-a60c-477b-94e2-403a0ed37199"); + GetTokenResponse getTokenResponse = payTrail.createGetTokenRequest(getTokenRequest); + if (getTokenResponse == null || getTokenResponse.getReturnCode() != ResponseMessage.OK.getCode()) { + return null; + } + return getTokenResponse.getData().getToken(); + } +} diff --git a/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateCitPaymentCommitTests.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateCitPaymentCommitTests.java new file mode 100644 index 0000000..42239db --- /dev/null +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateCitPaymentCommitTests.java @@ -0,0 +1,102 @@ +package io.paytrailpayment; + +import io.paytrailpayment.dto.request.CreateMitOrCitPaymentRequest; +import io.paytrailpayment.dto.request.model.*; +import io.paytrailpayment.dto.response.CreateMitOrCitPaymentResponse; +import io.paytrailpayment.utilites.ResponseMessage; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.UUID; + +public class CreateCitPaymentCommitTests { + private static final String MERCHANTIDN = "695874"; + private static final String MERCHANTIDSIS = "695861"; + private static final String SECRETKEYSIS = "MONISAIPPUAKAUPPIAS"; + private static final String SECRETKEYSIS_BAD = "MONISAIPPUAKAUPPIASS"; + + @Test + public void requestNullReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = null; + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCommit(request, "0e056dd8-408f-11ee-9cb4-e3059a523029"); + int actual = res.getReturnCode(); + + // Assert + Assertions.assertEquals(expected, actual); + } + + @Test + public void validateFalseReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = new CreateMitOrCitPaymentRequest(); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCommit(request, "0e056dd8-408f-11ee-9cb4-e3059a523029"); + int actual = res.getReturnCode(); + + // Assert + Assertions.assertEquals(expected, actual); + } + + @Test + public void successReturnCode200() { + // Arrange + int expected = ResponseMessage.OK.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCommit(payload, "0e056dd8-408f-11ee-9cb4-e3059a523029"); + int actual = res.getReturnCode(); + + // Assert + Assertions.assertEquals(expected, actual); + } + + @Test + public void callPaytrailReturnFailReturnCode401() { + // Arrange + int expected = ResponseMessage.UNAUTHORIZED.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS_BAD, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createCitPaymentCommit(payload, "0e056dd8-408f-11ee-9cb4-e3059a523029"); + int actual = res.getReturnCode(); + + // Assert + Assertions.assertEquals(expected, actual); + } + + private CreateMitOrCitPaymentRequest createValidPayload() { + CreateMitOrCitPaymentRequest payload = new CreateMitOrCitPaymentRequest(); + payload.setToken("c7441208-c2a1-4a10-8eb6-458bd8eaa64f"); + payload.setStamp(UUID.randomUUID().toString()); + payload.setReference("9187445"); + payload.setAmount(1590); + payload.setCurrency(PaytrailCurrency.EUR); + payload.setLanguage(PaytrailLanguage.FI); + payload.setOrderId(""); + payload.setItems(Arrays.asList(new ShopInShopItem( + 1590, 1, BigDecimal.valueOf(24), "#927502759", "Pet supplies", "Cat ladder", "695874", + UUID.randomUUID().toString(), "9187445", "12335"))); + payload.setCustomer(new Customer( + "erja.esimerkki@example.org", "Erja", "FI12345671", "nothing", + "+358501234567", "123")); + payload.setRedirectUrls(new CallbackUrl("https://ecom.example.org/success", "https://ecom.example.org/cancel")); + payload.setCallbackUrls(new CallbackUrl("https://ecom.example.org/success", "https://ecom.example.org/cancel")); + payload.setDeliveryAddress(new Address("Tampere", "FI", "Pirkanmaa", "33100", "Hämeenkatu 6 B")); + payload.setInvoicingAddress(new Address("Helsinki", "FI", "Uusimaa", "00510", "Testikatu 1")); + payload.setGroups(Arrays.asList(PaytrailPaymentMethodGroup.mobile.toString())); + return payload; + } +} diff --git a/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateMitPaymentAuthorizationHoldTests.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateMitPaymentAuthorizationHoldTests.java new file mode 100644 index 0000000..036204e --- /dev/null +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateMitPaymentAuthorizationHoldTests.java @@ -0,0 +1,159 @@ +package io.paytrailpayment; + +import io.paytrailpayment.dto.request.*; +import io.paytrailpayment.dto.request.model.*; +import io.paytrailpayment.dto.response.CreateMitOrCitPaymentResponse; +import io.paytrailpayment.dto.response.GetTokenResponse; +import io.paytrailpayment.utilites.ResponseMessage; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class CreateMitPaymentAuthorizationHoldTests { + private static final String MERCHANTIDN = "375917"; + private static final String MERCHANTIDSIS = "695861"; + private static final String SECRETKEYSIS = "MONISAIPPUAKAUPPIAS"; + private static final String SECRETKEYSIS_BAD = "MONISAIPPUAKAUPPIASS"; + + @Test + public void createMitPaymentAuthorizationHoldRequestNullReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = null; + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentAuthorizationHold(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createMitPaymentAuthorizationHoldValidateFalseReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = new CreateMitOrCitPaymentRequest(); + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentAuthorizationHold(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createMitPaymentAuthorizationHoldSuccessReturnCode200() { + // Arrange + int expected = ResponseMessage.OK.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentAuthorizationHold(payload); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createMitPaymentAuthorizationHoldCallPaytrailReturnFailReturnCode401() { + // Arrange + int expected = ResponseMessage.UNAUTHORIZED.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS_BAD, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentAuthorizationHold(payload); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + private CreateMitOrCitPaymentRequest createValidPayload() { + CreateMitOrCitPaymentRequest payload = new CreateMitOrCitPaymentRequest(); + payload.setToken("c7441208-c2a1-4a10-8eb6-458bd8eaa64f"); + payload.setStamp(UUID.randomUUID().toString()); + payload.setReference("9187445"); + payload.setAmount(1590); + payload.setCurrency(PaytrailCurrency.EUR); + payload.setLanguage(PaytrailLanguage.FI); + payload.setOrderId(""); + + ShopInShopItem item = new ShopInShopItem(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(BigDecimal.valueOf(24)); + item.setProductCode("#927502759"); + item.setCategory("Pet supplies"); + item.setDescription("Cat ladder"); + item.setStamp(UUID.randomUUID().toString()); + item.setReference("9187445"); + item.setMerchant("695874"); + payload.setItems(Arrays.asList(item)); + + Customer customer = new Customer(); + customer.setEmail("erja.esimerkki@example.org"); + customer.setFirstName("Erja"); + customer.setVatId("FI12345671"); + customer.setCompanyName("nothing"); + customer.setLastName("+358501234567"); + customer.setPhone("123"); + payload.setCustomer(customer); + + CallbackUrl redirectUrls = new CallbackUrl(); + redirectUrls.setSuccess("https://ecom.example.org/success"); + redirectUrls.setCancel("https://ecom.example.org/cancel"); + payload.setRedirectUrls(redirectUrls); + + CallbackUrl callbackUrls = new CallbackUrl(); + callbackUrls.setSuccess("https://ecom.example.org/success"); + callbackUrls.setCancel("https://ecom.example.org/cancel"); + payload.setCallbackUrls(callbackUrls); + + Address deliveryAddress = new Address(); + deliveryAddress.setCity("Tampere"); + deliveryAddress.setCountry("FI"); + deliveryAddress.setCounty("Pirkanmaa"); + deliveryAddress.setPostalCode("33100"); + deliveryAddress.setStreetAddress("Hämeenkatu 6 B"); + payload.setDeliveryAddress(deliveryAddress); + + Address invoicingAddress = new Address(); + invoicingAddress.setCity("Helsinki"); + invoicingAddress.setCountry("FI"); + invoicingAddress.setCounty("Uusimaa"); + invoicingAddress.setPostalCode("00510"); + invoicingAddress.setStreetAddress("Testikatu 1"); + payload.setInvoicingAddress(invoicingAddress); + + payload.setGroups(Arrays.asList(PaytrailPaymentMethodGroup.mobile.toString())); + payload.setToken(this.getToken()); + return payload; + } + + /** + * Get token + * + * @return + */ + private String getToken() { + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + GetTokenRequest getTokenRequest = new GetTokenRequest(); + getTokenRequest.setCheckoutTokenizationId("1d0a51f6-a60c-477b-94e2-403a0ed37199"); + GetTokenResponse getTokenResponse = payTrail.createGetTokenRequest(getTokenRequest); + if (getTokenResponse == null || getTokenResponse.getReturnCode() != ResponseMessage.OK.getCode()) { + return null; + } + return getTokenResponse.getData().getToken(); + } +} diff --git a/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateMitPaymentChargeTests.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateMitPaymentChargeTests.java new file mode 100644 index 0000000..c66edb8 --- /dev/null +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateMitPaymentChargeTests.java @@ -0,0 +1,159 @@ +package io.paytrailpayment; + +import io.paytrailpayment.dto.request.*; +import io.paytrailpayment.dto.request.model.*; +import io.paytrailpayment.dto.response.CreateMitOrCitPaymentResponse; +import io.paytrailpayment.dto.response.GetTokenResponse; +import io.paytrailpayment.utilites.ResponseMessage; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class CreateMitPaymentChargeTests { + private static final String MERCHANTIDN = "375917"; + private static final String MERCHANTIDSIS = "695861"; + private static final String SECRETKEYSIS = "MONISAIPPUAKAUPPIAS"; + private static final String SECRETKEYSIS_BAD = "MONISAIPPUAKAUPPIASS"; + + @Test + public void createMitPaymentCharge_RequestNull_ReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = null; + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentCharge(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createMitPaymentCharge_ValidateFalse_ReturnCode403() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = new CreateMitOrCitPaymentRequest(); + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentCharge(request); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createMitPaymentCharge_Success_ReturnCode200() { + // Arrange + int expected = ResponseMessage.OK.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentCharge(payload); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createMitPaymentCharge_CallPaytrailReturnFail_ReturnCode401() { + // Arrange + int expected = ResponseMessage.UNAUTHORIZED.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS_BAD, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentCharge(payload); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + private CreateMitOrCitPaymentRequest createValidPayload() { + CreateMitOrCitPaymentRequest payload = new CreateMitOrCitPaymentRequest(); + payload.setToken("c7441208-c2a1-4a10-8eb6-458bd8eaa64f"); + payload.setStamp(UUID.randomUUID().toString()); + payload.setReference("9187445"); + payload.setAmount(1590); + payload.setCurrency(PaytrailCurrency.EUR); + payload.setLanguage(PaytrailLanguage.FI); + payload.setOrderId(""); + + ShopInShopItem item = new ShopInShopItem(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(BigDecimal.valueOf(24)); + item.setProductCode("#927502759"); + item.setCategory("Pet supplies"); + item.setDescription("Cat ladder"); + item.setStamp(UUID.randomUUID().toString()); + item.setReference("9187445"); + item.setMerchant("695874"); + payload.setItems(Arrays.asList(item)); + + Customer customer = new Customer(); + customer.setEmail("erja.esimerkki@example.org"); + customer.setFirstName("Erja"); + customer.setVatId("FI12345671"); + customer.setCompanyName("nothing"); + customer.setLastName("+358501234567"); + customer.setPhone("123"); + payload.setCustomer(customer); + + CallbackUrl redirectUrls = new CallbackUrl(); + redirectUrls.setSuccess("https://ecom.example.org/success"); + redirectUrls.setCancel("https://ecom.example.org/cancel"); + payload.setRedirectUrls(redirectUrls); + + CallbackUrl callbackUrls = new CallbackUrl(); + callbackUrls.setSuccess("https://ecom.example.org/success"); + callbackUrls.setCancel("https://ecom.example.org/cancel"); + payload.setCallbackUrls(callbackUrls); + + Address deliveryAddress = new Address(); + deliveryAddress.setCity("Tampere"); + deliveryAddress.setCountry("FI"); + deliveryAddress.setCounty("Pirkanmaa"); + deliveryAddress.setPostalCode("33100"); + deliveryAddress.setStreetAddress("Hämeenkatu 6 B"); + payload.setDeliveryAddress(deliveryAddress); + + Address invoicingAddress = new Address(); + invoicingAddress.setCity("Helsinki"); + invoicingAddress.setCountry("FI"); + invoicingAddress.setCounty("Uusimaa"); + invoicingAddress.setPostalCode("00510"); + invoicingAddress.setStreetAddress("Testikatu 1"); + payload.setInvoicingAddress(invoicingAddress); + + payload.setGroups(Arrays.asList(PaytrailPaymentMethodGroup.mobile.toString())); + payload.setToken(this.getToken()); + return payload; + } + + /** + * Get token + * + * @return + */ + private String getToken() { + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + GetTokenRequest getTokenRequest = new GetTokenRequest(); + getTokenRequest.setCheckoutTokenizationId("1d0a51f6-a60c-477b-94e2-403a0ed37199"); + GetTokenResponse getTokenResponse = payTrail.createGetTokenRequest(getTokenRequest); + if (getTokenResponse == null || getTokenResponse.getReturnCode() != ResponseMessage.OK.getCode()) { + return null; + } + return getTokenResponse.getData().getToken(); + } +} diff --git a/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateMitPaymentCommitTests.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateMitPaymentCommitTests.java new file mode 100644 index 0000000..7663c42 --- /dev/null +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateMitPaymentCommitTests.java @@ -0,0 +1,142 @@ +package io.paytrailpayment; + +import io.paytrailpayment.dto.request.*; +import io.paytrailpayment.dto.request.model.*; +import io.paytrailpayment.dto.response.CreateMitOrCitPaymentResponse; +import io.paytrailpayment.utilites.ResponseMessage; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class CreateMitPaymentCommitTests { + private static final String MERCHANTIDN = "375917"; + private static final String MERCHANTIDSIS = "695861"; + private static final String SECRETKEYSIS = "MONISAIPPUAKAUPPIAS"; + private static final String SECRETKEYSIS_BAD = "MONISAIPPUAKAUPPIASS"; + + @Test + public void createMitPaymentCommit_RequestNull_ReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = null; + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentCommit(request, "0e056dd8-408f-11ee-9cb4-e3059a523029"); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createMitPaymentCommit_ValidateFalse_ReturnCode403() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest request = new CreateMitOrCitPaymentRequest(); + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentCommit(request, "0e056dd8-408f-11ee-9cb4-e3059a523029"); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createMitPaymentCommit_Success_ReturnCode200() { + // Arrange + int expected = ResponseMessage.OK.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentCommit(payload, "0e056dd8-408f-11ee-9cb4-e3059a523029"); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + @Test + public void createMitPaymentCommit_CallPaytrailReturnFail_ReturnCode401() { + // Arrange + int expected = ResponseMessage.UNAUTHORIZED.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDSIS, SECRETKEYSIS_BAD, "test"); + CreateMitOrCitPaymentRequest payload = createValidPayload(); + CreateMitOrCitPaymentResponse res = payTrail.createMitPaymentCommit(payload, "0e056dd8-408f-11ee-9cb4-e3059a523029"); + int actual = res.getReturnCode(); + + // Assert + assertEquals(expected, actual); + } + + private CreateMitOrCitPaymentRequest createValidPayload() { + CreateMitOrCitPaymentRequest payload = new CreateMitOrCitPaymentRequest(); + payload.setToken("c7441208-c2a1-4a10-8eb6-458bd8eaa64f"); + payload.setStamp(UUID.randomUUID().toString()); + payload.setReference("9187445"); + payload.setAmount(1590); + payload.setCurrency(PaytrailCurrency.EUR); + payload.setLanguage(PaytrailLanguage.FI); + payload.setOrderId(""); + + ShopInShopItem item = new ShopInShopItem(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(BigDecimal.valueOf(24)); + item.setProductCode("#927502759"); + item.setCategory("Pet supplies"); + item.setDescription("Cat ladder"); + item.setStamp(UUID.randomUUID().toString()); + item.setReference("9187445"); + item.setMerchant("695874"); + payload.setItems(Arrays.asList(item)); + + Customer customer = new Customer(); + customer.setEmail("erja.esimerkki@example.org"); + customer.setFirstName("Erja"); + customer.setVatId("FI12345671"); + customer.setCompanyName("nothing"); + customer.setLastName("+358501234567"); + customer.setPhone("123"); + payload.setCustomer(customer); + + CallbackUrl redirectUrls = new CallbackUrl(); + redirectUrls.setSuccess("https://ecom.example.org/success"); + redirectUrls.setCancel("https://ecom.example.org/cancel"); + payload.setRedirectUrls(redirectUrls); + + CallbackUrl callbackUrls = new CallbackUrl(); + callbackUrls.setSuccess("https://ecom.example.org/success"); + callbackUrls.setCancel("https://ecom.example.org/cancel"); + payload.setCallbackUrls(callbackUrls); + + Address deliveryAddress = new Address(); + deliveryAddress.setCity("Tampere"); + deliveryAddress.setCountry("FI"); + deliveryAddress.setCounty("Pirkanmaa"); + deliveryAddress.setPostalCode("33100"); + deliveryAddress.setStreetAddress("Hämeenkatu 6 B"); + payload.setDeliveryAddress(deliveryAddress); + + Address invoicingAddress = new Address(); + invoicingAddress.setCity("Helsinki"); + invoicingAddress.setCountry("FI"); + invoicingAddress.setCounty("Uusimaa"); + invoicingAddress.setPostalCode("00510"); + invoicingAddress.setStreetAddress("Testikatu 1"); + payload.setInvoicingAddress(invoicingAddress); + + payload.setGroups(Arrays.asList(PaytrailPaymentMethodGroup.mobile.toString())); + + return payload; + } +} diff --git a/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreatePaymentUnitTest.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreatePaymentUnitTest.java new file mode 100644 index 0000000..a6e68bf --- /dev/null +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreatePaymentUnitTest.java @@ -0,0 +1,343 @@ +package io.paytrailpayment; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.paytrailpayment.dto.request.CreatePaymentRequest; +import io.paytrailpayment.dto.request.model.*; +import io.paytrailpayment.dto.request.model.PaytrailCurrency; +import io.paytrailpayment.dto.response.CreatePaymentResponse; + +import io.paytrailpayment.utilites.ResponseMessage; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; + +public class CreatePaymentUnitTest extends TestCase { + private PaytrailClient client; + + @BeforeEach + public void init() { + // Initialize your PaytrailClient here with default values for all tests or any other setup. + client = new PaytrailClient(this.merchantId, this.secretKey, this.platformName); + } + + @Test() + public void createPaymentReturnStatusCode400WithPayloadNull() { + CreatePaymentResponse res = client.createPayment(null); + + assertNotNull(res); + assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); + assertNull(res.getData()); + } + + @Test() + public void createPaymentReturnStatusCode400WithFieldRequiredNotFilled() throws JsonProcessingException { + String messageExpect = "{\"reference\":\"Reference can't be null or empty.\",\"amount\":\"Amount doesn't match total of items.\",\"stamp\":\"Stamp can't be null or empty.\",\"currency\":\"Currency can't be null.\",\"language\":\"Language can't be null.\"}"; + CreatePaymentRequest req = new CreatePaymentRequest(); + + req.setOrderId("12335"); + + List items = new ArrayList<>(); + Item item = new Item(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(new BigDecimal(24)); + item.setProductCode("#927502759"); + items.add(item); + + req.setItems(items); + + Customer customer = new Customer(); + customer.setEmail("erja.esimerkki@example.org"); + customer.setFirstName("TEST"); + customer.setLastName("test"); + customer.setPhone("0369874566"); + customer.setVatId("156988"); + customer.setCompanyName("ttest"); + req.setCustomer(customer); + + CallbackUrl redirectUrls = new CallbackUrl(); + redirectUrls.setSuccess("https://ecom.example.org/success"); + redirectUrls.setCancel("https://ecom.example.org/cancel"); + req.setRedirectUrls(redirectUrls); + + CallbackUrl callbackUrls = new CallbackUrl(); + callbackUrls.setSuccess("https://ecom.example.org/success"); + callbackUrls.setCancel("https://ecom.example.org/cancel"); + req.setCallbackUrls(callbackUrls); + + CreatePaymentResponse res = client.createPayment(req); + + assertNotNull(res); + assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode expectedJson = objectMapper.readTree(messageExpect); + JsonNode actualJson = objectMapper.readTree(res.getReturnMessage()); + + assertEquals(expectedJson, actualJson); + assertNull(res.getData()); + } + + @Test() + public void createPaymentReturnStatusCode400WithPayloadValidateFail() { + CreatePaymentRequest req = new CreatePaymentRequest(); + + req.setStamp(UUID.randomUUID().toString()); + req.setReference("9187445"); + req.setCurrency(PaytrailCurrency.EUR); + req.setLanguage(PaytrailLanguage.EN); + req.setAmount(-1590); + + CreatePaymentResponse res = client.createPayment(req); + + assertNotNull(res); + assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); + assertNull(res.getData()); + } + + @Test() + public void createPaymentReturnStatusCode200() { + CreatePaymentRequest req = new CreatePaymentRequest(); + + req.setStamp(UUID.randomUUID().toString()); + req.setReference("9187445"); + req.setCurrency(PaytrailCurrency.EUR); + req.setLanguage(PaytrailLanguage.EN); + req.setOrderId("12335"); + req.setAmount(1590); + + List items = new ArrayList<>(); + Item item = new Item(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(new BigDecimal(24)); + item.setProductCode("#927502759"); + items.add(item); + + req.setItems(items); + + Customer customer = new Customer(); + customer.setEmail("erja.esimerkki@example.org"); + customer.setFirstName("TEST"); + customer.setLastName("test"); + customer.setPhone("0369874566"); + customer.setVatId("156988"); + customer.setCompanyName("ttest"); + req.setCustomer(customer); + + CallbackUrl redirectUrls = new CallbackUrl(); + redirectUrls.setSuccess("https://ecom.example.org/success"); + redirectUrls.setCancel("https://ecom.example.org/cancel"); + req.setRedirectUrls(redirectUrls); + + CallbackUrl callbackUrls = new CallbackUrl(); + callbackUrls.setSuccess("https://ecom.example.org/success"); + callbackUrls.setCancel("https://ecom.example.org/cancel"); + req.setCallbackUrls(callbackUrls); + + CreatePaymentResponse res = client.createPayment(req); + + assertNotNull(res); + assertEquals(ResponseMessage.OK.getCode(), res.getReturnCode()); + assertEquals(ResponseMessage.OK.getDescription(), res.getReturnMessage()); + assertNotNull(res.getData()); + } + + @Test() + public void createPaymentReturnStatusCode401WithFalseAuthenticationInformation() { + client = new PaytrailClient("375918", "SAIPPUAKAUPPIAS", "test"); + + CreatePaymentRequest req = new CreatePaymentRequest(); + + req.setStamp(UUID.randomUUID().toString()); + req.setReference("9187445"); + req.setCurrency(PaytrailCurrency.EUR); + req.setLanguage(PaytrailLanguage.EN); + req.setOrderId("12335"); + req.setAmount(1590); + + List items = new ArrayList<>(); + Item item = new Item(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(new BigDecimal(24)); + item.setProductCode("#927502759"); + items.add(item); + + req.setItems(items); + + Customer customer = new Customer(); + customer.setEmail("erja.esimerkki@example.org"); + customer.setFirstName("TEST"); + customer.setLastName("test"); + customer.setPhone("0369874566"); + customer.setVatId("156988"); + customer.setCompanyName("ttest"); + req.setCustomer(customer); + + CallbackUrl redirectUrls = new CallbackUrl(); + redirectUrls.setSuccess("https://ecom.example.org/success"); + redirectUrls.setCancel("https://ecom.example.org/cancel"); + req.setRedirectUrls(redirectUrls); + + CallbackUrl callbackUrls = new CallbackUrl(); + callbackUrls.setSuccess("https://ecom.example.org/success"); + callbackUrls.setCancel("https://ecom.example.org/cancel"); + req.setCallbackUrls(callbackUrls); + + CreatePaymentResponse res = client.createPayment(req); + + assertNotNull(res); + assertEquals(ResponseMessage.UNAUTHORIZED.getCode(), res.getReturnCode()); + } + + @Test() + public void createPaymentReturnStatusCode400WithVatPercentageMoreThanOneDecimalPlace() throws Exception { + CreatePaymentRequest req = new CreatePaymentRequest(); + + req.setStamp(UUID.randomUUID().toString()); + req.setReference("9187445"); + req.setCurrency(PaytrailCurrency.EUR); + req.setLanguage(PaytrailLanguage.EN); + req.setOrderId("12335"); + req.setAmount(1590); + + List items = new ArrayList<>(); + Item item = new Item(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(new BigDecimal("24.55")); // VatPercentage has more than one decimal place + item.setProductCode("#927502759"); + items.add(item); + + req.setItems(items); + + CreatePaymentResponse res = client.createPayment(req); + + assertNotNull(res); + assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); + + // Expected vatPercentage message + String expectedVatPercentageMessage = "Item's vat Percentage can't have more than one decimal place."; + + // Parse the actual response message to a JsonNode + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode actualJsonNode = objectMapper.readTree(res.getReturnMessage()); + + // Extract the "item" field which contains the nested JSON string + String itemField = actualJsonNode.get("item").asText(); + + // Parse the nested JSON string inside the "item" field + JsonNode itemJsonNode = objectMapper.readTree(itemField); + + // Extract and normalize the vatPercentage message + String actualVatPercentageMessage = itemJsonNode.get("vatPercentage").asText().replace("\\u0027", "'"); + + // Compare the actual vatPercentage message with the expected one + assertEquals(expectedVatPercentageMessage, actualVatPercentageMessage); + + assertNull(res.getData()); + } + + @Test() + public void createPaymentReturnStatusCode400WithVatPercentageNegative() throws Exception { + CreatePaymentRequest req = new CreatePaymentRequest(); + + req.setStamp(UUID.randomUUID().toString()); + req.setReference("9187445"); + req.setCurrency(PaytrailCurrency.EUR); + req.setLanguage(PaytrailLanguage.EN); + req.setOrderId("12335"); + req.setAmount(1590); + + List items = new ArrayList<>(); + Item item = new Item(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(new BigDecimal("-5.0")); // VatPercentage is negative + item.setProductCode("#927502759"); + items.add(item); + + req.setItems(items); + + CreatePaymentResponse res = client.createPayment(req); + + assertNotNull(res); + assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); + + // Expected vatPercentage message + String expectedVatPercentageMessage = "Item's vat Percentage can't be null or a negative number."; + + // Parse the actual response message to a JsonNode + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode actualJsonNode = objectMapper.readTree(res.getReturnMessage()); + + // Extract the "item" field which contains the nested JSON string + String itemField = actualJsonNode.get("item").asText(); + + // Parse the nested JSON string inside the "item" field + JsonNode itemJsonNode = objectMapper.readTree(itemField); + + // Extract and normalize the vatPercentage message + String actualVatPercentageMessage = itemJsonNode.get("vatPercentage").asText().replace("\\u0027", "'"); + + // Compare the actual vatPercentage message with the expected one + assertEquals(expectedVatPercentageMessage, actualVatPercentageMessage); + + assertNull(res.getData()); + } + + + + @Test() + public void createPaymentReturnStatusCode400WithVatPercentageNull() throws Exception { + CreatePaymentRequest req = new CreatePaymentRequest(); + req.setStamp(UUID.randomUUID().toString()); + req.setReference("9187445"); + req.setCurrency(PaytrailCurrency.EUR); + req.setLanguage(PaytrailLanguage.EN); + req.setOrderId("12335"); + req.setAmount(1590); + + List items = new ArrayList<>(); + Item item = new Item(); + item.setUnitPrice(1590); + item.setUnits(1); + item.setVatPercentage(null); // VatPercentage is null + item.setProductCode("#927502759"); + items.add(item); + + req.setItems(items); + + CreatePaymentResponse res = client.createPayment(req); + + assertNotNull(res); + assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); + + // Expected vatPercentage message + String expectedVatPercentageMessage = "Item's vat Percentage can't be null or a negative number."; + + // Parse the actual response message to a JsonNode + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode actualJsonNode = objectMapper.readTree(res.getReturnMessage()); + + // Extract the "item" field which contains the nested JSON string + String itemField = actualJsonNode.get("item").asText(); + + // Parse the nested JSON string inside the "item" field + JsonNode itemJsonNode = objectMapper.readTree(itemField); + + // Extract and normalize the vatPercentage message + String actualVatPercentageMessage = itemJsonNode.get("vatPercentage").asText().replace("\\u0027", "'"); + + // Compare the actual vatPercentage message with the expected one + assertEquals(expectedVatPercentageMessage, actualVatPercentageMessage); + + assertNull(res.getData()); + } +} diff --git a/paytrailpayment-sdk/src/test/java/CreateRefundRequestUnitTest.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateRefundRequestUnitTest.java similarity index 81% rename from paytrailpayment-sdk/src/test/java/CreateRefundRequestUnitTest.java rename to paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateRefundRequestUnitTest.java index 4bc0cd6..44020e0 100644 --- a/paytrailpayment-sdk/src/test/java/CreateRefundRequestUnitTest.java +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/CreateRefundRequestUnitTest.java @@ -1,13 +1,18 @@ -import io.paytrailpayment.PaytrailClient; +package io.paytrailpayment; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import io.paytrailpayment.dto.request.CreatePaymentRequest; import io.paytrailpayment.dto.request.CreateRefundRequest; import io.paytrailpayment.dto.request.model.*; import io.paytrailpayment.dto.response.CreatePaymentResponse; import io.paytrailpayment.dto.response.CreateRefundResponse; import io.paytrailpayment.utilites.ResponseMessage; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -18,8 +23,8 @@ public class CreateRefundRequestUnitTest extends TestCase { private PaytrailClient client; private String transactionId; - @Before - public void setUp() { + @BeforeEach + public void init() { client = new PaytrailClient(this.merchantId, this.secretKey, this.platformName); CreatePaymentRequest req = new CreatePaymentRequest(); @@ -35,7 +40,7 @@ public void setUp() { Item item = new Item(); item.setUnitPrice(1590); item.setUnits(1); - item.setVatPercentage(24); + item.setVatPercentage(new BigDecimal(24)); item.setProductCode("#927502759"); items.add(item); @@ -75,8 +80,8 @@ public void createRefundRequestReturnStatusCode400WithPayloadNull() { } @Test() - public void createRefundRequestReturnStatusCode400WithFieldRequiredNotFilled() { - String messageExpect = "{\"callbackUrls\":\"Callback Urls can't be null.\",\"items\":\"{\\\"amount\\\":\\\"Item's amount is invalid.\\\"}\"}\n"; + public void createRefundRequestReturnStatusCode400WithFieldRequiredNotFilled() throws JsonProcessingException { + String messageExpect = "{\"callbackUrls\":\"Callback Urls can't be null.\",\"items\":\"{\\\"amount\\\":\\\"Item's amount is invalid. \\\"}\"}\n"; CreateRefundRequest req = new CreateRefundRequest(); req.setEmail("test@gmail.com"); @@ -96,7 +101,21 @@ public void createRefundRequestReturnStatusCode400WithFieldRequiredNotFilled() { assertNotNull(res); assertEquals(ResponseMessage.BAD_REQUEST.getCode(), res.getReturnCode()); - assertEquals(messageExpect, res.getReturnMessage()); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode actualJsonNode = objectMapper.readTree(res.getReturnMessage()); + + // Extract the "item" field which contains the nested JSON string + String itemField = actualJsonNode.get("items").asText(); + + // Parse the nested JSON string inside the "item" field + JsonNode itemJsonNode = objectMapper.readTree(itemField); + // Extract and normalize the callbackUrls and amount messages + String actualCallbackUrlsMessage = actualJsonNode.get("callbackUrls").asText().replace("\\u0027", "'"); + String actualAmountMessage = itemJsonNode.get("amount").asText().replace("\\u0027", "'"); + + // Combine the messages if needed + String actualVatPercentageMessage = "{\"callbackUrls\":\"" + actualCallbackUrlsMessage + "\",\"items\":\"{\\\"amount\\\":\\\"" + actualAmountMessage + "\\\"}\"}\n"; + assertEquals(messageExpect, actualVatPercentageMessage); assertNull(res.getData()); } @@ -131,9 +150,8 @@ public void createRefundRequestReturnStatusCode403WithPayloadValidateFail() { } @Test() - public void createRefundRequestReturnStatusCode201() { + public void createRefundRequestReturnStatusCode200() { CreateRefundRequest req = new CreateRefundRequest(); - req.setAmount(1590); req.setEmail("test@gmail.com"); req.setRefundStamp(UUID.randomUUID().toString()); @@ -152,9 +170,7 @@ public void createRefundRequestReturnStatusCode201() { callbackUrls.setSuccess("https://ecom.example.org/success"); callbackUrls.setCancel("https://ecom.example.org/cancel"); req.setCallbackUrls(callbackUrls); - CreateRefundResponse res = client.createRefundRequest(req, transactionId); - assertNotNull(res); } diff --git a/paytrailpayment-sdk/src/test/java/GetPaymentUnitTest.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/GetPaymentUnitTest.java similarity index 93% rename from paytrailpayment-sdk/src/test/java/GetPaymentUnitTest.java rename to paytrailpayment-sdk/src/test/java/io/paytrailpayment/GetPaymentUnitTest.java index d20b6af..c7f9cca 100644 --- a/paytrailpayment-sdk/src/test/java/GetPaymentUnitTest.java +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/GetPaymentUnitTest.java @@ -1,12 +1,14 @@ -import io.paytrailpayment.PaytrailClient; +package io.paytrailpayment; + import io.paytrailpayment.dto.request.CreatePaymentRequest; import io.paytrailpayment.dto.request.model.*; import io.paytrailpayment.dto.response.CreatePaymentResponse; import io.paytrailpayment.dto.response.GetPaymentResponse; import io.paytrailpayment.utilites.ResponseMessage; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -17,8 +19,8 @@ public class GetPaymentUnitTest extends TestCase { private PaytrailClient client; private String transactionId; - @Before - public void setUp() { + @BeforeEach + public void init() { client = new PaytrailClient(this.merchantId, this.secretKey, this.platformName); CreatePaymentRequest req = new CreatePaymentRequest(); @@ -34,7 +36,7 @@ public void setUp() { Item item = new Item(); item.setUnitPrice(1590); item.setUnits(1); - item.setVatPercentage(24); + item.setVatPercentage(new BigDecimal(24)); item.setProductCode("#927502759"); items.add(item); diff --git a/paytrailpayment-sdk/src/test/java/io/paytrailpayment/PayAndAddCardTests.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/PayAndAddCardTests.java new file mode 100644 index 0000000..e4a8853 --- /dev/null +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/PayAndAddCardTests.java @@ -0,0 +1,146 @@ +package io.paytrailpayment; + +import io.paytrailpayment.dto.request.PayAddCardRequest; +import io.paytrailpayment.dto.request.model.*; +import io.paytrailpayment.dto.response.PayAddCardResponse; +import io.paytrailpayment.utilites.ResponseMessage; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.UUID; + +public class PayAndAddCardTests { + private static final String MERCHANTIDN = "375917"; + private static final String SECRETKEY = "SAIPPUAKAUPPIAS"; + private static final String MERCHANTIDSISS = "695874"; + private static final String SECRETKEY_BAD = "SAIPPUAKAUPPIASS"; + + @Test + public void requestNullReturnCode401() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEY, "test"); + PayAddCardRequest request = null; + PayAddCardResponse res = payTrail.payAndAddCard(request); + int actual = res.getReturnCode(); + + // Assert + Assertions.assertEquals(expected, actual); + } + + @Test + public void validateFalseReturnCode401() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEY, "test"); + PayAddCardRequest request = new PayAddCardRequest(); + PayAddCardResponse res = payTrail.payAndAddCard(request); + int actual = res.getReturnCode(); + + // Assert + Assertions.assertEquals(expected, actual); + } + + @Test + public void successReturnCode200() { + // Arrange + int expected = ResponseMessage.OK.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEY, "test"); + PayAddCardRequest request = new PayAddCardRequest(); + request.setStamp(UUID.randomUUID().toString()); + request.setReference("9187445"); + request.setAmount(1590); + request.setCurrency(PaytrailCurrency.EUR); + request.setLanguage(PaytrailLanguage.FI); + request.setOrderId(""); + request.setItems(Arrays.asList(new Item( + 1590, 1, BigDecimal.valueOf(24), "#927502759", "Pet supplies", "Cat ladder"))); + request.setCustomer(new Customer( + "erja.esimerkki@example.org", "Erja", "FI12345671", "nothing", + "+358501234567", "123")); + request.setRedirectUrls(new CallbackUrl("https://ecom.example.org/success", "https://ecom.example.org/cancel")); + request.setCallbackUrls(new CallbackUrl("https://ecom.example.org/success", "https://ecom.example.org/cancel")); + request.setDeliveryAddress(new Address("Tampere", "FI", "Pirkanmaa", "33100", "Hämeenkatu 6 B")); + request.setInvoicingAddress(new Address("Helsinki", "FI", "Uusimaa", "00510", "Testikatu 1")); + request.setGroups(Arrays.asList(PaytrailPaymentMethodGroup.mobile.toString())); + + PayAddCardResponse res = payTrail.payAndAddCard(request); + int actual = res.getReturnCode(); + + // Assert + Assertions.assertEquals(expected, actual); + } + + @Test + public void callPaytrailReturnNullReturnCode401() { + // Arrange + int expected = ResponseMessage.UNAUTHORIZED.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEY_BAD, "test"); + PayAddCardRequest request = new PayAddCardRequest(); + request.setStamp(UUID.randomUUID().toString()); + request.setReference("9187445"); + request.setAmount(1590); + request.setCurrency(PaytrailCurrency.EUR); + request.setLanguage(PaytrailLanguage.FI); + request.setOrderId(""); + request.setItems(Arrays.asList(new Item( + 1590, 1, BigDecimal.valueOf(24), "#927502759", "Pet supplies", "Cat ladder"))); + request.setCustomer(new Customer( + "erja.esimerkki@example.org", "Erja", "FI12345671", "nothing", + "+358501234567", "123")); + request.setRedirectUrls(new CallbackUrl("https://ecom.example.org/success", "https://ecom.example.org/cancel")); + request.setCallbackUrls(new CallbackUrl("https://ecom.example.org/success", "https://ecom.example.org/cancel")); + request.setDeliveryAddress(new Address("Tampere", "FI", "Pirkanmaa", "33100", "Hämeenkatu 6 B")); + request.setInvoicingAddress(new Address("Helsinki", "FI", "Uusimaa", "00510", "Testikatu 1")); + request.setGroups(Arrays.asList(PaytrailPaymentMethodGroup.mobile.toString())); + + PayAddCardResponse res = payTrail.payAndAddCard(request); + int actual = res.getReturnCode(); + + // Assert + Assertions.assertEquals(expected, actual); + } + + @Test + public void callPaytrailReturnFailReturnCode400() { + // Arrange + int expected = ResponseMessage.BAD_REQUEST.getCode(); + + // Act + PaytrailClient payTrail = new PaytrailClient(MERCHANTIDN, SECRETKEY, "test"); + PayAddCardRequest request = new PayAddCardRequest(); + request.setStamp(UUID.randomUUID().toString()); + request.setReference("9187445"); + request.setAmount(1590); + request.setCurrency(PaytrailCurrency.EUR); + request.setLanguage(PaytrailLanguage.FI); + request.setOrderId(""); + request.setItems(Arrays.asList(new ShopInShopItem( + 1590, 1, BigDecimal.valueOf(24), "#927502759", "Pet supplies", "Cat ladder", + MERCHANTIDSISS, UUID.randomUUID().toString(), "", ""))); + request.setCustomer(new Customer( + "erja.esimerkki@example.org", "Erja", "FI12345671", "nothing", + "+358501234567", "123")); + request.setRedirectUrls(new CallbackUrl("https://ecom.example.org/success", "https://ecom.example.org/cancel")); + request.setCallbackUrls(new CallbackUrl("https://ecom.example.org/success", "https://ecom.example.org/cancel")); + request.setDeliveryAddress(new Address("Tampere", "FI", "Pirkanmaa", "33100", "Hämeenkatu 6 B")); + request.setInvoicingAddress(new Address("Helsinki", "FI", "Uusimaa", "00510", "Testikatu 1")); + request.setGroups(Arrays.asList(PaytrailPaymentMethodGroup.mobile.toString())); + + PayAddCardResponse res = payTrail.payAndAddCard(request); + int actual = res.getReturnCode(); + + // Assert + Assertions.assertEquals(expected, actual); + } +} diff --git a/paytrailpayment-sdk/src/test/java/TestCase.java b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/TestCase.java similarity index 85% rename from paytrailpayment-sdk/src/test/java/TestCase.java rename to paytrailpayment-sdk/src/test/java/io/paytrailpayment/TestCase.java index 87c8b36..cdbc7d7 100644 --- a/paytrailpayment-sdk/src/test/java/TestCase.java +++ b/paytrailpayment-sdk/src/test/java/io/paytrailpayment/TestCase.java @@ -1,7 +1,7 @@ +package io.paytrailpayment; + public abstract class TestCase { protected final String merchantId = "375917"; protected final String secretKey = "SAIPPUAKAUPPIAS"; protected final String platformName = "test"; - - public abstract void setUp(); } diff --git a/pom.xml b/pom.xml index e619f0c..6822fca 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 8 UTF-8 5.9.0 - 1.18.26 + 1.18.36 io.paytrailpayment @@ -36,7 +36,8 @@ org.projectlombok lombok - 1.18.26 + 1.18.36 + provided org.junit.jupiter