Skip to content

Commit

Permalink
Merge pull request #85 from Adyen/develop
Browse files Browse the repository at this point in the history
Release 1.4.0
  • Loading branch information
lancergr authored Apr 4, 2018
2 parents 50c8a9d + 58f028f commit 7a67e52
Show file tree
Hide file tree
Showing 95 changed files with 5,004 additions and 360 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
*.iml
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Add this dependency to your project's POM:
<dependency>
<groupId>com.adyen</groupId>
<artifactId>adyen-java-api-library</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.adyen</groupId>
<artifactId>adyen-java-api-library</artifactId>
<packaging>jar</packaging>
<version>1.3.0</version>
<version>1.4.0</version>
<name>Adyen Java API Library</name>
<description>Adyen API Client Library for Java</description>
<url>https://github.com/adyen/adyen-java-api-library</url>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/adyen/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class Client {
public static final String RECURRING_API_VERSION = "v25";
public static final String MARKETPAY_API_VERSION = "v3";
public static final String USER_AGENT_SUFFIX = "adyen-java-api-library/";
public static final String LIB_VERSION = "1.3.0";
public static final String LIB_VERSION = "1.4.0";

public Client() {
this.config = new Config();
Expand Down
48 changes: 42 additions & 6 deletions src/main/java/com/adyen/Util/HMACValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,24 @@
*/
package com.adyen.Util;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import static com.adyen.constants.ApiConstants.AdditionalData.HMAC_SIGNATURE;

import com.adyen.model.Amount;
import com.adyen.model.notification.NotificationRequestItem;
import java.nio.charset.Charset;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

public class HMACValidator {
public final static String HMAC_SHA256_ALGORITHM = "HmacSHA256";
public final static Charset C_UTF8 = Charset.forName("UTF8");
public static final String DATA_SEPARATOR = ":";

// To calculate the HMAC SHA-256
public String calculateHMAC(String data, String key) throws java.security.SignatureException {
Expand All @@ -59,8 +63,40 @@ public String calculateHMAC(String data, String key) throws java.security.Signat
}
}

// To calculate the HMAC SHA-256
public String calculateHMAC(NotificationRequestItem notificationRequestItem, String key)
throws SignatureException {
return calculateHMAC(getDataToSign(notificationRequestItem), key);
}

public boolean validateHMAC(NotificationRequestItem notificationRequestItem, String key)
throws SignatureException {

final String expectedSign = calculateHMAC(notificationRequestItem, key);
final String merchantSign = notificationRequestItem.getAdditionalData().get(HMAC_SIGNATURE);

return expectedSign.equals(merchantSign);
}

public String getDataToSign(NotificationRequestItem notificationRequestItem) {
List<String> signedDataList = new ArrayList<>(8);
signedDataList.add(notificationRequestItem.getPspReference());
signedDataList.add(notificationRequestItem.getOriginalReference());
signedDataList.add(notificationRequestItem.getMerchantAccountCode());
signedDataList.add(notificationRequestItem.getMerchantReference());

Amount amount = notificationRequestItem.getAmount();
signedDataList.add(amount.getValue().toString());
signedDataList.add(amount.getCurrency());

signedDataList.add(notificationRequestItem.getEventCode());
signedDataList.add(String.valueOf(notificationRequestItem.isSuccess()));

return Util.implode(DATA_SEPARATOR, signedDataList);
}

public String getDataToSign(SortedMap<String, String> postParameters) {
List<String> parts = new ArrayList<String>();
List<String> parts = new ArrayList<>();

for (String key : postParameters.keySet()) {
parts.add(escapeVal(key));
Expand All @@ -70,10 +106,10 @@ public String getDataToSign(SortedMap<String, String> postParameters) {
parts.add(escapeVal(value));
}

return Util.implode(":", parts);
return Util.implode(DATA_SEPARATOR, parts);
}

private static String escapeVal(String val) {
private String escapeVal(String val) {
if (val == null) {
return "";
}
Expand Down
22 changes: 13 additions & 9 deletions src/main/java/com/adyen/Util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@
*/
package com.adyen.Util;

import com.adyen.model.Amount;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import com.adyen.model.Amount;

public final class Util {
private Util() {
}

/**
* Joins a list of items to a single string using "glue" as separator
* If the item is null, it will add as empty
*
* @param glue separator
* @param list list of elements to be joined
Expand All @@ -47,15 +47,19 @@ public static <T> String implode(String glue, List<T> list) {
return "";
}

Iterator<T> iter = list.iterator();

// init the builder with the first element
// init the builder
StringBuilder sb = new StringBuilder();
sb.append(iter.next());

boolean addGlue = false;
// concat each element
while (iter.hasNext()) {
sb.append(glue).append(iter.next());
for (T item : list) {
if (addGlue) {
sb.append(glue);
} else {
addGlue = true;
}
if (item != null) {
sb.append(item);
}
}

// return result
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/adyen/constants/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,21 @@ interface AdditionalData {
String THREE_D_AUTHENTICATED = "threeDAuthenticated";
String AVS_RESULT = "avsResult";
String PAYMENT_TOKEN = "payment.token";
String FRAUD_RESULT_TYPE = "fraudResultType";
String FRAUD_MANUAL_REVIEW = "fraudManualReview";

String BOLETO_BARCODE_REFERENCE = "boletobancario.barCodeReference";
String BOLETO_DATA = "boletobancario.data";
String BOLETO_DUE_DATE = "boletobancario.dueDate";
String BOLETO_URL = "boletobancario.url";
String BOLETO_EXPIRATION_DATE = "boletobancario.expirationDate";

String ENCRYPTED_CARD_NUMBER = "encryptedCardNumber";
String ENCRYPTED_EXPIRY_MONTH = "encryptedExpiryMonth";
String ENCRYPTED_EXPIRY_YEAR = "encryptedExpiryYear";
String ENCRYPTED_SECURITY_CODE = "encryptedSecurityCode";

String HMAC_SIGNATURE = "hmacSignature";

interface Card {
interface Encrypted {
Expand Down
46 changes: 46 additions & 0 deletions src/main/java/com/adyen/constants/ErrorTypeCodes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Java API Library
*
* Copyright (c) 2018 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/

package com.adyen.constants;

public interface ErrorTypeCodes {
Integer FIELD_MISSING = 1;
Integer EMAIL_INVALID = 2;
Integer COUNTRY_INVALID = 3;
Integer CONTAINS_NUMBERS = 4;
Integer WEB_ADDRESS_INVALID = 5;
Integer INVALID_DATE_FORMAT = 6;
Integer DATE_OUT_OF_RANGE = 7;
Integer BANK_DETAILS_INVALID = 8;
Integer POSTAL_CODE_INVALID = 9;
Integer STATE_CODE_INVALID = 10;
Integer STATE_CODE_UNKNOWN = 11;
Integer PHONE_NUMBER_OBJECT = 12;
Integer PHONE_NUMBER_INVALID = 13;
Integer PHONE_NUMBER_TOO_SHORT = 14;
Integer COUNTRY_NOT_SUPPORTED = 15;
Integer INVALID_CURRENCY = 16;
Integer IBAN_AND_ACCOUNT_NUMBER = 17;
Integer BANK_CODE_UNKNOWN = 18;
Integer TIER_NUMBER_INVALID = 19;
Integer FORBIDDEN_FIELD = 20;
Integer INVALID_ACCOUNT_DESCRIPTION = 21;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Java API Library
*
* Copyright (c) 2017 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/

package com.adyen.deserializer;

import java.lang.reflect.Type;
import com.adyen.model.marketpay.notification.AccountCreatedNotification;
import com.adyen.model.marketpay.notification.AccountHolderCreatedNotification;
import com.adyen.model.marketpay.notification.AccountHolderLimitReachedNotification;
import com.adyen.model.marketpay.notification.AccountHolderPayoutNotification;
import com.adyen.model.marketpay.notification.AccountHolderStatusChangeNotification;
import com.adyen.model.marketpay.notification.AccountHolderUpdatedNotification;
import com.adyen.model.marketpay.notification.AccountHolderVerificationNotification;
import com.adyen.model.marketpay.notification.BeneficiarySetupNotification;
import com.adyen.model.marketpay.notification.CompensateNegativeBalanceNotification;
import com.adyen.model.marketpay.notification.GenericNotification;
import com.adyen.model.marketpay.notification.PaymentFailureNotification;
import com.adyen.model.marketpay.notification.ReportAvailableNotification;
import com.adyen.model.marketpay.notification.ScheduledRefundsNotification;
import com.adyen.model.marketpay.notification.TransferFundsNotification;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;

public class MarketPayNotificationMessageDeserializer implements JsonDeserializer<GenericNotification> {
@Override
public GenericNotification deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObject = jsonElement.getAsJsonObject();

JsonElement jsonType = jsonObject.get("eventType");
String eventType = jsonType.getAsString();

if (GenericNotification.EventTypeEnum.ACCOUNT_CREATED.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, AccountCreatedNotification.class);
}
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_CREATED.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderCreatedNotification.class);
}
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_LIMIT_REACHED.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderLimitReachedNotification.class);
}
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_VERIFICATION.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderVerificationNotification.class);
}
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_STATUS_CHANGE.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderStatusChangeNotification.class);
}
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_PAYOUT.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderPayoutNotification.class);
}
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_UPDATED.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderUpdatedNotification.class);
}
if (GenericNotification.EventTypeEnum.BENEFICIARY_SETUP.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, BeneficiarySetupNotification.class);
}
if (GenericNotification.EventTypeEnum.SCHEDULED_REFUNDS.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, ScheduledRefundsNotification.class);
}
if (GenericNotification.EventTypeEnum.COMPENSATE_NEGATIVE_BALANCE.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, CompensateNegativeBalanceNotification.class);
}
if (GenericNotification.EventTypeEnum.PAYMENT_FAILURE.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, PaymentFailureNotification.class);
}
if (GenericNotification.EventTypeEnum.REPORT_AVAILABLE.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, ReportAvailableNotification.class);
}
if (GenericNotification.EventTypeEnum.TRANSFER_FUNDS.toString().equalsIgnoreCase(eventType)) {
return jsonDeserializationContext.deserialize(jsonElement, TransferFundsNotification.class);
}

return jsonDeserializationContext.deserialize(jsonElement, GenericNotification.class);
}
}
Loading

0 comments on commit 7a67e52

Please sign in to comment.