Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ dependencies {
implementation("com.google.guava:guava:28.0-jre")
implementation("org.slf4j:slf4j-api:1.7.28")
implementation("org.apache.httpcomponents:httpclient:4.5.10")
implementation("com.fasterxml.jackson.core:jackson-databind:2.9.2")
implementation("com.vaadin.external.google:android-json:0.0.20131108.vaadin1")
implementation("com.nimbusds:nimbus-jose-jwt:7.2.1")

//Lombok annotations support
annotationProcessor("org.projectlombok:lombok:1.18.8")
compileOnly("org.projectlombok:lombok:1.18.8")
testAnnotationProcessor("org.projectlombok:lombok:1.18.8")
testCompileOnly("org.projectlombok:lombok:1.18.8")

// Use JUnit Jupiter API for testing.
testImplementation("org.junit.jupiter:junit-jupiter-api:5.4.2")
Expand Down
4 changes: 0 additions & 4 deletions src/main/java/app/klix/GetOrderResponse.java

This file was deleted.

90 changes: 81 additions & 9 deletions src/main/java/app/klix/KlixClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,30 @@
*/
package app.klix;

import app.klix.error.KlixException;
import app.klix.order.KlixRejectReason;
import app.klix.request.ApproveOrderRequest;
import app.klix.request.GetOrderRequest;
import app.klix.request.RejectOrderRequest;
import app.klix.rest.KlixConnector;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClients;

@Slf4j
@ToString
public final class KlixClient {

private final HttpClient httpClient = defaultHttpClient();
private final ObjectMapper objectMapper = objectMapper();
private KlixEnvironment environment = KlixEnvironment.STAGING;

private String apiKey;

private HttpClient httpClient = defaultHttpClient();
private byte[] privateKey;
private String merchantCertificateId;

private HttpClient defaultHttpClient() {
return HttpClients.createDefault();
Expand All @@ -34,20 +48,78 @@ public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}

public byte[] getPrivateKey() {
return privateKey;
}

public void setPrivateKey(byte[] privateKey) {
this.privateKey = privateKey;
}

public String getMerchantCertificateId() {
return merchantCertificateId;
}

public void setMerchantCertificateId(String merchantCertificateId) {
this.merchantCertificateId = merchantCertificateId;
}

public HttpClient getHttpClient() {
return httpClient;
}

public void setHttpClient(HttpClient httpClient) {
this.httpClient = httpClient;
public ObjectMapper getObjectMapper() {
return objectMapper;
}

private void validateClientForRejectOrApprove() {
try {
Preconditions.checkNotNull(environment);
Preconditions.checkNotNull(merchantCertificateId);
Preconditions.checkNotNull(privateKey);
} catch (NullPointerException e) {
throw new KlixException("KlixClient properties apiKey or/and environment or/and privateKey are null", e);
}
}

private void validateClientForGet() {
try {
Preconditions.checkNotNull(environment);
Preconditions.checkNotNull(apiKey);
} catch (NullPointerException e) {
throw new KlixException("KlixClient properties apiKey or/and environment are null", e);
}
}

public GetOrderRequest retrieveOrderDetails(KlixConnector connector, String merchantId, String orderId) {
validateClientForGet();
GetOrderRequest getOrderRequest = new GetOrderRequest(connector);
getOrderRequest.withMerchantId(merchantId);
getOrderRequest.withOrderId(orderId);
return getOrderRequest;
}

public RejectOrderRequest rejectOrder(KlixConnector connector, String merchantId, String orderId, KlixRejectReason rejectReason) {
validateClientForRejectOrApprove();
RejectOrderRequest rejectOrderRequest = new RejectOrderRequest(connector);
rejectOrderRequest.withMerchantId(merchantId);
rejectOrderRequest.withOrderId(orderId);
rejectOrderRequest.withReasonCode(rejectReason);
return rejectOrderRequest;
}

public void validate() {
// TODO check all parameters
public ApproveOrderRequest approveOrder(KlixConnector connector, String merchantId, String orderId) {
validateClientForRejectOrApprove();
ApproveOrderRequest approveOrderRequest = new ApproveOrderRequest(connector);
approveOrderRequest.withMerchantId(merchantId);
approveOrderRequest.withOrderId(orderId);
return approveOrderRequest;
}

public GetOrderRequest retrieveOrderDetails() {
return new GetOrderRequest();
private ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return objectMapper;
}

}
4 changes: 0 additions & 4 deletions src/main/java/app/klix/RejectOrderRequest.java

This file was deleted.

4 changes: 0 additions & 4 deletions src/main/java/app/klix/VerifyOrderRequest.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package app.klix.callback;

import lombok.Data;

@Data
public class OrderVerificationCallback {
private String orderId;
private String externalOrderId;
}
15 changes: 15 additions & 0 deletions src/main/java/app/klix/callback/PurchaseConfirmationCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package app.klix.callback;

import app.klix.order.KlixPaymentStatus;
import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class PurchaseConfirmationCallback {

private KlixPaymentStatus status;
private String orderId;
private String externalOrderId;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package app.klix.callback;

import app.klix.order.KlixAddress;
import app.klix.order.KlixOrderItem;
import app.klix.order.KlixPickupPoint;
import lombok.Data;

@Data
public class ShippingCostCalculationCallback {

private String order_id;
private KlixOrderItem[] items;
private String shipping_method_id;
private KlixAddress address;
private KlixPickupPoint pickup_point;

//TODO check if actual structure is different
}
43 changes: 43 additions & 0 deletions src/main/java/app/klix/encoder/JwsEncoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package app.klix.encoder;

import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.RSASSASigner;
import lombok.extern.slf4j.Slf4j;


import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

@Slf4j
public class JwsEncoder {

public String encodeJwsBody(String payload, String merchantCertificateId, String privateKeyContent) {
try {

PrivateKey privateKey = createPrivateKeyObject(privateKeyContent);

JWSSigner signer = new RSASSASigner(privateKey, true);
JWSObject jwsObject = new JWSObject(
new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(merchantCertificateId).build(), new Payload(payload));
jwsObject.sign(signer);
return jwsObject.serialize();
} catch (Exception ex) {
log.error(ex.getLocalizedMessage());
return null;
}
}

private PrivateKey createPrivateKeyObject(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {

String privKeyPEM = privateKey.replace("-----BEGIN PRIVATE KEY-----", "");
privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privKeyPEM.replaceAll("\\n", "").replaceAll("\\r", "")));
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(keySpec);
}

}
10 changes: 10 additions & 0 deletions src/main/java/app/klix/encoder/JwsValidationResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package app.klix.encoder;


import lombok.Data;

@Data
public class JwsValidationResult {
private boolean isValid;
private String payload;
}
13 changes: 13 additions & 0 deletions src/main/java/app/klix/order/KlixAddress.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app.klix.order;

import lombok.Data;

@Data
public class KlixAddress {
private String city;
private String country;
private Double latitude;
private Double longitude;
private String postal_code;
private String street;
}
11 changes: 11 additions & 0 deletions src/main/java/app/klix/order/KlixCompany.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package app.klix.order;

import lombok.Data;

@Data
public class KlixCompany {
private String address;
private String name;
private String registration_number;
private String vat_number;
}
11 changes: 11 additions & 0 deletions src/main/java/app/klix/order/KlixCustomer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package app.klix.order;

import lombok.Data;

@Data
public class KlixCustomer {
private String first_name;
private String last_name;
private String email;
private String phone_number;
}
9 changes: 9 additions & 0 deletions src/main/java/app/klix/order/KlixMerchantShippingMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package app.klix.order;

import lombok.Data;

@Data
public class KlixMerchantShippingMethod {
private String id;
private String name;
}
11 changes: 11 additions & 0 deletions src/main/java/app/klix/order/KlixMerchantUrls.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package app.klix.order;

import lombok.Data;

@Data
public class KlixMerchantUrls {
private String confirmation;
private String place_order;
private String terms;
private String verification;
}
19 changes: 19 additions & 0 deletions src/main/java/app/klix/order/KlixOrderItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package app.klix.order;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class KlixOrderItem {
private BigDecimal amount;
private String label;
private BigDecimal tax_amount;
private BigDecimal total_amount;
private BigDecimal tax_rate;
private String order_item_id;
private BigDecimal quantity;
private String unit;
private String type;
private String reference;
}
9 changes: 9 additions & 0 deletions src/main/java/app/klix/order/KlixOrderStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package app.klix.order;

public enum KlixOrderStatus {
PENDING,
VERIFIED,
REJECTED,
INVALID,
DRAFT
}
6 changes: 6 additions & 0 deletions src/main/java/app/klix/order/KlixPaymentStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package app.klix.order;

public enum KlixPaymentStatus {
PAYMENT_APPROVED,
PAYMENT_REJECTED
}
11 changes: 11 additions & 0 deletions src/main/java/app/klix/order/KlixPickupPoint.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package app.klix.order;

import lombok.Data;

@Data
public class KlixPickupPoint {
private String comments;
private String external_id;
private String name;
private String service_hours;
}
5 changes: 5 additions & 0 deletions src/main/java/app/klix/order/KlixRejectReason.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package app.klix.order;

public enum KlixRejectReason {
PRICE_CHANGED
}
13 changes: 13 additions & 0 deletions src/main/java/app/klix/order/KlixShipping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app.klix.order;

import lombok.Data;

@Data
public class KlixShipping {
private KlixAddress address;
private String contact_phone;
private String date;
private KlixMerchantShippingMethod method;
private KlixPickupPoint pickup_point;
private String type;
}
Loading