Skip to content

Commit 7a67e52

Browse files
authored
Merge pull request #85 from Adyen/develop
Release 1.4.0
2 parents 50c8a9d + 58f028f commit 7a67e52

File tree

95 files changed

+5004
-360
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+5004
-360
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.idea
2+
*.iml

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Add this dependency to your project's POM:
2323
<dependency>
2424
<groupId>com.adyen</groupId>
2525
<artifactId>adyen-java-api-library</artifactId>
26-
<version>1.3.0</version>
26+
<version>1.4.0</version>
2727
</dependency>
2828
```
2929

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<groupId>com.adyen</groupId>
55
<artifactId>adyen-java-api-library</artifactId>
66
<packaging>jar</packaging>
7-
<version>1.3.0</version>
7+
<version>1.4.0</version>
88
<name>Adyen Java API Library</name>
99
<description>Adyen API Client Library for Java</description>
1010
<url>https://github.com/adyen/adyen-java-api-library</url>

src/main/java/com/adyen/Client.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class Client {
3838
public static final String RECURRING_API_VERSION = "v25";
3939
public static final String MARKETPAY_API_VERSION = "v3";
4040
public static final String USER_AGENT_SUFFIX = "adyen-java-api-library/";
41-
public static final String LIB_VERSION = "1.3.0";
41+
public static final String LIB_VERSION = "1.4.0";
4242

4343
public Client() {
4444
this.config = new Config();

src/main/java/com/adyen/Util/HMACValidator.java

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,24 @@
2020
*/
2121
package com.adyen.Util;
2222

23-
import javax.crypto.Mac;
24-
import javax.crypto.spec.SecretKeySpec;
23+
import static com.adyen.constants.ApiConstants.AdditionalData.HMAC_SIGNATURE;
24+
25+
import com.adyen.model.Amount;
26+
import com.adyen.model.notification.NotificationRequestItem;
2527
import java.nio.charset.Charset;
2628
import java.security.SignatureException;
2729
import java.util.ArrayList;
2830
import java.util.List;
2931
import java.util.SortedMap;
30-
32+
import javax.crypto.Mac;
33+
import javax.crypto.spec.SecretKeySpec;
3134
import org.apache.commons.codec.binary.Base64;
3235
import org.apache.commons.codec.binary.Hex;
3336

3437
public class HMACValidator {
3538
public final static String HMAC_SHA256_ALGORITHM = "HmacSHA256";
3639
public final static Charset C_UTF8 = Charset.forName("UTF8");
40+
public static final String DATA_SEPARATOR = ":";
3741

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

66+
// To calculate the HMAC SHA-256
67+
public String calculateHMAC(NotificationRequestItem notificationRequestItem, String key)
68+
throws SignatureException {
69+
return calculateHMAC(getDataToSign(notificationRequestItem), key);
70+
}
71+
72+
public boolean validateHMAC(NotificationRequestItem notificationRequestItem, String key)
73+
throws SignatureException {
74+
75+
final String expectedSign = calculateHMAC(notificationRequestItem, key);
76+
final String merchantSign = notificationRequestItem.getAdditionalData().get(HMAC_SIGNATURE);
77+
78+
return expectedSign.equals(merchantSign);
79+
}
80+
81+
public String getDataToSign(NotificationRequestItem notificationRequestItem) {
82+
List<String> signedDataList = new ArrayList<>(8);
83+
signedDataList.add(notificationRequestItem.getPspReference());
84+
signedDataList.add(notificationRequestItem.getOriginalReference());
85+
signedDataList.add(notificationRequestItem.getMerchantAccountCode());
86+
signedDataList.add(notificationRequestItem.getMerchantReference());
87+
88+
Amount amount = notificationRequestItem.getAmount();
89+
signedDataList.add(amount.getValue().toString());
90+
signedDataList.add(amount.getCurrency());
91+
92+
signedDataList.add(notificationRequestItem.getEventCode());
93+
signedDataList.add(String.valueOf(notificationRequestItem.isSuccess()));
94+
95+
return Util.implode(DATA_SEPARATOR, signedDataList);
96+
}
97+
6298
public String getDataToSign(SortedMap<String, String> postParameters) {
63-
List<String> parts = new ArrayList<String>();
99+
List<String> parts = new ArrayList<>();
64100

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

73-
return Util.implode(":", parts);
109+
return Util.implode(DATA_SEPARATOR, parts);
74110
}
75111

76-
private static String escapeVal(String val) {
112+
private String escapeVal(String val) {
77113
if (val == null) {
78114
return "";
79115
}

src/main/java/com/adyen/Util/Util.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,21 @@
2020
*/
2121
package com.adyen.Util;
2222

23+
import com.adyen.model.Amount;
2324
import java.math.BigDecimal;
2425
import java.math.RoundingMode;
2526
import java.text.SimpleDateFormat;
2627
import java.util.Calendar;
2728
import java.util.Date;
28-
import java.util.Iterator;
2929
import java.util.List;
30-
import com.adyen.model.Amount;
3130

3231
public final class Util {
3332
private Util() {
3433
}
3534

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

50-
Iterator<T> iter = list.iterator();
51-
52-
// init the builder with the first element
50+
// init the builder
5351
StringBuilder sb = new StringBuilder();
54-
sb.append(iter.next());
55-
52+
boolean addGlue = false;
5653
// concat each element
57-
while (iter.hasNext()) {
58-
sb.append(glue).append(iter.next());
54+
for (T item : list) {
55+
if (addGlue) {
56+
sb.append(glue);
57+
} else {
58+
addGlue = true;
59+
}
60+
if (item != null) {
61+
sb.append(item);
62+
}
5963
}
6064

6165
// return result

src/main/java/com/adyen/constants/ApiConstants.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,21 @@ interface AdditionalData {
4343
String THREE_D_AUTHENTICATED = "threeDAuthenticated";
4444
String AVS_RESULT = "avsResult";
4545
String PAYMENT_TOKEN = "payment.token";
46+
String FRAUD_RESULT_TYPE = "fraudResultType";
47+
String FRAUD_MANUAL_REVIEW = "fraudManualReview";
4648

4749
String BOLETO_BARCODE_REFERENCE = "boletobancario.barCodeReference";
4850
String BOLETO_DATA = "boletobancario.data";
4951
String BOLETO_DUE_DATE = "boletobancario.dueDate";
5052
String BOLETO_URL = "boletobancario.url";
5153
String BOLETO_EXPIRATION_DATE = "boletobancario.expirationDate";
5254

55+
String ENCRYPTED_CARD_NUMBER = "encryptedCardNumber";
56+
String ENCRYPTED_EXPIRY_MONTH = "encryptedExpiryMonth";
57+
String ENCRYPTED_EXPIRY_YEAR = "encryptedExpiryYear";
58+
String ENCRYPTED_SECURITY_CODE = "encryptedSecurityCode";
59+
60+
String HMAC_SIGNATURE = "hmacSignature";
5361

5462
interface Card {
5563
interface Encrypted {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* ######
3+
* ######
4+
* ############ ####( ###### #####. ###### ############ ############
5+
* ############# #####( ###### #####. ###### ############# #############
6+
* ###### #####( ###### #####. ###### ##### ###### ##### ######
7+
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
8+
* ###### ###### #####( ###### #####. ###### ##### ##### ######
9+
* ############# ############# ############# ############# ##### ######
10+
* ############ ############ ############# ############ ##### ######
11+
* ######
12+
* #############
13+
* ############
14+
*
15+
* Adyen Java API Library
16+
*
17+
* Copyright (c) 2018 Adyen B.V.
18+
* This file is open source and available under the MIT license.
19+
* See the LICENSE file for more info.
20+
*/
21+
22+
package com.adyen.constants;
23+
24+
public interface ErrorTypeCodes {
25+
Integer FIELD_MISSING = 1;
26+
Integer EMAIL_INVALID = 2;
27+
Integer COUNTRY_INVALID = 3;
28+
Integer CONTAINS_NUMBERS = 4;
29+
Integer WEB_ADDRESS_INVALID = 5;
30+
Integer INVALID_DATE_FORMAT = 6;
31+
Integer DATE_OUT_OF_RANGE = 7;
32+
Integer BANK_DETAILS_INVALID = 8;
33+
Integer POSTAL_CODE_INVALID = 9;
34+
Integer STATE_CODE_INVALID = 10;
35+
Integer STATE_CODE_UNKNOWN = 11;
36+
Integer PHONE_NUMBER_OBJECT = 12;
37+
Integer PHONE_NUMBER_INVALID = 13;
38+
Integer PHONE_NUMBER_TOO_SHORT = 14;
39+
Integer COUNTRY_NOT_SUPPORTED = 15;
40+
Integer INVALID_CURRENCY = 16;
41+
Integer IBAN_AND_ACCOUNT_NUMBER = 17;
42+
Integer BANK_CODE_UNKNOWN = 18;
43+
Integer TIER_NUMBER_INVALID = 19;
44+
Integer FORBIDDEN_FIELD = 20;
45+
Integer INVALID_ACCOUNT_DESCRIPTION = 21;
46+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* ######
3+
* ######
4+
* ############ ####( ###### #####. ###### ############ ############
5+
* ############# #####( ###### #####. ###### ############# #############
6+
* ###### #####( ###### #####. ###### ##### ###### ##### ######
7+
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
8+
* ###### ###### #####( ###### #####. ###### ##### ##### ######
9+
* ############# ############# ############# ############# ##### ######
10+
* ############ ############ ############# ############ ##### ######
11+
* ######
12+
* #############
13+
* ############
14+
*
15+
* Adyen Java API Library
16+
*
17+
* Copyright (c) 2017 Adyen B.V.
18+
* This file is open source and available under the MIT license.
19+
* See the LICENSE file for more info.
20+
*/
21+
22+
package com.adyen.deserializer;
23+
24+
import java.lang.reflect.Type;
25+
import com.adyen.model.marketpay.notification.AccountCreatedNotification;
26+
import com.adyen.model.marketpay.notification.AccountHolderCreatedNotification;
27+
import com.adyen.model.marketpay.notification.AccountHolderLimitReachedNotification;
28+
import com.adyen.model.marketpay.notification.AccountHolderPayoutNotification;
29+
import com.adyen.model.marketpay.notification.AccountHolderStatusChangeNotification;
30+
import com.adyen.model.marketpay.notification.AccountHolderUpdatedNotification;
31+
import com.adyen.model.marketpay.notification.AccountHolderVerificationNotification;
32+
import com.adyen.model.marketpay.notification.BeneficiarySetupNotification;
33+
import com.adyen.model.marketpay.notification.CompensateNegativeBalanceNotification;
34+
import com.adyen.model.marketpay.notification.GenericNotification;
35+
import com.adyen.model.marketpay.notification.PaymentFailureNotification;
36+
import com.adyen.model.marketpay.notification.ReportAvailableNotification;
37+
import com.adyen.model.marketpay.notification.ScheduledRefundsNotification;
38+
import com.adyen.model.marketpay.notification.TransferFundsNotification;
39+
import com.google.gson.JsonDeserializationContext;
40+
import com.google.gson.JsonDeserializer;
41+
import com.google.gson.JsonElement;
42+
import com.google.gson.JsonObject;
43+
import com.google.gson.JsonParseException;
44+
45+
public class MarketPayNotificationMessageDeserializer implements JsonDeserializer<GenericNotification> {
46+
@Override
47+
public GenericNotification deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
48+
JsonObject jsonObject = jsonElement.getAsJsonObject();
49+
50+
JsonElement jsonType = jsonObject.get("eventType");
51+
String eventType = jsonType.getAsString();
52+
53+
if (GenericNotification.EventTypeEnum.ACCOUNT_CREATED.toString().equalsIgnoreCase(eventType)) {
54+
return jsonDeserializationContext.deserialize(jsonElement, AccountCreatedNotification.class);
55+
}
56+
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_CREATED.toString().equalsIgnoreCase(eventType)) {
57+
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderCreatedNotification.class);
58+
}
59+
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_LIMIT_REACHED.toString().equalsIgnoreCase(eventType)) {
60+
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderLimitReachedNotification.class);
61+
}
62+
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_VERIFICATION.toString().equalsIgnoreCase(eventType)) {
63+
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderVerificationNotification.class);
64+
}
65+
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_STATUS_CHANGE.toString().equalsIgnoreCase(eventType)) {
66+
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderStatusChangeNotification.class);
67+
}
68+
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_PAYOUT.toString().equalsIgnoreCase(eventType)) {
69+
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderPayoutNotification.class);
70+
}
71+
if (GenericNotification.EventTypeEnum.ACCOUNT_HOLDER_UPDATED.toString().equalsIgnoreCase(eventType)) {
72+
return jsonDeserializationContext.deserialize(jsonElement, AccountHolderUpdatedNotification.class);
73+
}
74+
if (GenericNotification.EventTypeEnum.BENEFICIARY_SETUP.toString().equalsIgnoreCase(eventType)) {
75+
return jsonDeserializationContext.deserialize(jsonElement, BeneficiarySetupNotification.class);
76+
}
77+
if (GenericNotification.EventTypeEnum.SCHEDULED_REFUNDS.toString().equalsIgnoreCase(eventType)) {
78+
return jsonDeserializationContext.deserialize(jsonElement, ScheduledRefundsNotification.class);
79+
}
80+
if (GenericNotification.EventTypeEnum.COMPENSATE_NEGATIVE_BALANCE.toString().equalsIgnoreCase(eventType)) {
81+
return jsonDeserializationContext.deserialize(jsonElement, CompensateNegativeBalanceNotification.class);
82+
}
83+
if (GenericNotification.EventTypeEnum.PAYMENT_FAILURE.toString().equalsIgnoreCase(eventType)) {
84+
return jsonDeserializationContext.deserialize(jsonElement, PaymentFailureNotification.class);
85+
}
86+
if (GenericNotification.EventTypeEnum.REPORT_AVAILABLE.toString().equalsIgnoreCase(eventType)) {
87+
return jsonDeserializationContext.deserialize(jsonElement, ReportAvailableNotification.class);
88+
}
89+
if (GenericNotification.EventTypeEnum.TRANSFER_FUNDS.toString().equalsIgnoreCase(eventType)) {
90+
return jsonDeserializationContext.deserialize(jsonElement, TransferFundsNotification.class);
91+
}
92+
93+
return jsonDeserializationContext.deserialize(jsonElement, GenericNotification.class);
94+
}
95+
}

0 commit comments

Comments
 (0)