diff --git a/src/main/java/com/adyen/Util/DateUtil.java b/src/main/java/com/adyen/Util/DateUtil.java index 3e25f374c..929508f1b 100644 --- a/src/main/java/com/adyen/Util/DateUtil.java +++ b/src/main/java/com/adyen/Util/DateUtil.java @@ -28,13 +28,13 @@ public final class DateUtil { private DateUtil() { } - public static Date parseYmdDate(String dateString) { + public static Date parseDateToFormat(String dateString, String format) { if (dateString == null) { return null; } Date date; - SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat fmt = new SimpleDateFormat(format); try { date = fmt.parse(dateString); } catch (ParseException e) { @@ -43,4 +43,12 @@ public static Date parseYmdDate(String dateString) { return date; } + + public static Date parseYmdDate(String dateString) { + return parseDateToFormat(dateString, "yyyy-MM-dd"); + } + + public static Date parseMYDate(String dateString) { + return parseDateToFormat(dateString, "M/yyyy"); + } } diff --git a/src/main/java/com/adyen/constants/ApiConstants.java b/src/main/java/com/adyen/constants/ApiConstants.java index 8b270e7a4..4502565d3 100644 --- a/src/main/java/com/adyen/constants/ApiConstants.java +++ b/src/main/java/com/adyen/constants/ApiConstants.java @@ -45,6 +45,7 @@ interface AdditionalData { String PAYMENT_TOKEN = "payment.token"; String FRAUD_RESULT_TYPE = "fraudResultType"; String FRAUD_MANUAL_REVIEW = "fraudManualReview"; + String AUTH_CODE = "authCode"; String BOLETO_BARCODE_REFERENCE = "boletobancario.barCodeReference"; String BOLETO_DATA = "boletobancario.data"; @@ -69,4 +70,25 @@ interface Encrypted { interface SelectedBrand { String BOLETO_SANTANDER = "boletobancario_santander"; } + + interface PaymentMethod { + String ENCRYPTED_CARD_NUMBER = "encryptedCardNumber"; + String ENCRYPTED_EXPIRY_MONTH = "encryptedExpiryMonth"; + String ENCRYPTED_EXPIRY_YEAR = "encryptedExpiryYear"; + String ENCRYPTED_SECURITY_CODE = "encryptedSecurityCode"; + String METHOD_TYPE = "type"; + String HOLDER_NAME = "holderName"; + String RECURRING_DETAIL_REFERENCE = "recurringDetailReference"; + } + + interface Redirect { + interface Data { + String MD = "MD"; + String PAREQ = "PaReq"; + } + } + + interface PaymentMethodType { + String TYPE_SCHEME = "scheme"; + } } diff --git a/src/main/java/com/adyen/httpclient/HttpURLConnectionClient.java b/src/main/java/com/adyen/httpclient/HttpURLConnectionClient.java index 37b22ee96..abd256e77 100644 --- a/src/main/java/com/adyen/httpclient/HttpURLConnectionClient.java +++ b/src/main/java/com/adyen/httpclient/HttpURLConnectionClient.java @@ -55,8 +55,10 @@ public String request(String requestUrl, String requestBody, Config config) thro @Override public String request(String requestUrl, String requestBody, Config config, boolean isApiKeyRequired) throws IOException, HTTPClientException { HttpURLConnection httpConnection = createRequest(requestUrl, config.getApplicationName()); - if (isApiKeyRequired) { - setApiKey(httpConnection, config.getApiKey()); + String apiKey = config.getApiKey(); + // Use Api key if required or if provided + if (isApiKeyRequired || (apiKey != null && !apiKey.isEmpty())) { + setApiKey(httpConnection, apiKey); } else { setBasicAuthentication(httpConnection, config.getUsername(), config.getPassword()); } diff --git a/src/main/java/com/adyen/model/PaymentResult.java b/src/main/java/com/adyen/model/PaymentResult.java index 84fa3346f..863b2465f 100644 --- a/src/main/java/com/adyen/model/PaymentResult.java +++ b/src/main/java/com/adyen/model/PaymentResult.java @@ -398,19 +398,7 @@ public String getAdditionalDataByKey(String key) { public Date getExpiryDate() { String expiryDate = getAdditionalDataByKey(EXPIRY_DATE); - if (expiryDate == null) { - return null; - } - - Date date; - SimpleDateFormat monthYear = new SimpleDateFormat("M/yyyy"); - try { - date = monthYear.parse(expiryDate); - } catch (ParseException e) { - return null; - } - - return date; + return DateUtil.parseMYDate(expiryDate); } public String getCardBin() { diff --git a/src/main/java/com/adyen/model/checkout/PaymentsRequest.java b/src/main/java/com/adyen/model/checkout/PaymentsRequest.java index 6a2477659..99b5d47a4 100755 --- a/src/main/java/com/adyen/model/checkout/PaymentsRequest.java +++ b/src/main/java/com/adyen/model/checkout/PaymentsRequest.java @@ -22,6 +22,7 @@ package com.adyen.model.checkout; +import com.adyen.Util.Util; import com.adyen.model.*; import com.google.gson.TypeAdapter; import com.google.gson.annotations.JsonAdapter; @@ -31,6 +32,14 @@ import java.io.IOException; import java.util.*; +import static com.adyen.constants.ApiConstants.PaymentMethod.ENCRYPTED_CARD_NUMBER; +import static com.adyen.constants.ApiConstants.PaymentMethod.ENCRYPTED_EXPIRY_MONTH; +import static com.adyen.constants.ApiConstants.PaymentMethod.ENCRYPTED_EXPIRY_YEAR; +import static com.adyen.constants.ApiConstants.PaymentMethod.ENCRYPTED_SECURITY_CODE; +import static com.adyen.constants.ApiConstants.PaymentMethod.HOLDER_NAME; +import static com.adyen.constants.ApiConstants.PaymentMethod.METHOD_TYPE; +import static com.adyen.constants.ApiConstants.PaymentMethod.RECURRING_DETAIL_REFERENCE; +import static com.adyen.constants.ApiConstants.PaymentMethodType.TYPE_SCHEME; /** * PaymentsRequest @@ -112,6 +121,8 @@ public class PaymentsRequest { private String socialSecurityNumber = null; @SerializedName("telephoneNumber") private String telephoneNumber = null; + @SerializedName("browserInfo") + private BrowserInfo browserInfo = null; public PaymentsRequest additionalData(Map additionalData) { this.additionalData = additionalData; @@ -129,7 +140,8 @@ public PaymentsRequest putAdditionalDataItem(String key, String additionalDataIt } /** - * This field contains additional data, which may be required for a particular payment request. The `additionalData` object consists of entries, each of which includes the key and value. For more information on possible key-value pairs, refer to the [additionalData section](https://docs.adyen.com/developers/api-reference/payments-api#paymentrequestadditionaldata). + * This field contains additional data, which may be required for a particular payment request. The `additionalData` object consists of entries, each of which includes the key and + * value. For more information on possible key-value pairs, refer to the [additionalData section](https://docs.adyen.com/developers/api-reference/payments-api#paymentrequestadditionaldata). * * @return additionalData **/ @@ -159,6 +171,12 @@ public void setAmount(Amount amount) { this.amount = amount; } + public PaymentsRequest setAmountData(String amount, String currency) { + Amount amountData = Util.createAmount(amount, currency); + this.setAmount(amountData); + return this; + } + public PaymentsRequest billingAddress(Address billingAddress) { this.billingAddress = billingAddress; return this; @@ -201,7 +219,8 @@ public PaymentsRequest channel(ChannelEnum channel) { } /** - * The platform where a payment transaction takes place. This field is optional for filtering out payment methods that are only available on specific platforms. If this value is not set, then we will try to infer it from the `sdkVersion` or token. Possible values: * iOS * Android * Web + * The platform where a payment transaction takes place. This field is optional for filtering out payment methods that are only available on specific platforms. If this value is not set, then we + * will try to infer it from the `sdkVersion` or token. Possible values: * iOS * Android * Web * * @return channel **/ @@ -465,7 +484,8 @@ public PaymentsRequest mcc(String mcc) { } /** - * The [merchant category code](https://en.wikipedia.org/wiki/Merchant_category_code) (MCC) is a four-digit number, which relates to a particular market segment. This code reflects the predominant activity that is conducted by the merchant. + * The [merchant category code](https://en.wikipedia.org/wiki/Merchant_category_code) (MCC) is a four-digit number, which relates to a particular market segment. This code reflects the predominant + * activity that is conducted by the merchant. * * @return mcc **/ @@ -501,7 +521,8 @@ public PaymentsRequest merchantOrderReference(String merchantOrderReference) { } /** - * This reference allows linking multiple transactions to each other. > When providing the `merchantOrderReference` value, we also recommend you submit `retry.orderAttemptNumber`, `retry.chainAttemptNumber`, and `retry.skipRetry` values. + * This reference allows linking multiple transactions to each other. > When providing the `merchantOrderReference` value, we also recommend you submit + * `retry.orderAttemptNumber`, `retry.chainAttemptNumber`, and `retry.skipRetry` values. * * @return merchantOrderReference **/ @@ -583,13 +604,38 @@ public void setPaymentMethod(Map paymentMethod) { this.paymentMethod = paymentMethod; } + public PaymentsRequest addEncryptedCardData(String encryptedCardNumber, String encryptedExpiryMonth, String encryptedExpiryYear, String encryptedSecurityCode, String holderName) { + this.paymentMethod = new HashMap<>(); + this.paymentMethod.put(METHOD_TYPE, TYPE_SCHEME); + this.paymentMethod.put(ENCRYPTED_CARD_NUMBER, encryptedCardNumber); + this.paymentMethod.put(ENCRYPTED_EXPIRY_MONTH, encryptedExpiryMonth); + this.paymentMethod.put(ENCRYPTED_EXPIRY_YEAR, encryptedExpiryYear); + if (encryptedSecurityCode != null) { + this.paymentMethod.put(ENCRYPTED_SECURITY_CODE, encryptedSecurityCode); + } + if (holderName != null) { + this.paymentMethod.put(HOLDER_NAME, holderName); + } + + return this; + } + + public PaymentsRequest addOneClickData(String recurringDetailReference, String encryptedSecurityCode) { + this.paymentMethod = new HashMap<>(); + this.paymentMethod.put(METHOD_TYPE, TYPE_SCHEME); + this.paymentMethod.put(RECURRING_DETAIL_REFERENCE, recurringDetailReference); + this.paymentMethod.put(ENCRYPTED_SECURITY_CODE, encryptedSecurityCode); + return this; + } + public PaymentsRequest reference(String reference) { this.reference = reference; return this; } /** - * The reference to uniquely identify a payment. This reference is used in all communication with you about the payment status. We recommend using a unique value per payment; however, it is not a requirement. If you need to provide multiple references for a transaction, separate them with hyphens (\"-\"). Maximum length: 80 characters. + * The reference to uniquely identify a payment. This reference is used in all communication with you about the payment status. We recommend using a unique value per payment; however, it is not a + * requirement. If you need to provide multiple references for a transaction, separate them with hyphens (\"-\"). Maximum length: 80 characters. * * @return reference **/ @@ -661,7 +707,8 @@ public PaymentsRequest shopperIP(String shopperIP) { } /** - * The shopper's IP address. We recommend that you provide this data, as it is used in a number of risk checks (for instance, number of payment attempts or location-based checks). > This field is mandatory for some merchants depending on your business model. For more information, [contact Support](https://support.adyen.com/hc/en-us/requests/new). + * The shopper's IP address. We recommend that you provide this data, as it is used in a number of risk checks (for instance, number of payment attempts or location-based checks). > This + * field is mandatory for some merchants depending on your business model. For more information, [contact Support](https://support.adyen.com/hc/en-us/requests/new). * * @return shopperIP **/ @@ -679,7 +726,12 @@ public PaymentsRequest shopperInteraction(ShopperInteractionEnum shopperInteract } /** - * Specifies the sales channel, through which the shopper gives their card details, and whether the shopper is a returning customer. For the web service API, Adyen assumes Ecommerce shopper interaction by default. This field has the following possible values: * `Ecommerce` - Online transactions where the cardholder is present (online). For better authorisation rates, we recommend sending the card security code (CSC) along with the request. * `ContAuth` - Card on file and/or subscription transactions, where the cardholder is known to the merchant (returning customer). If the shopper is present (online), you can supply also the CSC to improve authorisation (one-click payment). * `Moto` - Mail-order and telephone-order transactions where the shopper is in contact with the merchant via email or telephone. * `POS` - Point-of-sale transactions where the shopper is physically present to make a payment using a secure payment terminal. + * Specifies the sales channel, through which the shopper gives their card details, and whether the shopper is a returning customer. For the web service API, Adyen assumes Ecommerce shopper + * interaction by default. This field has the following possible values: * `Ecommerce` - Online transactions where the cardholder is present (online). For better authorisation rates, we + * recommend sending the card security code (CSC) along with the request. * `ContAuth` - Card on file and/or subscription transactions, where the cardholder is known to the merchant + * (returning customer). If the shopper is present (online), you can supply also the CSC to improve authorisation (one-click payment). * `Moto` - Mail-order and telephone-order + * transactions where the shopper is in contact with the merchant via email or telephone. * `POS` - Point-of-sale transactions where the shopper is physically present to make a payment + * using a secure payment terminal. * * @return shopperInteraction **/ @@ -799,6 +851,28 @@ public void setTelephoneNumber(String telephoneNumber) { this.telephoneNumber = telephoneNumber; } + public BrowserInfo getBrowserInfo() { + return browserInfo; + } + + public void setBrowserInfo(BrowserInfo browserInfo) { + this.browserInfo = browserInfo; + } + + public PaymentsRequest browserInfo(BrowserInfo browserInfo) { + this.browserInfo = browserInfo; + return this; + } + + public PaymentsRequest addBrowserInfoData(String userAgent, String acceptHeader) { + BrowserInfo browserInfo = new BrowserInfo(); + browserInfo.setAcceptHeader(acceptHeader); + browserInfo.setUserAgent(userAgent); + + this.setBrowserInfo(browserInfo); + return this; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -808,47 +882,83 @@ public boolean equals(Object o) { return false; } PaymentsRequest paymentsRequest = (PaymentsRequest) o; - return Objects.equals(this.additionalData, paymentsRequest.additionalData) && - Objects.equals(this.amount, paymentsRequest.amount) && - Objects.equals(this.billingAddress, paymentsRequest.billingAddress) && - Objects.equals(this.captureDelayHours, paymentsRequest.captureDelayHours) && - Objects.equals(this.channel, paymentsRequest.channel) && - Objects.equals(this.company, paymentsRequest.company) && - Objects.equals(this.countryCode, paymentsRequest.countryCode) && - Objects.equals(this.dateOfBirth, paymentsRequest.dateOfBirth) && - Objects.equals(this.dccQuote, paymentsRequest.dccQuote) && - Objects.equals(this.deliveryAddress, paymentsRequest.deliveryAddress) && - Objects.equals(this.deliveryDate, paymentsRequest.deliveryDate) && - Objects.equals(this.enableOneClick, paymentsRequest.enableOneClick) && - Objects.equals(this.enablePayOut, paymentsRequest.enablePayOut) && - Objects.equals(this.enableRecurring, paymentsRequest.enableRecurring) && - Objects.equals(this.entityType, paymentsRequest.entityType) && - Objects.equals(this.fraudOffset, paymentsRequest.fraudOffset) && - Objects.equals(this.installments, paymentsRequest.installments) && - Objects.equals(this.lineItems, paymentsRequest.lineItems) && - Objects.equals(this.mcc, paymentsRequest.mcc) && - Objects.equals(this.merchantAccount, paymentsRequest.merchantAccount) && - Objects.equals(this.merchantOrderReference, paymentsRequest.merchantOrderReference) && - Objects.equals(this.metadata, paymentsRequest.metadata) && - Objects.equals(this.orderReference, paymentsRequest.orderReference) && - Objects.equals(this.paymentMethod, paymentsRequest.paymentMethod) && - Objects.equals(this.reference, paymentsRequest.reference) && - Objects.equals(this.returnUrl, paymentsRequest.returnUrl) && - Objects.equals(this.sessionValidity, paymentsRequest.sessionValidity) && - Objects.equals(this.shopperEmail, paymentsRequest.shopperEmail) && - Objects.equals(this.shopperIP, paymentsRequest.shopperIP) && - Objects.equals(this.shopperInteraction, paymentsRequest.shopperInteraction) && - Objects.equals(this.shopperLocale, paymentsRequest.shopperLocale) && - Objects.equals(this.shopperName, paymentsRequest.shopperName) && - Objects.equals(this.shopperReference, paymentsRequest.shopperReference) && - Objects.equals(this.shopperStatement, paymentsRequest.shopperStatement) && - Objects.equals(this.socialSecurityNumber, paymentsRequest.socialSecurityNumber) && - Objects.equals(this.telephoneNumber, paymentsRequest.telephoneNumber); + return Objects.equals(this.additionalData, paymentsRequest.additionalData) + && Objects.equals(this.amount, paymentsRequest.amount) + && Objects.equals(this.billingAddress, + paymentsRequest.billingAddress) + && Objects.equals(this.captureDelayHours, paymentsRequest.captureDelayHours) + && Objects.equals(this.channel, paymentsRequest.channel) + && Objects.equals(this.company, paymentsRequest.company) + && Objects.equals(this.countryCode, paymentsRequest.countryCode) + && Objects.equals(this.dateOfBirth, paymentsRequest.dateOfBirth) + && Objects.equals(this.dccQuote, paymentsRequest.dccQuote) + && Objects.equals(this.deliveryAddress, paymentsRequest.deliveryAddress) + && Objects.equals(this.deliveryDate, paymentsRequest.deliveryDate) + && Objects.equals(this.enableOneClick, paymentsRequest.enableOneClick) + && Objects.equals(this.enablePayOut, paymentsRequest.enablePayOut) + && Objects.equals(this.enableRecurring, paymentsRequest.enableRecurring) + && Objects.equals(this.entityType, paymentsRequest.entityType) + && Objects.equals(this.fraudOffset, paymentsRequest.fraudOffset) + && Objects.equals(this.installments, paymentsRequest.installments) + && Objects.equals(this.lineItems, paymentsRequest.lineItems) + && Objects.equals(this.mcc, paymentsRequest.mcc) + && Objects.equals(this.merchantAccount, paymentsRequest.merchantAccount) + && Objects.equals(this.merchantOrderReference, paymentsRequest.merchantOrderReference) + && Objects.equals(this.metadata, paymentsRequest.metadata) + && Objects.equals(this.orderReference, paymentsRequest.orderReference) + && Objects.equals(this.paymentMethod, paymentsRequest.paymentMethod) + && Objects.equals(this.reference, paymentsRequest.reference) + && Objects.equals(this.returnUrl, paymentsRequest.returnUrl) + && Objects.equals(this.sessionValidity, paymentsRequest.sessionValidity) + && Objects.equals(this.shopperEmail, paymentsRequest.shopperEmail) + && Objects.equals(this.shopperIP, paymentsRequest.shopperIP) + && Objects.equals(this.shopperInteraction, paymentsRequest.shopperInteraction) + && Objects.equals(this.shopperLocale, paymentsRequest.shopperLocale) + && Objects.equals(this.shopperName, paymentsRequest.shopperName) + && Objects.equals(this.shopperReference, paymentsRequest.shopperReference) + && Objects.equals(this.shopperStatement, paymentsRequest.shopperStatement) + && Objects.equals(this.socialSecurityNumber, paymentsRequest.socialSecurityNumber) + && Objects.equals(this.telephoneNumber, paymentsRequest.telephoneNumber); } @Override public int hashCode() { - return Objects.hash(additionalData, amount, billingAddress, captureDelayHours, channel, company, countryCode, dateOfBirth, dccQuote, deliveryAddress, deliveryDate, enableOneClick, enablePayOut, enableRecurring, entityType, fraudOffset, installments, lineItems, mcc, merchantAccount, merchantOrderReference, metadata, orderReference, paymentMethod, reference, returnUrl, sessionValidity, shopperEmail, shopperIP, shopperInteraction, shopperLocale, shopperName, shopperReference, shopperStatement, socialSecurityNumber, telephoneNumber); + return Objects.hash(additionalData, + amount, + billingAddress, + captureDelayHours, + channel, + company, + countryCode, + dateOfBirth, + dccQuote, + deliveryAddress, + deliveryDate, + enableOneClick, + enablePayOut, + enableRecurring, + entityType, + fraudOffset, + installments, + lineItems, + mcc, + merchantAccount, + merchantOrderReference, + metadata, + orderReference, + paymentMethod, + reference, + returnUrl, + sessionValidity, + shopperEmail, + shopperIP, + shopperInteraction, + shopperLocale, + shopperName, + shopperReference, + shopperStatement, + socialSecurityNumber, + telephoneNumber); } @Override @@ -908,7 +1018,8 @@ private String toIndentedString(Object o) { } /** - * The platform where a payment transaction takes place. This field is optional for filtering out payment methods that are only available on specific platforms. If this value is not set, then we will try to infer it from the `sdkVersion` or token. Possible values: * iOS * Android * Web + * The platform where a payment transaction takes place. This field is optional for filtering out payment methods that are only available on specific platforms. If this value is not set, then we + * will try to infer it from the `sdkVersion` or token. Possible values: * iOS * Android * Web */ @JsonAdapter(ChannelEnum.Adapter.class) public enum ChannelEnum { @@ -1003,7 +1114,12 @@ public EntityTypeEnum read(final JsonReader jsonReader) throws IOException { } /** - * Specifies the sales channel, through which the shopper gives their card details, and whether the shopper is a returning customer. For the web service API, Adyen assumes Ecommerce shopper interaction by default. This field has the following possible values: * `Ecommerce` - Online transactions where the cardholder is present (online). For better authorisation rates, we recommend sending the card security code (CSC) along with the request. * `ContAuth` - Card on file and/or subscription transactions, where the cardholder is known to the merchant (returning customer). If the shopper is present (online), you can supply also the CSC to improve authorisation (one-click payment). * `Moto` - Mail-order and telephone-order transactions where the shopper is in contact with the merchant via email or telephone. * `POS` - Point-of-sale transactions where the shopper is physically present to make a payment using a secure payment terminal. + * Specifies the sales channel, through which the shopper gives their card details, and whether the shopper is a returning customer. For the web service API, Adyen assumes Ecommerce shopper + * interaction by default. This field has the following possible values: * `Ecommerce` - Online transactions where the cardholder is present (online). For better authorisation rates, we + * recommend sending the card security code (CSC) along with the request. * `ContAuth` - Card on file and/or subscription transactions, where the cardholder is known to the merchant + * (returning customer). If the shopper is present (online), you can supply also the CSC to improve authorisation (one-click payment). * `Moto` - Mail-order and telephone-order + * transactions where the shopper is in contact with the merchant via email or telephone. * `POS` - Point-of-sale transactions where the shopper is physically present to make a payment + * using a secure payment terminal. */ @JsonAdapter(ShopperInteractionEnum.Adapter.class) public enum ShopperInteractionEnum { diff --git a/src/main/java/com/adyen/model/checkout/PaymentsResponse.java b/src/main/java/com/adyen/model/checkout/PaymentsResponse.java index 3932c3d66..83a7c3545 100755 --- a/src/main/java/com/adyen/model/checkout/PaymentsResponse.java +++ b/src/main/java/com/adyen/model/checkout/PaymentsResponse.java @@ -21,18 +21,36 @@ package com.adyen.model.checkout; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import com.adyen.Util.DateUtil; import com.adyen.model.FraudResult; import com.google.gson.TypeAdapter; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import static com.adyen.constants.ApiConstants.AdditionalData.AUTH_CODE; +import static com.adyen.constants.ApiConstants.AdditionalData.AVS_RESULT; +import static com.adyen.constants.ApiConstants.AdditionalData.BOLETO_BARCODE_REFERENCE; +import static com.adyen.constants.ApiConstants.AdditionalData.BOLETO_DATA; +import static com.adyen.constants.ApiConstants.AdditionalData.BOLETO_DUE_DATE; +import static com.adyen.constants.ApiConstants.AdditionalData.BOLETO_EXPIRATION_DATE; +import static com.adyen.constants.ApiConstants.AdditionalData.BOLETO_URL; +import static com.adyen.constants.ApiConstants.AdditionalData.CARD_BIN; +import static com.adyen.constants.ApiConstants.AdditionalData.CARD_HOLDER_NAME; +import static com.adyen.constants.ApiConstants.AdditionalData.CARD_SUMMARY; +import static com.adyen.constants.ApiConstants.AdditionalData.EXPIRY_DATE; +import static com.adyen.constants.ApiConstants.AdditionalData.PAYMENT_METHOD; +import static com.adyen.constants.ApiConstants.AdditionalData.THREE_D_AUTHENTICATED; +import static com.adyen.constants.ApiConstants.AdditionalData.THREE_D_OFFERERED; /** * PaymentsResponse @@ -70,7 +88,7 @@ public PaymentsResponse additionalData(Map additionalData) { public PaymentsResponse putAdditionalDataItem(String key, String additionalDataItem) { if (this.additionalData == null) { - this.additionalData = null; + this.additionalData = new HashMap<>(); } this.additionalData.put(key, additionalDataItem); @@ -78,7 +96,8 @@ public PaymentsResponse putAdditionalDataItem(String key, String additionalDataI } /** - * This field contains additional data, which may be required to return in a particular payment response. To choose data fields to be returned, go to **Customer Area** > **Settings** > **API and Response**. + * This field contains additional data, which may be required to return in a particular payment response. To choose data fields to be returned, go to **Customer Area** > **Settings** > **API + * and Response**. * * @return additionalData **/ @@ -90,6 +109,14 @@ public void setAdditionalData(Map additionalData) { this.additionalData = additionalData; } + public String getAdditionalDataByKey(String key) { + if (additionalData == null) { + return null; + } + + return additionalData.get(key); + } + public PaymentsResponse details(List details) { this.details = details; return this; @@ -160,7 +187,8 @@ public PaymentsResponse pspReference(String pspReference) { } /** - * Adyen's 16-digit unique reference associated with the transaction/the request. This value is globally unique; quote it when communicating with us about this request. > `pspReference` is returned only for non-redirect payment methods. + * Adyen's 16-digit unique reference associated with the transaction/the request. This value is globally unique; quote it when communicating with us about this request. > + * `pspReference` is returned only for non-redirect payment methods. * * @return pspReference **/ @@ -196,7 +224,8 @@ public PaymentsResponse refusalReason(String refusalReason) { } /** - * If the payment's authorisation is refused or an error occurs during authorisation, this field holds Adyen's mapped reason for the refusal or a description of the error. When a transaction fails, the authorisation response includes `resultCode` and `refusalReason` values. + * If the payment's authorisation is refused or an error occurs during authorisation, this field holds Adyen's mapped reason for the refusal or a description of the error. When a + * transaction fails, the authorisation response includes `resultCode` and `refusalReason` values. * * @return refusalReason **/ @@ -214,7 +243,15 @@ public PaymentsResponse resultCode(ResultCodeEnum resultCode) { } /** - * The result of the payment. Possible values: * **Authorised** – Indicates the payment authorisation was successfully completed. This state serves as an indicator to proceed with the delivery of goods and services. This is a final state. * **Refused** – Indicates the payment was refused. The reason is given in the `refusalReason` field. This is a final state. * **RedirectShopper** – Indicates the shopper should be redirected to an external web page or app to complete the authorisation. For more information on handling a redirect, refer to [Handling a redirect](https://docs.adyen.com/developers/checkout/api-integration/payments#handlingaredirect). * **Received** – Indicates the payment has successfully been received by Adyen, and will be processed. This is the initial state for all payments. * **Cancelled** – Indicates the payment has been cancelled (either by the shopper or the merchant) before processing was completed. This is a final state. * **Pending** – Indicates that it is not possible to obtain the final status of the payment. This can happen if the systems providing final status information for the payment are unavailable, or if the shopper needs to take further action to complete the payment. For more information on handling a pending payment, refer to [Payments with pending status](https://docs.adyen.com/developers/development-resources/payments-with-pending-status). * **Error** – Indicates an error occurred during processing of the payment. The reason is given in the `refusalReason` field. This is a final state. + * The result of the payment. Possible values: * **Authorised** – Indicates the payment authorisation was successfully completed. This state serves as an indicator to proceed with the delivery of + * goods and services. This is a final state. * **Refused** – Indicates the payment was refused. The reason is given in the `refusalReason` field. This is a final state. * + * **RedirectShopper** – Indicates the shopper should be redirected to an external web page or app to complete the authorisation. For more information on handling a redirect, refer to [Handling a + * redirect](https://docs.adyen.com/developers/checkout/api-integration/payments#handlingaredirect). * **Received** – Indicates the payment has successfully been received by Adyen, and will be + * processed. This is the initial state for all payments. * **Cancelled** – Indicates the payment has been cancelled (either by the shopper or the merchant) before processing was completed. This + * is a final state. * **Pending** – Indicates that it is not possible to obtain the final status of the payment. This can happen if the systems providing final status information for the payment + * are unavailable, or if the shopper needs to take further action to complete the payment. For more information on handling a pending payment, refer to [Payments with pending + * status](https://docs.adyen.com/developers/development-resources/payments-with-pending-status). * **Error** – Indicates an error occurred during processing of the payment. The reason is given in + * the `refusalReason` field. This is a final state. * * @return resultCode **/ @@ -235,14 +272,15 @@ public boolean equals(Object o) { return false; } PaymentsResponse paymentsResponse = (PaymentsResponse) o; - return Objects.equals(this.additionalData, paymentsResponse.additionalData) && - Objects.equals(this.details, paymentsResponse.details) && - Objects.equals(this.fraudResult, paymentsResponse.fraudResult) && - Objects.equals(this.paymentData, paymentsResponse.paymentData) && - Objects.equals(this.pspReference, paymentsResponse.pspReference) && - Objects.equals(this.redirect, paymentsResponse.redirect) && - Objects.equals(this.refusalReason, paymentsResponse.refusalReason) && - Objects.equals(this.resultCode, paymentsResponse.resultCode); + return Objects.equals(this.additionalData, paymentsResponse.additionalData) + && Objects.equals(this.details, paymentsResponse.details) + && Objects.equals(this.fraudResult, + paymentsResponse.fraudResult) + && Objects.equals(this.paymentData, paymentsResponse.paymentData) + && Objects.equals(this.pspReference, paymentsResponse.pspReference) + && Objects.equals(this.redirect, paymentsResponse.redirect) + && Objects.equals(this.refusalReason, paymentsResponse.refusalReason) + && Objects.equals(this.resultCode, paymentsResponse.resultCode); } @Override @@ -279,7 +317,15 @@ private String toIndentedString(Object o) { } /** - * The result of the payment. Possible values: * **Authorised** – Indicates the payment authorisation was successfully completed. This state serves as an indicator to proceed with the delivery of goods and services. This is a final state. * **Refused** – Indicates the payment was refused. The reason is given in the `refusalReason` field. This is a final state. * **RedirectShopper** – Indicates the shopper should be redirected to an external web page or app to complete the authorisation. For more information on handling a redirect, refer to [Handling a redirect](https://docs.adyen.com/developers/checkout/api-integration/payments#handlingaredirect). * **Received** – Indicates the payment has successfully been received by Adyen, and will be processed. This is the initial state for all payments. * **Cancelled** – Indicates the payment has been cancelled (either by the shopper or the merchant) before processing was completed. This is a final state. * **Pending** – Indicates that it is not possible to obtain the final status of the payment. This can happen if the systems providing final status information for the payment are unavailable, or if the shopper needs to take further action to complete the payment. For more information on handling a pending payment, refer to [Payments with pending status](https://docs.adyen.com/developers/development-resources/payments-with-pending-status). * **Error** – Indicates an error occurred during processing of the payment. The reason is given in the `refusalReason` field. This is a final state. + * The result of the payment. Possible values: * **Authorised** – Indicates the payment authorisation was successfully completed. This state serves as an indicator to proceed with the delivery of + * goods and services. This is a final state. * **Refused** – Indicates the payment was refused. The reason is given in the `refusalReason` field. This is a final state. * + * **RedirectShopper** – Indicates the shopper should be redirected to an external web page or app to complete the authorisation. For more information on handling a redirect, refer to [Handling a + * redirect](https://docs.adyen.com/developers/checkout/api-integration/payments#handlingaredirect). * **Received** – Indicates the payment has successfully been received by Adyen, and will be + * processed. This is the initial state for all payments. * **Cancelled** – Indicates the payment has been cancelled (either by the shopper or the merchant) before processing was completed. This + * is a final state. * **Pending** – Indicates that it is not possible to obtain the final status of the payment. This can happen if the systems providing final status information for the payment + * are unavailable, or if the shopper needs to take further action to complete the payment. For more information on handling a pending payment, refer to [Payments with pending + * status](https://docs.adyen.com/developers/development-resources/payments-with-pending-status). * **Error** – Indicates an error occurred during processing of the payment. The reason is given in + * the `refusalReason` field. This is a final state. */ @JsonAdapter(ResultCodeEnum.Adapter.class) public enum ResultCodeEnum { @@ -330,6 +376,65 @@ public ResultCodeEnum read(final JsonReader jsonReader) throws IOException { } } + public String getCardBin() { + return getAdditionalDataByKey(CARD_BIN); + } + + public String getCardHolderName() { + return getAdditionalDataByKey(CARD_HOLDER_NAME); + } + + public String getCardSummary() { + return getAdditionalDataByKey(CARD_SUMMARY); + } + + public String getPaymentMethod() { + return getAdditionalDataByKey(PAYMENT_METHOD); + } + + public String getAvsResult() { + return getAdditionalDataByKey(AVS_RESULT); + } + + public boolean get3DOffered() { + return String.valueOf("true").equals(getAdditionalDataByKey(THREE_D_OFFERERED)); + } + + public boolean get3DAuthenticated() { + return String.valueOf("true").equals(getAdditionalDataByKey(THREE_D_AUTHENTICATED)); + } + + public String getBoletoBarCodeReference() { + return getAdditionalDataByKey(BOLETO_BARCODE_REFERENCE); + } + + public String getBoletoData() { + return getAdditionalDataByKey(BOLETO_DATA); + } + + public String getAuthCode() { + return getAdditionalDataByKey(AUTH_CODE); + } + + public Date getBoletoDueDate() { + String date = getAdditionalDataByKey(BOLETO_DUE_DATE); + return DateUtil.parseYmdDate(date); + } + + public Date getBoletoExpirationDate() { + String date = getAdditionalDataByKey(BOLETO_EXPIRATION_DATE); + return DateUtil.parseYmdDate(date); + } + + public String getBoletoUrl() { + return getAdditionalDataByKey(BOLETO_URL); + } + + + public Date getExpiryDate() { + String expiryDate = getAdditionalDataByKey(EXPIRY_DATE); + return DateUtil.parseMYDate(expiryDate); + } }