diff --git a/.gitignore b/.gitignore index 80e6594..f615c3c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ .project .settings .idea +/connect2pay-client.iml diff --git a/README.md b/README.md index 0744a54..241338e 100644 --- a/README.md +++ b/README.md @@ -4,84 +4,123 @@ Connect2Pay Payment Page Java Client This is the Java implementation of the Connect2pay Payment Page API. The main class to use is ```Connect2payClient``` that implements all the API calls. -It requires request object as entries and returns response objects. - +It requires request object as entries and returns response objects. + Example of a payment creation with user redirection: ```java - // Process a payment of €39.99 - PaymentRequest request = new PaymentRequest(); - request.setOrderId("1234ABCD").setCurrency("EUR").setAmount(3999); - request.setShippingType(ShippingType.VIRTUAL); - request.setPaymentMode(PaymentMode.SINGLE); - // User will be redirected here when clicking on "Go back to merchant" button - request.setCtrlRedirectURL("http://my.website/somewhere"); - // The payment page will do a callback on this URL after the payment is processed - request.setCtrlCallbackURL("http://my.website/payment-callback"); - - // Validate the request - try { - request.validate(); - } catch (BadRequestException e) { - logger.error("Ooops, an error occurred validating the payment request: " + e.getMessage()); - // Handle the error... - } - - // Instantiate the client and send the prepare request - // Second argument is the originator ID, third one is the associated API key - Connect2payClient c2p = new Connect2payClient("https://provided.url", "123456", "GreatP4ssw0rd"); - PaymentResponse response = null; - try { - response = c2p.preparePayment(request); - } catch (Exception e) { - logger.error("Ooops, an error occurred preparing the payment: " + e.getMessage()); - // Handle the error... - } - - if (response != null && ResultCode.SUCCESS.equals(response.getCode()) { - // Get the URL to redirect the user to - String redirectURL = response.getCustomerRedirectURL(); - if (redirectURL != null) { - // Redirect the user towards this URL, this will display the payment page - } - } else { - // Handle the failure - } +import com.payxpert.connect2pay.client.containers.Account; +import com.payxpert.connect2pay.client.containers.Order; +import com.payxpert.connect2pay.client.containers.Shipping; +import com.payxpert.connect2pay.client.containers.Shopper; +import com.payxpert.connect2pay.client.requests.PaymentRequest; +import com.payxpert.connect2pay.constants.PaymentMode; +import com.payxpert.connect2pay.constants.sca.ShippingType; +import com.payxpert.connect2pay.constants.sca.ShopperAccountAge; +import com.payxpert.connect2pay.constants.sca.ShopperAccountLastChange; + +class TestPayment { + public void processPayment() { + // Process a payment of €39.99 + PaymentRequest request = new PaymentRequest(); + request.setCurrency("EUR").setAmount(3999); + request.setPaymentMode(PaymentMode.SINGLE); + // User will be redirected here when clicking on "Go back to merchant" button + request.setCtrlRedirectURL("http://my.website/somewhere"); + // The payment page will do a callback on this URL after the payment is processed + request.setCtrlCallbackURL("http://my.website/payment-callback"); + + Order order = new Order(); + order.setId("1234ABCD").setShippingType(ShippingType.DIGITAL_GOODS); + Shopper shopper = new Shopper(); + shopper.setEmail("test@example.com").setFirstName("John").setLastName("Doe") + .setHomePhonePrefix("47").setHomePhone("123456789").setAddress1("Main Street 41") + .setZipcode("123456").setCity("London").setCountryCode("GB"); + Account account = new Account(); + account.setAge(ShopperAccountAge.BETWEEN_30_60_DAYS).setSuspicious(false) + .setLastChange(ShopperAccountLastChange.BETWEEN_30_60_DAYS); + shopper.setAccount(account); + Shipping shipping = new Shipping(); + shipping.setName("Jane Doe").setAddress1("Other Street, 54").setCity("London") + .setZipcode("654321").setCountryCode("GB"); + + request.setOrder(order); + request.setShopper(shopper); + request.setShipping(shipping); + + // Validate the request + try { + request.validate(); + } catch (BadRequestException e) { + logger.error("Ooops, an error occurred validating the payment request: " + e.getMessage()); + // Handle the error... + } + + // Instantiate the client and send the prepare request + // Second argument is the originator ID, third one is the associated API key + Connect2payClient c2p = new Connect2payClient("https://provided.url", "123456", "GreatP4ssw0rd"); + PaymentResponse response = null; + try { + response = c2p.preparePayment(request); + } catch (Exception e) { + logger.error("Ooops, an error occurred preparing the payment: " + e.getMessage()); + // Handle the error... + } + + if (response != null && ResultCode.SUCCESS.equals(response.getCode())) { + // Get the URL to redirect the user to + String redirectURL = response.getCustomerRedirectURL(); + if (redirectURL != null) { + // Redirect the user towards this URL, this will display the payment page + } + } else { + // Handle the failure + } + } +} ``` Example of the payment callback handling: ```java - // Instantiate the client and handle the callback - Connect2payClient c2p = new Connect2payClient("https://provided.url", "123456", "GreatP4ssw0rd"); - PaymentStatusResponse response = null; - try { - // Request is either the body of the received request as a string or an InputStream pointing to the received body - response = c2p.handleCallbackStatus(request); - } catch (Exception e) { - logger.error("Ooops, an error occurred handling the callback: " + e.getMessage()); - // Handle the error... - } - - if (response != null && ResultCode.SUCCESS.equals(response.getCode()) { - // Check the payment status: 000 means success - if ("000".equals(response.getErrorCode()) { - // Handle the payment success case - // ... - // Access the payment mean information - CreditCardPaymentMeanInfo pmInfo = response.getCCPaymentMeanInfo(); - logger.info("Successful payment done by " + pmInfo.getCardHolderName() + "with card " + pmInfo.getCardNumber()); - } else { - // Handle the payment failure case - } - - if (handledSuccessfully) { - out.write(CallbackStatusResponse.getDefaultSuccessResponse().toJson()) // out is the output stream - } else { - out.write(CallbackStatusResponse.getDefaultFailureResponse().toJson()) // out is the output stream - } - } else { - // Handle the failure - out.write(CallbackStatusResponse.getDefaultFailureResponse().toJson()) // out is the output stream - } +import java.io.OutputStream; + +class TestPayment { + private OutputStream out; + + public void handleCallback(String request) { + // Instantiate the client and handle the callback + Connect2payClient c2p = new Connect2payClient("https://provided.url", "123456", "GreatP4ssw0rd"); + PaymentStatusResponse response = null; + try { + // Request is either the body of the received request as a string or an InputStream pointing to the received body + response = c2p.handleCallbackStatus(request); + } catch (Exception e) { + logger.error("Ooops, an error occurred handling the callback: " + e.getMessage()); + // Handle the error... + } + + if (response != null && ResultCode.SUCCESS.equals(response.getCode())) { + // Check the payment status: 000 means success + if ("000".equals(response.getErrorCode())) { + // Handle the payment success case + // ... + // Access the payment mean information + CreditCardPaymentMeanInfo pmInfo = response.getCCPaymentMeanInfo(); + logger.info("Successful payment done by " + pmInfo.getCardHolderName() + "with card " + pmInfo.getCardNumber()); + } else { + // Handle the payment failure case + } + + if (handledSuccessfully) { + this.out.write(CallbackStatusResponse.getDefaultSuccessResponse().toJson()); // out is the output stream + } else { + this.out.write(CallbackStatusResponse.getDefaultFailureResponse().toJson()); // out is the output stream + } + } else { + // Handle the failure + this.out.write(CallbackStatusResponse.getDefaultFailureResponse().toJson()); // out is the output stream + } + } +} ``` diff --git a/pom.xml b/pom.xml index e7f30b2..d000229 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ Connect2pay Java Client com.payxpert connect2pay-client - 1.0.20 + 2.0.1 jar This is the Java implementation of the PayXpert Connect2pay Payment Page API. https://www.payxpert.com/ @@ -108,6 +108,8 @@ com/payxpert/connect2pay/utils/Utils.java com.payxpert.connect2pay.utils.json + ${java.home}/bin/javadoc + 8 @@ -178,7 +180,13 @@ junit junit - 4.12 + 4.13 + test + + + com.sun.activation + javax.activation + 1.2.0 test @@ -197,7 +205,7 @@ commons-codec commons-codec - 1.12 + 1.15 ch.qos.logback @@ -212,12 +220,12 @@ com.fasterxml.jackson.core jackson-core - 2.10.3 + 2.11.2 com.fasterxml.jackson.core jackson-databind - 2.10.3 + 2.11.2 net.sf.oval diff --git a/src/main/java/com/payxpert/connect2pay/client/containers/Account.java b/src/main/java/com/payxpert/connect2pay/client/containers/Account.java new file mode 100644 index 0000000..7529b2f --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/client/containers/Account.java @@ -0,0 +1,194 @@ +package com.payxpert.connect2pay.client.containers; + +import com.payxpert.connect2pay.constants.sca.*; +import com.payxpert.connect2pay.utils.Utils; +import net.sf.oval.constraint.MatchPattern; +import net.sf.oval.constraint.MaxLength; + +public class Account { + private ShopperAccountAge age; + + @MaxLength(8) + @MatchPattern(pattern = "^[0-9]{8}$") + private String date; + + private ShopperAccountLastChange lastChange; + + @MaxLength(8) + @MatchPattern(pattern = "^[0-9]{8}$") + private String lastChangeDate; + + private ShopperAccountPwChange pwChange; + + @MaxLength(8) + @MatchPattern(pattern = "^[0-9]{8}$") + private String pwChangeDate; + + private ShippingInfoAge shipInfoAge; + + @MaxLength(8) + @MatchPattern(pattern = "^[0-9]{8}$") + private String shipInfoDate; + + private Integer transLastDay; + + private Integer transLastYear; + + private Integer cardsAddLastDay; + + private Integer orderSixMonths; + + private Boolean suspicious; + + private Boolean namesMatching; + + private PaymentMeanAge paymentMeanAge; + + @MaxLength(8) + @MatchPattern(pattern = "^[0-9]{8}$") + private String paymentMeanDate; + + public ShopperAccountAge getAge() { + return age; + } + + public Account setAge(ShopperAccountAge age) { + this.age = age; + return this; + } + + public String getDate() { + return date; + } + + public Account setDate(String date) { + this.date = Utils.limitLength(date, 8); + return this; + } + + public ShopperAccountLastChange getLastChange() { + return lastChange; + } + + public Account setLastChange(ShopperAccountLastChange lastChange) { + this.lastChange = lastChange; + return this; + } + + public String getLastChangeDate() { + return lastChangeDate; + } + + public Account setLastChangeDate(String lastChangeDate) { + this.lastChangeDate = Utils.limitLength(lastChangeDate, 8); + return this; + } + + public ShopperAccountPwChange getPwChange() { + return pwChange; + } + + public Account setPwChange(ShopperAccountPwChange pwChange) { + this.pwChange = pwChange; + return this; + } + + public String getPwChangeDate() { + return pwChangeDate; + } + + public Account setPwChangeDate(String pwChangeDate) { + this.pwChangeDate = Utils.limitLength(pwChangeDate, 8); + return this; + } + + public ShippingInfoAge getShipInfoAge() { + return shipInfoAge; + } + + public Account setShipInfoAge(ShippingInfoAge shipInfoAge) { + this.shipInfoAge = shipInfoAge; + return this; + } + + public String getShipInfoDate() { + return shipInfoDate; + } + + public Account setShipInfoDate(String shipInfoDate) { + this.shipInfoDate = Utils.limitLength(shipInfoDate, 8); + return this; + } + + public Integer getTransLastDay() { + return transLastDay; + } + + public Account setTransLastDay(Integer transLastDay) { + this.transLastDay = transLastDay; + return this; + } + + public Integer getTransLastYear() { + return transLastYear; + } + + public Account setTransLastYear(Integer transLastYear) { + this.transLastYear = transLastYear; + return this; + } + + public Integer getCardsAddLastDay() { + return cardsAddLastDay; + } + + public Account setCardsAddLastDay(Integer cardsAddLastDay) { + this.cardsAddLastDay = cardsAddLastDay; + return this; + } + + public Integer getOrderSixMonths() { + return orderSixMonths; + } + + public Account setOrderSixMonths(Integer orderSixMonths) { + this.orderSixMonths = orderSixMonths; + return this; + } + + public Boolean getSuspicious() { + return suspicious; + } + + public Account setSuspicious(Boolean suspicious) { + this.suspicious = suspicious; + return this; + } + + public Boolean getNamesMatching() { + return namesMatching; + } + + public Account setNamesMatching(Boolean namesMatching) { + this.namesMatching = namesMatching; + return this; + } + + public PaymentMeanAge getPaymentMeanAge() { + return paymentMeanAge; + } + + public Account setPaymentMeanAge(PaymentMeanAge paymentMeanAge) { + this.paymentMeanAge = paymentMeanAge; + return this; + } + + public String getPaymentMeanDate() { + return paymentMeanDate; + } + + public Account setPaymentMeanDate(String paymentMeanDate) { + this.paymentMeanDate = Utils.limitLength(paymentMeanDate, 8); + return this; + } +} diff --git a/src/main/java/com/payxpert/connect2pay/client/containers/AliPayPaymentMeanInfo.java b/src/main/java/com/payxpert/connect2pay/client/containers/AliPayPaymentMeanInfo.java new file mode 100644 index 0000000..00a00a9 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/client/containers/AliPayPaymentMeanInfo.java @@ -0,0 +1,31 @@ +package com.payxpert.connect2pay.client.containers; + +import java.math.BigDecimal; + +/** + * Information from the AliPay callback + */ +public class AliPayPaymentMeanInfo extends PaymentMeanInfo { + + /** + * Total fee in cents + */ + private Long totalFee; + private BigDecimal exchangeRate; + + public Long getTotalFee() { + return totalFee; + } + + public void setTotalFee(Long totalFee) { + this.totalFee = totalFee; + } + + public BigDecimal getExchangeRate() { + return exchangeRate; + } + + public void setExchangeRate(BigDecimal exchangeRate) { + this.exchangeRate = exchangeRate; + } +} diff --git a/src/main/java/com/payxpert/connect2pay/client/containers/CartProduct.java b/src/main/java/com/payxpert/connect2pay/client/containers/CartProduct.java new file mode 100644 index 0000000..ebb8abe --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/client/containers/CartProduct.java @@ -0,0 +1,98 @@ +package com.payxpert.connect2pay.client.containers; + +import com.payxpert.connect2pay.utils.Utils; +import net.sf.oval.constraint.MaxLength; + +public class CartProduct { + private Integer cartProductId; + + @MaxLength(256) + private String cartProductName; + + private Float cartProductUnitPrice; + + private Integer cartProductQuantity; + + @MaxLength(128) + private String cartProductBrand; + + @MaxLength(128) + private String cartProductMPN; + + @MaxLength(128) + private String cartProductCategoryName; + + private Integer cartProductCategoryID; + + public Integer getCartProductId() { + return cartProductId; + } + + public CartProduct setCartProductId(Integer cartProductId) { + this.cartProductId = cartProductId; + return this; + } + + public String getCartProductName() { + return cartProductName; + } + + public CartProduct setCartProductName(String cartProductName) { + this.cartProductName = Utils.limitLength(cartProductName, 256); + return this; + } + + public Float getCartProductUnitPrice() { + return cartProductUnitPrice; + } + + public CartProduct setCartProductUnitPrice(Float cartProductUnitPrice) { + this.cartProductUnitPrice = cartProductUnitPrice; + return this; + } + + public Integer getCartProductQuantity() { + return cartProductQuantity; + } + + public CartProduct setCartProductQuantity(Integer cartProductQuantity) { + this.cartProductQuantity = cartProductQuantity; + return this; + } + + public String getCartProductBrand() { + return cartProductBrand; + } + + public CartProduct setCartProductBrand(String cartProductBrand) { + this.cartProductBrand = Utils.limitLength(cartProductBrand, 128); + return this; + } + + public String getCartProductMPN() { + return cartProductMPN; + } + + public CartProduct setCartProductMPN(String cartProductMPN) { + this.cartProductMPN = Utils.limitLength(cartProductMPN, 128); + return this; + } + + public String getCartProductCategoryName() { + return cartProductCategoryName; + } + + public CartProduct setCartProductCategoryName(String cartProductCategoryName) { + this.cartProductCategoryName = Utils.limitLength(cartProductCategoryName, 128); + return this; + } + + public Integer getCartProductCategoryID() { + return cartProductCategoryID; + } + + public CartProduct setCartProductCategoryID(Integer cartProductCategoryID) { + this.cartProductCategoryID = cartProductCategoryID; + return this; + } +} diff --git a/src/main/java/com/payxpert/connect2pay/client/containers/Order.java b/src/main/java/com/payxpert/connect2pay/client/containers/Order.java new file mode 100644 index 0000000..f0474a8 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/client/containers/Order.java @@ -0,0 +1,248 @@ +package com.payxpert.connect2pay.client.containers; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.payxpert.connect2pay.constants.sca.OrderDeliveryDelay; +import com.payxpert.connect2pay.constants.sca.OrderType; +import com.payxpert.connect2pay.constants.sca.ShippingType; +import com.payxpert.connect2pay.utils.Utils; +import net.sf.oval.constraint.*; + +import java.util.List; + +public class Order { + @NotNull + @NotEmpty + @MaxLength(100) + private String id; + + private OrderType type; + + private ShippingType shippingType; + + private OrderDeliveryDelay deliveryDelay; + + @MaxLength(100) + @MatchPattern(pattern = { + "NA|[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?" }) + private String deliveryEmail; + + private Boolean reorder; + + private Boolean preOrder; + + @MaxLength(8) + @MatchPattern(pattern = "^[0-9]{8}$") + private String preOrderDate; + + private Integer prepaidAmount; + + @MaxLength(3) + private String prepaidCurrency; + + private Integer prepaidCount; + + @MaxLength(50) + private String shopperLoyaltyProgram; + + private Integer totalWithoutShipping; + + private Integer shippingPrice; + + private Integer discount; + + @MaxLength(500) + private String description; + + private List cartContent; + + @MaxLength(16) + @MatchPattern(pattern = "^[0-9]+$") + @JsonProperty("affiliateID") + private String affiliateId; + + @MaxLength(128) + private String campaignName; + + @AssertValid + private Recurrence recurrence; + + public String getId() { + return id; + } + + public Order setId(String id) { + this.id = Utils.limitLength(id, 100); + return this; + } + + public OrderType getType() { + return type; + } + + public Order setType(OrderType type) { + this.type = type; + return this; + } + + public ShippingType getShippingType() { + return shippingType; + } + + public Order setShippingType(ShippingType shippingType) { + this.shippingType = shippingType; + return this; + } + + public OrderDeliveryDelay getDeliveryDelay() { + return deliveryDelay; + } + + public Order setDeliveryDelay(OrderDeliveryDelay deliveryDelay) { + this.deliveryDelay = deliveryDelay; + return this; + } + + public String getDeliveryEmail() { + return deliveryEmail; + } + + public Order setDeliveryEmail(String deliveryEmail) { + this.deliveryEmail = Utils.limitLength(deliveryEmail, 100); + return this; + } + + public Boolean getReorder() { + return reorder; + } + + public Order setReorder(Boolean reorder) { + this.reorder = reorder; + return this; + } + + public Boolean getPreOrder() { + return preOrder; + } + + public Order setPreOrder(Boolean preOrder) { + this.preOrder = preOrder; + return this; + } + + public String getPreOrderDate() { + return preOrderDate; + } + + public Order setPreOrderDate(String preOrderDate) { + this.preOrderDate = Utils.limitLength(preOrderDate, 8); + return this; + } + + public Integer getPrepaidAmount() { + return prepaidAmount; + } + + public Order setPrepaidAmount(Integer prepaidAmount) { + this.prepaidAmount = prepaidAmount; + return this; + } + + public String getPrepaidCurrency() { + return prepaidCurrency; + } + + public Order setPrepaidCurrency(String prepaidCurrency) { + this.prepaidCurrency = Utils.limitLength(prepaidCurrency, 3); + return this; + } + + public Integer getPrepaidCount() { + return prepaidCount; + } + + public Order setPrepaidCount(Integer prepaidCount) { + this.prepaidCount = prepaidCount; + return this; + } + + public String getShopperLoyaltyProgram() { + return shopperLoyaltyProgram; + } + + public Order setShopperLoyaltyProgram(String shopperLoyaltyProgram) { + this.shopperLoyaltyProgram = Utils.limitLength(shopperLoyaltyProgram, 50); + return this; + } + + public Integer getTotalWithoutShipping() { + return totalWithoutShipping; + } + + public Order setTotalWithoutShipping(Integer totalWithoutShipping) { + this.totalWithoutShipping = totalWithoutShipping; + return this; + } + + public Integer getShippingPrice() { + return shippingPrice; + } + + public Order setShippingPrice(Integer shippingPrice) { + this.shippingPrice = shippingPrice; + return this; + } + + public Integer getDiscount() { + return discount; + } + + public Order setDiscount(Integer discount) { + this.discount = discount; + return this; + } + + public String getDescription() { + return description; + } + + public Order setDescription(String description) { + this.description = Utils.limitLength(description, 500); + return this; + } + + public List getCartContent() { + return cartContent; + } + + public Order setCartContent(List cartContent) { + this.cartContent = cartContent; + return this; + } + + public String getAffiliateId() { + return affiliateId; + } + + public Order setAffiliateId(String affiliateId) { + this.affiliateId = Utils.limitLength(affiliateId, 16); + return this; + } + + public String getCampaignName() { + return campaignName; + } + + public Order setCampaignName(String campaignName) { + this.campaignName = Utils.limitLength(campaignName, 128); + return this; + } + + public Recurrence getRecurrence() { + return recurrence; + } + + public Order setRecurrence(Recurrence recurrence) { + this.recurrence = recurrence; + return this; + } +} diff --git a/src/main/java/com/payxpert/connect2pay/client/containers/Recurrence.java b/src/main/java/com/payxpert/connect2pay/client/containers/Recurrence.java new file mode 100644 index 0000000..48b5d77 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/client/containers/Recurrence.java @@ -0,0 +1,54 @@ +package com.payxpert.connect2pay.client.containers; + +import com.payxpert.connect2pay.constants.SubscriptionType; +import com.payxpert.connect2pay.utils.Utils; +import net.sf.oval.constraint.MatchPattern; +import net.sf.oval.constraint.MaxLength; + +public class Recurrence { + private SubscriptionType type; + + private Integer totalIterations; + + @MaxLength(8) + @MatchPattern(pattern = "^[0-9]{8}$") + private String expiry; + + private Integer frequency; + + public SubscriptionType getType() { + return type; + } + + public Recurrence setType(SubscriptionType type) { + this.type = type; + return this; + } + + public Integer getTotalIterations() { + return totalIterations; + } + + public Recurrence setTotalIterations(Integer totalIterations) { + this.totalIterations = totalIterations; + return this; + } + + public String getExpiry() { + return expiry; + } + + public Recurrence setExpiry(String expiry) { + this.expiry = Utils.limitLength(expiry, 8); + return this; + } + + public Integer getFrequency() { + return frequency; + } + + public Recurrence setFrequency(Integer frequency) { + this.frequency = frequency; + return this; + } +} diff --git a/src/main/java/com/payxpert/connect2pay/client/containers/Shipping.java b/src/main/java/com/payxpert/connect2pay/client/containers/Shipping.java new file mode 100644 index 0000000..496b491 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/client/containers/Shipping.java @@ -0,0 +1,126 @@ +package com.payxpert.connect2pay.client.containers; + +import com.payxpert.connect2pay.utils.Utils; +import net.sf.oval.constraint.MaxLength; + +public class Shipping { + @MaxLength(80) + private String name; + + @MaxLength(128) + private String company; + + @MaxLength(50) + private String address1; + + @MaxLength(50) + private String address2; + + @MaxLength(50) + private String address3; + + @MaxLength(16) + private String zipcode; + + @MaxLength(50) + private String city; + + @MaxLength(3) + private String state; + + @MaxLength(2) + private String countryCode; + + @MaxLength(20) + private String phone; + + public String getName() { + return name; + } + + public Shipping setName(String name) { + this.name = Utils.limitLength(name, 80); + return this; + } + + public String getCompany() { + return company; + } + + public Shipping setCompany(String company) { + this.company = Utils.limitLength(company, 128); + return this; + } + + public String getAddress1() { + return address1; + } + + public Shipping setAddress1(String address1) { + this.address1 = Utils.limitLength(address1, 50); + return this; + } + + public String getAddress2() { + return address2; + } + + public Shipping setAddress2(String address2) { + this.address2 = Utils.limitLength(address2, 50); + return this; + } + + public String getAddress3() { + return address3; + } + + public Shipping setAddress3(String address3) { + this.address3 = Utils.limitLength(address3, 50); + return this; + } + + public String getZipcode() { + return zipcode; + } + + public Shipping setZipcode(String zipcode) { + this.zipcode = Utils.limitLength(zipcode, 16); + return this; + } + + public String getCity() { + return city; + } + + public Shipping setCity(String city) { + this.city = Utils.limitLength(city, 50); + return this; + } + + public String getState() { + return state; + } + + public Shipping setState(String state) { + this.state = Utils.limitLength(state, 3); + return this; + } + + public String getCountryCode() { + return countryCode; + } + + public Shipping setCountryCode(String countryCode) { + this.countryCode = Utils.limitLength(countryCode, 2); + return this; + } + + public String getPhone() { + return phone; + } + + public Shipping setPhone(String phone) { + this.phone = Utils.limitLength(phone, 20); + return this; + } +} diff --git a/src/main/java/com/payxpert/connect2pay/client/containers/Shopper.java b/src/main/java/com/payxpert/connect2pay/client/containers/Shopper.java index 4fda458..181504c 100644 --- a/src/main/java/com/payxpert/connect2pay/client/containers/Shopper.java +++ b/src/main/java/com/payxpert/connect2pay/client/containers/Shopper.java @@ -1,27 +1,99 @@ package com.payxpert.connect2pay.client.containers; +import com.payxpert.connect2pay.utils.Utils; +import net.sf.oval.constraint.AssertValid; +import net.sf.oval.constraint.MatchPattern; +import net.sf.oval.constraint.MaxLength; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + public class Shopper { + @MaxLength(100) + private String id; + @MaxLength(80) private String name; - private String address; + + @MaxLength(35) + public String firstName; + + @MaxLength(35) + private String lastName; + + @MaxLength(50) + private String address1; + + @MaxLength(50) + private String address2; + + @MaxLength(50) + private String address3; + + @MaxLength(16) private String zipcode; + + @MaxLength(50) private String city; + + @MaxLength(3) private String state; + + @MaxLength(2) private String countryCode; - private String phone; + + @MaxLength(4) + private String homePhonePrefix; + + @MaxLength(20) + private String homePhone; + + @MaxLength(4) + private String mobilePhonePrefix; + + @MaxLength(20) + public String mobilePhone; + + @MaxLength(4) + public String workPhonePrefix; + + @MaxLength(20) + public String workPhone; + + @MaxLength(100) + @MatchPattern(pattern = { + "NA|[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?" }) private String email; + + @MaxLength(128) + public String company; + private String ipAddress; /** * Date of shopper birth date, format YYYYMMDD - * */ + @MaxLength(8) private String birthDate; /** * Customers document (passport number, ID number, taxpayer ID...) */ + @MaxLength(32) private String idNumber; + @AssertValid + private Account account; + + public String getId() { + return id; + } + + public Shopper setId(String id) { + this.id = Utils.limitLength(id, 100); + return this; + } + /** * @return the name */ @@ -29,27 +101,55 @@ public String getName() { return name; } - /** - * @param name - * the name to set - */ - public void setName(String name) { - this.name = name; + public String getFirstName() { + return firstName; + } + + public Shopper setFirstName(String firstName) { + this.firstName = Utils.limitLength(firstName, 35); + return this; + } + + public String getLastName() { + return lastName; + } + + public Shopper setLastName(String lastName) { + this.lastName = Utils.limitLength(lastName, 35); + return this; } /** * @return the address */ - public String getAddress() { - return address; + public String getAddress1() { + return address1; } /** - * @param address - * the address to set + * @param address1 the address to set */ - public void setAddress(String address) { - this.address = address; + public Shopper setAddress1(String address1) { + this.address1 = Utils.limitLength(address1, 50); + return this; + } + + public String getAddress2() { + return address2; + } + + public Shopper setAddress2(String address2) { + this.address2 = Utils.limitLength(address2, 50); + return this; + } + + public String getAddress3() { + return address3; + } + + public Shopper setAddress3(String address3) { + this.address3 = Utils.limitLength(address3, 50); + return this; } /** @@ -60,11 +160,11 @@ public String getZipcode() { } /** - * @param zipcode - * the zipcode to set + * @param zipcode the zipcode to set */ - public void setZipcode(String zipcode) { - this.zipcode = zipcode; + public Shopper setZipcode(String zipcode) { + this.zipcode = Utils.limitLength(zipcode, 16); + return this; } /** @@ -75,11 +175,11 @@ public String getCity() { } /** - * @param city - * the city to set + * @param city the city to set */ - public void setCity(String city) { - this.city = city; + public Shopper setCity(String city) { + this.city = Utils.limitLength(city, 50); + return this; } /** @@ -90,11 +190,11 @@ public String getState() { } /** - * @param state - * the state to set + * @param state the state to set */ - public void setState(String state) { - this.state = state; + public Shopper setState(String state) { + this.state = Utils.limitLength(state, 3); + return this; } /** @@ -105,26 +205,71 @@ public String getCountryCode() { } /** - * @param countryCode - * the countryCode to set + * @param countryCode the countryCode to set */ - public void setCountryCode(String countryCode) { - this.countryCode = countryCode; + public Shopper setCountryCode(String countryCode) { + this.countryCode = Utils.limitLength(countryCode, 2); + return this; + } + + public String getHomePhonePrefix() { + return homePhonePrefix; + } + + public Shopper setHomePhonePrefix(String homePhonePrefix) { + this.homePhonePrefix = Utils.limitLength(homePhonePrefix, 4); + return this; } /** * @return the phone */ - public String getPhone() { - return phone; + public String getHomePhone() { + return homePhone; } /** - * @param phone - * the phone to set + * @param homePhone the phone to set */ - public void setPhone(String phone) { - this.phone = phone; + public Shopper setHomePhone(String homePhone) { + this.homePhone = Utils.limitLength(homePhone, 20); + return this; + } + + public String getMobilePhonePrefix() { + return mobilePhonePrefix; + } + + public Shopper setMobilePhonePrefix(String mobilePhonePrefix) { + this.mobilePhonePrefix = Utils.limitLength(mobilePhonePrefix, 4); + return this; + } + + public String getMobilePhone() { + return mobilePhone; + } + + public Shopper setMobilePhone(String mobilePhone) { + this.mobilePhone = Utils.limitLength(mobilePhone, 20); + return this; + } + + public String getWorkPhonePrefix() { + return workPhonePrefix; + } + + public Shopper setWorkPhonePrefix(String workPhonePrefix) { + this.workPhonePrefix = Utils.limitLength(workPhonePrefix, 4); + return this; + } + + public String getWorkPhone() { + return workPhone; + } + + public Shopper setWorkPhone(String workPhone) { + this.workPhone = Utils.limitLength(workPhone, 20); + return this; } /** @@ -135,11 +280,20 @@ public String getEmail() { } /** - * @param email - * the email to set + * @param email the email to set */ - public void setEmail(String email) { - this.email = email; + public Shopper setEmail(String email) { + this.email = Utils.limitLength(email, 100); + return this; + } + + public String getCompany() { + return company; + } + + public Shopper setCompany(String company) { + this.company = Utils.limitLength(company, 128); + return this; } /** @@ -149,14 +303,6 @@ public String getIpAddress() { return ipAddress; } - /** - * @param ipAddress - * the ipAddress to set - */ - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - /** * @return the birthDate */ @@ -165,11 +311,24 @@ public String getBirthDate() { } /** - * @param birthDate - * the birthDate to set + * @param birthDate the birthDate to set */ - public void setBirthDate(String birthDate) { - this.birthDate = birthDate; + public Shopper setBirthDate(String birthDate) { + this.birthDate = Utils.limitLength(birthDate, 8); + return this; + } + + public Shopper setBirthDate(Date birthDate) { + if (birthDate != null) { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Etc/UTC")); + calendar.setTime(birthDate); + + // Format as YYYYMMDD + this.birthDate = String.format("%04d%02d%02d", calendar.get(Calendar.YEAR), + calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH)); + } + + return this; } /** @@ -180,10 +339,19 @@ public String getIdNumber() { } /** - * @param idNumber - * the idNumber to set + * @param idNumber the idNumber to set */ - public void setIdNumber(String idNumber) { - this.idNumber = idNumber; + public Shopper setIdNumber(String idNumber) { + this.idNumber = Utils.limitLength(idNumber, 32); + return this; + } + + public Account getAccount() { + return account; + } + + public Shopper setAccount(Account account) { + this.account = account; + return this; } } diff --git a/src/main/java/com/payxpert/connect2pay/client/containers/TransactionAttempt.java b/src/main/java/com/payxpert/connect2pay/client/containers/TransactionAttempt.java index 3a91f19..c3dfde1 100644 --- a/src/main/java/com/payxpert/connect2pay/client/containers/TransactionAttempt.java +++ b/src/main/java/com/payxpert/connect2pay/client/containers/TransactionAttempt.java @@ -29,6 +29,8 @@ public class TransactionAttempt implements Comparable { private Integer amount; + private String currency; + private PaymentMethod paymentMethod; private String paymentNetwork; @@ -50,6 +52,8 @@ public class TransactionAttempt implements Comparable { @JsonProperty("refTransactionID") private String refTransactionId; + private Integer refundedAmount; + @JsonProperty("providerTransactionID") private String providerTransactionId; @@ -59,15 +63,22 @@ public class TransactionAttempt implements Comparable { @JsonProperty("orderID") private String orderId; + @JsonProperty("paymentID") + private String paymentId; + + private String paymentMerchantToken; + private String orderDescription; + private Boolean isTest; + private List logs; private List notifications; /** * Shopper informations - * + * */ private Shopper shopper; @@ -101,6 +112,14 @@ public void setAmount(Integer amount) { this.amount = amount; } + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + @Deprecated public PaymentMethod getPaymentType() { return this.getPaymentMethod(); @@ -147,19 +166,11 @@ public CreditCardPaymentMeanInfo getCCPaymentMeanInfo() { } /** - * Return the payment mean info for Credit Card transaction. This is a shortcut for - * getPaymentMeanInfo(CreditCardPaymentMeanInfo.class) (with paymentMethod check). - * - * @return The CreditCardPaymentMeanInfo for this transaction + * @return {@link CreditCardPaymentMeanInfo} for this transaction, + * {@code null} if {@link TransactionAttempt#paymentMethod} is not equal to {@link PaymentMethod#CREDIT_CARD} */ public CreditCardPaymentMeanInfo getCreditCardPaymentMeanInfo() { - if (!PaymentMethod.CREDIT_CARD.equals(this.paymentMethod)) { - logger.error("Payment type is not Credit Card, can not return payment mean info for credit card."); - - return null; - } - - return this.getPaymentMeanInfo(CreditCardPaymentMeanInfo.class); + return this.getPaymentMeanInfo(CreditCardPaymentMeanInfo.class, PaymentMethod.CREDIT_CARD); } @Deprecated @@ -168,19 +179,11 @@ public BankTransferPaymentMeanInfo getBTPaymentMeanInfo() { } /** - * Return the payment mean info for Bank transfer transaction. This is a shortcut for - * getPaymentMeanInfo(BankTransferPaymentMeanInfo.class) (with paymentMethod check). - * - * @return The BankTransferPaymentMeanInfo for this transaction + * @return {@link BankTransferPaymentMeanInfo} for this transaction, + * {@code null} if {@link TransactionAttempt#paymentMethod} is not equal to {@link PaymentMethod#BANK_TRANSFER} */ public BankTransferPaymentMeanInfo getBankTransferPaymentMeanInfo() { - if (!PaymentMethod.BANK_TRANSFER.equals(this.paymentMethod)) { - logger.error("Payment type is not Bank Transfer, can not return payment mean info for bank transfer."); - - return null; - } - - return this.getPaymentMeanInfo(BankTransferPaymentMeanInfo.class); + return this.getPaymentMeanInfo(BankTransferPaymentMeanInfo.class, PaymentMethod.BANK_TRANSFER); } @Deprecated @@ -189,74 +192,72 @@ public ToditoPaymentMeanInfo getToditoPaymentMeanInfo() { } /** - * Return the payment mean info for Todito transaction. This is a shortcut for - * getPaymentMeanInfo(ToditoPaymentMeanInfo.class) (with paymentMethod check). - * - * @return The ToditoPaymentMeanInfo for this transaction + * @return {@link ToditoPaymentMeanInfo} for this transaction, + * {@code null} if {@link TransactionAttempt#paymentMethod} is not equal to {@link PaymentMethod#TODITO_CASH} */ public ToditoPaymentMeanInfo getToditoCashPaymentMeanInfo() { - if (!PaymentMethod.TODITO_CASH.equals(this.paymentMethod)) { - logger.error("Payment type is not Todito cash, can not return payment mean info for Todito cash."); - - return null; - } - - return this.getPaymentMeanInfo(ToditoPaymentMeanInfo.class); + return this.getPaymentMeanInfo(ToditoPaymentMeanInfo.class, PaymentMethod.TODITO_CASH); } /** - * Return the payment mean info for Direct Debit transaction. This is a shortcut for - * getPaymentMeanInfo(DirectDebitPaymentMeanInfo.class) (with paymentMethod check). - * - * @return The DirectDebitPaymentMeanInfo for this transaction + * @return {@link DirectDebitPaymentMeanInfo} for this transaction, + * {@code null} if {@link TransactionAttempt#paymentMethod} is not equal to {@link PaymentMethod#DIRECT_DEBIT} */ public DirectDebitPaymentMeanInfo getDirectDebitPaymentMeanInfo() { - if (!PaymentMethod.DIRECT_DEBIT.equals(this.paymentMethod)) { - logger.error("Payment type is not Direct Debit, can not return payment mean info for Direct Debit."); - - return null; - } - - return this.getPaymentMeanInfo(DirectDebitPaymentMeanInfo.class); + return this.getPaymentMeanInfo(DirectDebitPaymentMeanInfo.class, PaymentMethod.DIRECT_DEBIT); } /** - * Return the payment mean info for chargeback transaction. This is a shortcut for - * getPaymentMeanInfo(ChargebackPaymentMeanInfo.class) (with paymentMethod check). - * - * @return The ChargebackPaymentMeanInfo for this transaction + * @return {@link ChargebackPaymentMeanInfo} for this transaction, + * {@code null} if {@link TransactionAttempt#paymentMethod} is not equal to {@link PaymentMethod#CHARGEBACK} */ public ChargebackPaymentMeanInfo getChargebackPaymentMeanInfo() { - if (!PaymentMethod.CHARGEBACK.equals(this.paymentMethod)) { - logger.error("Payment type is not Chargeback, can not return payment mean info for Chargeback."); + return this.getPaymentMeanInfo(ChargebackPaymentMeanInfo.class, PaymentMethod.CHARGEBACK); + } - return null; - } + /** + * @return {@link ReversalPaymentMeanInfo} for this transaction, + * {@code null} if {@link TransactionAttempt#paymentMethod} is not equal to {@link PaymentMethod#REVERSAL} + */ + public ReversalPaymentMeanInfo getReversalPaymentMeanInfo() { + return this.getPaymentMeanInfo(ReversalPaymentMeanInfo.class, PaymentMethod.REVERSAL); + } - return this.getPaymentMeanInfo(ChargebackPaymentMeanInfo.class); + /** + * @return {@link AliPayPaymentMeanInfo} for this transaction, + * {@code null} if {@link TransactionAttempt#paymentMethod} is not equal to {@link PaymentMethod#ALIPAY} + */ + public AliPayPaymentMeanInfo getAliPayPaymentMeanInfo() { + return this.getPaymentMeanInfo(AliPayPaymentMeanInfo.class, PaymentMethod.ALIPAY); } /** - * Return the payment mean info for reversal transaction. This is a shortcut for - * getPaymentMeanInfo(ReversalPaymentMeanInfo.class) (with paymentMethod check). - * - * @return The ReversalPaymentMeanInfo for this transaction + * @return {@link WeChatPaymentMeanInfo} for this transaction, + * {@code null} if {@link TransactionAttempt#paymentMethod} is not equal to {@link PaymentMethod#WECHAT} */ - public ReversalPaymentMeanInfo getReversalPaymentMeanInfo() { - if (!PaymentMethod.REVERSAL.equals(this.paymentMethod)) { - logger.error("Payment type is not Reversal, can not return payment mean info for Reversal."); + public WeChatPaymentMeanInfo getWeChatPaymentMeanInfo() { + return this.getPaymentMeanInfo(WeChatPaymentMeanInfo.class, PaymentMethod.WECHAT); + } - return null; + /** + * @return specific {@link PaymentMeanInfo} for this transaction, + * {@code null} if {@link TransactionAttempt#paymentMethod} is not equal to {@code expectedPaymentMethod} + */ + private T getPaymentMeanInfo(final Class paymentMeanInfoClass, + final PaymentMethod expectedPaymentMethod) { + if (this.paymentMethod == expectedPaymentMethod) { + return this.getPaymentMeanInfo(paymentMeanInfoClass); } - return this.getPaymentMeanInfo(ReversalPaymentMeanInfo.class); + logger.error("Cannot return payment mean info for [{}] because payment method is: [{}]", expectedPaymentMethod, this.paymentMethod); + return null; } /** - * @param c - * Class of the PaymentMeanInfo to return, this varies according to the paymentMethod value - * @return the paymentMeanInfo - */ + * @param c + * Class of the PaymentMeanInfo to return, this varies according to the paymentMethod value + * @return the paymentMeanInfo + */ public T getPaymentMeanInfo(Class c) { T pmInfo = null; @@ -366,6 +367,18 @@ public String getRefTransactionId() { return this.refTransactionId; } + /** + * @return The amount already refunded on the transaction if applicable + */ + public Integer getRefundedAmount() { + return refundedAmount; + } + + public TransactionAttempt setRefundedAmount(Integer refundedAmount) { + this.refundedAmount = refundedAmount; + return this; + } + /** * @param refTransactionId * the refTransactionId to set @@ -463,7 +476,7 @@ public String getOrderId() { /** * Sets the merchant internal unique order identifier as provided during payment creation - * + * * @param orderId * the orderId to set */ @@ -471,6 +484,29 @@ public void setOrderId(String orderId) { this.orderId = orderId; } + /** + * @return The Payment identifier this transaction is related to + */ + public String getPaymentId() { + return paymentId; + } + + public void setPaymentId(String paymentId) { + this.paymentId = paymentId; + } + + /** + * @return The merchant token associated with the payment this transaction belongs to + */ + public String getPaymentMerchantToken() { + return paymentMerchantToken; + } + + public TransactionAttempt setPaymentMerchantToken(String paymentMerchantToken) { + this.paymentMerchantToken = paymentMerchantToken; + return this; + } + /** * @return the description of the product purchased by the customer as provided during payment creation */ @@ -480,7 +516,7 @@ public String getOrderDescription() { /** * Sets the description of the product purchased by the customer as provided during payment creation - * + * * @param orderDescription * the description to set */ @@ -488,9 +524,20 @@ public void setOrderDescription(String orderDescription) { this.orderDescription = orderDescription; } + /** + * @return If the transaction was executed as a test or not + */ + public Boolean getTest() { + return isTest; + } + + public void setTest(Boolean test) { + isTest = test; + } + /** * Usage of transaction logs requires special permissions, thus the list will usually be empty. - * + * * @return the transaction logs */ public List getLogs() { @@ -507,7 +554,7 @@ public void setLogs(List logs) { /** * Usage of notifications requires special permissions, thus the list will usually be empty. - * + * * @return the notifications */ public List getNotifications() { diff --git a/src/main/java/com/payxpert/connect2pay/client/containers/WeChatPaymentMeanInfo.java b/src/main/java/com/payxpert/connect2pay/client/containers/WeChatPaymentMeanInfo.java new file mode 100644 index 0000000..7f59592 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/client/containers/WeChatPaymentMeanInfo.java @@ -0,0 +1,31 @@ +package com.payxpert.connect2pay.client.containers; + +import java.math.BigDecimal; + +/** + * Information from the WeChat callback + */ +public class WeChatPaymentMeanInfo extends PaymentMeanInfo { + + /** + * Total fee in cents + */ + private Long totalFee; + private BigDecimal exchangeRate; + + public Long getTotalFee() { + return totalFee; + } + + public void setTotalFee(Long totalFee) { + this.totalFee = totalFee; + } + + public BigDecimal getExchangeRate() { + return exchangeRate; + } + + public void setExchangeRate(BigDecimal exchangeRate) { + this.exchangeRate = exchangeRate; + } +} diff --git a/src/main/java/com/payxpert/connect2pay/client/requests/AlipayDirectProcessRequest.java b/src/main/java/com/payxpert/connect2pay/client/requests/AlipayDirectProcessRequest.java index b924098..5e41855 100644 --- a/src/main/java/com/payxpert/connect2pay/client/requests/AlipayDirectProcessRequest.java +++ b/src/main/java/com/payxpert/connect2pay/client/requests/AlipayDirectProcessRequest.java @@ -4,6 +4,7 @@ import com.payxpert.connect2pay.constants.AlipayIdentityCodeType; import com.payxpert.connect2pay.constants.AlipayPaymentMode; +import com.payxpert.connect2pay.utils.Utils; import net.sf.oval.constraint.CheckWith; import net.sf.oval.constraint.CheckWithCheck; import net.sf.oval.constraint.MaxLength; @@ -57,7 +58,7 @@ public String getBuyerIdentityCode() { } public AlipayDirectProcessRequest setBuyerIdentityCode(String buyerIdentityCode) { - this.buyerIdentityCode = this.limitLength(buyerIdentityCode, 32); + this.buyerIdentityCode = Utils.limitLength(buyerIdentityCode, 32); return getThis(); } @@ -75,7 +76,7 @@ public String getNotificationLang() { } public AlipayDirectProcessRequest setNotificationLang(String notificationLang) { - this.notificationLang = this.limitLength(notificationLang, 10); + this.notificationLang = Utils.limitLength(notificationLang, 10); return getThis(); } @@ -84,7 +85,7 @@ public String getNotificationTimeZone() { } public AlipayDirectProcessRequest setNotificationTimeZone(String notificationTimeZone) { - this.notificationTimeZone = this.limitLength(notificationTimeZone, 64); + this.notificationTimeZone = Utils.limitLength(notificationTimeZone, 64); return getThis(); } diff --git a/src/main/java/com/payxpert/connect2pay/client/requests/GenericRequest.java b/src/main/java/com/payxpert/connect2pay/client/requests/GenericRequest.java index 509fc84..3a89fc1 100644 --- a/src/main/java/com/payxpert/connect2pay/client/requests/GenericRequest.java +++ b/src/main/java/com/payxpert/connect2pay/client/requests/GenericRequest.java @@ -33,7 +33,7 @@ public abstract class GenericRequest> { protected static final Logger logger = LoggerFactory.getLogger(GenericRequest.class); - public static final String DEFAULT_API_VERSION = "002.61"; + public static final String DEFAULT_API_VERSION = "002.70"; @NotNull @NotEmpty @@ -130,12 +130,4 @@ public String toJson() throws JsonGenerationException, JsonMappingException, IOE return json; } - - protected String limitLength(String value, int length) { - if (value != null && value.length() > length) { - value = value.substring(0, length); - } - - return value; - } } diff --git a/src/main/java/com/payxpert/connect2pay/client/requests/PaymentRequest.java b/src/main/java/com/payxpert/connect2pay/client/requests/PaymentRequest.java index 354af05..60b3214 100644 --- a/src/main/java/com/payxpert/connect2pay/client/requests/PaymentRequest.java +++ b/src/main/java/com/payxpert/connect2pay/client/requests/PaymentRequest.java @@ -1,28 +1,14 @@ package com.payxpert.connect2pay.client.requests; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; - import com.fasterxml.jackson.annotation.JsonProperty; import com.payxpert.connect2pay.client.Connect2payClient; -import com.payxpert.connect2pay.constants.C2PLang; -import com.payxpert.connect2pay.constants.PaymentMethod; -import com.payxpert.connect2pay.constants.PaymentMode; -import com.payxpert.connect2pay.constants.ShippingType; -import com.payxpert.connect2pay.constants.SubscriptionType; -import com.payxpert.connect2pay.constants.TransactionOperation; - -import net.sf.oval.constraint.CheckWith; -import net.sf.oval.constraint.CheckWithCheck; -import net.sf.oval.constraint.Email; -import net.sf.oval.constraint.MatchPattern; -import net.sf.oval.constraint.MaxLength; -import net.sf.oval.constraint.MinLength; -import net.sf.oval.constraint.NotEmpty; -import net.sf.oval.constraint.NotNull; -import net.sf.oval.constraint.Range; +import com.payxpert.connect2pay.client.containers.Order; +import com.payxpert.connect2pay.client.containers.Shipping; +import com.payxpert.connect2pay.client.containers.Shopper; +import com.payxpert.connect2pay.constants.*; + +import com.payxpert.connect2pay.utils.Utils; +import net.sf.oval.constraint.*; /** * This class represents the initial request made by the merchant to initialize a payment: @@ -40,107 +26,21 @@ */ public class PaymentRequest extends GenericRequest { - // Customer fields - // Shipping Information - @JsonProperty("shopperID") - @MaxLength(32) - private String shopperId; - - @MatchPattern(pattern = { - "NA|[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?" }) - @MaxLength(100) - private String shopperEmail; - @MaxLength(35) - private String shipToFirstName; - @MaxLength(35) - private String shipToLastName; - @MaxLength(128) - private String shipToCompany; - @MaxLength(20) - private String shipToPhone; - @MaxLength(255) - private String shipToAddress; - @MaxLength(30) - private String shipToState; - @MaxLength(10) - private String shipToZipcode; - @MaxLength(50) - private String shipToCity; - @MaxLength(2) - private String shipToCountryCode; - - // Invoicing Information - @MaxLength(35) - private String shopperFirstName; - @MaxLength(35) - private String shopperLastName; - @MaxLength(20) - private String shopperPhone; - @MaxLength(255) - private String shopperAddress; - @MaxLength(30) - private String shopperState; - @MaxLength(10) - private String shopperZipcode; - @MaxLength(50) - private String shopperCity; - @MaxLength(2) - private String shopperCountryCode; - @MaxLength(128) - private String shopperCompany; - @MaxLength(50) - private String shopperLoyaltyProgram; - @MinLength(8) - @MaxLength(8) - private String shopperBirthDate; - @MaxLength(32) - private String shopperIDNumber; - - // Affiliation fields - @JsonProperty("affiliateID") - @MaxLength(16) - private String affiliateId; - @MaxLength(128) - private String campaignName; - - // Order fields - @NotNull - @NotEmpty - @MaxLength(100) - @JsonProperty("orderID") - private String orderId; - @NotNull @NotEmpty @MaxLength(3) private String currency; + @NotNull @Range(min = 1, max = 999999999) private Integer amount; - private Integer orderTotalWithoutShipping; - private Integer orderShippingPrice; - private Integer orderDiscount; - - @MaxLength(50) - private String orderFOLanguage; - - @MaxLength(500) - private String orderDescription; - private List orderCartContent; - - // Shipping fields - @NotNull - private ShippingType shippingType; - @MaxLength(50) - private String shippingName; - // Payment fields @NotNull private PaymentMode paymentMode; private PaymentMethod paymentMethod; - private String paymentNetwork; + private PaymentNetwork paymentNetwork; private TransactionOperation operation; @@ -188,553 +88,20 @@ public class PaymentRequest extends GenericRequest { @JsonProperty("themeID") private Long themeId; - @Override - protected PaymentRequest getThis() { - return this; - } - - /** - * @return the afClientId - * @deprecated Removed since API 002.02 - */ - @Deprecated - public Integer getAfClientId() { - return null; - } - - /** - * @param afClientId - * the afClientId to set - * - * @return The current request for method chaining - * @deprecated Removed since API 002.02 - */ - @Deprecated - public PaymentRequest setAfClientId(Integer afClientId) { - return getThis(); - } - - /** - * @return the afPassword - * @deprecated Removed since API 002.02 - */ - @Deprecated - public String getAfPassword() { - return null; - } - - /** - * @param afPassword - * the afPassword to set - * - * @return The current request for method chaining - * @deprecated Removed since API 002.02 - */ - @Deprecated - public PaymentRequest setAfPassword(String afPassword) { - return getThis(); - } - - /** - * @return the shopperId - */ - public String getShopperId() { - return this.shopperId; - } - - /** - * @param shopperId - * the shopperId to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperId(String shopperId) { - this.shopperId = shopperId; - return getThis(); - } - - /** - * @param shopperId - * the shopperId to set - * - * @return The current request for method chaining - * @deprecated since 002.50 - */ - @Deprecated - public PaymentRequest setShopperId(Integer shopperId) { - if (shopperId == null) { - this.shopperId = null; - } else { - this.shopperId = shopperId.toString(); - } - return getThis(); - } - - /** - * @return the shopperEmail - */ - public String getShopperEmail() { - return shopperEmail; - } - - /** - * @param shopperEmail - * the shopperEmail to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperEmail(String shopperEmail) { - this.shopperEmail = this.limitLength(shopperEmail, 100); - return getThis(); - } - - /** - * @return the shipToFirstName - */ - public String getShipToFirstName() { - return shipToFirstName; - } - - /** - * @param shipToFirstName - * the shipToFirstName to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShipToFirstName(String shipToFirstName) { - this.shipToFirstName = this.limitLength(shipToFirstName, 35); - return getThis(); - } - - /** - * @return the shipToLastName - */ - public String getShipToLastName() { - return shipToLastName; - } - - /** - * @param shipToLastName - * the shipToLastName to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShipToLastName(String shipToLastName) { - this.shipToLastName = this.limitLength(shipToLastName, 35); - return getThis(); - } - - /** - * @return the shipToCompany - */ - public String getShipToCompany() { - return shipToCompany; - } - - /** - * @param shipToCompany - * the shipToCompany to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShipToCompany(String shipToCompany) { - this.shipToCompany = this.limitLength(shipToCompany, 128); - return getThis(); - } - - /** - * @return the shipToPhone - */ - public String getShipToPhone() { - return shipToPhone; - } - - /** - * @param shipToPhone - * the shipToPhone to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShipToPhone(String shipToPhone) { - this.shipToPhone = this.limitLength(shipToPhone, 20); - return getThis(); - } - - /** - * @return the shipToAddress - */ - public String getShipToAddress() { - return shipToAddress; - } - - /** - * @param shipToAddress - * the shipToAddress to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShipToAddress(String shipToAddress) { - this.shipToAddress = this.limitLength(shipToAddress, 255); - return getThis(); - } - - /** - * @return the shipToState - */ - public String getShipToState() { - return shipToState; - } - - /** - * @param shipToState - * the shipToState to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShipToState(String shipToState) { - this.shipToState = this.limitLength(shipToState, 30); - return getThis(); - } - - /** - * @return the shipToZipcode - */ - public String getShipToZipcode() { - return shipToZipcode; - } - - /** - * @param shipToZipcode - * the shipToZipcode to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShipToZipcode(String shipToZipcode) { - this.shipToZipcode = this.limitLength(shipToZipcode, 10); - return getThis(); - } - - /** - * @return the shipToCity - */ - public String getShipToCity() { - return shipToCity; - } - - /** - * @param shipToCity - * the shipToCity to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShipToCity(String shipToCity) { - this.shipToCity = this.limitLength(shipToCity, 50); - return getThis(); - } - - /** - * @return the shipToCountryCode - */ - public String getShipToCountryCode() { - return shipToCountryCode; - } - - /** - * @param shipToCountryCode - * the shipToCountryCode to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShipToCountryCode(String shipToCountryCode) { - this.shipToCountryCode = this.limitLength(shipToCountryCode, 2); - return getThis(); - } - - /** - * @return the shopperFirstName - */ - public String getShopperFirstName() { - return shopperFirstName; - } - - /** - * @param shopperFirstName - * the shopperFirstName to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperFirstName(String shopperFirstName) { - this.shopperFirstName = this.limitLength(shopperFirstName, 35); - return getThis(); - } - - /** - * @return the shopperLastName - */ - public String getShopperLastName() { - return shopperLastName; - } - - /** - * @param shopperLastName - * the shopperLastName to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperLastName(String shopperLastName) { - this.shopperLastName = this.limitLength(shopperLastName, 35); - return getThis(); - } - - /** - * @return the shopperPhone - */ - public String getShopperPhone() { - return shopperPhone; - } - - /** - * @param shopperPhone - * the shopperPhone to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperPhone(String shopperPhone) { - this.shopperPhone = this.limitLength(shopperPhone, 20); - return getThis(); - } - - /** - * @return the shopperAddress - */ - public String getShopperAddress() { - return shopperAddress; - } + @AssertValid + private Shopper shopper; - /** - * @param shopperAddress - * the shopperAddress to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperAddress(String shopperAddress) { - this.shopperAddress = this.limitLength(shopperAddress, 255); - return getThis(); - } + @AssertValid + private Shipping shipping; - /** - * @return the shopperState - */ - public String getShopperState() { - return shopperState; - } + @AssertValid + private Order order; - /** - * @param shopperState - * the shopperState to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperState(String shopperState) { - this.shopperState = this.limitLength(shopperState, 30); - return getThis(); - } - - /** - * @return the shopperZipcode - */ - public String getShopperZipcode() { - return shopperZipcode; - } - - /** - * @param shopperZipcode - * the shopperZipcode to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperZipcode(String shopperZipcode) { - this.shopperZipcode = this.limitLength(shopperZipcode, 10); - return getThis(); - } - - /** - * @return the shopperCity - */ - public String getShopperCity() { - return shopperCity; - } - - /** - * @param shopperCity - * the shopperCity to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperCity(String shopperCity) { - this.shopperCity = this.limitLength(shopperCity, 50); - return getThis(); - } - - /** - * @return the shopperCountryCode - */ - public String getShopperCountryCode() { - return shopperCountryCode; - } - - /** - * @param shopperCountryCode - * the shopperCountryCode to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperCountryCode(String shopperCountryCode) { - this.shopperCountryCode = this.limitLength(shopperCountryCode, 2); - return getThis(); - } - - /** - * @return the shopperCompany - */ - public String getShopperCompany() { - return shopperCompany; - } - - /** - * @param shopperCompany - * the shopperCompany to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperCompany(String shopperCompany) { - this.shopperCompany = this.limitLength(shopperCompany, 128); - return getThis(); - } - - /** - * @return the shopperLoyaltyProgram - */ - public String getShopperLoyaltyProgram() { - return shopperLoyaltyProgram; - } - - /** - * @param shopperLoyaltyProgram - * the shopperLoyaltyProgram to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperLoyaltyProgram(String shopperLoyaltyProgram) { - this.shopperLoyaltyProgram = this.limitLength(shopperLoyaltyProgram, 50); - return getThis(); - } - - /** - * @return the shopperBirthDate - */ - public String getShopperBirthDate() { - return this.shopperBirthDate; - } - - /** - * @param shopperBirthDate - * the date of shopper birth date, format YYYYMMDD - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperBirthDate(String shopperBirthDate) { - this.shopperBirthDate = this.limitLength(shopperBirthDate, 8); - return getThis(); - } - - /** - * @param shopperBirthDate - * the date of shopper birth date - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperBirthDate(Date shopperBirthDate) { - if (shopperBirthDate == null) { - this.shopperBirthDate = null; - } else { - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Etc/UTC")); - calendar.setTime(shopperBirthDate); - // Format as YYYYMMDD - this.shopperBirthDate = String.format("%04d%02d%02d", calendar.get(Calendar.YEAR), - calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH)); - } - - return getThis(); - } - - /** - * @return the shopperIDNumber - */ - public String getShopperIDNumber() { - return this.shopperIDNumber; - } - - /** - * @param shopperIDNumber - * Customers document (passport number, ID number, taxpayer ID...) - * - * @return The current request for method chaining - */ - public PaymentRequest setShopperIDNumber(String shopperIDNumber) { - this.shopperIDNumber = this.limitLength(shopperIDNumber, 32); - return getThis(); - } - - /** - * @return the affiliate ID - */ - public String getAffiliateId() { - return this.affiliateId; - } - - /** - * @param affiliateId - * The affiliate ID to set - */ - public PaymentRequest setAffiliateId(String affiliateId) { - this.affiliateId = this.limitLength(affiliateId, 16); - return getThis(); - } - - /** - * @return The affiliation campaign name - */ - public String getCampaignName() { - return this.campaignName; - } - - /** - * @param campaignName - * The affiliation campaign name to set - */ - public PaymentRequest setCampaignName(String campaignName) { - this.campaignName = this.limitLength(campaignName, 128); - return getThis(); - } - - /** - * @return the orderID - */ - public String getOrderId() { - return orderId; + @Override + protected PaymentRequest getThis() { + return this; } - /** - * @param orderId - * the orderId to set - * - * @return The current request for method chaining - */ - public PaymentRequest setOrderId(String orderId) { - this.orderId = this.limitLength(orderId, 100); - return getThis(); - } /** * @return the currency @@ -750,7 +117,7 @@ public String getCurrency() { * @return The current request for method chaining */ public PaymentRequest setCurrency(String currency) { - this.currency = this.limitLength(currency, 3); + this.currency = Utils.limitLength(currency, 3); return getThis(); } @@ -772,171 +139,6 @@ public PaymentRequest setAmount(Integer amount) { return getThis(); } - /** - * @return the orderTotalWithoutShipping - */ - public Integer getOrderTotalWithoutShipping() { - return orderTotalWithoutShipping; - } - - /** - * @param orderTotalWithoutShipping - * the orderTotalWithoutShipping to set - * - * @return The current request for method chaining - */ - public PaymentRequest setOrderTotalWithoutShipping(Integer orderTotalWithoutShipping) { - this.orderTotalWithoutShipping = orderTotalWithoutShipping; - return getThis(); - } - - /** - * @return the orderShippingPrice - */ - public Integer getOrderShippingPrice() { - return orderShippingPrice; - } - - /** - * @param orderShippingPrice - * the orderShippingPrice to set - * - * @return The current request for method chaining - */ - public PaymentRequest setOrderShippingPrice(Integer orderShippingPrice) { - this.orderShippingPrice = orderShippingPrice; - return getThis(); - } - - /** - * @return the orderDiscount - */ - public Integer getOrderDiscount() { - return orderDiscount; - } - - /** - * @param orderDiscount - * the orderDiscount to set - * - * @return The current request for method chaining - */ - public PaymentRequest setOrderDiscount(Integer orderDiscount) { - this.orderDiscount = orderDiscount; - return getThis(); - } - - /** - * @return the customerIP - * @deprecated This field is not present anymore in the API, the value is obtained from the connected user - */ - @Deprecated - public String getCustomerIP() { - return null; - } - - /** - * @param customerIP - * the customerIP to set - * - * @return The current request for method chaining - * @deprecated This field is not present anymore in the API, the value is obtained from the connected user - */ - @Deprecated - public PaymentRequest setCustomerIP(String customerIP) { - return getThis(); - } - - /** - * @return the orderFOLanguage - */ - public String getOrderFOLanguage() { - return orderFOLanguage; - } - - /** - * @param orderFOLanguage - * the orderFOLanguage to set - * - * @return The current request for method chaining - */ - public PaymentRequest setOrderFOLanguage(String orderFOLanguage) { - this.orderFOLanguage = this.limitLength(orderFOLanguage, 50); - return getThis(); - } - - /** - * @return the orderDescription - */ - public String getOrderDescription() { - return orderDescription; - } - - /** - * @param orderDescription - * the orderDescription to set - * - * @return The current request for method chaining - */ - public PaymentRequest setOrderDescription(String orderDescription) { - this.orderDescription = this.limitLength(orderDescription, 500); - return getThis(); - } - - /** - * @return the orderCartContent - */ - public List getOrderCartContent() { - return orderCartContent; - } - - /** - * @param orderCartContent - * the orderCartContent to set - * - * @return The current request for method chaining - */ - public PaymentRequest setOrderCartContent(List orderCartContent) { - this.orderCartContent = orderCartContent; - return getThis(); - } - - /** - * @return the shippingType - */ - public ShippingType getShippingType() { - return shippingType; - } - - /** - * @param shippingType - * the shippingType to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShippingType(ShippingType shippingType) { - this.shippingType = shippingType; - return getThis(); - } - - /** - * @return the shippingName - */ - public String getShippingName() { - return shippingName; - } - - /** - * @param shippingName - * the shippingName to set - * - * @return The current request for method chaining - */ - public PaymentRequest setShippingName(String shippingName) { - this.shippingName = this.limitLength(shippingName, 50); - return getThis(); - } - /** * @return the paymentMode */ @@ -955,16 +157,6 @@ public PaymentRequest setPaymentMode(PaymentMode paymentMode) { return getThis(); } - @Deprecated - public PaymentMethod getPaymentType() { - return this.getPaymentMethod(); - } - - @Deprecated - public PaymentRequest setPaymentType(PaymentMethod paymentType) { - return this.setPaymentMethod(paymentType); - } - /** * @return the paymentMethod */ @@ -983,24 +175,13 @@ public PaymentRequest setPaymentMethod(PaymentMethod paymentMethod) { return getThis(); } - @Deprecated - public PaymentRequest setProvider(String provider) { - this.paymentNetwork = provider; - return getThis(); - } - - @Deprecated - public String getProvider() { - return paymentNetwork; - } - /** * @param paymentNetwork * the Payment Network to set * * @return The current request for method chaining */ - public PaymentRequest setPaymentNetwork(String paymentNetwork) { + public PaymentRequest setPaymentNetwork(PaymentNetwork paymentNetwork) { this.paymentNetwork = paymentNetwork; return getThis(); } @@ -1008,7 +189,7 @@ public PaymentRequest setPaymentNetwork(String paymentNetwork) { /** * @return the Payment Network */ - public String getPaymentNetwork() { + public PaymentNetwork getPaymentNetwork() { return paymentNetwork; } @@ -1098,7 +279,7 @@ public String getTrialPeriod() { * @return The current request for method chaining */ public PaymentRequest setTrialPeriod(String trialPeriod) { - this.trialPeriod = this.limitLength(trialPeriod, 10); + this.trialPeriod = Utils.limitLength(trialPeriod, 10); return getThis(); } @@ -1134,7 +315,7 @@ public String getRebillPeriod() { * @return The current request for method chaining */ public PaymentRequest setRebillPeriod(String rebillPeriod) { - this.rebillPeriod = this.limitLength(rebillPeriod, 10); + this.rebillPeriod = Utils.limitLength(rebillPeriod, 10); return getThis(); } @@ -1170,7 +351,7 @@ public String getCtrlRedirectURL() { * @return The current request for method chaining */ public PaymentRequest setCtrlRedirectURL(String ctrlRedirectURL) { - this.ctrlRedirectURL = this.limitLength(ctrlRedirectURL, 2048); + this.ctrlRedirectURL = Utils.limitLength(ctrlRedirectURL, 2048); return getThis(); } @@ -1188,7 +369,7 @@ public String getCtrlCallbackURL() { * @return The current request for method chaining */ public PaymentRequest setCtrlCallbackURL(String ctrlCallbackURL) { - this.ctrlCallbackURL = this.limitLength(ctrlCallbackURL, 2048); + this.ctrlCallbackURL = Utils.limitLength(ctrlCallbackURL, 2048); return getThis(); } @@ -1206,7 +387,7 @@ public String getCtrlCustomData() { * @return The current request for method chaining */ public PaymentRequest setCtrlCustomData(String ctrlCustomData) { - this.ctrlCustomData = this.limitLength(ctrlCustomData, 2048); + this.ctrlCustomData = Utils.limitLength(ctrlCustomData, 2048); return getThis(); } @@ -1224,7 +405,7 @@ public String getTimeOut() { * @return The current request for method chaining */ public PaymentRequest setTimeOut(String timeOut) { - this.timeOut = timeOut; + this.timeOut = Utils.limitLength(timeOut, 10); return getThis(); } @@ -1260,7 +441,7 @@ public String getMerchantNotificationTo() { * @return The current request for method chaining */ public PaymentRequest setMerchantNotificationTo(String merchantNotificationTo) { - this.merchantNotificationTo = merchantNotificationTo; + this.merchantNotificationTo = Utils.limitLength(merchantNotificationTo, 100); return getThis(); } @@ -1298,6 +479,33 @@ public PaymentRequest setThemeId(Long themeId) { return getThis(); } + public Shopper getShopper() { + return shopper; + } + + public PaymentRequest setShopper(Shopper shopper) { + this.shopper = shopper; + return this; + } + + public Shipping getShipping() { + return shipping; + } + + public PaymentRequest setShipping(Shipping shipping) { + this.shipping = shipping; + return this; + } + + public Order getOrder() { + return order; + } + + public PaymentRequest setOrder(Order order) { + this.order = order; + return this; + } + /** * Automatically compute orderAmount according to orderTotalWithoutShipping, orderShippingPrice and orderDiscount * values. @@ -1396,93 +604,4 @@ public boolean isSatisfied(Object validatedObject, Object value) { return true; } } - - /** - * Class to deal with ordered products. - * - * @author jsh - * - */ - public static class Product { - private int cartProductId; - private String cartProductName; - private Float cartProductUnitPrice; - private int cartProductQuantity; - private String cartProductBrand; - private String cartProductMPN; - private String cartProductCategoryName; - private int cartProductCategoryID; - - public int getCartProductId() { - return cartProductId; - } - - public Product setCartProductId(int cartProductId) { - this.cartProductId = cartProductId; - return this; - } - - public String getCartProductName() { - return cartProductName; - } - - public Product setCartProductName(String cartProductName) { - this.cartProductName = cartProductName; - return this; - } - - public Float getCartProductUnitPrice() { - return cartProductUnitPrice; - } - - public Product setCartProductUnitPrice(Float cartProductUnitPrice) { - this.cartProductUnitPrice = cartProductUnitPrice; - return this; - } - - public int getCartProductQuantity() { - return cartProductQuantity; - } - - public Product setCartProductQuantity(int cartProductQuantity) { - this.cartProductQuantity = cartProductQuantity; - return this; - } - - public String getCartProductBrand() { - return cartProductBrand; - } - - public Product setCartProductBrand(String cartProductBrand) { - this.cartProductBrand = cartProductBrand; - return this; - } - - public String getCartProductMPN() { - return cartProductMPN; - } - - public Product setCartProductMPN(String cartProductMPN) { - this.cartProductMPN = cartProductMPN; - return this; - } - - public String getCartProductCategoryName() { - return cartProductCategoryName; - } - - public Product setCartProductCategoryName(String cartProductCategoryName) { - this.cartProductCategoryName = cartProductCategoryName; - return this; - } - - public int getCartProductCategoryID() { - return cartProductCategoryID; - } - - public Product setCartProductCategoryID(int cartProductCategoryID) { - this.cartProductCategoryID = cartProductCategoryID; - return this; - } - } } diff --git a/src/main/java/com/payxpert/connect2pay/client/requests/TransactionRebillRequest.java b/src/main/java/com/payxpert/connect2pay/client/requests/TransactionRebillRequest.java index 2674973..e4d2f14 100644 --- a/src/main/java/com/payxpert/connect2pay/client/requests/TransactionRebillRequest.java +++ b/src/main/java/com/payxpert/connect2pay/client/requests/TransactionRebillRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; +import com.payxpert.connect2pay.utils.Utils; +import net.sf.oval.constraint.MaxLength; import net.sf.oval.constraint.NotNull; /** @@ -16,6 +18,9 @@ public class TransactionRebillRequest extends GenericRequest { protected static final Logger logger = LoggerFactory.getLogger(GenericResponse.class); + private String apiVersion; + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + @SuppressWarnings("unchecked") public T fromJson(String json) throws Exception { return (T) Utils.readJson(json, getClass()); diff --git a/src/main/java/com/payxpert/connect2pay/client/response/PaymentStatusResponse.java b/src/main/java/com/payxpert/connect2pay/client/response/PaymentStatusResponse.java index 78ac3e5..eb17fe4 100644 --- a/src/main/java/com/payxpert/connect2pay/client/response/PaymentStatusResponse.java +++ b/src/main/java/com/payxpert/connect2pay/client/response/PaymentStatusResponse.java @@ -7,6 +7,8 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonProperty; +import com.payxpert.connect2pay.client.containers.Order; +import com.payxpert.connect2pay.client.containers.Shipping; import com.payxpert.connect2pay.client.containers.TransactionAttempt; import com.payxpert.connect2pay.constants.PaymentStatusValue; import com.payxpert.connect2pay.constants.ResultCode; @@ -31,13 +33,15 @@ public class PaymentStatusResponse extends GenericResponse transactions; + private Order order; + + private Shipping shipping; + /** * @return the code */ @@ -158,21 +162,6 @@ public void setCtrlCustomData(String ctrlCustomData) { this.ctrlCustomData = ctrlCustomData; } - /** - * @return the orderId - */ - public String getOrderId() { - return orderId; - } - - /** - * @param orderId - * the orderId to set - */ - public void setOrderId(String orderId) { - this.orderId = orderId; - } - /** * @return the currency */ @@ -207,6 +196,24 @@ public List getTransactions() { return this.transactions; } + public Order getOrder() { + return order; + } + + public PaymentStatusResponse setOrder(Order order) { + this.order = order; + return this; + } + + public Shipping getShipping() { + return shipping; + } + + public PaymentStatusResponse setShipping(Shipping shipping) { + this.shipping = shipping; + return this; + } + /** * * @param index diff --git a/src/main/java/com/payxpert/connect2pay/constants/PaymentNetwork.java b/src/main/java/com/payxpert/connect2pay/constants/PaymentNetwork.java index 48b491a..f446b91 100644 --- a/src/main/java/com/payxpert/connect2pay/constants/PaymentNetwork.java +++ b/src/main/java/com/payxpert/connect2pay/constants/PaymentNetwork.java @@ -29,6 +29,10 @@ public enum PaymentNetwork { this.supportedPaymentMethod = belongsToMethod; } + public String getValue() { + return this.value; + } + public String valueToString() { return this.value; } @@ -37,7 +41,7 @@ public boolean supports(PaymentMethod paymentMethod) { return paymentMethod == this.supportedPaymentMethod; } - public static PaymentNetwork fromValue(String value) { + public static PaymentNetwork valueOfFromString(String value) { for (PaymentNetwork network : PaymentNetwork.values()) { if (network.value.equalsIgnoreCase(value)) { return network; diff --git a/src/main/java/com/payxpert/connect2pay/constants/sca/OrderDeliveryDelay.java b/src/main/java/com/payxpert/connect2pay/constants/sca/OrderDeliveryDelay.java new file mode 100644 index 0000000..5f688e7 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/constants/sca/OrderDeliveryDelay.java @@ -0,0 +1,39 @@ +package com.payxpert.connect2pay.constants.sca; + +import java.util.Arrays; +import java.util.Optional; + +public enum OrderDeliveryDelay { + /** + * 01 -> Electronic Delivery + */ + ELECTRONIC("01"), + /** + * 02 -> Same day shipping + */ + SAME_DAY("02"), + /** + * 03 -> Overnight shipping + */ + OVERNIGHT("03"), + /** + * 04 -> Two-day or more shipping + */ + TWO_OR_MORE_DAY("04"); + + private String value; + + OrderDeliveryDelay(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static Optional fromValue(String value) { + return Arrays.stream(OrderDeliveryDelay.values()).filter(orderDeliveryDelay -> { + return orderDeliveryDelay.getValue().equalsIgnoreCase(value); + }).findFirst().map(Optional::of).orElse(Optional.empty()); + } +} \ No newline at end of file diff --git a/src/main/java/com/payxpert/connect2pay/constants/sca/OrderType.java b/src/main/java/com/payxpert/connect2pay/constants/sca/OrderType.java new file mode 100644 index 0000000..573a55d --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/constants/sca/OrderType.java @@ -0,0 +1,43 @@ +package com.payxpert.connect2pay.constants.sca; + +import java.util.Arrays; +import java.util.Optional; + +public enum OrderType { + /** + * 01 -> Goods / Service purchase + */ + GOODS_SERVICE("01"), + /** + * 03 -> Check Acceptance + */ + CHECK_ACCEPTANCE("03"), + /** + * 10 -> Account Funding + */ + ACCOUNT_FUNDING("10"), + /** + * 11 -> Quasi-Cash Transaction + */ + QUASI_CASH("11"), + /** + * 28 -> Prepaid activation and Loan + */ + PREPAID_LOAN("28"); + + private String value; + + OrderType(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static Optional fromValue(String value) { + return Arrays.stream(OrderType.values()).filter(orderType -> { + return orderType.getValue().equalsIgnoreCase(value); + }).findFirst().map(Optional::of).orElse(Optional.empty()); + } +} diff --git a/src/main/java/com/payxpert/connect2pay/constants/sca/PaymentMeanAge.java b/src/main/java/com/payxpert/connect2pay/constants/sca/PaymentMeanAge.java new file mode 100644 index 0000000..e050e95 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/constants/sca/PaymentMeanAge.java @@ -0,0 +1,43 @@ +package com.payxpert.connect2pay.constants.sca; + +import java.util.Arrays; +import java.util.Optional; + +public enum PaymentMeanAge { + /** + * 01 -> No account + */ + NO_ACCOUNT("01"), + /** + * 02 -> Created during this transaction + */ + DURING_TRANSACTION("02"), + /** + * 03 -> Less than 30 days + */ + LESS_30_DAYS("03"), + /** + * 04 -> Between 30 and 60 days + */ + BETWEEN_30_60_DAYS("04"), + /** + * 05 -> More than 60 days + */ + MORE_60_DAYS("05"); + + private String value; + + PaymentMeanAge(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static Optional fromValue(String value) { + return Arrays.stream(PaymentMeanAge.values()).filter(paymentMeanAge -> { + return paymentMeanAge.getValue().equalsIgnoreCase(value); + }).findFirst().map(Optional::of).orElse(Optional.empty()); + } +} diff --git a/src/main/java/com/payxpert/connect2pay/constants/sca/ShippingInfoAge.java b/src/main/java/com/payxpert/connect2pay/constants/sca/ShippingInfoAge.java new file mode 100644 index 0000000..02c8a3c --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/constants/sca/ShippingInfoAge.java @@ -0,0 +1,39 @@ +package com.payxpert.connect2pay.constants.sca; + +import java.util.Arrays; +import java.util.Optional; + +public enum ShippingInfoAge { + /** + * 01 -> Changed during this transaction + */ + DURING_TRANSACTION("01"), + /** + * 02 -> Less than 30 days + */ + LESS_30_DAYS("02"), + /** + * 03 -> Between 30 and 60 days + */ + BETWEEN_30_60_DAYS("03"), + /** + * 04 -> More than 60 days + */ + MORE_60_DAYS("04"); + + private String value; + + ShippingInfoAge(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static Optional fromValue(String value) { + return Arrays.stream(ShippingInfoAge.values()).filter(shippingInfoAge -> { + return shippingInfoAge.getValue().equalsIgnoreCase(value); + }).findFirst().map(Optional::of).orElse(Optional.empty()); + } +} diff --git a/src/main/java/com/payxpert/connect2pay/constants/sca/ShippingType.java b/src/main/java/com/payxpert/connect2pay/constants/sca/ShippingType.java new file mode 100644 index 0000000..65a6df6 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/constants/sca/ShippingType.java @@ -0,0 +1,51 @@ +package com.payxpert.connect2pay.constants.sca; + +import java.util.Arrays; +import java.util.Optional; + +public enum ShippingType { + /** + * 01 -> Ship to cardholder's billing address + */ + TO_CARDHOLDER("01"), + /** + * 02 -> Ship to another verified address on file with merchant + */ + TO_VERIFIED_ADDRESS("02"), + /** + * 03 -> Ship to address that is different than the cardholder's billing address + */ + TO_NON_BILLING_ADDRESS("03"), + /** + * 04 -> "Ship to Store" / Pick-up at local store (Store address shall be populated in shipping address fields) + */ + SHIP_TO_STORE("04"), + /** + * 05 -> Digital goods (includes online services, electronic gift cards and redemption codes) + */ + DIGITAL_GOODS("05"), + /** + * 06 -> Travel and Event tickets, not shipped + */ + TRAVEL_EVENT_TICKET("06"), + /** + * 07 -> Other (for example, Gaming, digital services not shipped, e-media subscriptions, etc.) + */ + OTHER("07"); + + private String value; + + ShippingType(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static Optional fromValue(String value) { + return Arrays.stream(ShippingType.values()).filter(shippingType -> { + return shippingType.getValue().equalsIgnoreCase(value); + }).findFirst().map(Optional::of).orElse(Optional.empty()); + } +} diff --git a/src/main/java/com/payxpert/connect2pay/constants/sca/ShopperAccountAge.java b/src/main/java/com/payxpert/connect2pay/constants/sca/ShopperAccountAge.java new file mode 100644 index 0000000..331ace4 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/constants/sca/ShopperAccountAge.java @@ -0,0 +1,43 @@ +package com.payxpert.connect2pay.constants.sca; + +import java.util.Arrays; +import java.util.Optional; + +public enum ShopperAccountAge { + /** + * 01 -> No account + */ + NO_ACCOUNT("01"), + /** + * 02 -> Created during this transaction + */ + DURING_TRANSACTION("02"), + /** + * 03 -> Less than 30 days + */ + LESS_30_DAYS("03"), + /** + * 04 -> Between 30 and 60 days + */ + BETWEEN_30_60_DAYS("04"), + /** + * 05 -> More than 60 days + */ + MORE_60_DAYS("05"); + + private String value; + + ShopperAccountAge(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static Optional fromValue(String value) { + return Arrays.stream(ShopperAccountAge.values()).filter(shopperAccountAge -> { + return shopperAccountAge.getValue().equalsIgnoreCase(value); + }).findFirst().map(Optional::of).orElse(Optional.empty()); + } +} diff --git a/src/main/java/com/payxpert/connect2pay/constants/sca/ShopperAccountLastChange.java b/src/main/java/com/payxpert/connect2pay/constants/sca/ShopperAccountLastChange.java new file mode 100644 index 0000000..c4820b1 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/constants/sca/ShopperAccountLastChange.java @@ -0,0 +1,39 @@ +package com.payxpert.connect2pay.constants.sca; + +import java.util.Arrays; +import java.util.Optional; + +public enum ShopperAccountLastChange { + /** + * 01 -> Changed during this transaction + */ + DURING_TRANSACTION("01"), + /** + * 02 -> Less than 30 days + */ + LESS_30_DAYS("02"), + /** + * 03 -> Between 30 and 60 days + */ + BETWEEN_30_60_DAYS("03"), + /** + * 04 -> More than 60 days + */ + MORE_60_DAYS("04"); + + private String value; + + ShopperAccountLastChange(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static Optional fromValue(String value) { + return Arrays.stream(ShopperAccountLastChange.values()).filter(shopperAccountLastChange -> { + return shopperAccountLastChange.getValue().equalsIgnoreCase(value); + }).findFirst().map(Optional::of).orElse(Optional.empty()); + } +} diff --git a/src/main/java/com/payxpert/connect2pay/constants/sca/ShopperAccountPwChange.java b/src/main/java/com/payxpert/connect2pay/constants/sca/ShopperAccountPwChange.java new file mode 100644 index 0000000..bec4143 --- /dev/null +++ b/src/main/java/com/payxpert/connect2pay/constants/sca/ShopperAccountPwChange.java @@ -0,0 +1,43 @@ +package com.payxpert.connect2pay.constants.sca; + +import java.util.Arrays; +import java.util.Optional; + +public enum ShopperAccountPwChange { + /** + * 01 -> No change + */ + NO_CHANGE("01"), + /** + * 02 -> Created during this transaction + */ + DURING_TRANSACTION("02"), + /** + * 03 -> Less than 30 days + */ + LESS_30_DAYS("03"), + /** + * 04 -> Between 30 and 60 days + */ + BETWEEN_30_60_DAYS("04"), + /** + * 05 -> More than 60 days + */ + MORE_60_DAYS("05"); + + private String value; + + ShopperAccountPwChange(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static Optional fromValue(String value) { + return Arrays.stream(ShopperAccountPwChange.values()).filter(shopperAccountPwChange -> { + return shopperAccountPwChange.getValue().equalsIgnoreCase(value); + }).findFirst().map(Optional::of).orElse(Optional.empty()); + } +} diff --git a/src/main/java/com/payxpert/connect2pay/utils/Utils.java b/src/main/java/com/payxpert/connect2pay/utils/Utils.java index 93e9d03..43d6017 100644 --- a/src/main/java/com/payxpert/connect2pay/utils/Utils.java +++ b/src/main/java/com/payxpert/connect2pay/utils/Utils.java @@ -1,5 +1,6 @@ package com.payxpert.connect2pay.utils; +import com.fasterxml.jackson.annotation.JsonInclude; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,6 +18,8 @@ public static ObjectMapper getJSONObjectMapper() { mapper.registerModule(new Connect2payClientJacksonModule()); // Ignore unknown fields, this can ease API changes mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + // Don't serialize absent fields, don't use NON_NULL otherwise empty optional gets included + mapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT); return mapper; } @@ -33,4 +36,12 @@ public static T readJson(String json, Class type) throws Exception { throw e; } } + + public static String limitLength(String value, int length) { + if (value != null && value.length() > length) { + return value.substring(0, length); + } + + return value; + } } diff --git a/src/main/java/com/payxpert/connect2pay/utils/json/Connect2payClientJacksonModule.java b/src/main/java/com/payxpert/connect2pay/utils/json/Connect2payClientJacksonModule.java index e507484..3121745 100644 --- a/src/main/java/com/payxpert/connect2pay/utils/json/Connect2payClientJacksonModule.java +++ b/src/main/java/com/payxpert/connect2pay/utils/json/Connect2payClientJacksonModule.java @@ -1,6 +1,7 @@ package com.payxpert.connect2pay.utils.json; import java.io.IOException; +import java.util.Optional; import java.util.function.Function; import com.fasterxml.jackson.core.JsonGenerator; @@ -14,21 +15,14 @@ import com.fasterxml.jackson.databind.exc.InvalidFormatException; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.StdSerializer; -import com.payxpert.connect2pay.constants.C2PLang; -import com.payxpert.connect2pay.constants.PaymentMode; -import com.payxpert.connect2pay.constants.PaymentMethod; -import com.payxpert.connect2pay.constants.ResultCode; -import com.payxpert.connect2pay.constants.ShippingType; -import com.payxpert.connect2pay.constants.SubscriptionCancelReason; -import com.payxpert.connect2pay.constants.SubscriptionType; -import com.payxpert.connect2pay.constants.TransactionOperation; -import com.payxpert.connect2pay.constants.PaymentStatusValue; +import com.payxpert.connect2pay.constants.*; +import com.payxpert.connect2pay.constants.sca.*; +import com.payxpert.connect2pay.constants.sca.ShippingType; /** * Jackson JSON module for the application. - * + * * @author jsh - * */ public class Connect2payClientJacksonModule extends SimpleModule { private static final long serialVersionUID = -5487183222015832502L; @@ -38,7 +32,7 @@ public Connect2payClientJacksonModule() { this.setupEnum(PaymentMode.class, PaymentMode::getValue, PaymentMode::valueOfFromString); this.setupEnum(PaymentMethod.class, PaymentMethod::getValue, PaymentMethod::valueOfFromString); - this.setupEnum(ShippingType.class, ShippingType::getValue, ShippingType::valueOfFromString); + this.setupEnum(PaymentNetwork.class, PaymentNetwork::getValue, PaymentNetwork::valueOfFromString); this.setupIntEnum(SubscriptionCancelReason.class, // SubscriptionCancelReason::getCode, SubscriptionCancelReason::valueOf); this.setupEnum(SubscriptionType.class, SubscriptionType::getValue, SubscriptionType::valueOfFromString); @@ -47,6 +41,14 @@ public Connect2payClientJacksonModule() { TransactionOperation::valueToString, TransactionOperation::valueOfFromString); this.setupEnum(PaymentStatusValue.class, PaymentStatusValue::getLabel, PaymentStatusValue::valueOfFromLabel); this.setupEnum(C2PLang.class, C2PLang::getValue, C2PLang::valueOfFromString); + this.setupEnumWithOptional(OrderDeliveryDelay.class, OrderDeliveryDelay::getValue, OrderDeliveryDelay::fromValue); + this.setupEnumWithOptional(OrderType.class, OrderType::getValue, OrderType::fromValue); + this.setupEnumWithOptional(PaymentMeanAge.class, PaymentMeanAge::getValue, PaymentMeanAge::fromValue); + this.setupEnumWithOptional(ShippingInfoAge.class, ShippingInfoAge::getValue, ShippingInfoAge::fromValue); + this.setupEnumWithOptional(ShippingType.class, ShippingType::getValue, ShippingType::fromValue); + this.setupEnumWithOptional(ShopperAccountAge.class, ShopperAccountAge::getValue, ShopperAccountAge::fromValue); + this.setupEnumWithOptional(ShopperAccountLastChange.class, ShopperAccountLastChange::getValue, ShopperAccountLastChange::fromValue); + this.setupEnumWithOptional(ShopperAccountPwChange.class, ShopperAccountPwChange::getValue, ShopperAccountPwChange::fromValue); } @Override @@ -59,61 +61,63 @@ public Version version() { return new Version(1, 0, 0, this.getModuleName(), "com.payxpert", "connect2pay-client"); } + private > void setupEnumWithOptional( // + Class enumType, // + Function serializer, // + Function> deserializer) { + this.addEnumStringSerializer(enumType, serializer); + + this.addEnumOptionalStringDeserializer(enumType, deserializer); + } + private > void setupEnum( // - Class enumType, // - Function serializer, // - Function deserializer) { + Class enumType, // + Function serializer, // + Function deserializer) { + this.addEnumStringSerializer(enumType, serializer); + + this.addEnumStringDeserializer(enumType, deserializer); + } + + private > void setupIntEnum( // + Class enumType, // + Function serializer, // + Function deserializer) { + this.addEnumIntSerializer(enumType, serializer); + + this.addEnumIntDeserializer(enumType, deserializer); + } + + private > void addEnumIntSerializer(Class enumType, Function serializer) { this.addSerializer(enumType, new StdSerializer(enumType) { @Override public void serialize(T value, JsonGenerator gen, SerializerProvider provider) throws IOException { - gen.writeString(serializer.apply(value)); - } - }); - this.addDeserializer(enumType, new StdDeserializer(enumType) { - @Override - public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { - if (p.getCurrentToken() == JsonToken.VALUE_STRING) { - T value = deserializer.apply(p.getText()); - if (value == null) { - throw InvalidFormatException.from(p, "Can not deserialize value to enum. Invalid value.", p.getText(), - enumType); - } - return value; - } else { - throw InvalidFormatException.from(p, "Can not deserialize value to enum. Expected VALUE_STRING", p.getText(), - enumType); - } + gen.writeNumber(serializer.apply(value)); } }); } - private > void setupIntEnum( // - Class enumType, // - Function serializer, // - Function deserializer) { + private > void addEnumStringSerializer(Class enumType, Function serializer) { this.addSerializer(enumType, new StdSerializer(enumType) { @Override public void serialize(T value, JsonGenerator gen, SerializerProvider provider) throws IOException { - gen.writeNumber(serializer.apply(value)); + gen.writeString(serializer.apply(value)); } }); + } + + private > void addEnumIntDeserializer(Class enumType, Function deserializer) { this.addDeserializer(enumType, new StdDeserializer(enumType) { @Override public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { - if (p.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) { - return deserializer.apply(p.getIntValue()); - } else if (p.getCurrentToken() == JsonToken.VALUE_STRING) { - try { - return deserializer.apply(Integer.parseInt(p.getText())); } catch (NumberFormatException e) { // handled below } - } throw InvalidFormatException.from(p, @@ -122,4 +126,42 @@ public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOExcepti } }); } + + private > void addEnumStringDeserializer(Class enumType, Function deserializer) { + this.addDeserializer(enumType, new StdDeserializer(enumType) { + @Override + public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + if (p.getCurrentToken() == JsonToken.VALUE_STRING) { + T value = deserializer.apply(p.getText()); + if (value == null) { + throw InvalidFormatException.from(p, "Can not deserialize value to enum. Invalid value.", p.getText(), + enumType); + } + return value; + } else { + throw InvalidFormatException.from(p, "Can not deserialize value to enum. Expected VALUE_STRING", p.getText(), + enumType); + } + } + }); + } + + private > void addEnumOptionalStringDeserializer(Class enumType, Function> deserializer) { + this.addDeserializer(enumType, new StdDeserializer(enumType) { + @Override + public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + if (p.getCurrentToken() == JsonToken.VALUE_STRING) { + T value = deserializer.apply(p.getText()).orElse(null); + if (value == null) { + throw InvalidFormatException.from(p, "Can not deserialize value to enum. Invalid value.", p.getText(), + enumType); + } + return value; + } else { + throw InvalidFormatException.from(p, "Can not deserialize value to enum. Expected VALUE_STRING", p.getText(), + enumType); + } + } + }); + } } \ No newline at end of file