├── ingenicoconnect-sdk ├── src │ ├── test │ │ ├── resources │ │ │ ├── minimalIINResponseMC.json │ │ │ ├── minimalIINResponseVisa.json │ │ │ ├── normalIINResponseVisaNoCoBrand.json │ │ │ ├── normalIINResponseMC.json │ │ │ ├── normalIINResponseVisa.json │ │ │ ├── paymentProductPayPal.json │ │ │ ├── paymentProductFieldWithoutMask.json │ │ │ ├── accountOnFileVisa.json │ │ │ ├── paymentProductIDeal.json │ │ │ ├── paymentProductInVoice.json │ │ │ └── paymentProductVisa.json │ │ └── java │ │ │ └── com │ │ │ └── ingenico │ │ │ └── connect │ │ │ └── gateway │ │ │ └── sdk │ │ │ └── client │ │ │ └── android │ │ │ ├── SDKTest.java │ │ │ ├── testUtil │ │ │ └── GsonHelper.java │ │ │ └── sdk │ │ │ └── model │ │ │ ├── paymentproduct │ │ │ └── AccountOnFileTest.kt │ │ │ ├── PaymentProductFieldTest.java │ │ │ └── iin │ │ │ └── IinDetailsResponseTest.java │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── ingenico │ │ └── connect │ │ └── gateway │ │ └── sdk │ │ └── client │ │ └── android │ │ └── sdk │ │ ├── model │ │ ├── iin │ │ │ ├── IinStatus.java │ │ │ ├── IinDetailsRequest.java │ │ │ ├── IinDetail.java │ │ │ └── IinDetailsResponse.java │ │ ├── EncryptedPaymentRequest.kt │ │ ├── paymentproduct │ │ │ ├── MobileIntegrationLevel.java │ │ │ ├── PaymentItem.java │ │ │ ├── validation │ │ │ │ ├── Luhn.java │ │ │ │ ├── IBAN.java │ │ │ │ ├── EmailAddress.java │ │ │ │ ├── ExpirationDate.java │ │ │ │ ├── ResidentIdNumber.java │ │ │ │ ├── TermsAndConditions.java │ │ │ │ ├── RegularExpression.java │ │ │ │ ├── Range.java │ │ │ │ ├── BoletoBancarioRequiredness.java │ │ │ │ ├── Length.java │ │ │ │ ├── FixedList.java │ │ │ │ └── Validator.java │ │ │ ├── AuthenticationIndicator.java │ │ │ ├── BasicPaymentItem.java │ │ │ ├── specificdata │ │ │ │ ├── PaymentProduct302SpecificData.java │ │ │ │ ├── PaymentProduct863SpecificData.java │ │ │ │ └── PaymentProduct320SpecificData.java │ │ │ ├── AccountOnFileDisplay.java │ │ │ ├── ValueMap.java │ │ │ ├── displayhints │ │ │ │ ├── DisplayHintsAccountOnFile.java │ │ │ │ ├── DisplayHintsPaymentItem.java │ │ │ │ └── DisplayHintsProductFields.java │ │ │ ├── PaymentProductFieldDisplayElement.java │ │ │ ├── Tooltip.java │ │ │ ├── FormElement.java │ │ │ ├── KeyValuePair.java │ │ │ ├── PaymentProduct.java │ │ │ ├── PaymentProductGroup.java │ │ │ ├── BasicPaymentProductGroup.java │ │ │ ├── AccountOnFile.java │ │ │ └── BasicPaymentItems.java │ │ ├── ThirdPartyStatus.java │ │ ├── validation │ │ │ ├── ValidationRule.java │ │ │ ├── ValidationType.java │ │ │ ├── AbstractValidationRule.java │ │ │ ├── ValidationErrorMessage.java │ │ │ ├── ValidationRuleTermsAndConditions.java │ │ │ ├── ValidationRuleRegex.java │ │ │ ├── ValidationRuleLuhn.java │ │ │ ├── ValidationRuleEmailAddress.java │ │ │ ├── ValidationRuleFixedList.java │ │ │ ├── ValidationRuleIBAN.java │ │ │ ├── ValidationRuleRange.java │ │ │ ├── ValidationRuleResidentIdNumber.java │ │ │ ├── ValidationRuleLength.java │ │ │ └── ValidationRuleBoletoBancarioRequiredness.java │ │ ├── Size.java │ │ ├── PaymentProductDirectoryResponse.java │ │ ├── FormatResult.java │ │ ├── ConvertedAmountResponse.java │ │ ├── ThirdPartyStatusResponse.java │ │ ├── DirectoryEntry.java │ │ ├── PreparedPaymentRequest.java │ │ ├── AmountOfMoney.java │ │ ├── PublicKeyResponse.java │ │ ├── PaymentContext.java │ │ └── PaymentItemCacheKey.java │ │ ├── network │ │ ├── NetworkConsumer.kt │ │ ├── ApiErrorResponse.kt │ │ ├── NetworkResponse.kt │ │ ├── extension │ │ │ └── RXJavaExtension.kt │ │ └── OkHttpClientBuilder.kt │ │ ├── drawable │ │ ├── DrawableService.kt │ │ ├── DrawableRepository.kt │ │ ├── GetDrawableFromUrl.kt │ │ └── RemoteDrawableRepository.kt │ │ ├── exception │ │ ├── EncryptDataException.java │ │ ├── CommunicationException.java │ │ ├── UnknownNetworkException.java │ │ └── BadPaymentItemException.java │ │ ├── support │ │ ├── GetPublicKey.kt │ │ ├── ConvertAmount.kt │ │ ├── GetThirdPartyStatus.kt │ │ ├── SupportService.kt │ │ ├── SupportRepository.kt │ │ ├── GetIINDetails.kt │ │ └── EncryptPaymentRequest.kt │ │ ├── configuration │ │ ├── PaymentConfiguration.kt │ │ ├── SessionConfiguration.kt │ │ └── ConnectSDKConfiguration.kt │ │ ├── product │ │ ├── GetPaymentProductDirectory.kt │ │ ├── PaymentProductService.kt │ │ ├── PaymentProductRepository.kt │ │ ├── GetPaymentProducts.kt │ │ └── RemotePaymentProductRepository.kt │ │ ├── productsgroup │ │ ├── PaymentProductGroupService.kt │ │ ├── PaymentProductGroupRepository.kt │ │ ├── GetPaymentProductGroups.kt │ │ ├── GetPaymentProductGroup.kt │ │ └── RemotePaymentProductGroupRepository.kt │ │ ├── encryption │ │ ├── EncryptDataJsonSerializer.java │ │ └── EncryptData.java │ │ ├── communicate │ │ └── TLSSocketFactory.java │ │ ├── caching │ │ ├── CacheHandler.java │ │ ├── Preferences.java │ │ └── ReadInternalStorage.java │ │ ├── asynctask │ │ └── PublicKeyAsyncTask.java │ │ └── session │ │ └── SessionEncryptionHelper.java ├── detekt-config.yml ├── lint.xml ├── consumer-rules.pro └── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── README.md ├── gradle.properties └── gradlew.bat /ingenicoconnect-sdk/src/test/resources/minimalIINResponseMC.json: -------------------------------------------------------------------------------- 1 | { 2 | "countryCode" : "US", 3 | "paymentProductId" : 3 4 | } -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/minimalIINResponseVisa.json: -------------------------------------------------------------------------------- 1 | { 2 | "countryCode" : "99", 3 | "paymentProductId" : 1 4 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ingenico-ePayments/connect-sdk-client-android/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ingenicoconnect-sdk/detekt-config.yml: -------------------------------------------------------------------------------- 1 | complexity: 2 | TooManyFunctions: 3 | active: false 4 | 5 | style: 6 | ReturnCount: 7 | active: false 8 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/normalIINResponseVisaNoCoBrand.json: -------------------------------------------------------------------------------- 1 | { 2 | "countryCode" : "99", 3 | "isAllowedInContext" : true, 4 | "paymentProductId" : 1 5 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Sep 20 14:52:46 CEST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022. Global Collect Services B.V 3 | */ 4 | 5 | dependencyResolutionManagement { 6 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 7 | repositories { 8 | google() 9 | mavenCentral() 10 | } 11 | } 12 | include ':ingenicoconnect-sdk' 13 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/normalIINResponseMC.json: -------------------------------------------------------------------------------- 1 | { 2 | "coBrands" : [ { 3 | "isAllowedInContext" : true, 4 | "paymentProductId" : 3 5 | }, { 6 | "isAllowedInContext" : true, 7 | "paymentProductId" : 119 8 | } ], 9 | "countryCode" : "US", 10 | "isAllowedInContext" : true, 11 | "paymentProductId" : 3 12 | } -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/normalIINResponseVisa.json: -------------------------------------------------------------------------------- 1 | { 2 | "coBrands" : [ { 3 | "isAllowedInContext" : true, 4 | "paymentProductId" : 1 5 | }, { 6 | "isAllowedInContext" : true, 7 | "paymentProductId" : 122 8 | } ], 9 | "countryCode" : "99", 10 | "isAllowedInContext" : true, 11 | "paymentProductId" : 1 12 | } -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/iin/IinStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin; 6 | 7 | public enum IinStatus { 8 | SUPPORTED, 9 | UNKNOWN, 10 | NOT_ENOUGH_DIGITS, 11 | EXISTING_BUT_NOT_ALLOWED 12 | } 13 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/paymentProductPayPal.json: -------------------------------------------------------------------------------- 1 | { 2 | "allowsRecurring" : true, 3 | "allowsTokenization" : false, 4 | "autoTokenized" : false, 5 | "displayHints" : { 6 | "displayOrder" : 2, 7 | "label" : "PayPal", 8 | "logo" : "templates/master/global/css/img/ppimages/pp_logo_840_v1.png" 9 | }, 10 | "fields" : [ ], 11 | "id" : 840, 12 | "mobileIntegrationLevel" : "OPTIMISED_SUPPORT", 13 | "paymentMethod" : "redirect" 14 | } -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/EncryptedPaymentRequest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model 6 | 7 | /** 8 | * Contains all encrypted payment request data needed for doing a payment. 9 | */ 10 | data class EncryptedPaymentRequest( 11 | val encryptedFields: String, 12 | val encodedClientMetaInfo: String, 13 | ) 14 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/MobileIntegrationLevel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | /** 8 | * Enum containing all the possible Mobile Integration Levels. 9 | */ 10 | public enum MobileIntegrationLevel { 11 | NO_SUPPORT, 12 | BASIC_SUPPORT, 13 | OPTIMISED_SUPPORT; 14 | } 15 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/ThirdPartyStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | /** 8 | * An enumeration of the possible statuses that a third party payment may be in. 9 | */ 10 | public enum ThirdPartyStatus { 11 | WAITING, 12 | INITIALIZED, 13 | AUTHORIZED, 14 | COMPLETED, 15 | 16 | ; 17 | } 18 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 9 | 10 | /** 11 | * Interface for ValidationRule. 12 | */ 13 | public interface ValidationRule { 14 | 15 | boolean validate(PaymentRequest paymentRequest, String fieldId); 16 | } 17 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/PaymentItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * POJO that represents a PaymentItem. 12 | */ 13 | public interface PaymentItem extends BasicPaymentItem, Serializable { 14 | 15 | List getPaymentProductFields(); 16 | } 17 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/Luhn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the Luhn data. 11 | * Used for validation. 12 | */ 13 | public class Luhn implements Serializable { 14 | 15 | private static final long serialVersionUID = -1145093943834460166L; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/network/NetworkConsumer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.network 6 | 7 | @FunctionalInterface 8 | fun interface Success { 9 | fun success(it: X) 10 | } 11 | 12 | @FunctionalInterface 13 | fun interface ApiError { 14 | fun apiError(it: ApiErrorResponse) 15 | } 16 | 17 | @FunctionalInterface 18 | fun interface Failure { 19 | fun failure(it: Throwable) 20 | } 21 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/IBAN.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the IBAN data. 11 | * Used for validation. 12 | */ 13 | 14 | public class IBAN implements Serializable { 15 | 16 | private static final long serialVersionUID = -2599896096694861251L; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/EmailAddress.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the EmailAddress data. 11 | * Used for validation. 12 | */ 13 | public class EmailAddress implements Serializable { 14 | 15 | private static final long serialVersionUID = -2599214976694861251L; 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/ExpirationDate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the ExpirationDate data. 11 | * Used for validation. 12 | */ 13 | public class ExpirationDate implements Serializable { 14 | 15 | private static final long serialVersionUID = -4759119724035738836L; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/ResidentIdNumber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the ResidentIdNumber data. 11 | * Used for validation. 12 | */ 13 | public class ResidentIdNumber implements Serializable { 14 | 15 | private static final long serialVersionUID = 155962744343050927L; 16 | } 17 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/TermsAndConditions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the TermsAndConditions data. 11 | * Used for validation. 12 | */ 13 | public class TermsAndConditions implements Serializable { 14 | 15 | private static final long serialVersionUID = 155962715343050927L; 16 | } 17 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/drawable/DrawableService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.drawable 6 | 7 | import io.reactivex.rxjava3.core.Observable 8 | import okhttp3.ResponseBody 9 | import retrofit2.http.GET 10 | import retrofit2.http.Path 11 | 12 | internal interface DrawableService { 13 | 14 | @GET("{drawableUrl}") 15 | fun getDrawableFromUrl(@Path("drawableUrl",encoded = true) drawableUrl: String): Observable 16 | } 17 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/network/ApiErrorResponse.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.network 6 | 7 | data class ApiErrorResponse( 8 | val errorId: String, 9 | val errors: List 10 | ) 11 | 12 | data class Error( 13 | val category: String, 14 | val code: String, 15 | val httpStatusCode: Int, 16 | val id: String, 17 | val message: String, 18 | val propertyName: String?, 19 | val requestId: String? 20 | ) 21 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/AuthenticationIndicator.java: -------------------------------------------------------------------------------- 1 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 2 | 3 | import java.io.Serializable; 4 | 5 | public class AuthenticationIndicator implements Serializable { 6 | 7 | private static final long serialVersionUID = -3800684034835741771L; 8 | 9 | private String name; 10 | private String value; 11 | 12 | public String getName() { 13 | return name; 14 | } 15 | 16 | public String getValue() { 17 | return value; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | /** 8 | * Enum containing all the validation types. 9 | */ 10 | public enum ValidationType { 11 | EXPIRATIONDATE, 12 | EMAILADDRESS, 13 | FIXEDLIST, 14 | IBAN, 15 | LENGTH, 16 | LUHN, 17 | RANGE, 18 | REGULAREXPRESSION, 19 | REQUIRED, 20 | TYPE, 21 | BOLETOBANCARIOREQUIREDNESS, 22 | TERMSANDCONDITIONS, 23 | RESIDENTIDNUMBER, 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/drawable/DrawableRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.drawable 6 | 7 | import android.graphics.drawable.Drawable 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 9 | import io.reactivex.rxjava3.core.Observable 10 | 11 | internal interface DrawableRepository { 12 | 13 | fun getDrawableFromUrl(connectSDKConfiguration: ConnectSDKConfiguration, drawableUrl: String): Observable 14 | } 15 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/Size.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | /** 8 | * POJO for getting scaled images. 9 | */ 10 | public class Size { 11 | 12 | private Integer width; 13 | private Integer height; 14 | 15 | public Size(Integer width, Integer height){ 16 | this.width = width; 17 | this.height = height; 18 | } 19 | 20 | public Integer getWidth(){ 21 | return width; 22 | } 23 | 24 | public Integer getHeight(){ 25 | return height; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/network/NetworkResponse.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.network 6 | 7 | sealed class NetworkResponse( 8 | val data: T? = null, 9 | val apiErrorResponse: ApiErrorResponse? = null 10 | ) { 11 | 12 | class Success(data: T) : NetworkResponse(data) 13 | class ApiError(apiErrorResponse: ApiErrorResponse?, data: T? = null) : NetworkResponse(data, apiErrorResponse) 14 | } 15 | 16 | object UnknownNetworkResponseException: Exception("Unknown NetworkResponse") 17 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/java/com/ingenico/connect/gateway/sdk/client/android/SDKTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin.IinDetailsResponseTest; 8 | 9 | import org.junit.runner.RunWith; 10 | import org.junit.runners.Suite; 11 | 12 | 13 | /** 14 | * Android InstrumentationTestRunner used for running all the tests in the SDK 15 | */ 16 | @RunWith(Suite.class) 17 | @Suite.SuiteClasses({IinDetailsResponseTest.class, MaskTest.class, ValidationTest.class}) 18 | public class SDKTest { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/RegularExpression.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the RegularExpression data. 11 | * Used for validation. 12 | */ 13 | public class RegularExpression implements Serializable { 14 | 15 | private static final long serialVersionUID = -1242536946684504857L; 16 | 17 | private String regularExpression; 18 | 19 | public String getRegularExpression(){ 20 | return regularExpression; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/paymentProductFieldWithoutMask.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataRestrictions" : { 3 | "isRequired" : false, 4 | "validators" : { 5 | "boletoBancarioRequiredness" : { 6 | "fiscalNumberLength" : 11 7 | }, 8 | "length" : { 9 | "maxLength" : 15, 10 | "minLength" : 0 11 | } 12 | } 13 | }, 14 | "displayHints" : { 15 | "alwaysShow" : true, 16 | "displayOrder" : 2, 17 | "formElement" : { 18 | "type" : "text" 19 | }, 20 | "label" : "First name", 21 | "obfuscate" : false, 22 | "placeholderLabel" : "First name", 23 | "preferredInputType" : "StringKeyboard" 24 | }, 25 | "id" : "firstName", 26 | "type" : "string" 27 | } -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/PaymentProductDirectoryResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * POJO that contains the response for PaymentProductDirectory lookup. 11 | */ 12 | public class PaymentProductDirectoryResponse { 13 | 14 | private ArrayList entries; 15 | 16 | 17 | public PaymentProductDirectoryResponse(ArrayList entries) { 18 | this.entries = entries; 19 | } 20 | 21 | public ArrayList getEntries() { 22 | return entries; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/BasicPaymentItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.displayhints.DisplayHintsPaymentItem; 8 | 9 | import java.io.Serializable; 10 | import java.util.List; 11 | 12 | public interface BasicPaymentItem extends Serializable { 13 | 14 | String getId(); 15 | 16 | DisplayHintsPaymentItem getDisplayHints(); 17 | 18 | List getAccountsOnFile(); 19 | 20 | String getAcquirerCountry(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/drawable/GetDrawableFromUrl.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.drawable 6 | 7 | import android.graphics.drawable.Drawable 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 9 | import io.reactivex.rxjava3.core.Observable 10 | 11 | internal class GetDrawableFromUrl { 12 | 13 | operator fun invoke(connectSDKConfiguration: ConnectSDKConfiguration, drawableUrl: String): Observable{ 14 | return RemoteDrawableRepository().getDrawableFromUrl(connectSDKConfiguration, drawableUrl) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/exception/EncryptDataException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.exception; 6 | 7 | public class EncryptDataException extends Exception { 8 | 9 | 10 | private static final long serialVersionUID = 1060449781983665636L; 11 | 12 | public EncryptDataException() { 13 | super(); 14 | } 15 | 16 | public EncryptDataException(String message) { 17 | super(message); 18 | } 19 | 20 | public EncryptDataException(Throwable t) { 21 | super(t); 22 | } 23 | 24 | public EncryptDataException(String message, Throwable t) { 25 | super(message, t); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/specificdata/PaymentProduct302SpecificData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.specificdata; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * POJO which holds the payment product 302 specific properties. 12 | */ 13 | public class PaymentProduct302SpecificData implements Serializable { 14 | 15 | private static final long serialVersionUID = 4006738016411138300L; 16 | 17 | private List networks; 18 | 19 | 20 | public List getNetworks() { 21 | return networks; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/Range.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the Range data. 11 | * Used for validation. 12 | */ 13 | public class Range implements Serializable { 14 | 15 | private static final long serialVersionUID = 4659640500627126711L; 16 | 17 | private Integer minValue; 18 | private Integer maxValue; 19 | 20 | public Integer getMinValue(){ 21 | return minValue; 22 | } 23 | 24 | public Integer getMaxValue(){ 25 | return maxValue; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/FormatResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | /** 8 | * Result after a mask is applied on a field. 9 | */ 10 | public class FormatResult { 11 | 12 | private String formattedResult; 13 | private Integer cursorIndex; 14 | 15 | public FormatResult(String formattedResult, Integer cursorIndex) { 16 | this.formattedResult = formattedResult; 17 | this.cursorIndex = cursorIndex; 18 | } 19 | 20 | public Integer getCursorIndex() { 21 | return cursorIndex; 22 | } 23 | 24 | public String getFormattedResult() { 25 | return formattedResult; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/BoletoBancarioRequiredness.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the BoletoBancarioRequiredness data. 11 | * Used for validation. 12 | */ 13 | public class BoletoBancarioRequiredness implements Serializable { 14 | 15 | private static final long serialVersionUID = 8801553901212702765L; 16 | 17 | private Integer fiscalNumberLength; 18 | 19 | public Integer getFiscalNumberLength() { 20 | return fiscalNumberLength; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/Length.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the Length data. 11 | * Used for validation. 12 | */ 13 | public class Length implements Serializable { 14 | 15 | private static final long serialVersionUID = -8127911803708372125L; 16 | 17 | private Integer minLength; 18 | private Integer maxLength; 19 | 20 | public Integer getMinLength(){ 21 | return minLength; 22 | } 23 | 24 | public Integer getMaxLength(){ 25 | return maxLength; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/FixedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * POJO which holds the FixedList data. 13 | * Used for validation. 14 | */ 15 | public class FixedList implements Serializable { 16 | 17 | private static final long serialVersionUID = -7191166722186646029L; 18 | 19 | private List allowedValues = new ArrayList<>(); 20 | 21 | public List getAllowedValues(){ 22 | return allowedValues; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/ConvertedAmountResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO that contains the response for a converted amount. 11 | */ 12 | public class ConvertedAmountResponse implements Serializable { 13 | 14 | private static final long serialVersionUID = -4043745317792003304L; 15 | 16 | private Long convertedAmount; 17 | 18 | public ConvertedAmountResponse(Long convertedAmount) { 19 | this.convertedAmount = convertedAmount; 20 | } 21 | 22 | public Long getConvertedAmount() { 23 | return convertedAmount; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/specificdata/PaymentProduct863SpecificData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.specificdata; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * POJO which holds the payment product 863 specific properties. 12 | */ 13 | public class PaymentProduct863SpecificData implements Serializable { 14 | 15 | private static final long serialVersionUID = -3455606815519003280L; 16 | 17 | private List integrationTypes; 18 | 19 | 20 | public List getIntegrationTypes() { 21 | return integrationTypes; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/ThirdPartyStatusResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | /** 8 | * POJO that holds the ThirdPartyStatus call response. 9 | */ 10 | public class ThirdPartyStatusResponse { 11 | 12 | private ThirdPartyStatus thirdPartyStatus; 13 | 14 | public ThirdPartyStatusResponse(ThirdPartyStatus thirdPartyStatus) { 15 | this.thirdPartyStatus = thirdPartyStatus; 16 | } 17 | 18 | public ThirdPartyStatus getThirdPartyStatus() { 19 | return thirdPartyStatus; 20 | } 21 | public void setThirdPartyStatus(ThirdPartyStatus thirdPartyStatus) { 22 | this.thirdPartyStatus = thirdPartyStatus; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/exception/CommunicationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.exception; 6 | 7 | /** 8 | * @deprecated this class will be removed in the future. 9 | */ 10 | @Deprecated 11 | public class CommunicationException extends Exception { 12 | 13 | private static final long serialVersionUID = 378923281056384514L; 14 | 15 | public CommunicationException() { 16 | super(); 17 | } 18 | 19 | public CommunicationException(String message) { 20 | super(message); 21 | } 22 | 23 | public CommunicationException(Throwable t) { 24 | super(t); 25 | } 26 | 27 | public CommunicationException(String message, Throwable t) { 28 | super(message, t); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/specificdata/PaymentProduct320SpecificData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.specificdata; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * POJO which holds the payment product 320 specific properties. 12 | */ 13 | public class PaymentProduct320SpecificData implements Serializable { 14 | 15 | private static final long serialVersionUID = 8538500042642795722L; 16 | 17 | private String gateway; 18 | private List networks; 19 | 20 | 21 | public String getGateway() { 22 | return gateway; 23 | } 24 | 25 | public List getNetworks() { 26 | return networks; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/support/GetPublicKey.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.support 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PublicKeyResponse 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 10 | import io.reactivex.rxjava3.core.Observable 11 | 12 | internal class GetPublicKey { 13 | 14 | operator fun invoke( 15 | connectSDKConfiguration: ConnectSDKConfiguration 16 | ): Observable>{ 17 | return RemoteSupportRepository().getPublicKey(connectSDKConfiguration) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/java/com/ingenico/connect/gateway/sdk/client/android/testUtil/GsonHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.testUtil; 6 | 7 | import com.google.gson.Gson; 8 | 9 | import java.io.IOException; 10 | import java.io.InputStreamReader; 11 | import java.io.Reader; 12 | 13 | public class GsonHelper { 14 | 15 | private static final Gson gson = new Gson(); 16 | 17 | public static T fromResourceJson(String resource, Class classOfT) { 18 | try (Reader reader = new InputStreamReader(GsonHelper.class.getClassLoader().getResourceAsStream(resource))) { 19 | return gson.fromJson(reader, classOfT); 20 | } catch (IOException e) { 21 | throw new RuntimeException(e); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/exception/UnknownNetworkException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.exception; 6 | 7 | /** 8 | * @deprecated this class will be removed in the future. 9 | */ 10 | @Deprecated 11 | public class UnknownNetworkException extends RuntimeException { 12 | 13 | private static final long serialVersionUID = 7604981282147428917L; 14 | 15 | public UnknownNetworkException() { 16 | super(); 17 | } 18 | 19 | public UnknownNetworkException(String message) { 20 | super(message); 21 | } 22 | 23 | public UnknownNetworkException(Throwable t) { 24 | super(t); 25 | } 26 | 27 | public UnknownNetworkException(String message, Throwable t) { 28 | super(message, t); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/AccountOnFileDisplay.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import java.io.Serializable; 8 | 9 | 10 | /** 11 | * POJO that represents an AccountOnFileDisplay object. 12 | */ 13 | public class AccountOnFileDisplay implements Serializable { 14 | 15 | private static final long serialVersionUID = -7793293988073972532L; 16 | 17 | private String attributeKey; 18 | private String mask; 19 | 20 | public AccountOnFileDisplay(String attributeKey, String mask) { 21 | this.attributeKey = attributeKey; 22 | this.mask = mask; 23 | } 24 | 25 | public String getKey() { 26 | return attributeKey; 27 | } 28 | 29 | public String getMask() { 30 | return mask; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/exception/BadPaymentItemException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.exception; 6 | 7 | /** 8 | * @deprecated this class will be removed in the future. 9 | */ 10 | @Deprecated 11 | public class BadPaymentItemException extends RuntimeException { 12 | 13 | 14 | private static final long serialVersionUID = -4164065223871993498L; 15 | 16 | public BadPaymentItemException() { 17 | super(); 18 | } 19 | 20 | public BadPaymentItemException(String message) { 21 | super(message); 22 | } 23 | 24 | public BadPaymentItemException(Throwable t) { 25 | super(t); 26 | } 27 | 28 | public BadPaymentItemException(String message, Throwable t) { 29 | super(message, t); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\android\adt-bundle-windows-x86_64-20131030\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # The line below ensures that JSON deserialisation succeeds when using obfuscation in your app. 20 | -keep class com.ingenico.connect.gateway.sdk.client.android.sdk.model.** { *; } 21 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/ValueMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * POJO which holds the ValueMap data and its paymentProductFieldDisplayElements. 12 | * If the {@link FormElement} is a list, ValueMap is used to display a value and its displayElements. 13 | */ 14 | public class ValueMap implements Serializable { 15 | 16 | private static final long serialVersionUID = -8334806247597370688L; 17 | 18 | 19 | private String value; 20 | private List displayElements; 21 | 22 | 23 | public String getValue() { 24 | return value; 25 | } 26 | 27 | public List getDisplayElements() { 28 | return displayElements; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/displayhints/DisplayHintsAccountOnFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.displayhints; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.AccountOnFileDisplay; 8 | 9 | import java.io.Serializable; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | /** 14 | * POJO that represents an DisplayHintsAccountOnFile object. 15 | */ 16 | public class DisplayHintsAccountOnFile implements Serializable { 17 | 18 | private static final long serialVersionUID = 3446099654728722104L; 19 | 20 | 21 | private List labelTemplate = new ArrayList<>(); 22 | private String logo; 23 | 24 | public List getLabelTemplate(){ 25 | return labelTemplate; 26 | } 27 | 28 | public String getLogo() { 29 | return logo; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/accountOnFileVisa.json: -------------------------------------------------------------------------------- 1 | { 2 | "attributes" : [ { 3 | "key" : "alias", 4 | "value" : "411111XXXXXX1111", 5 | "status" : "READ_ONLY" 6 | }, { 7 | "key" : "firstName", 8 | "value" : "Wile", 9 | "status" : "READ_ONLY" 10 | }, { 11 | "key" : "surname", 12 | "value" : "E. Coyote", 13 | "status" : "READ_ONLY" 14 | }, { 15 | "key" : "cardholderName", 16 | "value" : "Wile E. Coyote", 17 | "status" : "READ_ONLY" 18 | }, { 19 | "key" : "cardNumber", 20 | "value" : "411111XXXXXX1111", 21 | "status" : "READ_ONLY" 22 | }, { 23 | "key" : "cvv", 24 | "value" : "111", 25 | "status" : "CAN_WRITE" 26 | }, { 27 | "key" : "expiryDate", 28 | "value" : "0120", 29 | "status" : "CAN_WRITE" 30 | } ], 31 | "displayHints" : { 32 | "labelTemplate" : [ { 33 | "attributeKey" : "alias", 34 | "mask" : "{{9999}} {{9999}} {{9999}} {{9999}} {{999}}" 35 | } ], 36 | "logo" : "templates/master/global/css/img/ppimages/pp_logo_1_v1.png" 37 | }, 38 | "id" : 0, 39 | "paymentProductId" : 1 40 | } -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/configuration/PaymentConfiguration.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.configuration 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 8 | 9 | class PaymentConfiguration private constructor( 10 | val paymentContext: PaymentContext, 11 | var groupPaymentProducts: Boolean, 12 | ) { 13 | 14 | data class Builder( 15 | var paymentContext: PaymentContext, 16 | var groupPaymentProducts: Boolean = false, 17 | var isRecurring: Boolean = false 18 | ) { 19 | constructor(paymentContext: PaymentContext) : this( 20 | paymentContext, false, false 21 | ) 22 | 23 | fun groupPaymentProducts(groupPaymentProducts: Boolean) = 24 | apply { this.groupPaymentProducts = groupPaymentProducts } 25 | 26 | fun build() = PaymentConfiguration( 27 | paymentContext, 28 | groupPaymentProducts 29 | ) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/product/GetPaymentProductDirectory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.product 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentProductDirectoryResponse 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 11 | import io.reactivex.rxjava3.core.Observable 12 | 13 | internal class GetPaymentProductDirectory { 14 | 15 | operator fun invoke( 16 | paymentContext: PaymentContext, 17 | connectSDKConfiguration: ConnectSDKConfiguration, 18 | paymentProductId: String 19 | ): Observable> { 20 | return RemotePaymentProductRepository() 21 | .getPaymentProductDirectory(paymentContext, connectSDKConfiguration, paymentProductId) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/paymentProductIDeal.json: -------------------------------------------------------------------------------- 1 | { 2 | "allowsRecurring" : false, 3 | "allowsTokenization" : false, 4 | "autoTokenized" : false, 5 | "displayHints" : { 6 | "displayOrder" : 35, 7 | "label" : "iDEAL", 8 | "logo" : "templates/master/global/css/img/ppimages/pp_logo_809_v1.png" 9 | }, 10 | "fields" : [ { 11 | "dataRestrictions" : { 12 | "isRequired" : true, 13 | "validators" : { 14 | "fixedList" : { 15 | "allowedValues" : [ "INGBNL2A" ] 16 | } 17 | } 18 | }, 19 | "displayHints" : { 20 | "alwaysShow" : false, 21 | "displayOrder" : 1, 22 | "formElement" : { 23 | "type" : "list", 24 | "valueMapping" : [ { 25 | "displayName" : "Issuer Simulation V3 - ING", 26 | "value" : "INGBNL2A" 27 | } ] 28 | }, 29 | "label" : "Selecteer uw bank", 30 | "obfuscate" : false, 31 | "placeholderLabel" : "Selecteer uw bank" 32 | }, 33 | "id" : "issuerId", 34 | "type" : "string" 35 | } ], 36 | "id" : 809, 37 | "mobileIntegrationLevel" : "OPTIMISED_SUPPORT", 38 | "paymentMethod" : "redirect" 39 | } -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/productsgroup/PaymentProductGroupService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.productsgroup 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.BasicPaymentProductGroups 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.PaymentProductGroup 9 | import io.reactivex.rxjava3.core.Observable 10 | import retrofit2.Response 11 | import retrofit2.http.GET 12 | import retrofit2.http.Path 13 | import retrofit2.http.QueryMap 14 | 15 | interface PaymentProductGroupService { 16 | 17 | @GET("productgroups") 18 | fun getPaymentProductGroups( 19 | @QueryMap parameters: Map 20 | ): Observable> 21 | 22 | @GET("productgroups/{paymentProductGroupId}") 23 | fun getPaymentProductGroup( 24 | @Path("paymentProductGroupId") paymentProductGroupId: String, 25 | @QueryMap parameters: Map 26 | ): Observable> 27 | } 28 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/support/ConvertAmount.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.support 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 9 | import io.reactivex.rxjava3.core.Observable 10 | 11 | internal class ConvertAmount { 12 | 13 | operator fun invoke( 14 | connectSDKConfiguration: ConnectSDKConfiguration, 15 | source: String, 16 | target: String, 17 | amount: Long 18 | ): Observable> { 19 | return RemoteSupportRepository().convertAmount(connectSDKConfiguration, source, target, amount) 20 | .map { 21 | if (it is NetworkResponse.Success) { 22 | NetworkResponse.Success(it.data?.convertedAmount!!) 23 | } else { 24 | NetworkResponse.ApiError(it.apiErrorResponse) 25 | } 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/iin/IinDetailsRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin; 6 | 7 | import com.google.gson.annotations.SerializedName; 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | * POJO that contains the request for IIN lookup. 14 | */ 15 | public class IinDetailsRequest implements Serializable { 16 | 17 | private static final long serialVersionUID = 8401271765455867950L; 18 | 19 | @SerializedName("bin") 20 | private String ccPartial; 21 | 22 | private PaymentContext paymentContext; 23 | 24 | public IinDetailsRequest(String ccPartial) { 25 | this.ccPartial = ccPartial; 26 | } 27 | 28 | public IinDetailsRequest(String ccPartial, PaymentContext paymentContext) { 29 | this.ccPartial = ccPartial; 30 | this.paymentContext = paymentContext; 31 | } 32 | 33 | public String getCcPartial() { 34 | return ccPartial; 35 | } 36 | 37 | public PaymentContext getPaymentContext () { 38 | return paymentContext; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/PaymentProductFieldDisplayElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds a PaymentProductFieldDisplayElement. 11 | */ 12 | public class PaymentProductFieldDisplayElement implements Serializable { 13 | 14 | private static final long serialVersionUID = 3137435990791529227L; 15 | 16 | public enum PaymentProductFieldDisplayElementType { 17 | INTEGER, 18 | STRING, 19 | CURRENCY, 20 | PERCENTAGE, 21 | URI, 22 | ; 23 | } 24 | 25 | private String id; 26 | private PaymentProductFieldDisplayElementType type; 27 | private String value; 28 | 29 | protected PaymentProductFieldDisplayElement() { } 30 | 31 | public String getId() { 32 | return id; 33 | } 34 | 35 | public PaymentProductFieldDisplayElementType getType() { 36 | return type; 37 | } 38 | 39 | public String getValue() { 40 | return value; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/support/GetThirdPartyStatus.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.support 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.ThirdPartyStatus 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 10 | import io.reactivex.rxjava3.core.Observable 11 | 12 | internal class GetThirdPartyStatus { 13 | 14 | operator fun invoke( 15 | connectSDKConfiguration: ConnectSDKConfiguration, 16 | paymentId: String 17 | ): Observable> { 18 | return RemoteSupportRepository().getThirdPartyStatus(connectSDKConfiguration, paymentId) 19 | .map { 20 | if (it is NetworkResponse.Success) { 21 | NetworkResponse.Success(it.data?.thirdPartyStatus!!) 22 | } else { 23 | NetworkResponse.ApiError(it.apiErrorResponse) 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/DirectoryEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | import java.util.ArrayList; 8 | 9 | 10 | /** 11 | * POJO that contains the DirectoryEntry, which is used as a list type in a {@link PaymentProductDirectoryResponse}. 12 | */ 13 | public class DirectoryEntry { 14 | 15 | 16 | private ArrayList countryNames; 17 | private String issuerId; 18 | private String issuerList; 19 | private String issuerName; 20 | 21 | 22 | public DirectoryEntry(String issuerId, String issuerList, String issuerName, ArrayList countryNames) { 23 | 24 | this.countryNames = countryNames; 25 | this.issuerId = issuerId; 26 | this.issuerList = issuerList; 27 | this.issuerName = issuerName; 28 | } 29 | 30 | public ArrayList getCountryNames() { 31 | return countryNames; 32 | } 33 | 34 | public String getIssuerId() { 35 | return issuerId; 36 | } 37 | 38 | public String getIssuerList() { 39 | return issuerList; 40 | } 41 | 42 | public String getIssuerName() { 43 | return issuerName; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/PreparedPaymentRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | /** 8 | * Contains all encrypted {@link PaymentRequest} data needed for doing a payment. 9 | * 10 | * @deprecated use {@link EncryptedPaymentRequest} instead 11 | */ 12 | 13 | @Deprecated 14 | public class PreparedPaymentRequest { 15 | 16 | private String encryptedFields; 17 | private String encodedClientMetaInfo; 18 | 19 | public PreparedPaymentRequest(String encryptedFields, String encodedClientMetaInfo) { 20 | 21 | if (encryptedFields == null) { 22 | throw new IllegalArgumentException("Error creating PreparedPaymentRequest, encryptedFields may not be null"); 23 | } 24 | if (encodedClientMetaInfo == null) { 25 | throw new IllegalArgumentException("Error creating PreparedPaymentRequest, encodedClientMetaInfo may not be null"); 26 | } 27 | 28 | this.encryptedFields = encryptedFields; 29 | this.encodedClientMetaInfo = encodedClientMetaInfo; 30 | } 31 | 32 | 33 | public String getEncodedClientMetaInfo() { 34 | return encodedClientMetaInfo; 35 | } 36 | 37 | public String getEncryptedFields() { 38 | return encryptedFields; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/productsgroup/PaymentProductGroupRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.productsgroup 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.BasicPaymentProductGroups 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.PaymentProductGroup 12 | import io.reactivex.rxjava3.core.Observable 13 | 14 | internal interface PaymentProductGroupRepository { 15 | 16 | fun getPaymentProductGroups( 17 | paymentContext: PaymentContext, 18 | connectSDKConfiguration: ConnectSDKConfiguration 19 | ): Observable> 20 | 21 | fun getPaymentProductGroup( 22 | paymentContext: PaymentContext, 23 | connectSDKConfiguration: ConnectSDKConfiguration, 24 | paymentProductGroupId: String 25 | ): Observable> 26 | } 27 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/AbstractValidationRule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * Abstract class which contains functionality to handle validation. 11 | */ 12 | public abstract class AbstractValidationRule implements Serializable, ValidationRule { 13 | 14 | private static final long serialVersionUID = -1068723487645115780L; 15 | 16 | // Validation message that must be translated 17 | private String messageId; 18 | 19 | // Validationtype 20 | private ValidationType validationType; 21 | 22 | 23 | public AbstractValidationRule(String messageId, ValidationType type) { 24 | 25 | if (messageId == null) { 26 | throw new IllegalArgumentException("Error initialising ValidationRule, messageId may not be null"); 27 | } 28 | if (type == null) { 29 | throw new IllegalArgumentException("Error initialising ValidationRule, type may not be null"); 30 | } 31 | this.messageId = messageId; 32 | this.validationType = type; 33 | } 34 | 35 | 36 | public String getMessageId() { 37 | return messageId; 38 | } 39 | 40 | public ValidationType getType() { 41 | return validationType; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/Tooltip.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import android.graphics.drawable.Drawable; 8 | 9 | import com.google.gson.annotations.SerializedName; 10 | 11 | import java.io.Serializable; 12 | 13 | /** 14 | * POJO that represents a Tooltip object. 15 | * Tooltips are payment product specific and are used to show extra information about an input field. 16 | */ 17 | public class Tooltip implements Serializable { 18 | 19 | private static final long serialVersionUID = -317203058533669043L; 20 | 21 | private String label; 22 | @SerializedName("image") 23 | private String imageURL; 24 | private transient Drawable imageDrawable; 25 | 26 | public String getLabel(){ 27 | return label; 28 | } 29 | 30 | public String getImageURL(){ 31 | return imageURL; 32 | } 33 | 34 | /** 35 | * @deprecated use {@link #getImageURL()} instead. 36 | */ 37 | @Deprecated 38 | public String getImage(){ 39 | return imageURL; 40 | } 41 | 42 | public Drawable getImageDrawable() { 43 | return imageDrawable; 44 | } 45 | 46 | public void setImageDrawable(Drawable imageDrawable){ 47 | this.imageDrawable = imageDrawable; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/FormElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import com.google.gson.annotations.SerializedName; 8 | 9 | import java.io.Serializable; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | /** 14 | * POJO that represents a FormElement object. 15 | * The FormElement is used for determining its list type (text, list, currency, date or boolean). 16 | * In case of a list, it also has values inside the valueMapping. 17 | */ 18 | public class FormElement implements Serializable { 19 | 20 | private static final long serialVersionUID = 7081218270681792356L; 21 | 22 | 23 | public enum ListType { 24 | @SerializedName("text") 25 | TEXT, 26 | 27 | @SerializedName("list") 28 | LIST, 29 | 30 | @SerializedName("currency") 31 | CURRENCY, 32 | 33 | @SerializedName("date") 34 | DATE, 35 | 36 | @SerializedName("boolean") 37 | BOOLEAN, 38 | ; 39 | } 40 | 41 | private ListType type; 42 | private List valueMapping = new ArrayList<>(); 43 | 44 | 45 | public ListType getType(){ 46 | return type; 47 | } 48 | 49 | public List getValueMapping(){ 50 | return valueMapping; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/AmountOfMoney.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | import java.io.Serializable; 8 | 9 | 10 | /** 11 | * POJO that contains money information for a payment. 12 | */ 13 | public class AmountOfMoney implements Serializable { 14 | 15 | private static final long serialVersionUID = 3077405745639575054L; 16 | 17 | private final Long amount; 18 | private final String currencyCode; 19 | 20 | /** 21 | * @param amount the amount in the smallest possible denominator of the provided currency 22 | * @param currencyCode the ISO-4217 Currency Code 23 | * @see ISO 4217 Currency Codes 24 | */ 25 | public AmountOfMoney(Long amount, String currencyCode) { 26 | this.amount = amount; 27 | this.currencyCode = currencyCode; 28 | } 29 | 30 | public Long getAmount() { 31 | return amount; 32 | } 33 | 34 | public String getCurrencyCode() { 35 | return currencyCode; 36 | } 37 | 38 | /** 39 | * @deprecated use {@link #getCurrencyCode()} instead. 40 | */ 41 | @Deprecated 42 | public String getCurrencyCodeString() { 43 | return currencyCode; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/product/PaymentProductService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.product 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentProductDirectoryResponse 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.BasicPaymentProducts 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.PaymentProduct 10 | import io.reactivex.rxjava3.core.Observable 11 | import retrofit2.Response 12 | import retrofit2.http.GET 13 | import retrofit2.http.Path 14 | import retrofit2.http.QueryMap 15 | 16 | internal interface PaymentProductService { 17 | 18 | @GET("products") 19 | fun getPaymentProducts(@QueryMap parameters: Map): Observable> 20 | 21 | @GET("products/{paymentProductId}") 22 | fun getPaymentProduct( 23 | @Path("paymentProductId") paymentProductId: String, 24 | @QueryMap parameters: Map 25 | ): Observable> 26 | 27 | @GET("products/{paymentProductId}/directory") 28 | fun getPaymentProductDirectory( 29 | @Path("paymentProductId") paymentProductId: String, 30 | @QueryMap parameters: Map 31 | ): Observable> 32 | } 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Ingenico Connect - Android SDK 2 | 3 | **This SDK has been rebranded to Worldline. As part of the rebranding the SDK has moved to https://github.com/Worldline-Global-Collect/connect-sdk-client-android.** 4 | 5 | --- 6 | 7 | The Ingenico Connect Android SDK provides a convenient way to support a large number of payment methods inside your Android app. 8 | It supports Lollipop (Api version 21) and up out-of-the box. 9 | The Android SDK comes with an [example application](https:/github.com/Ingenico-ePayments/connect-sdk-client-android-example-kotlin) that illustrates the use of the SDK and the services provided by Ingenico ePayments on the Ingenico ePayments platform. 10 | 11 | See the [Ingenico Connect Developer Hub](https://epayments.developer-ingenico.com/documentation/sdk/mobile/android/) for more information on how to use the SDK. 12 | 13 | # Installation via Gradle 14 | Add an implementation to your build configuration by adding the dependency to your project build.gradle file where `x.y.z` is the version number: 15 | 16 | dependencies { 17 | implementation "com.ingenico.connect.gateway:connect-sdk-client-android:x.y.z' 18 | } 19 | 20 | # Migration Guide 21 | A migration guide was written to help you migrate from version 5 to version 6 of the SDK. This guide explains the new architecture of the SDK, as well as the breaking changes made for version 6. 22 | 23 | You can find the migration guide [here](/documentation/Migration%20Guide%20v5%20to%20v6.md). -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/displayhints/DisplayHintsPaymentItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.displayhints; 6 | 7 | import android.graphics.drawable.Drawable; 8 | 9 | import com.google.gson.annotations.SerializedName; 10 | 11 | import java.io.Serializable; 12 | 13 | /** 14 | * POJO that represents an DisplayHintsPaymentItem object. 15 | */ 16 | public class DisplayHintsPaymentItem implements Serializable{ 17 | 18 | private static final long serialVersionUID = 5783120855027244241L; 19 | 20 | private Integer displayOrder; 21 | private String label; 22 | 23 | @SerializedName("logo") 24 | private String logoUrl; 25 | 26 | private transient Drawable logoDrawable; 27 | 28 | 29 | public Integer getDisplayOrder(){ 30 | return displayOrder; 31 | } 32 | 33 | public String getLabel(){ 34 | return label; 35 | } 36 | 37 | public Drawable getLogo(){ 38 | return logoDrawable; 39 | } 40 | 41 | public String getLogoUrl() { 42 | return logoUrl; 43 | } 44 | 45 | public void setDisplayOrder(Integer displayOrder) { 46 | this.displayOrder = displayOrder; 47 | } 48 | 49 | public void setLogo(Drawable logoDrawable){ 50 | this.logoDrawable = logoDrawable; 51 | } 52 | 53 | public void setLogoUrl(String logoUrl) { 54 | this.logoUrl = logoUrl; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationErrorMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * Contains error message information for a specific field. 11 | */ 12 | public class ValidationErrorMessage implements Serializable { 13 | 14 | private static final long serialVersionUID = 5842038484067693459L; 15 | 16 | private String errorMessage; 17 | private String paymentProductFieldId; 18 | private ValidationRule rule; 19 | 20 | public ValidationErrorMessage(String errorMessage, String paymentProductFieldId, ValidationRule rule) { 21 | 22 | if (errorMessage == null) { 23 | throw new IllegalArgumentException("Error creating ValidationErrorMessage, errorMessage may not be null"); 24 | } 25 | if (paymentProductFieldId == null) { 26 | throw new IllegalArgumentException("Error creating ValidationErrorMessage, paymentProductFieldId may not be null"); 27 | } 28 | 29 | this.errorMessage = errorMessage; 30 | this.paymentProductFieldId = paymentProductFieldId; 31 | this.rule = rule; 32 | } 33 | 34 | 35 | public String getErrorMessage() { 36 | return errorMessage; 37 | } 38 | 39 | public String getPaymentProductFieldId() { 40 | return paymentProductFieldId; 41 | } 42 | 43 | public ValidationRule getRule() { 44 | return rule; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/configuration/SessionConfiguration.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.configuration 6 | 7 | import java.util.Locale 8 | 9 | data class SessionConfiguration( 10 | val clientSessionId: String, 11 | val customerId: String, 12 | val clientApiUrl: String, 13 | val assetUrl: String, 14 | ) { 15 | 16 | internal fun getFormattedClientApiUrl(): String { 17 | var formattedClientApiUrl = clientApiUrl 18 | 19 | // The URL must always end with a slash 20 | if (!formattedClientApiUrl.endsWith("/")) { 21 | formattedClientApiUrl = "$formattedClientApiUrl/" 22 | } 23 | 24 | // Check if the URL is correct 25 | if (formattedClientApiUrl.lowercase(Locale.ROOT).endsWith(API_PATH)) { 26 | return formattedClientApiUrl 27 | } 28 | 29 | // Add the version if it is missing 30 | if (formattedClientApiUrl.lowercase(Locale.ROOT).endsWith(API_BASE)) { 31 | return formattedClientApiUrl + API_VERSION 32 | } 33 | 34 | // Add the complete API path to the provided URL 35 | return formattedClientApiUrl + API_PATH 36 | } 37 | 38 | private companion object { 39 | 40 | const val API_VERSION = "v1/" 41 | const val API_BASE = "client/" 42 | const val API_PATH = API_BASE + API_VERSION 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/iin/IinDetail.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO that contains IinDetail. 11 | */ 12 | public class IinDetail implements Serializable { 13 | 14 | private static final long serialVersionUID = 6951132953680660913L; 15 | 16 | private String paymentProductId; 17 | private boolean isAllowedInContext; 18 | 19 | public String getPaymentProductId() { 20 | return paymentProductId; 21 | } 22 | 23 | public boolean isAllowedInContext() { 24 | return isAllowedInContext; 25 | } 26 | 27 | @Override 28 | public boolean equals(Object o) { 29 | 30 | if (this == o) { 31 | return true; 32 | } 33 | 34 | if (o == null || o.getClass() != getClass()) { 35 | return false; 36 | } 37 | 38 | IinDetail otherDetail = (IinDetail)o; 39 | return (paymentProductId != null ? paymentProductId.equals(otherDetail.getPaymentProductId()) : otherDetail.paymentProductId == null) && 40 | isAllowedInContext() == otherDetail.isAllowedInContext(); 41 | } 42 | 43 | @Override 44 | public int hashCode() { 45 | int hash = 17; 46 | hash = 31 * hash + (paymentProductId != null ? paymentProductId.hashCode() : 0); 47 | hash = 31 * hash + Boolean.valueOf(isAllowedInContext).hashCode(); 48 | return hash; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/product/PaymentProductRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.product 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentProductDirectoryResponse 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.BasicPaymentProducts 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.PaymentProduct 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 13 | import io.reactivex.rxjava3.core.Observable 14 | 15 | internal interface PaymentProductRepository { 16 | 17 | fun getPaymentProducts( 18 | paymentContext: PaymentContext, 19 | connectSDKConfiguration: ConnectSDKConfiguration 20 | ): Observable> 21 | 22 | fun getPaymentProduct( 23 | paymentContext: PaymentContext, 24 | connectSDKConfiguration: ConnectSDKConfiguration, 25 | paymentProductId: String 26 | ): Observable> 27 | 28 | fun getPaymentProductDirectory( 29 | paymentContext: PaymentContext, 30 | connectSDKConfiguration: ConnectSDKConfiguration, 31 | paymentProductId: String 32 | ): Observable> 33 | } 34 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/support/SupportService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.support 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.ConvertedAmountResponse 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PublicKeyResponse 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.ThirdPartyStatusResponse 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin.IinDetailsRequest 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin.IinDetailsResponse 12 | import io.reactivex.rxjava3.core.Observable 13 | import retrofit2.Response 14 | import retrofit2.http.Body 15 | import retrofit2.http.GET 16 | import retrofit2.http.Headers 17 | import retrofit2.http.Path 18 | import retrofit2.http.POST 19 | import retrofit2.http.QueryMap 20 | 21 | internal interface SupportService { 22 | 23 | @Headers("Content-Type: application/json") 24 | @POST("services/getIINdetails") 25 | fun getIINDetails(@Body iinDetailsRequest: IinDetailsRequest): Observable> 26 | 27 | @GET("crypto/publickey") 28 | fun getPublicKey(): Observable> 29 | 30 | @GET("payments/{paymentId}/thirdpartystatus") 31 | fun getThirdPartyStatus(@Path("paymentId") paymentId: String): Observable> 32 | 33 | @GET("services/convert/amount") 34 | fun convertAmount(@QueryMap parameters: Map): Observable> 35 | } 36 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/support/SupportRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.support 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.ConvertedAmountResponse 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PublicKeyResponse 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.ThirdPartyStatusResponse 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin.IinDetailsResponse 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 14 | import io.reactivex.rxjava3.core.Observable 15 | 16 | internal interface SupportRepository { 17 | 18 | fun getIINDetails( 19 | paymentContext: PaymentContext, 20 | connectSDKConfiguration: ConnectSDKConfiguration, 21 | bin: String 22 | ): Observable> 23 | 24 | fun getPublicKey(connectSDKConfiguration: ConnectSDKConfiguration): Observable> 25 | 26 | fun getThirdPartyStatus( 27 | connectSDKConfiguration: ConnectSDKConfiguration, 28 | paymentId: String 29 | ): Observable> 30 | 31 | fun convertAmount( 32 | connectSDKConfiguration: ConnectSDKConfiguration, 33 | source: String, 34 | target: String, 35 | amount: Long 36 | ): Observable> 37 | } 38 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/support/GetIINDetails.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.support 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin.IinDetailsResponse 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin.IinStatus 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 12 | import io.reactivex.rxjava3.core.Observable 13 | 14 | internal class GetIINDetails { 15 | 16 | operator fun invoke( 17 | paymentContext: PaymentContext, 18 | connectSDKConfiguration: ConnectSDKConfiguration, 19 | bin: String 20 | ): Observable> { 21 | 22 | return if (bin.length < MINIMUM_BIN_LENGTH) { 23 | Observable.just(NetworkResponse.Success(IinDetailsResponse(IinStatus.NOT_ENOUGH_DIGITS))) 24 | } else { 25 | RemoteSupportRepository().getIINDetails( 26 | paymentContext, connectSDKConfiguration, bin.take(MINIMUM_BIN_LENGTH) 27 | ).map { 28 | if (it.data?.isAllowedInContext == false) { 29 | it.data.status = IinStatus.EXISTING_BUT_NOT_ALLOWED 30 | } else { 31 | it.data?.status = IinStatus.SUPPORTED 32 | } 33 | it 34 | } 35 | } 36 | } 37 | 38 | private companion object { 39 | 40 | const val MINIMUM_BIN_LENGTH = 6 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/configuration/ConnectSDKConfiguration.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.configuration 6 | 7 | import android.content.Context 8 | 9 | class ConnectSDKConfiguration private constructor( 10 | val sessionConfiguration: SessionConfiguration, 11 | val applicationContext: Context, 12 | val enableNetworkLogs: Boolean, 13 | val applicationId: String?, 14 | val ipAddress: String?, 15 | val preLoadImages: Boolean 16 | ) { 17 | 18 | data class Builder( 19 | var sessionConfiguration: SessionConfiguration, 20 | var applicationContext: Context, 21 | var enableNetworkLogs: Boolean = false, 22 | var applicationId: String? = null, 23 | var ipAddress: String? = null, 24 | var preLoadImages: Boolean = true 25 | ) { 26 | constructor(sessionConfiguration: SessionConfiguration, applicationContext: Context) : this( 27 | sessionConfiguration,applicationContext, false, null, null, true 28 | ) 29 | 30 | fun enableNetworkLogs(enableNetworkLogs: Boolean) = 31 | apply { this.enableNetworkLogs = enableNetworkLogs } 32 | 33 | fun applicationId(applicationId: String) = 34 | apply { this.applicationId = applicationId } 35 | 36 | fun ipAddress(ipAddress: String) = 37 | apply { this.ipAddress = ipAddress } 38 | 39 | fun preLoadImages(preLoadImages: Boolean) = 40 | apply { this.preLoadImages = preLoadImages } 41 | 42 | fun build() = ConnectSDKConfiguration( 43 | sessionConfiguration, 44 | applicationContext, 45 | enableNetworkLogs, 46 | applicationId, 47 | ipAddress, 48 | preLoadImages 49 | ) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/KeyValuePair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO that represents an KeyValuePair object. 11 | * The KeyValuePairs contains the information from the {@link AccountOnFile}. 12 | */ 13 | public class KeyValuePair implements Serializable { 14 | 15 | private static final long serialVersionUID = -8520100614239969197L; 16 | 17 | /** 18 | * Enum containing all the possible KeyValuePair statuses 19 | */ 20 | public enum Status { 21 | 22 | READ_ONLY(false), 23 | CAN_WRITE(true), 24 | MUST_WRITE(true); 25 | 26 | private boolean isEditingAllowed; 27 | 28 | Status(boolean isEditingAllowed) { 29 | this.isEditingAllowed = isEditingAllowed; 30 | } 31 | 32 | public boolean isEditingAllowed() { 33 | return isEditingAllowed; 34 | } 35 | } 36 | 37 | private String key; 38 | private String value; 39 | private Status status; 40 | private String mustWriteReason; 41 | 42 | 43 | public String getKey() { 44 | return key; 45 | } 46 | 47 | public void setKey(String key) { 48 | this.key = key; 49 | } 50 | 51 | public String getValue() { 52 | return value; 53 | } 54 | 55 | public void setValue(String value) { 56 | this.value = value; 57 | } 58 | 59 | public Status getStatus() { 60 | return status; 61 | } 62 | 63 | public void setStatus(Status status) { 64 | this.status = status; 65 | } 66 | 67 | public String getMustWriteReason() { 68 | return mustWriteReason; 69 | } 70 | 71 | public void setMustWriteReason(String mustWriteReason) { 72 | this.mustWriteReason = mustWriteReason; 73 | } 74 | 75 | public boolean isEditingAllowed() { 76 | return status != null && status.isEditingAllowed(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/validation/Validator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.validation; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the Validator data. 11 | * Containing all the validation types. 12 | */ 13 | public class Validator implements Serializable { 14 | 15 | private static final long serialVersionUID = 8524174888810141991L; 16 | 17 | private ExpirationDate expirationDate; 18 | private EmailAddress emailAddress; 19 | private IBAN iban; 20 | private FixedList fixedList; 21 | private Length length; 22 | private Luhn luhn; 23 | private Range range; 24 | private RegularExpression regularExpression; 25 | private BoletoBancarioRequiredness boletoBancarioRequiredness; 26 | private TermsAndConditions termsAndConditions; 27 | private ResidentIdNumber residentIdNumber; 28 | 29 | public ExpirationDate getExpirationDate(){ 30 | return expirationDate; 31 | } 32 | 33 | public EmailAddress getEmailAddress(){ 34 | return emailAddress; 35 | } 36 | 37 | public FixedList getFixedList(){ 38 | return fixedList; 39 | } 40 | 41 | public IBAN getIBAN(){ return iban; } 42 | 43 | public Length getLength(){ 44 | return length; 45 | } 46 | 47 | public Luhn getLuhn(){ 48 | return luhn; 49 | } 50 | 51 | public Range getRange(){ 52 | return range; 53 | } 54 | 55 | public RegularExpression getRegularExpression(){ 56 | return regularExpression; 57 | } 58 | 59 | public BoletoBancarioRequiredness getBoletoBancarioRequiredness() { 60 | return boletoBancarioRequiredness; 61 | } 62 | 63 | public TermsAndConditions getTermsAndConditions() { 64 | return termsAndConditions; 65 | } 66 | 67 | public ResidentIdNumber getResidentIdNumber() { 68 | return residentIdNumber; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/encryption/EncryptDataJsonSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.encryption; 6 | 7 | import com.google.gson.JsonArray; 8 | import com.google.gson.JsonElement; 9 | import com.google.gson.JsonObject; 10 | import com.google.gson.JsonSerializationContext; 11 | import com.google.gson.JsonSerializer; 12 | 13 | import java.lang.reflect.Type; 14 | import java.util.Map.Entry; 15 | 16 | class EncryptDataJsonSerializer implements JsonSerializer { 17 | 18 | @Override 19 | public JsonElement serialize(EncryptData encryptData, Type type, JsonSerializationContext context) { 20 | 21 | JsonObject jsonObject = new JsonObject(); 22 | 23 | if (encryptData.getTokenize() != null && encryptData.getTokenize()) { 24 | jsonObject.addProperty("tokenize", encryptData.getTokenize()); 25 | } 26 | 27 | if (encryptData.getPaymentProductId() != null) { 28 | jsonObject.addProperty("paymentProductId", encryptData.getPaymentProductId()); 29 | } 30 | 31 | if (encryptData.getAccountOnFileId() != null) { 32 | jsonObject.addProperty("accountOnFileId", encryptData.getAccountOnFileId()); 33 | } 34 | 35 | if (encryptData.getClientSessionId() != null && !encryptData.getClientSessionId().isEmpty()) { 36 | jsonObject.addProperty("clientSessionId", encryptData.getClientSessionId()); 37 | } 38 | 39 | if (encryptData.getNonce() != null && !encryptData.getNonce().isEmpty()) { 40 | jsonObject.addProperty("nonce", encryptData.getNonce()); 41 | } 42 | 43 | JsonArray paymentValues = new JsonArray(); 44 | for (Entry entry : encryptData.getPaymentValues().entrySet()) { 45 | 46 | JsonObject paymentValue = new JsonObject(); 47 | paymentValue.addProperty("key", entry.getKey()); 48 | paymentValue.addProperty("value", entry.getValue()); 49 | paymentValues.add(paymentValue); 50 | } 51 | 52 | jsonObject.add("paymentValues", paymentValues); 53 | return jsonObject; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/AccountOnFileTest.kt: -------------------------------------------------------------------------------- 1 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct 2 | 3 | import com.ingenico.connect.gateway.sdk.client.android.testUtil.GsonHelper 4 | import org.junit.Assert.assertEquals 5 | import org.junit.Assert.assertFalse 6 | import org.junit.Assert.assertTrue 7 | import org.junit.Test 8 | import org.junit.runner.RunWith 9 | import org.mockito.junit.MockitoJUnitRunner 10 | 11 | /** 12 | * Junit Testclass which tests account on file keyvaluepairs and masking 13 | */ 14 | @RunWith(MockitoJUnitRunner::class) 15 | class AccountOnFileTest { 16 | private val accountOnFile: AccountOnFile = GsonHelper.fromResourceJson( 17 | "accountOnFileVisa.json", 18 | AccountOnFile::class.java 19 | ) 20 | 21 | @Test 22 | fun testIsEditingAllowed() { 23 | val aofaAlias: KeyValuePair = accountOnFile.attributes[0] 24 | assertFalse(aofaAlias.isEditingAllowed) 25 | val aofaFirstName: KeyValuePair = 26 | accountOnFile.attributes[1] 27 | assertFalse(aofaFirstName.isEditingAllowed) 28 | val aofaSurname: KeyValuePair = accountOnFile.attributes[2] 29 | assertFalse(aofaSurname.isEditingAllowed) 30 | val aofaCardholderName: KeyValuePair = 31 | accountOnFile.attributes[3] 32 | assertFalse(aofaCardholderName.isEditingAllowed) 33 | val aofaCardNumber: KeyValuePair = 34 | accountOnFile.attributes[4] 35 | assertFalse(aofaCardNumber.isEditingAllowed) 36 | val aofaCvv: KeyValuePair = accountOnFile.attributes[5] 37 | assertTrue(aofaCvv.isEditingAllowed) 38 | val aofaExpiryDate: KeyValuePair = 39 | accountOnFile.attributes[6] 40 | assertTrue(aofaExpiryDate.isEditingAllowed) 41 | } 42 | 43 | @Test 44 | fun testMaskingValue() { 45 | assertEquals("4111 11XX XXXX 1111 ", accountOnFile.getMaskedValue("alias")) 46 | } 47 | 48 | @Test 49 | fun testCustomMaskingValue() { 50 | assertEquals("41 111", accountOnFile.getMaskedValue("alias", "{{xx}} {{xxx}}")) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | POM_GROUP_ID=com.ingenico.connect.gateway 20 | POM_ARTIFACT_ID=connect-sdk-client-android 21 | POM_VERSION=6.2.0 22 | POM_NAME=connect-sdk-client-android 23 | POM_DESCRIPTION=SDK to communicate with the Ingenico ePayments platform using the Ingenico Connect Client API 24 | POM_URL=https://github.com/Ingenico-ePayments/connect-sdk-client-android 25 | 26 | POM_ORGANIZATION_NAME=Ingenico ePayments 27 | POM_ORGANIZATION_URL=https://www.ingenico.com/epayments/ 28 | 29 | POM_LICENSE_NAME=MIT 30 | POM_LICENSE_URL=https://github.com/Ingenico-ePayments/connect-sdk-client-android/blob/master/LICENSE.txt 31 | 32 | POM_DEVELOPER_NAME=Ingenico ePayments 33 | POM_DEVELOPER_EMAIL=github@epay.ingenico.com 34 | POM_DEVELOPER_ORGANIZATION=Ingenico ePayments 35 | POM_DEVELOPER_ORGANIZATIONURL=https://www.ingenico.com/epayments/ 36 | 37 | POM_SCM_CONNECTION=scm:git:git@github.com:Ingenico-ePayments/connect-sdk-client-android.git 38 | POM_SCM_DEVELOPERCONNECTION=scm:git:git@github.com:Ingenico-ePayments/connect-sdk-client-android.git 39 | POM_SCM_URL=https://github.com/Ingenico-ePayments/connect-sdk-client-android 40 | 41 | POM_ISSUEMANAGEMENT_SYSTEM=GitHub 42 | POM_ISSUEMANAGEMENT_URL=https://github.com/Ingenico-ePayments/connect-sdk-client-android/issues 43 | android.useAndroidX=true 44 | android.enableJetifier=true 45 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleTermsAndConditions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | 9 | /** 10 | * Validation rule for terms and conditions. 11 | */ 12 | public class ValidationRuleTermsAndConditions extends AbstractValidationRule { 13 | 14 | private static final long serialVersionUID = 2209679897444037061L; 15 | 16 | private static final String TAG = ValidationRuleTermsAndConditions.class.getName(); 17 | 18 | /** 19 | * @deprecated This constructor is for internal use only. 20 | */ 21 | @Deprecated 22 | public ValidationRuleTermsAndConditions() { 23 | super("termsAndConditions", ValidationType.TERMSANDCONDITIONS); 24 | } 25 | 26 | /** 27 | * @deprecated In a future release, this constructor will be removed. 28 | */ 29 | @Deprecated 30 | public ValidationRuleTermsAndConditions(String errorMessage, ValidationType type) { 31 | super(errorMessage, type); 32 | } 33 | 34 | /** 35 | * Validates that the terms and conditions have been accepted. 36 | * 37 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 38 | * @param fieldId the ID of the field to which to apply the current validator 39 | * 40 | * @return true, if the value in the field with fieldId is true; false, if the value in the field is false or if the fieldId could not be found 41 | */ 42 | @Override 43 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 44 | if (paymentRequest == null) { 45 | throw new IllegalArgumentException("Error validating, paymentRequest may not be null"); 46 | } 47 | if (fieldId == null) { 48 | throw new IllegalArgumentException("Error validating, fieldId may not be null"); 49 | } 50 | 51 | String value = paymentRequest.getValue(fieldId); 52 | return Boolean.parseBoolean(value); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/encryption/EncryptData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.encryption; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.Failure; 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.Success; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | /** 15 | * POJO which contains all the possible EncryptData fields. 16 | * 17 | * @deprecated This class will become internal to the SDK. Use {@link com.ingenico.connect.gateway.sdk.client.android.ConnectSDK#encryptPaymentRequest(PaymentRequest, Success, Failure)} for encryption instead. 18 | */ 19 | @Deprecated 20 | public class EncryptData { 21 | 22 | Integer accountOnFileId; 23 | String clientSessionId; 24 | String nonce; 25 | Integer paymentProductId; 26 | Boolean tokenize; 27 | Map paymentValues = new HashMap<>(); 28 | 29 | public void setAccountOnFileId(Integer accountOnFileId) { 30 | this.accountOnFileId = accountOnFileId; 31 | } 32 | 33 | public void setClientSessionId(String clientSessionId) { 34 | this.clientSessionId = clientSessionId; 35 | } 36 | 37 | public void setPaymentProductId(Integer paymentProductId) { 38 | this.paymentProductId = paymentProductId; 39 | } 40 | 41 | public void setPaymentValues(Map paymentValues) { 42 | this.paymentValues = paymentValues; 43 | } 44 | 45 | public void setTokenize(Boolean tokenize) { 46 | this.tokenize = tokenize; 47 | } 48 | 49 | public void setNonce(String nonce) { 50 | this.nonce = nonce; 51 | } 52 | 53 | public Integer getAccountOnFileId() { 54 | return accountOnFileId; 55 | } 56 | 57 | public String getClientSessionId() { 58 | return clientSessionId; 59 | } 60 | 61 | public String getNonce() { 62 | return nonce; 63 | } 64 | 65 | public Integer getPaymentProductId() { 66 | return paymentProductId; 67 | } 68 | 69 | public Boolean getTokenize() { 70 | return tokenize; 71 | } 72 | 73 | public Map getPaymentValues() { 74 | return paymentValues; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/paymentProductInVoice.json: -------------------------------------------------------------------------------- 1 | { 2 | "allowsRecurring" : false, 3 | "allowsTokenization" : false, 4 | "autoTokenized" : false, 5 | "displayHints" : { 6 | "displayOrder" : 11, 7 | "label" : "Factuur", 8 | "logo" : "templates/master/global/css/img/ppimages/pp_logo_201_v1.png" 9 | }, 10 | "fields" : [ { 11 | "dataRestrictions" : { 12 | "isRequired" : false, 13 | "validators" : { 14 | "length" : { 15 | "maxLength" : 9, 16 | "minLength" : 0 17 | } 18 | } 19 | }, 20 | "displayHints" : { 21 | "alwaysShow" : false, 22 | "displayOrder" : 1, 23 | "formElement" : { 24 | "type" : "text" 25 | }, 26 | "label" : "Code staat", 27 | "obfuscate" : false, 28 | "placeholderLabel" : "Code staat", 29 | "preferredInputType" : "StringKeyboard" 30 | }, 31 | "id" : "stateCode", 32 | "type" : "string" 33 | }, { 34 | "dataRestrictions" : { 35 | "isRequired" : true, 36 | "validators" : { 37 | "length" : { 38 | "maxLength" : 40, 39 | "minLength" : 0 40 | } 41 | } 42 | }, 43 | "displayHints" : { 44 | "alwaysShow" : false, 45 | "displayOrder" : 20, 46 | "formElement" : { 47 | "type" : "text" 48 | }, 49 | "label" : "Stad", 50 | "obfuscate" : false, 51 | "placeholderLabel" : "Stad", 52 | "preferredInputType" : "StringKeyboard" 53 | }, 54 | "id" : "city", 55 | "type" : "string" 56 | }, { 57 | "dataRestrictions" : { 58 | "isRequired" : false, 59 | "validators" : { 60 | "length" : { 61 | "maxLength" : 50, 62 | "minLength" : 0 63 | } 64 | } 65 | }, 66 | "displayHints" : { 67 | "alwaysShow" : false, 68 | "displayOrder" : 600, 69 | "formElement" : { 70 | "type" : "text" 71 | }, 72 | "label" : "Straat", 73 | "obfuscate" : false, 74 | "placeholderLabel" : "Straat", 75 | "preferredInputType" : "StringKeyboard" 76 | }, 77 | "id" : "street", 78 | "type" : "string" 79 | } ], 80 | "id" : 201, 81 | "mobileIntegrationLevel" : "OPTIMISED_SUPPORT", 82 | "paymentMethod" : "invoice" 83 | } -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/drawable/RemoteDrawableRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.drawable 6 | 7 | import android.content.Context 8 | import android.graphics.BitmapFactory 9 | import android.graphics.drawable.BitmapDrawable 10 | import android.graphics.drawable.Drawable 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.OkHttpClientBuilder 13 | import io.reactivex.rxjava3.core.Observable 14 | import io.reactivex.rxjava3.core.ObservableSource 15 | import okhttp3.ResponseBody 16 | import retrofit2.Retrofit 17 | import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory 18 | 19 | internal class RemoteDrawableRepository : DrawableRepository { 20 | 21 | override fun getDrawableFromUrl( 22 | connectSDKConfiguration: ConnectSDKConfiguration, 23 | drawableUrl: String 24 | ): Observable { 25 | return getDrawableService(connectSDKConfiguration).getDrawableFromUrl(drawableUrl) 26 | .flatMap { response -> 27 | mapResponseToDrawable(connectSDKConfiguration.applicationContext, response) 28 | } 29 | } 30 | 31 | private fun mapResponseToDrawable( 32 | context: Context, 33 | response: ResponseBody 34 | ): ObservableSource { 35 | val bitmap = BitmapFactory.decodeStream(response.byteStream()) 36 | return Observable.just(BitmapDrawable(context.resources, bitmap)) 37 | } 38 | 39 | private companion object { 40 | 41 | fun getDrawableService(connectSdkConfiguration: ConnectSDKConfiguration): DrawableService = 42 | Retrofit.Builder() 43 | .baseUrl(connectSdkConfiguration.sessionConfiguration.assetUrl) 44 | .client( 45 | OkHttpClientBuilder.okHttpClient( 46 | connectSdkConfiguration 47 | ) 48 | ) 49 | .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) 50 | .build() 51 | .create(DrawableService::class.java) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/PaymentProduct.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import java.io.Serializable; 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.Comparator; 11 | import java.util.List; 12 | 13 | /** 14 | * POJO which holds the {@link BasicPaymentProduct} data and its paymentProductFields. 15 | */ 16 | public class PaymentProduct extends BasicPaymentProduct implements PaymentItem, Serializable { 17 | 18 | private static final long serialVersionUID = -8362704974696989741L; 19 | 20 | 21 | private boolean hasBeenSorted = false; 22 | 23 | private List fields = new ArrayList<>(); 24 | private String fieldsWarning; 25 | 26 | public List getPaymentProductFields() { 27 | sortList(); 28 | return fields; 29 | } 30 | 31 | public String getFieldsWarning() { 32 | return fieldsWarning; 33 | } 34 | 35 | public void setPaymentProductFields(List paymentProductFields) { 36 | this.fields = paymentProductFields; 37 | sortList(); 38 | } 39 | 40 | public PaymentProductField getPaymentProductFieldById(String id) { 41 | 42 | for(PaymentProductField field : fields) { 43 | if(field.getId().equals(id)) { 44 | return field; 45 | } 46 | } 47 | return null; 48 | } 49 | 50 | 51 | private void sortList(){ 52 | 53 | if (!hasBeenSorted) { 54 | Collections.sort(fields, new Comparator() { 55 | public int compare(PaymentProductField field1, PaymentProductField field2) { 56 | if (field1 == field2) return 0; 57 | if (field1 == null) return -1; 58 | if (field2 == null) return 1; 59 | 60 | Integer displayOrder1 = field1.getDisplayHints().getDisplayOrder(); 61 | Integer displayOrder2 = field2.getDisplayHints().getDisplayOrder(); 62 | 63 | if (displayOrder1 == null) return -1; 64 | if (displayOrder2 == null) return 1; 65 | if (displayOrder1.equals(displayOrder2)) return 0; 66 | return displayOrder1.compareTo(displayOrder2); 67 | } 68 | }); 69 | hasBeenSorted = true; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleRegex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | 9 | /** 10 | * Validation rule for regex. 11 | */ 12 | public class ValidationRuleRegex extends AbstractValidationRule { 13 | 14 | private static final long serialVersionUID = 5054525275294003657L; 15 | 16 | private static final String TAG = ValidationRuleRegex.class.getName(); 17 | 18 | private String regex; 19 | 20 | /** 21 | * @deprecated This constructor is for internal use only. 22 | */ 23 | @Deprecated 24 | public ValidationRuleRegex(String regex) { 25 | super("regularExpression", ValidationType.REGULAREXPRESSION); 26 | 27 | if (regex == null) { 28 | throw new IllegalArgumentException("Error initialising ValidationRuleRegex, regex may not be null"); 29 | } 30 | 31 | this.regex = regex; 32 | } 33 | 34 | /** 35 | * @deprecated In a future release, this constructor will be removed. 36 | */ 37 | @Deprecated 38 | public ValidationRuleRegex(String regex, String errorMessage, ValidationType type) { 39 | super(errorMessage, type); 40 | 41 | if (regex == null) { 42 | throw new IllegalArgumentException("Error initialising ValidationRuleRegex, regex may not be null"); 43 | } 44 | 45 | this.regex = regex; 46 | } 47 | 48 | /** 49 | * Validates that the value in the field with fieldId matches the regular expression of this validator. 50 | * 51 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 52 | * @param fieldId the ID of the field to which to apply the current validator 53 | * 54 | * @return true, if the value in the field with fieldId matches the regex; false, if it doesn't or if the fieldId could not be found 55 | */ 56 | @Override 57 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 58 | 59 | String text = paymentRequest.getValue(fieldId); 60 | 61 | if (text == null) { 62 | return false; 63 | } 64 | 65 | text = paymentRequest.getUnmaskedValue(fieldId, text); 66 | 67 | return text.matches(regex); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleLuhn.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | 9 | /** 10 | * Validation rule for luhn check. 11 | */ 12 | public class ValidationRuleLuhn extends AbstractValidationRule { 13 | 14 | private static final long serialVersionUID = -6609650480352325271L; 15 | 16 | private static final String TAG = ValidationRuleLuhn.class.getName(); 17 | 18 | /** 19 | * @deprecated This constructor is for internal use only. 20 | */ 21 | @Deprecated 22 | public ValidationRuleLuhn() { 23 | super("luhn", ValidationType.LUHN); 24 | } 25 | 26 | /** 27 | * @deprecated In a future release, this constructor will be removed. 28 | */ 29 | @Deprecated 30 | public ValidationRuleLuhn(String errorMessage, ValidationType type) { 31 | super(errorMessage, type); 32 | } 33 | 34 | /** 35 | * Validates that the value in the field with fieldId passes the Luhn check. 36 | * 37 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 38 | * @param fieldId the ID of the field to which to apply the current validator 39 | * 40 | * @return true, if the value in the field with fieldId passes the Luhn check; false, if it doesn't or if the fieldId could not be found 41 | */ 42 | @Override 43 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 44 | 45 | String text = paymentRequest.getValue(fieldId); 46 | 47 | if (text == null) { 48 | return false; 49 | } 50 | 51 | text = text.replaceAll(" ", ""); 52 | if (text.length() < 12) { 53 | return false; 54 | } 55 | 56 | int sum = 0; 57 | boolean alternate = false; 58 | 59 | for (int i = text.length() - 1; i >= 0; i--) { 60 | 61 | int n = Character.digit(text.charAt(i), 10); 62 | if (n == -1) { 63 | // not a valid number 64 | return false; 65 | } 66 | 67 | if (alternate) { 68 | n *= 2; 69 | 70 | if (n > 9) { 71 | n = (n % 10) + 1; 72 | } 73 | } 74 | sum += n; 75 | alternate = !alternate; 76 | } 77 | 78 | return (sum % 10 == 0); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/PaymentProductGroup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import java.io.Serializable; 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.Comparator; 11 | import java.util.List; 12 | import java.util.Objects; 13 | 14 | /** 15 | * POJO which holds the {@link BasicPaymentProductGroup} data and its paymentProductFields. 16 | */ 17 | public class PaymentProductGroup extends BasicPaymentProductGroup implements PaymentItem, Serializable { 18 | 19 | private static final long serialVersionUID = 7205708292113705649L; 20 | 21 | 22 | private boolean hasBeenSorted = false; 23 | 24 | private List fields = new ArrayList<>(); 25 | 26 | public List getPaymentProductFields() { 27 | sortList(); 28 | return fields; 29 | } 30 | 31 | public PaymentProductField getPaymentProductFieldById(String id) { 32 | 33 | for(PaymentProductField field : fields) { 34 | if(field.getId().equals(id)) { 35 | return field; 36 | } 37 | } 38 | return null; 39 | } 40 | 41 | 42 | private void sortList(){ 43 | 44 | if (!hasBeenSorted) { 45 | Collections.sort(fields, new Comparator() { 46 | public int compare(PaymentProductField field1, PaymentProductField field2) { 47 | if (Objects.equals(field1, field2)) return 0; 48 | if (field1 == null) return -1; 49 | if (field2 == null) return 1; 50 | 51 | Integer displayOrder1 = field1.getDisplayHints().getDisplayOrder(); 52 | Integer displayOrder2 = field2.getDisplayHints().getDisplayOrder(); 53 | 54 | if (Objects.equals(displayOrder1, displayOrder2)) return 0; 55 | if (displayOrder1 == null) return -1; 56 | if (displayOrder2 == null) return 1; 57 | return displayOrder1.compareTo(displayOrder2); 58 | } 59 | }); 60 | hasBeenSorted = true; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleEmailAddress.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | 9 | /** 10 | * Validation rule for email address. 11 | */ 12 | public class ValidationRuleEmailAddress extends AbstractValidationRule { 13 | 14 | private static final long serialVersionUID = -2476401279131525956L; 15 | 16 | private static final String TAG = ValidationRuleEmailAddress.class.getName(); 17 | 18 | private static final String EMAIL_REGEX = "[^@\\.]+(\\.[^@\\.]+)*@([^@\\.]+\\.)*[^@\\.]+\\.[^@\\.][^@\\.]+"; 19 | 20 | /** 21 | * @deprecated This constructor is for internal use only. 22 | */ 23 | @Deprecated 24 | public ValidationRuleEmailAddress() { 25 | super("emailAddress", ValidationType.EMAILADDRESS); 26 | } 27 | 28 | /** 29 | * @deprecated In a future release, this constructor will be removed. 30 | */ 31 | @Deprecated 32 | public ValidationRuleEmailAddress(String errorMessage, ValidationType type) { 33 | super(errorMessage, type); 34 | } 35 | 36 | /** 37 | * Validates an email address. 38 | * 39 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 40 | * @param fieldId the ID of the field to which to apply the current validator 41 | * 42 | * @return true, if the value in the field with fieldId is a valid e-mail address; false, if it is not a valid email address or if the fieldId could not be found 43 | */ 44 | @Override 45 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 46 | if (paymentRequest == null) { 47 | throw new IllegalArgumentException("Error validating email address, paymentRequest may not be null"); 48 | } 49 | if (fieldId == null) { 50 | throw new IllegalArgumentException("Error validating email address, fieldId may not be null"); 51 | } 52 | 53 | String text = paymentRequest.getValue(fieldId); 54 | 55 | if (text == null) { 56 | return false; 57 | } 58 | 59 | text = paymentRequest.getUnmaskedValue(fieldId, text); 60 | 61 | // Check whether text matches the regex for email addresses 62 | return text.matches(EMAIL_REGEX); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/network/extension/RXJavaExtension.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.network.extension 6 | 7 | import com.google.gson.Gson 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.ApiError 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.ApiErrorResponse 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.Failure 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.Success 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.UnknownNetworkResponseException 14 | import io.reactivex.rxjava3.core.Observable 15 | import io.reactivex.rxjava3.core.ObservableSource 16 | import io.reactivex.rxjava3.disposables.Disposable 17 | import retrofit2.Response 18 | 19 | internal fun Observable>.subscribeAndMapNetworkResponse( 20 | onSuccess: Success, 21 | onApiError: ApiError, 22 | onFailure: Failure 23 | ): Disposable = 24 | subscribe( 25 | { networkResponse -> 26 | when (networkResponse) { 27 | is NetworkResponse.ApiError -> networkResponse.apiErrorResponse?.let { 28 | (onApiError::apiError)( 29 | it 30 | ) 31 | } ?: (onFailure::failure)(UnknownNetworkResponseException) 32 | is NetworkResponse.Success -> networkResponse.data?.let { 33 | (onSuccess::success)( 34 | it 35 | ) 36 | } ?: (onFailure::failure)(UnknownNetworkResponseException) 37 | } 38 | }, { 39 | (onFailure::failure)(it) 40 | } 41 | ) 42 | 43 | internal fun mapRetrofitResponseToNetworkResponse(response: Response): ObservableSource> { 44 | return if (response.isSuccessful) { 45 | Observable.just(NetworkResponse.Success(response.body()!!)) 46 | } else { 47 | val errorResponse: ApiErrorResponse = Gson().fromJson( 48 | response.errorBody()?.charStream(), 49 | ApiErrorResponse::class.java 50 | ) 51 | Observable.just(NetworkResponse.ApiError(errorResponse)) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/network/OkHttpClientBuilder.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.network 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.Util 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 9 | import okhttp3.Interceptor 10 | import okhttp3.OkHttpClient 11 | import okhttp3.Request 12 | import okhttp3.logging.HttpLoggingInterceptor 13 | 14 | internal object OkHttpClientBuilder { 15 | 16 | private fun getHeaderInterceptor( 17 | clientSessionId: String, 18 | connectSDKConfiguration: ConnectSDKConfiguration 19 | ) = Interceptor { chain -> 20 | val request: Request = chain.request().newBuilder() 21 | .header("Authorization", "GCS v1Client:$clientSessionId") 22 | .header( 23 | "X-GCS-ClientMetaInfo", 24 | Util.getBase64EncodedMetadata( 25 | Util.getMetadata( 26 | connectSDKConfiguration.applicationContext, 27 | connectSDKConfiguration.applicationId, 28 | connectSDKConfiguration.ipAddress 29 | ) 30 | ) 31 | ) 32 | .build() 33 | 34 | chain.proceed(request) 35 | } 36 | 37 | fun okHttpClient(connectSDKConfiguration: ConnectSDKConfiguration) = 38 | if (connectSDKConfiguration.enableNetworkLogs) { 39 | val loggingInterceptor = HttpLoggingInterceptor() 40 | loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY) 41 | OkHttpClient.Builder() 42 | .addInterceptor(loggingInterceptor) 43 | .addInterceptor( 44 | getHeaderInterceptor( 45 | connectSDKConfiguration.sessionConfiguration.clientSessionId, 46 | connectSDKConfiguration 47 | ) 48 | ) 49 | .build() 50 | } else { 51 | OkHttpClient 52 | .Builder() 53 | .addInterceptor( 54 | getHeaderInterceptor( 55 | connectSDKConfiguration.sessionConfiguration.clientSessionId, 56 | connectSDKConfiguration 57 | ) 58 | ) 59 | .build() 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleFixedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Validation rule for fixed list. 13 | */ 14 | public class ValidationRuleFixedList extends AbstractValidationRule { 15 | 16 | private static final long serialVersionUID = -1388124383409175742L; 17 | 18 | private static final String TAG = ValidationRuleFixedList.class.getName(); 19 | 20 | private List listValues; 21 | 22 | /** 23 | * @deprecated This constructor is for internal use only. 24 | */ 25 | @Deprecated 26 | public ValidationRuleFixedList(List listValues) { 27 | super("fixedList", ValidationType.FIXEDLIST); 28 | 29 | if (listValues == null) { 30 | throw new IllegalArgumentException("Error initialising ValidationRuleFixedList, listValues may not be null"); 31 | } 32 | 33 | this.listValues = listValues; 34 | } 35 | 36 | /** 37 | * @deprecated In a future release, this constructor will be removed. 38 | */ 39 | @Deprecated 40 | public ValidationRuleFixedList(List listValues, String errorMessage, ValidationType type) { 41 | 42 | super(errorMessage, type); 43 | this.listValues = listValues; 44 | } 45 | 46 | public List getListValues() { 47 | return listValues; 48 | } 49 | 50 | /** 51 | * Validates a field value based on a list of possibilities. 52 | * 53 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 54 | * @param fieldId the ID of the field to which to apply the current validator 55 | * 56 | * @return true, if the value in the field with fieldId is a value in the list; false, if it is not in the lost or if the fieldId could not be found 57 | */ 58 | @Override 59 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 60 | 61 | String text = paymentRequest.getValue(fieldId); 62 | 63 | if (text == null) { 64 | return false; 65 | } 66 | 67 | text = paymentRequest.getUnmaskedValue(fieldId, text); 68 | 69 | // Loop through all allowed values and see if the text is one of them 70 | for (String value : listValues) { 71 | 72 | if (value.equals(text)) { 73 | return true; 74 | } 75 | } 76 | return false; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/BasicPaymentProductGroup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.displayhints.DisplayHintsPaymentItem; 8 | 9 | import java.io.Serializable; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | /** 14 | * 15 | * POJO which holds the BasicPaymentProductGroup properties. 16 | */ 17 | public class BasicPaymentProductGroup implements BasicPaymentItem, Serializable { 18 | 19 | private static final long serialVersionUID = -2069385568756342978L; 20 | 21 | 22 | private String id; 23 | private DisplayHintsPaymentItem displayHints; 24 | 25 | // List containing all AccountsOnFile 26 | private List accountsOnFile = new ArrayList<>(); 27 | 28 | /** 29 | * @deprecated In a future release, this property will be removed since it is not returned from the API. 30 | */ 31 | @Deprecated 32 | private String acquirerCountry; 33 | private boolean deviceFingerprintEnabled; 34 | private boolean allowsInstallments; 35 | 36 | 37 | public String getId(){ 38 | return id; 39 | } 40 | 41 | public List getAccountsOnFile() { 42 | return accountsOnFile; 43 | } 44 | 45 | public AccountOnFile getAccountOnFileById(String accountOnFileId) { 46 | 47 | if (accountOnFileId == null) { 48 | throw new IllegalArgumentException("Error getting AccountOnFile by id, accountOnFileId may not be null"); 49 | } 50 | 51 | for (AccountOnFile accountOnFile : accountsOnFile) { 52 | if (accountOnFile.getId().toString().equals(accountOnFileId)) { 53 | return accountOnFile; 54 | } 55 | } 56 | return null; 57 | } 58 | 59 | public DisplayHintsPaymentItem getDisplayHints(){ 60 | return displayHints; 61 | } 62 | 63 | /** 64 | * @deprecated In a future release, this getter will be removed since its value is not returned from the API. 65 | */ 66 | @Deprecated 67 | public String getAcquirerCountry() { 68 | return acquirerCountry; 69 | } 70 | 71 | public boolean deviceFingerprintEnabled() { 72 | return deviceFingerprintEnabled; 73 | } 74 | 75 | public boolean allowsInstallments() { 76 | return allowsInstallments; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/PublicKeyResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | import android.util.Base64; 8 | import android.util.Log; 9 | 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.encryption.Encryptor; 11 | 12 | import java.nio.charset.StandardCharsets; 13 | import java.security.KeyFactory; 14 | import java.security.NoSuchAlgorithmException; 15 | import java.security.PublicKey; 16 | import java.security.spec.InvalidKeySpecException; 17 | import java.security.spec.X509EncodedKeySpec; 18 | 19 | /** 20 | * POJO that holds the PublicKey call response from the GC gateway. 21 | */ 22 | public class PublicKeyResponse { 23 | 24 | // Tag used for logging 25 | private static final String TAG = Encryptor.class.getName(); 26 | 27 | // Algorithm type for converting publicKey string to publicKey object 28 | private final String RSA_ALGORITHM_TYPE = "RSA"; 29 | 30 | private String keyId; 31 | private String publicKey; 32 | private PublicKey parsedPublicKey; 33 | 34 | 35 | public PublicKeyResponse(String keyId, String publicKey) { 36 | this.keyId = keyId; 37 | this.publicKey = publicKey; 38 | } 39 | 40 | /** 41 | * Gets the keyId. 42 | * 43 | * @return String keyId 44 | */ 45 | public String getKeyId() { 46 | return keyId; 47 | } 48 | 49 | /** 50 | * Gets the PublicKey. 51 | * 52 | * @return PublicKey 53 | */ 54 | public PublicKey getPublicKey() { 55 | // If parsedPublicKey is already parsed from the publicKey string return it. 56 | if (parsedPublicKey != null) { 57 | return parsedPublicKey; 58 | } 59 | 60 | // Else parse the publicKey string to a PublicKey object 61 | if (publicKey != null) { 62 | 63 | try { 64 | 65 | // Decode base64 and convert the String to a PublicKey instance 66 | byte[] keyBytes = Base64.decode(publicKey.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); 67 | X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); 68 | KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM_TYPE); 69 | 70 | // Store the result in parsedPublicKey and return it 71 | parsedPublicKey = keyFactory.generatePublic(spec); 72 | return parsedPublicKey; 73 | 74 | } catch (NoSuchAlgorithmException e) { 75 | Log.i(TAG, "Error parsing publicKey response to public key, " + e.getMessage()); 76 | } catch (InvalidKeySpecException e) { 77 | Log.i(TAG, "Error parsing publicKey response to public key, " + e.getMessage()); 78 | } 79 | } 80 | return null; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/displayhints/DisplayHintsProductFields.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.displayhints; 6 | 7 | import com.google.gson.annotations.SerializedName; 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.FormElement; 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.Tooltip; 10 | 11 | import java.io.Serializable; 12 | 13 | /** 14 | * POJO that represents an DisplayHintsProductFields object. 15 | */ 16 | public class DisplayHintsProductFields implements Serializable { 17 | 18 | private static final long serialVersionUID = -4396644758512959868L; 19 | 20 | /** 21 | * Enum containing all the possible input types. 22 | * 23 | */ 24 | public enum PreferredInputType { 25 | @SerializedName("IntegerKeyboard") 26 | INTEGER_KEYBOARD, 27 | 28 | @SerializedName("StringKeyboard") 29 | STRING_KEYBOARD, 30 | 31 | @SerializedName("PhoneNumberKeyboard") 32 | PHONE_NUMBER_KEYBOARD, 33 | 34 | @SerializedName("EmailAddressKeyboard") 35 | EMAIL_ADDRESS_KEYBOARD, 36 | 37 | @SerializedName("DateKeyboard") 38 | DATE_PICKER 39 | ; 40 | } 41 | 42 | private Boolean alwaysShow; 43 | private Boolean obfuscate; 44 | private Integer displayOrder; 45 | private String label; 46 | private String placeholderLabel; 47 | private String link; 48 | private String mask; 49 | private PreferredInputType preferredInputType; 50 | private Tooltip tooltip; 51 | private FormElement formElement; 52 | 53 | public Tooltip getTooltip(){ 54 | return tooltip; 55 | } 56 | 57 | public Integer getDisplayOrder() { 58 | return displayOrder; 59 | } 60 | 61 | public String getLabel() { 62 | return label; 63 | } 64 | 65 | public String getPlaceholderLabel() { 66 | return placeholderLabel; 67 | } 68 | 69 | public String getLink() { 70 | return link; 71 | } 72 | 73 | public String getMask() { 74 | return mask; 75 | } 76 | 77 | public Boolean getAlwaysShow() { 78 | return alwaysShow; 79 | } 80 | 81 | public Boolean isObfuscate() { 82 | return obfuscate; 83 | } 84 | 85 | public PreferredInputType getPreferredInputType(){ 86 | return preferredInputType; 87 | } 88 | 89 | public FormElement getFormElement() { 90 | return formElement; 91 | } 92 | 93 | public void setFormElement(FormElement formElement) { 94 | this.formElement = formElement; 95 | } 96 | 97 | 98 | public static long getSerialversionuid() { 99 | return serialVersionUID; 100 | } 101 | 102 | 103 | 104 | 105 | } 106 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleIBAN.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | 9 | import java.math.BigInteger; 10 | 11 | /** 12 | * Validation rule for IBAN. 13 | */ 14 | public class ValidationRuleIBAN extends AbstractValidationRule { 15 | 16 | private static final long serialVersionUID = -2638250936233171926L; 17 | 18 | private static final String TAG = ValidationRuleIBAN.class.getName(); 19 | 20 | private static final BigInteger IBANNUMBER_MODULO = new BigInteger("97"); 21 | 22 | /** 23 | * @deprecated This constructor is for internal use only. 24 | */ 25 | @Deprecated 26 | public ValidationRuleIBAN() { 27 | super("iban", ValidationType.IBAN); 28 | } 29 | 30 | /** 31 | * @deprecated In a future release, this constructor will be removed. 32 | */ 33 | @Deprecated 34 | public ValidationRuleIBAN(String errorMessage, ValidationType type) { 35 | super(errorMessage, type); 36 | } 37 | 38 | /** 39 | * Validates that the value in the field with ID fieldId is a valid IBAN. 40 | * 41 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 42 | * @param fieldId the ID of the field to which to apply the current validator 43 | * 44 | * @return true, if the value in the field with fieldId is a proper IBAN; false, if it is not or if the fieldId could not be found 45 | */ 46 | @Override 47 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 48 | 49 | String newAccountNumber = paymentRequest.getValue(fieldId).trim(); 50 | 51 | if (newAccountNumber.matches("^[A-Z]{2}[0-9]{2}[A-Z0-9]{4}[0-9]{7}([A-Z0-9]?){0,16}$")) { 52 | 53 | // Move the four initial characters to the end of the string. 54 | newAccountNumber = newAccountNumber.substring(4) + newAccountNumber.substring(0, 4); 55 | 56 | // Replace each letter in the string with two digits, thereby expanding the string, where A = 10, B = 11, ..., Z = 35. 57 | StringBuilder numericAccountNumber = new StringBuilder(); 58 | for (int i = 0; i < newAccountNumber.length(); i++) { 59 | numericAccountNumber.append(Character.getNumericValue(newAccountNumber.charAt(i))); 60 | } 61 | 62 | // Interpret the string as a decimal integer and compute the remainder of that number on division by 97. 63 | BigInteger ibanNumber = new BigInteger(numericAccountNumber.toString()); 64 | return ibanNumber.mod(IBANNUMBER_MODULO).intValue() == 1; 65 | } 66 | 67 | return false; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/iin/IinDetailsResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * POJO that contains the response for IIN lookup. 12 | */ 13 | public class IinDetailsResponse implements Serializable { 14 | 15 | private static final long serialVersionUID = -4043745317792003304L; 16 | 17 | private String paymentProductId; 18 | private String countryCode; 19 | private boolean isAllowedInContext; 20 | private List coBrands; 21 | private IinStatus status; 22 | 23 | public IinDetailsResponse(IinStatus status) { 24 | paymentProductId = null; 25 | countryCode = null; 26 | isAllowedInContext = false; 27 | coBrands = null; 28 | this.status = status; 29 | } 30 | 31 | public String getPaymentProductId() { 32 | return paymentProductId; 33 | } 34 | 35 | public IinStatus getStatus() { 36 | return status; 37 | } 38 | 39 | public void setStatus(IinStatus status) { 40 | this.status = status; 41 | } 42 | 43 | public String getCountryCode() { 44 | return countryCode; 45 | } 46 | 47 | public boolean isAllowedInContext() { 48 | return isAllowedInContext; 49 | } 50 | 51 | public List getCoBrands() { 52 | return coBrands; 53 | } 54 | 55 | 56 | @Override 57 | public boolean equals(Object o) { 58 | 59 | if (this == o) { 60 | return true; 61 | } 62 | 63 | if (o == null || o.getClass() != getClass()) { 64 | return false; 65 | } 66 | 67 | IinDetailsResponse otherResponse = (IinDetailsResponse)o; 68 | return (status != null ? status.equals(otherResponse.status) : otherResponse.status == null) && 69 | (coBrands != null ? coBrands.equals(otherResponse.coBrands) : otherResponse.coBrands == null) && 70 | (countryCode != null ? countryCode.equals(otherResponse.countryCode) : otherResponse.countryCode == null) && 71 | (paymentProductId != null ? paymentProductId.equals(otherResponse.paymentProductId) : otherResponse.paymentProductId == null) && 72 | isAllowedInContext == otherResponse.isAllowedInContext(); 73 | } 74 | 75 | @Override 76 | public int hashCode() { 77 | int hash = 17; 78 | hash = 31 * hash + (status != null ? status.hashCode() : 0); 79 | hash = 31 * hash + (paymentProductId != null ? paymentProductId.hashCode() : 0); 80 | hash = 31 * hash + (countryCode != null ? countryCode.hashCode() : 0); 81 | hash = 31 * hash + (coBrands != null ? coBrands.hashCode() : 0); 82 | hash = 31 * hash + Boolean.valueOf(isAllowedInContext).hashCode(); 83 | return hash; 84 | } 85 | 86 | /** 87 | * @deprecated use {@link #getCountryCode()} instead. 88 | */ 89 | @Deprecated 90 | public String getCountryCodeString(){ 91 | return countryCode; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/communicate/TLSSocketFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.communicate; 6 | 7 | import java.io.IOException; 8 | import java.net.InetAddress; 9 | import java.net.Socket; 10 | import java.net.UnknownHostException; 11 | import java.security.KeyManagementException; 12 | import java.security.NoSuchAlgorithmException; 13 | 14 | import javax.net.ssl.SSLSocket; 15 | import javax.net.ssl.SSLSocketFactory; 16 | 17 | /** 18 | * @deprecated This class will be removed in the next major release. 19 | */ 20 | 21 | @Deprecated 22 | class TLSSocketFactory extends SSLSocketFactory { 23 | 24 | private SSLSocketFactory internalSSLSocketFactory; 25 | 26 | public TLSSocketFactory(SSLSocketFactory sslSocketFactory) throws KeyManagementException, NoSuchAlgorithmException { 27 | internalSSLSocketFactory = sslSocketFactory; 28 | } 29 | 30 | @Override 31 | public String[] getDefaultCipherSuites() { 32 | return internalSSLSocketFactory.getDefaultCipherSuites(); 33 | } 34 | 35 | @Override 36 | public String[] getSupportedCipherSuites() { 37 | return internalSSLSocketFactory.getSupportedCipherSuites(); 38 | } 39 | 40 | @Override 41 | public Socket createSocket() throws IOException { 42 | return enableTLSOnSocket(internalSSLSocketFactory.createSocket()); 43 | } 44 | 45 | @Override 46 | public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { 47 | return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)); 48 | } 49 | 50 | @Override 51 | public Socket createSocket(String host, int port) throws IOException, UnknownHostException { 52 | return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); 53 | } 54 | 55 | @Override 56 | public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { 57 | return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)); 58 | } 59 | 60 | @Override 61 | public Socket createSocket(InetAddress host, int port) throws IOException { 62 | return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); 63 | } 64 | 65 | @Override 66 | public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { 67 | return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)); 68 | } 69 | 70 | private Socket enableTLSOnSocket(Socket socket) { 71 | if(socket instanceof SSLSocket) { 72 | ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); 73 | } 74 | return socket; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleRange.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | 9 | /** 10 | * Validation rule for range. 11 | */ 12 | public class ValidationRuleRange extends AbstractValidationRule { 13 | 14 | private static final long serialVersionUID = 1199939638104378041L; 15 | 16 | private static final String TAG = ValidationRuleRange.class.getName(); 17 | 18 | private Integer minValue; 19 | private Integer maxValue; 20 | 21 | /** 22 | * @deprecated This constructor is for internal use only. 23 | */ 24 | @Deprecated 25 | public ValidationRuleRange(Integer minValue, Integer maxValue) { 26 | super("range", ValidationType.RANGE); 27 | 28 | if (minValue == null) { 29 | throw new IllegalArgumentException("Error initialising ValidationRuleRange, minValue may not be null"); 30 | } 31 | 32 | if (maxValue == null) { 33 | throw new IllegalArgumentException("Error initialising ValidationRuleRange, maxValue may not be null"); 34 | } 35 | 36 | this.minValue = minValue; 37 | this.maxValue = maxValue; 38 | } 39 | 40 | /** 41 | * @deprecated In a future release, this constructor will be removed. 42 | */ 43 | @Deprecated 44 | public ValidationRuleRange(Integer minValue, Integer maxValue, String errorMessage, ValidationType type) { 45 | super(errorMessage, type); 46 | 47 | if (minValue == null) { 48 | throw new IllegalArgumentException("Error initialising ValidationRuleRange, minValue may not be null"); 49 | } 50 | 51 | if (maxValue == null) { 52 | throw new IllegalArgumentException("Error initialising ValidationRuleRange, maxValue may not be null"); 53 | } 54 | 55 | this.minValue = minValue; 56 | this.maxValue = maxValue; 57 | } 58 | 59 | /** 60 | * Validates that the value in the field with fieldId has a value within the set bounds. 61 | * 62 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 63 | * @param fieldId the ID of the field to which to apply the current validator 64 | * 65 | * @return true, if the value in the field with fieldId is in the correct range; false, if it is out of bounds or if the fieldId could not be found 66 | */ 67 | @Override 68 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 69 | 70 | String text = paymentRequest.getValue(fieldId); 71 | 72 | if (text == null) { 73 | return false; 74 | } 75 | 76 | text = paymentRequest.getUnmaskedValue(fieldId, text); 77 | 78 | try { 79 | Integer enteredValue = Integer.parseInt(text); 80 | return enteredValue > minValue && enteredValue < maxValue; 81 | } catch (NumberFormatException e) { 82 | return false; 83 | } 84 | } 85 | 86 | public Integer getMinValue() { 87 | return minValue; 88 | } 89 | 90 | public Integer getMaxValue() { 91 | return maxValue; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/productsgroup/GetPaymentProductGroups.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.productsgroup 6 | 7 | import android.util.Log 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.drawable.GetDrawableFromUrl 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.UnknownNetworkResponseException 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.BasicPaymentProductGroups 14 | import io.reactivex.rxjava3.core.Observable 15 | 16 | internal class GetPaymentProductGroups { 17 | 18 | operator fun invoke( 19 | paymentContext: PaymentContext, 20 | connectSDKConfiguration: ConnectSDKConfiguration 21 | ): Observable> { 22 | return if (connectSDKConfiguration.preLoadImages) { 23 | getPaymentProductGroupsWithImages(paymentContext, connectSDKConfiguration) 24 | } else { 25 | RemotePaymentProductGroupRepository().getPaymentProductGroups( 26 | paymentContext, 27 | connectSDKConfiguration 28 | ) 29 | } 30 | } 31 | 32 | private fun getPaymentProductGroupsWithImages( 33 | paymentContext: PaymentContext, 34 | connectSDKConfiguration: ConnectSDKConfiguration 35 | ): Observable> { 36 | return RemotePaymentProductGroupRepository().getPaymentProductGroups( 37 | paymentContext, 38 | connectSDKConfiguration 39 | ).flatMap { networkResponse -> 40 | if (networkResponse is NetworkResponse.Success) { 41 | networkResponse.data?.basicPaymentProductGroups?.forEach { basicPaymentProductGroup -> 42 | GetDrawableFromUrl().invoke( 43 | connectSDKConfiguration, 44 | basicPaymentProductGroup.displayHints.logoUrl 45 | ).subscribe ({ 46 | basicPaymentProductGroup.displayHints.logo = it 47 | },{ 48 | Log.w( 49 | "ConnectSDK", 50 | "Drawable for paymentProductGroup: ${basicPaymentProductGroup.id} can't be loaded", 51 | it 52 | ) 53 | }) 54 | } 55 | Observable.just(networkResponse.data?.let { NetworkResponse.Success(it) } 56 | ?: throw UnknownNetworkResponseException) 57 | } else { 58 | Observable.just(NetworkResponse.ApiError(networkResponse.apiErrorResponse, null)) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/caching/CacheHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.caching; 6 | 7 | import android.content.Context; 8 | import android.content.res.Resources; 9 | import android.graphics.drawable.Drawable; 10 | 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin.IinDetailsResponse; 12 | 13 | import java.util.Map; 14 | 15 | /** 16 | * Handles all cache related functionality. 17 | * The cache is stored in internal storage. 18 | * 19 | * @deprecated this class will be removed in a future release. 20 | */ 21 | 22 | @Deprecated 23 | public class CacheHandler { 24 | 25 | 26 | // Classes for reading and writing files of the internal storage 27 | private ReadInternalStorage fileReader; 28 | private WriteInternalStorage fileWriter; 29 | 30 | 31 | /** 32 | * Create CacheHandler 33 | * 34 | * @param context used for file operations on the cached files 35 | */ 36 | public CacheHandler(Context context) { 37 | 38 | if (context == null) { 39 | throw new IllegalArgumentException("Error creating CacheHandler, context may not be null"); 40 | } 41 | 42 | fileReader = new ReadInternalStorage(context); 43 | fileWriter = new WriteInternalStorage(context); 44 | } 45 | 46 | 47 | /** 48 | * Gets all cached IinDetailsResponses. 49 | * 50 | * @return all cached IinDetailsResponses 51 | */ 52 | public Map getIinResponsesFromCache() { 53 | return fileReader.getIinResponsesFromCache(); 54 | } 55 | 56 | 57 | /** 58 | * Retrieves an Image from the Internal Storage. 59 | * 60 | * @param paymentProductId the id of the product of which the image should be retrieved 61 | * @param resources used to create a BitmapDrawable from the retrieved image 62 | * 63 | * @return the image which is retrieved from the internal storage 64 | */ 65 | public Drawable getImageFromInternalStorage(String paymentProductId, Resources resources) { 66 | 67 | if (paymentProductId == null) { 68 | throw new IllegalArgumentException("Error getting drawable from cache, paymentProductId may not be null"); 69 | } 70 | if (resources == null) { 71 | throw new IllegalArgumentException("Error getting drawable from cache, resources may not be null"); 72 | } 73 | 74 | return fileReader.getLogoFromInternalStorage(paymentProductId, resources); 75 | } 76 | 77 | 78 | /** 79 | * Saves an Image to the Internal Storage. 80 | * 81 | * @param paymentProductId the identifier of the image to save 82 | * @param image the image which is saved 83 | */ 84 | public void saveImageOnInternalStorage(String paymentProductId, Drawable image) { 85 | 86 | if (paymentProductId == null) { 87 | throw new IllegalArgumentException("Error saving drawable in cache, paymentProductId may not be null"); 88 | } 89 | if (image == null) { 90 | throw new IllegalArgumentException("Error saving drawable in cache, image may not be null"); 91 | } 92 | 93 | fileWriter.storeLogoOnInternalStorage(paymentProductId, image); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/productsgroup/GetPaymentProductGroup.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.productsgroup 6 | 7 | import android.util.Log 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.drawable.GetDrawableFromUrl 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.UnknownNetworkResponseException 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.PaymentProductGroup 14 | import io.reactivex.rxjava3.core.Observable 15 | 16 | internal class GetPaymentProductGroup { 17 | 18 | operator fun invoke( 19 | paymentContext: PaymentContext, 20 | connectSDKConfiguration: ConnectSDKConfiguration, 21 | paymentProductGroupId: String 22 | ): Observable> { 23 | return if (connectSDKConfiguration.preLoadImages) { 24 | getPaymentProductGroupWithImage( 25 | paymentContext, 26 | connectSDKConfiguration, 27 | paymentProductGroupId 28 | ) 29 | } else { 30 | RemotePaymentProductGroupRepository().getPaymentProductGroup( 31 | paymentContext, 32 | connectSDKConfiguration, 33 | paymentProductGroupId 34 | ) 35 | } 36 | } 37 | 38 | private fun getPaymentProductGroupWithImage( 39 | paymentContext: PaymentContext, 40 | connectSDKConfiguration: ConnectSDKConfiguration, 41 | paymentProductGroupId: String 42 | ): Observable> { 43 | return RemotePaymentProductGroupRepository().getPaymentProductGroup( 44 | paymentContext, 45 | connectSDKConfiguration, 46 | paymentProductGroupId 47 | ).flatMap { networkResponse -> 48 | if (networkResponse is NetworkResponse.Success) { 49 | networkResponse.data?.displayHints?.logoUrl?.let { logoUrl -> 50 | GetDrawableFromUrl().invoke(connectSDKConfiguration, logoUrl).subscribe( { drawable -> 51 | networkResponse.data.displayHints.logo = drawable 52 | },{ 53 | Log.w( 54 | "ConnectSDK", 55 | "Drawable for paymentProductGroup: ${networkResponse.data.id} can't be loaded", 56 | it 57 | ) 58 | }) 59 | } 60 | 61 | Observable.just(networkResponse.data?.let { NetworkResponse.Success(it) } 62 | ?: throw UnknownNetworkResponseException) 63 | } else { 64 | Observable.just(NetworkResponse.ApiError(networkResponse.apiErrorResponse, null)) 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleResidentIdNumber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | 9 | /** 10 | * Validation rule for China Resident ID number 11 | */ 12 | public class ValidationRuleResidentIdNumber extends AbstractValidationRule { 13 | 14 | private static final long serialVersionUID = 1199939638104555041L; 15 | 16 | private static final String TAG = ValidationRuleRange.class.getName(); 17 | 18 | /** 19 | * @deprecated This constructor is for internal use only. 20 | */ 21 | @Deprecated 22 | public ValidationRuleResidentIdNumber() { 23 | super("residentIdNumber", ValidationType.RESIDENTIDNUMBER); 24 | } 25 | 26 | /** 27 | * @deprecated In a future release, this constructor will be removed. 28 | */ 29 | @Deprecated 30 | public ValidationRuleResidentIdNumber(String errorMessage, ValidationType type) { 31 | super(errorMessage, type); 32 | } 33 | 34 | /** 35 | * Validates that the value in the field with fieldId is a valid Chinese Resident ID number. 36 | * 37 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 38 | * @param fieldId the ID of the field to which to apply the current validator 39 | * 40 | * @return true, if the value in the field with fieldId is a valid Resident ID number; false, if the value does not pass the check or if the fieldId could not be found 41 | */ 42 | @Override 43 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 44 | 45 | String idNumber = paymentRequest.getValue(fieldId); 46 | 47 | if (idNumber == null) { 48 | return false; 49 | } 50 | 51 | idNumber = paymentRequest.getUnmaskedValue(fieldId, idNumber); 52 | 53 | try { 54 | if (idNumber.length() == 15) { 55 | // Resident ID numbers of length 15 are older, and can not be validated by the checksum 56 | // algorithm. 57 | 58 | Long.parseLong(idNumber); 59 | 60 | return true; 61 | } else if (idNumber.length() == 18) { 62 | return checkSumIsValid(idNumber); 63 | } else { 64 | return false; 65 | } 66 | } catch (NumberFormatException e) { 67 | return false; 68 | } 69 | } 70 | 71 | private boolean checkSumIsValid(String idNumber) { 72 | int modulo = 11; 73 | int digits = idNumber.length() - 1; 74 | 75 | int sum = 0; 76 | 77 | for (int i = 0; i < digits; i++) { 78 | int weight = (int) (Math.pow(2, digits - i) % modulo); 79 | 80 | sum += weight * Integer.parseInt(String.valueOf(idNumber.charAt(i))); 81 | } 82 | 83 | int checkSum = (12 - (sum % modulo)) % modulo; 84 | 85 | if (checkSum == 10) { 86 | return idNumber.charAt(idNumber.length() - 1) == 'X'; 87 | } 88 | return Integer.parseInt(String.valueOf(idNumber.charAt(idNumber.length() - 1))) == checkSum; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleLength.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 8 | 9 | import org.apache.commons.lang3.StringUtils; 10 | 11 | /** 12 | * Validation rule for length. 13 | */ 14 | public class ValidationRuleLength extends AbstractValidationRule { 15 | 16 | private static final long serialVersionUID = 6453263230504247824L; 17 | 18 | private static final String TAG = ValidationRuleLength.class.getName(); 19 | 20 | private Integer minLength; 21 | private Integer maxLength; 22 | /** 23 | * @deprecated In a future release, this property will be removed since it is not returned from the API. 24 | */ 25 | @Deprecated 26 | private Integer maskedMaxLength; 27 | 28 | /** 29 | * @deprecated This constructor is for internal use only. 30 | */ 31 | @Deprecated 32 | public ValidationRuleLength(Integer minLength, Integer maxLength) { 33 | super("length", ValidationType.LENGTH); 34 | 35 | if (minLength == null) { 36 | throw new IllegalArgumentException("Error initialising ValidationRuleLength, minLength may not be null"); 37 | } 38 | 39 | if (maxLength == null) { 40 | throw new IllegalArgumentException("Error initialising ValidationRuleLength, maxLength may not be null"); 41 | } 42 | 43 | this.minLength = minLength; 44 | this.maxLength = maxLength; 45 | } 46 | 47 | /** 48 | * @deprecated In a future release, this constructor will be removed. 49 | */ 50 | @Deprecated 51 | public ValidationRuleLength(Integer minLength, Integer maxLength, String errorMessage, ValidationType type) { 52 | 53 | super(errorMessage, type); 54 | 55 | this.minLength = minLength; 56 | this.maxLength = maxLength; 57 | } 58 | 59 | /** 60 | * Validates that the value has the desired length. 61 | * 62 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 63 | * @param fieldId the ID of the field to which to apply the current validator 64 | * 65 | * @return true, if the value in the field with fieldId has the correct length; false, if it is not of the correct length or if the fieldId could not be found. 66 | */ 67 | @Override 68 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 69 | 70 | String text = paymentRequest.getValue(fieldId); 71 | 72 | // Text is allowed to be empty if the minimal required length is 0 73 | if (StringUtils.isEmpty(text) && minLength == 0) { 74 | return true; 75 | } 76 | 77 | if (text == null) { 78 | return false; 79 | } 80 | 81 | text = paymentRequest.getUnmaskedValue(fieldId, text); 82 | 83 | return text.length() >= minLength && text.length() <= maxLength; 84 | } 85 | 86 | public Integer getMaxLength() { 87 | return maxLength; 88 | } 89 | 90 | public Integer getMinLength() { 91 | return minLength; 92 | } 93 | 94 | /** 95 | * @deprecated In a future release, this getter will be removed since its value is not returned from the API. 96 | */ 97 | @Deprecated 98 | public Integer getMaskedMaxLength(){ 99 | return maskedMaxLength; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/PaymentContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | import java.io.Serializable; 8 | import java.util.HashMap; 9 | import java.util.Locale; 10 | import java.util.Map; 11 | 12 | 13 | /** 14 | * POJO that contains PaymentContext information. 15 | * It contains information about a payment, like its {@link AmountOfMoney}, countryCode and locale. 16 | */ 17 | public class PaymentContext implements Serializable { 18 | 19 | private static final long serialVersionUID = -4845945197600321181L; 20 | 21 | private AmountOfMoney amountOfMoney; 22 | private String countryCode; 23 | private boolean isRecurring; 24 | private Boolean forceBasicFlow; 25 | private Locale locale; 26 | 27 | public PaymentContext() {} 28 | 29 | public PaymentContext(AmountOfMoney amountOfMoney, String countryCode, boolean isRecurring) { 30 | this(amountOfMoney, countryCode, isRecurring, null); 31 | } 32 | 33 | public PaymentContext(AmountOfMoney amountOfMoney, String countryCode, boolean isRecurring, Locale locale) { 34 | this.countryCode = countryCode; 35 | this.isRecurring = isRecurring; 36 | this.amountOfMoney = amountOfMoney; 37 | this.locale = locale; 38 | } 39 | 40 | public AmountOfMoney getAmountOfMoney() { 41 | return amountOfMoney; 42 | } 43 | public void setAmountOfMoney(AmountOfMoney amountOfMoney) { 44 | this.amountOfMoney = amountOfMoney; 45 | } 46 | 47 | public String getCountryCode(){ 48 | return countryCode; 49 | } 50 | 51 | /** 52 | * @param countryCode the Country Code of the Country where the transaction will take place. The provided code should match the ISO-3166-alpha-2 standard. 53 | * @see ISO 3166 Country Codes 54 | */ 55 | public void setCountryCode(String countryCode){ 56 | this.countryCode = countryCode; 57 | } 58 | 59 | public Boolean isRecurring() { 60 | return isRecurring; 61 | } 62 | public void setIsRecurring(Boolean isRecurring) { 63 | this.isRecurring = isRecurring; 64 | } 65 | 66 | public Boolean isForceBasicFlow() { 67 | return forceBasicFlow; 68 | } 69 | public void setForceBasicFlow(Boolean forceBasicFlow) { 70 | this.forceBasicFlow = forceBasicFlow; 71 | } 72 | 73 | public Locale getLocale() { 74 | return locale; 75 | } 76 | 77 | public void setLocale(Locale locale) { 78 | this.locale = locale; 79 | } 80 | 81 | public Map convertToNetworkRequestParameters() { 82 | HashMap parameters = new HashMap<>(); 83 | parameters.put("countryCode", countryCode); 84 | parameters.put("currencyCode", amountOfMoney.getCurrencyCode()); 85 | parameters.put("locale", locale.toString()); 86 | parameters.put("amount", amountOfMoney.getAmount().toString()); 87 | parameters.put("isRecurring", String.valueOf(isRecurring)); 88 | return parameters; 89 | } 90 | 91 | /** 92 | * @deprecated use {@link #getCountryCode()} instead. 93 | */ 94 | @Deprecated 95 | public String getCountryCodeString() { 96 | return countryCode; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/PaymentItemCacheKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * POJO which holds the PaymentProductCacheKey data. 11 | * It's used to determine if a PaymentProduct should be retrieved from the Ingenico ePayments platform, or retrieved from the memory cache. 12 | */ 13 | public class PaymentItemCacheKey implements Serializable { 14 | 15 | private static final long serialVersionUID = 930873231953051398L; 16 | 17 | Long amount; 18 | String countryCode; 19 | String currencyCode; 20 | boolean isRecurring; 21 | String paymentProductId; 22 | 23 | public PaymentItemCacheKey(Long amount, String countryCode, String currencyCode, boolean isRecurring, String paymentProductId) { 24 | 25 | if (amount == null) { 26 | throw new IllegalArgumentException("Error creating PaymentItemCacheKey, amount may not be null"); 27 | } 28 | if (countryCode == null) { 29 | throw new IllegalArgumentException("Error creating PaymentItemCacheKey, countryCode may not be null"); 30 | } 31 | if (currencyCode == null) { 32 | throw new IllegalArgumentException("Error creating PaymentItemCacheKey, currencyCode may not be null"); 33 | } 34 | if (paymentProductId == null) { 35 | throw new IllegalArgumentException("Error creating PaymentItemCacheKey, paymentProductId may not be null"); 36 | } 37 | 38 | this.amount = amount; 39 | this.countryCode = countryCode; 40 | this.currencyCode = currencyCode; 41 | this.isRecurring = isRecurring; 42 | this.paymentProductId = paymentProductId; 43 | } 44 | 45 | 46 | public Long getAmount() { 47 | return amount; 48 | } 49 | 50 | public String getCountryCode() { 51 | return countryCode; 52 | } 53 | 54 | public String getCurrencyCode() { 55 | return currencyCode; 56 | } 57 | 58 | public String getPaymentProductId() { 59 | return paymentProductId; 60 | } 61 | 62 | public boolean getIsRecurring() { 63 | return isRecurring; 64 | } 65 | 66 | @Override 67 | public boolean equals(Object o) { 68 | 69 | if (this == o) { 70 | return true; 71 | } 72 | 73 | if (o == null || o.getClass() != getClass()) { 74 | return false; 75 | } 76 | 77 | PaymentItemCacheKey otherKey = (PaymentItemCacheKey)o; 78 | return otherKey.getAmount().equals(amount) && 79 | otherKey.getCountryCode().equals(countryCode) && 80 | otherKey.getCurrencyCode().equals(currencyCode) && 81 | otherKey.getPaymentProductId().equals(paymentProductId) && 82 | otherKey.getIsRecurring() == isRecurring; 83 | } 84 | 85 | @Override 86 | public int hashCode() { 87 | int hash = 17; 88 | hash = 31 * hash + amount.hashCode(); 89 | hash = 31 * hash + countryCode.hashCode(); 90 | hash = 31 * hash + currencyCode.hashCode(); 91 | hash = 31 * hash + paymentProductId.hashCode(); 92 | hash = 31 * hash + Boolean.valueOf(isRecurring).hashCode(); 93 | return hash; 94 | } 95 | 96 | /** 97 | * @deprecated use {@link #getCountryCode()} instead. 98 | */ 99 | @Deprecated 100 | public String getCountryCodeString() { 101 | return countryCode; 102 | } 103 | 104 | /** 105 | * @deprecated use {@link #getCurrencyCode()} instead. 106 | */ 107 | @Deprecated 108 | public String getCurrencyCodeString() { 109 | return currencyCode; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/productsgroup/RemotePaymentProductGroupRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.productsgroup 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.OkHttpClientBuilder 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.extension.mapRetrofitResponseToNetworkResponse 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.BasicPaymentProductGroups 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.PaymentProductGroup 14 | import io.reactivex.rxjava3.core.Observable 15 | import retrofit2.Retrofit 16 | import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory 17 | import retrofit2.converter.gson.GsonConverterFactory 18 | 19 | internal class RemotePaymentProductGroupRepository : PaymentProductGroupRepository { 20 | 21 | override fun getPaymentProductGroups( 22 | paymentContext: PaymentContext, 23 | connectSDKConfiguration: ConnectSDKConfiguration 24 | ): Observable> { 25 | return getPaymentProductGroupService(connectSDKConfiguration).getPaymentProductGroups( 26 | paymentContext.convertToNetworkRequestParameters() 27 | ) 28 | .flatMap { response -> 29 | mapRetrofitResponseToNetworkResponse(response) 30 | } 31 | } 32 | 33 | override fun getPaymentProductGroup( 34 | paymentContext: PaymentContext, 35 | connectSDKConfiguration: ConnectSDKConfiguration, 36 | paymentProductGroupId: String 37 | ): Observable> { 38 | return getPaymentProductGroupService(connectSDKConfiguration).getPaymentProductGroup( 39 | paymentProductGroupId, 40 | paymentContext.convertToNetworkRequestParameters() 41 | ) 42 | .flatMap { response -> 43 | response.body()?.let { paymentProductGroup -> 44 | for (field in paymentProductGroup.paymentProductFields) { 45 | field.setValidationRules() 46 | } 47 | } 48 | mapRetrofitResponseToNetworkResponse(response) 49 | } 50 | } 51 | 52 | private companion object { 53 | 54 | fun getPaymentProductGroupService( 55 | connectSdkConfiguration: ConnectSDKConfiguration 56 | ): PaymentProductGroupService = 57 | Retrofit.Builder() 58 | .baseUrl( 59 | connectSdkConfiguration.sessionConfiguration.getFormattedClientApiUrl() + 60 | "${connectSdkConfiguration.sessionConfiguration.customerId}/" 61 | ) 62 | .client( 63 | OkHttpClientBuilder.okHttpClient( 64 | connectSdkConfiguration 65 | ) 66 | ) 67 | .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) 68 | .addConverterFactory(GsonConverterFactory.create()) 69 | .build() 70 | .create(PaymentProductGroupService::class.java) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/caching/Preferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.caching; 6 | 7 | import android.content.Context; 8 | import android.content.SharedPreferences; 9 | 10 | import com.google.gson.Gson; 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.Constants; 12 | 13 | import java.lang.reflect.Type; 14 | import java.util.Map; 15 | 16 | /** 17 | * Handles all SharedPreferences related functionality. 18 | * 19 | * @deprecated this class will be removed in a future release. 20 | */ 21 | 22 | @Deprecated 23 | public class Preferences { 24 | 25 | 26 | /** 27 | * Store key/value in SharedPreferences. 28 | * 29 | * @param key the key under who the value is added to the SharedPreferences 30 | * @param value the value which is added to the SharedPreferences 31 | * @param context needed for getting the SharedPreferences object 32 | */ 33 | public void storeInSharedPreferences(String key, Object value, Context context) { 34 | 35 | SharedPreferences sharedPref = context.getSharedPreferences(Constants.PREFERENCES_NAME, Context.MODE_PRIVATE); 36 | SharedPreferences.Editor editor = sharedPref.edit(); 37 | 38 | // Serialise the value to jsonstring so it can be stored 39 | Gson gson = new Gson(); 40 | editor.putString(key, gson.toJson(value)); 41 | 42 | // Commit to SharedPreferences 43 | editor.apply(); 44 | } 45 | 46 | 47 | /** 48 | * Get value from SharedPreferences. 49 | * 50 | * @param the type of object that should be retrieved from SharedPreferences 51 | * @param key the key whose value will be retrieved 52 | * @param context needed for getting the SharedPreferences object 53 | * @param type a Class reference of the type of object that should be retrieved from SharedPreferences 54 | * 55 | * @return the value belonging with the given key in SharedPreferences 56 | */ 57 | public Object getValueFromSharedPreferences(String key, Context context, Class type) { 58 | SharedPreferences sharedPref = context.getSharedPreferences(Constants.PREFERENCES_NAME, Context.MODE_PRIVATE); 59 | 60 | Gson gson = new Gson(); 61 | return gson.fromJson(sharedPref.getString(key, null), type); 62 | } 63 | 64 | /** 65 | * Get map from SharedPreferences. 66 | * 67 | * @param key the key whose value will be retrieved 68 | * @param context needed for getting the SharedPreferences object 69 | * @param listType the type of object that should be retrieved from SharedPreferences 70 | * 71 | * @return the value belonging with the given key in SharedPreferences 72 | */ 73 | public Map getMapFromSharedPreferences(String key, Context context, Type listType, Map type) { 74 | 75 | SharedPreferences sharedPref = context.getSharedPreferences(Constants.PREFERENCES_NAME, Context.MODE_PRIVATE); 76 | 77 | Gson gson = new Gson(); 78 | return gson.fromJson(sharedPref.getString(key, null), listType); 79 | } 80 | 81 | 82 | /** 83 | * Remove key/value from SharedPreferences. 84 | * 85 | * @param key the key which will be removed 86 | * @param context needed for getting the SharedPreferences object 87 | */ 88 | public void removeValueFromSharedPreferences(String key, Context context) { 89 | SharedPreferences sharedPref = context.getSharedPreferences(Constants.PREFERENCES_NAME, Context.MODE_PRIVATE); 90 | SharedPreferences.Editor editor = sharedPref.edit(); 91 | editor.remove(key); 92 | editor.apply(); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/asynctask/PublicKeyAsyncTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.asynctask; 6 | 7 | import android.content.Context; 8 | import android.os.AsyncTask; 9 | 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.ClientApi; 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.communicate.C2sCommunicator; 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PublicKeyResponse; 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.ApiError; 14 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.Failure; 15 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.Success; 16 | 17 | /** 18 | * AsyncTask which executes a public key lookup call to the GC Gateway. 19 | * 20 | * @deprecated use {@link ClientApi#getPublicKey(Success, ApiError, Failure)} instead. 21 | */ 22 | 23 | @Deprecated 24 | public class PublicKeyAsyncTask extends AsyncTask { 25 | 26 | // The listener which will be called by the AsyncTask when a PublicKeyResponse has been received 27 | private OnPublicKeyLoadedListener listener; 28 | 29 | // Context needed for reading metadata which is sent to the GC gateway 30 | private Context context; 31 | 32 | // Communicator which does the communication to the GC gateway 33 | private C2sCommunicator communicator; 34 | 35 | /** 36 | * Create PublicKeyAsyncTask 37 | * 38 | * @param context used for reading device metadata which is sent to the GC gateway 39 | * @param communicator {@link C2sCommunicator} which does the communication to the GC gateway 40 | * @param listener {@link OnPublicKeyLoadedListener} which will be called by the AsyncTask when a {@link PublicKeyResponse} has been received 41 | */ 42 | public PublicKeyAsyncTask(Context context, C2sCommunicator communicator, OnPublicKeyLoadedListener listener) { 43 | 44 | if (context == null) { 45 | throw new IllegalArgumentException("Error creating PublicKeyAsyncTask, context may not be null"); 46 | } 47 | if (communicator == null) { 48 | throw new IllegalArgumentException("Error creating PublicKeyAsyncTask, communicator may not be null"); 49 | } 50 | if (listener == null) { 51 | throw new IllegalArgumentException("Error creating PublicKeyAsyncTask, listener may not be null"); 52 | } 53 | 54 | this.context = context; 55 | this.communicator = communicator; 56 | this.listener = listener; 57 | } 58 | 59 | 60 | @Override 61 | protected PublicKeyResponse doInBackground(String... params) { 62 | 63 | // Do the call to the Ingenico ePayments platform 64 | return communicator.getPublicKey(context); 65 | } 66 | 67 | 68 | @Override 69 | protected void onPostExecute(PublicKeyResponse response) { 70 | 71 | // Call listener callback 72 | listener.onPublicKeyLoaded(response); 73 | } 74 | 75 | 76 | /** 77 | * Interface for the Async task that executes a public key lookup call. 78 | * Is called from the {@link PublicKeyAsyncTask} when it has received a {@link PublicKeyResponse}. 79 | * 80 | * @deprecated use {@link ClientApi#getPublicKey(Success, ApiError, Failure)} instead. 81 | */ 82 | @Deprecated 83 | public interface OnPublicKeyLoadedListener { 84 | /** 85 | * Listener that is called when publickey is loaded. 86 | * 87 | * @param response the {@link PublicKeyResponse} which contains the public key data 88 | */ 89 | void onPublicKeyLoaded(PublicKeyResponse response); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/product/GetPaymentProducts.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.product 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.drawable.GetDrawableFromUrl 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.BasicPaymentProduct 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.BasicPaymentProducts 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.UnknownNetworkResponseException 14 | import io.reactivex.rxjava3.core.Observable 15 | 16 | internal class GetPaymentProducts { 17 | 18 | operator fun invoke( 19 | paymentContext: PaymentContext, 20 | connectSDKConfiguration: ConnectSDKConfiguration 21 | ): Observable> { 22 | return if (connectSDKConfiguration.preLoadImages) { 23 | getPaymentProductsWithLogos(paymentContext, connectSDKConfiguration) 24 | } else { 25 | RemotePaymentProductRepository().getPaymentProducts( 26 | paymentContext, 27 | connectSDKConfiguration 28 | ) 29 | } 30 | } 31 | 32 | private fun getPaymentProductsWithLogos( 33 | paymentContext: PaymentContext, 34 | connectSDKConfiguration: ConnectSDKConfiguration 35 | ): Observable> { 36 | return RemotePaymentProductRepository().getPaymentProducts( 37 | paymentContext, 38 | connectSDKConfiguration 39 | ).flatMap { networkResponse -> 40 | if (networkResponse is NetworkResponse.Success) { 41 | Observable.just(networkResponse.data?.let { 42 | NetworkResponse.Success(it) 43 | } 44 | ?: throw UnknownNetworkResponseException) 45 | .delaySubscription( 46 | getLogos(networkResponse.data.basicPaymentProducts, connectSDKConfiguration) 47 | ) 48 | } else { 49 | Observable.just(NetworkResponse.ApiError(networkResponse.apiErrorResponse, null)) 50 | } 51 | } 52 | } 53 | 54 | private fun getLogos( 55 | paymentProducts: List, 56 | connectSDKConfiguration: ConnectSDKConfiguration, 57 | ): Observable { 58 | return Observable.create { 59 | var count = 0 60 | paymentProducts.forEach { basicPaymentProduct -> 61 | if (!basicPaymentProduct.displayHints.logoUrl.isNullOrBlank()) { 62 | GetDrawableFromUrl().invoke( 63 | connectSDKConfiguration, 64 | basicPaymentProduct.displayHints.logoUrl 65 | ).doFinally { 66 | count++ 67 | if (count == paymentProducts.count()) it.onComplete() 68 | }.subscribe({ drawable -> 69 | basicPaymentProduct.displayHints.logo = drawable 70 | }, {}) 71 | } else { 72 | count++ 73 | if (count == paymentProducts.count()) it.onComplete() 74 | } 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/AccountOnFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.formatter.StringFormatter; 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.displayhints.DisplayHintsAccountOnFile; 9 | 10 | import java.io.Serializable; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | 15 | /** 16 | * POJO that represents an AccountOnFile object. 17 | */ 18 | public class AccountOnFile implements Serializable { 19 | 20 | private static final long serialVersionUID = 4898075257024154390L; 21 | 22 | private String id; 23 | private String paymentProductId; 24 | 25 | private DisplayHintsAccountOnFile displayHints; 26 | 27 | 28 | private List attributes = new ArrayList<>(); 29 | 30 | // Used for masking fields 31 | private StringFormatter formatter = new StringFormatter(); 32 | 33 | public Integer getId() { 34 | return Integer.valueOf(id); 35 | } 36 | 37 | public String getPaymentProductId() { 38 | return paymentProductId; 39 | } 40 | 41 | public DisplayHintsAccountOnFile getDisplayHints() { 42 | return displayHints; 43 | } 44 | 45 | public List getAttributes() { 46 | return attributes; 47 | } 48 | 49 | /** 50 | * Gets the label of this AccountOnFile based on the DisplayHints and the Attributes values 51 | * 52 | * @return the label which can be displayed on an AccountOnFile selection screen 53 | */ 54 | public String getLabel() { 55 | 56 | String label = ""; 57 | if (getDisplayHints().getLabelTemplate().get(0) != null) { 58 | AccountOnFileDisplay display = getDisplayHints().getLabelTemplate().get(0); 59 | 60 | for (KeyValuePair pair : attributes) { 61 | if (display.getKey().equals(pair.getKey())) { 62 | label = pair.getValue(); 63 | } 64 | } 65 | } 66 | 67 | return label; 68 | } 69 | 70 | /** 71 | * Returns the masked value for the given payment product field id. 72 | * 73 | * @param paymentProductFieldId the id of the {@link PaymentProductField} whose masked value should be returned 74 | * 75 | * @return String which is the masked value of the provided payment product field. 76 | */ 77 | public String getMaskedValue(String paymentProductFieldId) { 78 | String mask = ""; 79 | for (AccountOnFileDisplay display: displayHints.getLabelTemplate()) { 80 | if (display.getKey().equals(paymentProductFieldId)) { 81 | mask = display.getMask(); 82 | } 83 | } 84 | 85 | return getMaskedValue(paymentProductFieldId, mask); 86 | } 87 | 88 | /** 89 | * Returns the value for the given payment product field id with a custom mask applied. 90 | * 91 | * @param paymentProductFieldId the id of the {@link PaymentProductField} whose masked value should be returned 92 | * @param mask the mask that should be applied to the value of the {@link PaymentProductField} 93 | * 94 | * @return String which is the value of the provided payment product field with a custom mask applied. 95 | */ 96 | public String getMaskedValue(String paymentProductFieldId, String mask) { 97 | String value = ""; 98 | for (KeyValuePair attribute: attributes) { 99 | if (attribute.getKey().equals(paymentProductFieldId)) { 100 | value = attribute.getValue(); 101 | } 102 | } 103 | 104 | String relaxedMask = formatter.relaxMask(mask); 105 | return formatter.applyMask(relaxedMask, value); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | plugins { 6 | id 'com.android.library' 7 | id 'org.jetbrains.kotlin.android' 8 | id 'signing' 9 | id 'maven-publish' 10 | id 'org.sonarqube' 11 | } 12 | 13 | android { 14 | namespace 'com.ingenico.connect.gateway.sdk.client.android.sdk' 15 | 16 | defaultConfig { 17 | minSdkVersion 21 18 | compileSdk 34 19 | targetSdkVersion 34 20 | versionCode 1 21 | versionName "6.2.0" 22 | consumerProguardFiles 'consumer-rules.pro' 23 | } 24 | 25 | compileOptions { 26 | sourceCompatibility JavaVersion.VERSION_17 27 | targetCompatibility JavaVersion.VERSION_17 28 | } 29 | 30 | lint { 31 | abortOnError false 32 | lintConfig file('lint.xml') 33 | } 34 | 35 | buildTypes { 36 | release { 37 | minifyEnabled false 38 | } 39 | } 40 | 41 | publishing { 42 | singleVariant("release") { 43 | withSourcesJar() 44 | withJavadocJar() 45 | } 46 | } 47 | } 48 | 49 | dependencies { 50 | implementation 'com.google.android.gms:play-services-wallet:19.2.1' 51 | implementation 'org.apache.commons:commons-lang3:3.13.0' 52 | 53 | testImplementation 'junit:junit:4.13.2' 54 | testImplementation 'org.mockito:mockito-core:5.9.0' 55 | 56 | // RX 57 | implementation "io.reactivex.rxjava3:rxjava:3.1.8" 58 | implementation "io.reactivex.rxjava3:rxkotlin:3.0.1" 59 | implementation 'io.reactivex.rxjava3:rxandroid:3.0.2' 60 | 61 | // Network 62 | implementation 'com.squareup.retrofit2:converter-gson:2.9.0' 63 | implementation 'com.squareup.retrofit2:retrofit:2.9.0' 64 | implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") 65 | implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0' 66 | implementation 'com.google.code.gson:gson:2.10.1' 67 | } 68 | 69 | afterEvaluate { 70 | publishing { 71 | publications { 72 | mavenJava(MavenPublication) { 73 | from components.release 74 | 75 | groupId = POM_GROUP_ID 76 | artifactId = POM_ARTIFACT_ID 77 | version = POM_VERSION 78 | pom { 79 | name = POM_NAME 80 | description = POM_DESCRIPTION 81 | url = POM_URL 82 | 83 | organization { 84 | name = POM_ORGANIZATION_NAME 85 | url = POM_ORGANIZATION_URL 86 | } 87 | 88 | licenses { 89 | license { 90 | name = POM_LICENSE_NAME 91 | url = POM_LICENSE_URL 92 | } 93 | } 94 | 95 | developers { 96 | developer { 97 | name = POM_DEVELOPER_NAME 98 | email = POM_DEVELOPER_EMAIL 99 | organization = POM_DEVELOPER_ORGANIZATION 100 | organizationUrl = POM_DEVELOPER_ORGANIZATIONURL 101 | } 102 | } 103 | 104 | issueManagement { 105 | system = POM_ISSUEMANAGEMENT_SYSTEM 106 | url = POM_ISSUEMANAGEMENT_URL 107 | } 108 | 109 | scm { 110 | connection = POM_SCM_CONNECTION 111 | developerConnection = POM_SCM_DEVELOPERCONNECTION 112 | url = POM_SCM_URL 113 | } 114 | } 115 | } 116 | } 117 | } 118 | 119 | signing { 120 | sign publishing.publications.mavenJava 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/PaymentProductFieldTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.PaymentProductField; 8 | 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | import org.mockito.junit.MockitoJUnitRunner; 12 | 13 | import static com.ingenico.connect.gateway.sdk.client.android.testUtil.GsonHelper.fromResourceJson; 14 | import static org.junit.Assert.assertEquals; 15 | 16 | /** 17 | * Junit Testclass which tests PaymentProductField apply-/removeMask methods with no Mask present 18 | */ 19 | @RunWith(MockitoJUnitRunner.class) 20 | public class PaymentProductFieldTest { 21 | 22 | private PaymentProductField paymentProductFieldWithoutMask = fromResourceJson("paymentProductFieldWithoutMask.json", PaymentProductField.class); 23 | 24 | 25 | @Test 26 | public void testMaskingSingleAddedCharacterInclCursor() { 27 | FormatResult result = paymentProductFieldWithoutMask.applyMask("123", "12", 2, 0, 1); 28 | assertEquals("123", result.getFormattedResult()); 29 | assertEquals(3, result.getCursorIndex().intValue()); 30 | } 31 | 32 | @Test 33 | public void testMaskingTwoAddedCharactersInclCursor() { 34 | FormatResult result = paymentProductFieldWithoutMask.applyMask("123", "1", 1, 0, 2); 35 | assertEquals("123", result.getFormattedResult()); 36 | assertEquals(3, result.getCursorIndex().intValue()); 37 | } 38 | 39 | @Test 40 | public void testMaskingSingleRemovedCharacterInclCursor() { 41 | FormatResult result = paymentProductFieldWithoutMask.applyMask("12", "123", 3, 1, 0); 42 | assertEquals("12", result.getFormattedResult()); 43 | assertEquals(2, result.getCursorIndex().intValue()); 44 | } 45 | 46 | @Test 47 | public void testMaskingTwoRemovedCharactersInclCursor() { 48 | FormatResult result = paymentProductFieldWithoutMask.applyMask("1", "123", 3, 2, 0); 49 | assertEquals("1", result.getFormattedResult()); 50 | assertEquals(1, result.getCursorIndex().intValue()); 51 | } 52 | 53 | 54 | @Test 55 | public void testMaskingSingleAddedCharacterInclCursorDeprecatedVersion() { 56 | FormatResult result = paymentProductFieldWithoutMask.applyMask("123", "12", 2); 57 | assertEquals("123", result.getFormattedResult()); 58 | assertEquals(2, result.getCursorIndex().intValue()); 59 | } 60 | 61 | @Test 62 | public void testMaskingTwoAddedCharactersInclCursorDeprecatedVersion() { 63 | FormatResult result = paymentProductFieldWithoutMask.applyMask("123", "1", 1); 64 | assertEquals("123", result.getFormattedResult()); 65 | assertEquals(1, result.getCursorIndex().intValue()); 66 | } 67 | 68 | @Test 69 | public void testMaskingSingleRemovedCharacterInclCursorDeprecatedVersion() { 70 | FormatResult result = paymentProductFieldWithoutMask.applyMask("12", "123", 2); 71 | assertEquals("12", result.getFormattedResult()); 72 | assertEquals(2, result.getCursorIndex().intValue()); 73 | } 74 | 75 | @Test 76 | public void testMaskingTwoRemovedCharactersInclCursorDeprecatedVersion() { 77 | FormatResult result = paymentProductFieldWithoutMask.applyMask("1", "123", 1); 78 | assertEquals("1", result.getFormattedResult()); 79 | assertEquals(1, result.getCursorIndex().intValue()); 80 | } 81 | 82 | 83 | @Test 84 | public void testMaskingValueOnly() { 85 | String result = paymentProductFieldWithoutMask.applyMask("123"); 86 | assertEquals("123", result); 87 | } 88 | 89 | @Test 90 | public void testUnmaskingValueOnly() { 91 | String result = paymentProductFieldWithoutMask.applyMask("123"); 92 | assertEquals("123", result); 93 | } 94 | 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/iin/IinDetailsResponseTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.testUtil.GsonHelper; 8 | 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | import org.mockito.junit.MockitoJUnitRunner; 12 | 13 | import static org.junit.Assert.assertEquals; 14 | import static org.junit.Assert.assertNotEquals; 15 | import static org.junit.Assert.assertNotNull; 16 | 17 | /** 18 | * Junit Testclass which tests iin details response equality 19 | */ 20 | @RunWith(MockitoJUnitRunner.class) 21 | public class IinDetailsResponseTest { 22 | 23 | private final IinDetailsResponse fstNormalVisa = GsonHelper.fromResourceJson("normalIINResponseVisa.json", IinDetailsResponse.class); 24 | private final IinDetailsResponse sndNormalVisa = GsonHelper.fromResourceJson("normalIINResponseVisa.json", IinDetailsResponse.class); 25 | 26 | private final IinDetailsResponse fstNormalMC = GsonHelper.fromResourceJson("normalIINResponseMC.json", IinDetailsResponse.class); 27 | 28 | private final IinDetailsResponse fstMinimalVisa = GsonHelper.fromResourceJson("minimalIINResponseVisa.json", IinDetailsResponse.class); 29 | private final IinDetailsResponse sndMinimalVisa = GsonHelper.fromResourceJson("minimalIINResponseVisa.json", IinDetailsResponse.class); 30 | 31 | private final IinDetailsResponse fstMinimalMC = GsonHelper.fromResourceJson("minimalIINResponseMC.json", IinDetailsResponse.class); 32 | 33 | private final IinDetailsResponse fstEmptyWithCodeUnknown = new IinDetailsResponse(IinStatus.UNKNOWN); 34 | private final IinDetailsResponse sndEmptyWithCodeUnknown = new IinDetailsResponse(IinStatus.UNKNOWN); 35 | private final IinDetailsResponse fstEmptyWithCodeSupported = new IinDetailsResponse(IinStatus.SUPPORTED); 36 | private final IinDetailsResponse fstEmptyWithCodeExistingButNotAllowed = new IinDetailsResponse(IinStatus.EXISTING_BUT_NOT_ALLOWED); 37 | private final IinDetailsResponse fstEmptyWithCodeNotEnoughDigits = new IinDetailsResponse(IinStatus.NOT_ENOUGH_DIGITS); 38 | 39 | private final IinDetailsResponse fstNormalResponseVisaNoCoBrands = GsonHelper.fromResourceJson("normalIINResponseVisaNoCoBrand.json", IinDetailsResponse.class); 40 | 41 | @Test 42 | public void testEqualsIinDetailsResponse() { 43 | // Test equality of two normal IinResponses 44 | assertEquals(fstNormalVisa, sndNormalVisa); 45 | assertEquals(sndNormalVisa, fstNormalVisa); 46 | 47 | // Test inequality of two normal IinResponses 48 | assertNotEquals(fstNormalMC, fstNormalVisa); 49 | 50 | // Test equality of two minimal IinResponses 51 | assertEquals(fstMinimalVisa, sndMinimalVisa); 52 | assertEquals(sndMinimalVisa, fstMinimalVisa); 53 | 54 | // Test inequality of two minimal IinResponses 55 | assertNotEquals(fstMinimalVisa, fstMinimalMC); 56 | 57 | // Test inequality of normal and minimal IinResponses 58 | assertNotEquals(fstNormalVisa, fstMinimalVisa); 59 | assertNotEquals(fstNormalMC, fstMinimalMC); 60 | 61 | // Test (in)equality of empty with different statuscodes 62 | assertEquals(fstEmptyWithCodeUnknown, sndEmptyWithCodeUnknown); 63 | assertNotEquals(fstEmptyWithCodeUnknown, fstEmptyWithCodeExistingButNotAllowed); 64 | assertNotEquals(fstEmptyWithCodeUnknown, fstEmptyWithCodeNotEnoughDigits); 65 | assertNotEquals(fstEmptyWithCodeUnknown, fstEmptyWithCodeSupported); 66 | 67 | // Test inequality of normals response with and without co-brands 68 | assertNotEquals(fstNormalVisa, fstNormalResponseVisaNoCoBrands); 69 | 70 | // Test null 71 | assertNotNull(fstNormalVisa); 72 | assertNotNull(fstEmptyWithCodeUnknown); 73 | assertNotNull(fstEmptyWithCodeSupported); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/paymentproduct/BasicPaymentItems.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct; 6 | 7 | import java.io.Serializable; 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.Comparator; 11 | import java.util.List; 12 | import java.util.Objects; 13 | 14 | /** 15 | * POJO with convenience methods for getting {@link BasicPaymentItem} and {@link AccountOnFile} objects. 16 | */ 17 | public class BasicPaymentItems implements Serializable { 18 | 19 | private static final long serialVersionUID = 2481207529146031966L; 20 | 21 | 22 | private List basicPaymentItems = new ArrayList<>(); 23 | 24 | private List accountsOnFile = new ArrayList<>(); 25 | 26 | private Boolean hasBeenSorted = false; 27 | 28 | 29 | public BasicPaymentItems(List basicPaymentItems, List accountsOnFile) { 30 | this.basicPaymentItems = basicPaymentItems; 31 | this.accountsOnFile = accountsOnFile; 32 | hasBeenSorted = false; 33 | } 34 | 35 | /** 36 | * Gets all basicPaymentItems. 37 | * 38 | * @return A sorted list of basicPaymentItems 39 | */ 40 | public List getBasicPaymentItems() { 41 | sortList(); 42 | return basicPaymentItems; 43 | } 44 | 45 | private void sortList() { 46 | if (!hasBeenSorted) { 47 | Collections.sort(basicPaymentItems, new Comparator() { 48 | public int compare(BasicPaymentItem product1, BasicPaymentItem product2) { 49 | if (Objects.equals(product1, product2)) return 0; 50 | if (product1 == null) return -1; 51 | if (product2 == null) return 1; 52 | 53 | Integer displayOrder1 = product1.getDisplayHints().getDisplayOrder(); 54 | Integer displayOrder2 = product2.getDisplayHints().getDisplayOrder(); 55 | 56 | if (Objects.equals(displayOrder1, displayOrder2)) return 0; 57 | if (displayOrder1 == null) return -1; 58 | if (displayOrder2 == null) return 1; 59 | return displayOrder1.compareTo(displayOrder2); 60 | } 61 | }); 62 | hasBeenSorted = true; 63 | } 64 | } 65 | 66 | /** 67 | * Gets a {@link BasicPaymentItem} by its id. 68 | * 69 | * @param basicPaymentItemId the id of the {@link BasicPaymentItem} that should be retrieved 70 | * 71 | * @return the retrieved {@link BasicPaymentItem}, or null if not found 72 | */ 73 | public BasicPaymentItem getBasicPaymentItemById(String basicPaymentItemId) { 74 | 75 | if (basicPaymentItemId == null) { 76 | throw new IllegalArgumentException("Error getting basicPaymentItem by id, basicPaymentItemId may not be null"); 77 | } 78 | 79 | for (BasicPaymentItem basicPaymentItem : basicPaymentItems) { 80 | if (basicPaymentItem.getId().equals(basicPaymentItemId)) { 81 | return basicPaymentItem; 82 | } 83 | } 84 | 85 | return null; 86 | } 87 | 88 | 89 | /** 90 | * Gets all AccountsOnFile for all BasicPaymentItems. 91 | * 92 | * @return a list of all AccountsOnFile 93 | */ 94 | public List getAccountsOnFile() { 95 | 96 | // Check if accountsOnFile list is filled, else fill it and return it 97 | if (accountsOnFile.isEmpty()) { 98 | for (BasicPaymentItem product : getBasicPaymentItems()) { 99 | accountsOnFile.addAll(product.getAccountsOnFile()); 100 | } 101 | } 102 | 103 | return accountsOnFile; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/caching/ReadInternalStorage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.caching; 6 | 7 | import android.content.Context; 8 | import android.content.res.Resources; 9 | import android.graphics.BitmapFactory; 10 | import android.graphics.drawable.BitmapDrawable; 11 | import android.graphics.drawable.Drawable; 12 | import android.util.Log; 13 | 14 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.Constants; 15 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.iin.IinDetailsResponse; 16 | 17 | import java.io.File; 18 | import java.io.FileInputStream; 19 | import java.io.IOException; 20 | import java.io.ObjectInputStream; 21 | import java.io.StreamCorruptedException; 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | /** 26 | * This class is responsible for reading files on disk that act as a cache for certain data. 27 | * 28 | * @deprecated this class will be removed in a future release. 29 | */ 30 | 31 | @Deprecated 32 | class ReadInternalStorage { 33 | 34 | // Tag for logging 35 | private static final String TAG = ReadInternalStorage.class.getName(); 36 | 37 | // Context used for accessing files 38 | private Context context; 39 | 40 | public ReadInternalStorage(Context context) { 41 | this.context = context; 42 | } 43 | 44 | 45 | /** 46 | * Reads all IinResponses from the cache on disk 47 | */ 48 | @SuppressWarnings("unchecked") 49 | public Map getIinResponsesFromCache() { 50 | 51 | if (context == null) { 52 | throw new IllegalArgumentException("Error getting response in cache, context may not be null"); 53 | } 54 | 55 | // Create new map which contains all the iinResponses 56 | Map iinResponses = new HashMap<>(); 57 | 58 | // Check if the cachefile exists 59 | String directory = context.getFilesDir() + Constants.DIRECTORY_IINRESPONSES; 60 | File file = new File(directory, Constants.FILENAME_IINRESPONSE_CACHE); 61 | if (file.exists()) { 62 | // read the content and parse it to Map 63 | try(FileInputStream fileInputStream = new FileInputStream(file); 64 | ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream) 65 | ) { 66 | iinResponses = (Map)objectInputStream.readObject(); 67 | } catch (ClassNotFoundException | IOException e) { 68 | Log.e(TAG, "Error getting List from internal file ", e); 69 | } 70 | } 71 | 72 | return iinResponses; 73 | } 74 | 75 | 76 | /** 77 | * Retrieves the logo from the cache on disk. 78 | * 79 | * @param paymentProductId, the id of the product of which the logo should be retrieved 80 | * @param resources used to create a BitmapDrawable from the retrieved image 81 | * 82 | * @return the image which is retrieved from the internal storage 83 | */ 84 | public Drawable getLogoFromInternalStorage(String paymentProductId, Resources resources) { 85 | 86 | if (paymentProductId == null) { 87 | throw new IllegalArgumentException("Error getting drawable from file, paymentProductId may not be null"); 88 | } 89 | 90 | Drawable imageFromFile = null; 91 | 92 | // Check if the cachefile exists 93 | String directory = context.getFilesDir() + Constants.DIRECTORY_LOGOS; 94 | File file = new File(directory, Constants.FILENAME_LOGO_PREFIX + paymentProductId); 95 | if (file.exists()) { 96 | // read the content and parse it to BitmapDrawable 97 | try(FileInputStream fileInputStream = new FileInputStream(file)) { 98 | imageFromFile = new BitmapDrawable(resources, BitmapFactory.decodeStream(fileInputStream)); 99 | 100 | } catch (IOException e) { 101 | Log.e(TAG, "Error getting drawable from file ", e); 102 | } 103 | } 104 | 105 | return imageFromFile; 106 | 107 | } 108 | 109 | 110 | } 111 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/session/SessionEncryptionHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.session; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.Util; 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.asynctask.EncryptDataAsyncTask; 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.asynctask.PublicKeyAsyncTask; 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PreparedPaymentRequest; 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PublicKeyResponse; 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.Failure; 14 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.Success; 15 | 16 | import java.util.Map; 17 | 18 | /** 19 | * SessionEncryptionHelper contains methods needed to encrypt a Session related data. 20 | * @deprecated This class will become internal to the SDK. Use {@link com.ingenico.connect.gateway.sdk.client.android.ConnectSDK#encryptPaymentRequest(PaymentRequest, Success, Failure)} for encryption instead. 21 | */ 22 | @Deprecated 23 | public class SessionEncryptionHelper implements EncryptDataAsyncTask.OnEncryptDataCompleteListener, PublicKeyAsyncTask.OnPublicKeyLoadedListener { 24 | 25 | 26 | private OnPaymentRequestPreparedListener listener; 27 | private PaymentRequest paymentRequest; 28 | private String clientSessionId; 29 | private Map metaData; 30 | 31 | /** 32 | * Helper for encrypting the {@link PaymentRequest}. 33 | * 34 | * @param paymentRequest the {@link PaymentRequest} that will be encrypted 35 | * @param clientSessionId the sessionId that is used to communicate with the GC gateway 36 | * @param metaData the metadata which is sent to the GC gateway 37 | * @param listener {@link OnPaymentRequestPreparedListener} that will be called when encryption is completed 38 | */ 39 | public SessionEncryptionHelper(PaymentRequest paymentRequest, String clientSessionId, Map metaData, OnPaymentRequestPreparedListener listener) { 40 | 41 | if (paymentRequest == null ) { 42 | throw new IllegalArgumentException("Error creating SessionEncryptionHelper, paymentRequest may not be null"); 43 | } 44 | if (clientSessionId == null ) { 45 | throw new IllegalArgumentException("Error creating SessionEncryptionHelper, clientSessionId may not be null"); 46 | } 47 | if (listener == null ) { 48 | throw new IllegalArgumentException("Error creating SessionEncryptionHelper, listener may not be null"); 49 | } 50 | if (metaData == null) { 51 | throw new IllegalArgumentException("Error creating SessionEncryptionHelper, metaData may not be null"); 52 | } 53 | 54 | this.clientSessionId = clientSessionId; 55 | this.listener = listener; 56 | this.paymentRequest = paymentRequest; 57 | this.metaData = metaData; 58 | } 59 | 60 | 61 | /** 62 | * Listener for loaded public key as {@link PublicKeyResponse} from the GC gateway. 63 | */ 64 | @Override 65 | public void onPublicKeyLoaded(PublicKeyResponse response) { 66 | EncryptDataAsyncTask task = new EncryptDataAsyncTask(response, paymentRequest, clientSessionId, this); 67 | task.execute(); 68 | } 69 | 70 | 71 | /** 72 | * Listener for encrypting data. 73 | */ 74 | @Override 75 | public void onEncryptDataComplete(String encryptedData) { 76 | listener.onPaymentRequestPrepared(new PreparedPaymentRequest(encryptedData, Util.getBase64EncodedMetadata(metaData))); 77 | } 78 | 79 | 80 | /** 81 | * Interface for OnPaymentRequestPreparedListener. 82 | * Is called from the {@link Session} when it has encrypted the given payment product fields and composed the {@link PreparedPaymentRequest} object with them. 83 | * 84 | * @deprecated the result of a request is handled in the method itself. 85 | */ 86 | @Deprecated 87 | public interface OnPaymentRequestPreparedListener { 88 | void onPaymentRequestPrepared(PreparedPaymentRequest preparedPaymentRequest); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/test/resources/paymentProductVisa.json: -------------------------------------------------------------------------------- 1 | { 2 | "accountsOnFile" : [ { 3 | "attributes" : [ { 4 | "key" : "alias", 5 | "value" : "************1111", 6 | "status" : "READ_ONLY" 7 | }, { 8 | "key" : "firstName", 9 | "value" : "Wile", 10 | "status" : "READ_ONLY" 11 | }, { 12 | "key" : "surname", 13 | "value" : "E. Coyote", 14 | "status" : "READ_ONLY" 15 | }, { 16 | "key" : "cardholderName", 17 | "value" : "Wile E. Coyote", 18 | "status" : "READ_ONLY" 19 | }, { 20 | "key" : "cardNumber", 21 | "value" : "************1111", 22 | "status" : "READ_ONLY" 23 | }, { 24 | "key" : "expiryDate", 25 | "value" : "0120", 26 | "status" : "MUST_WRITE" 27 | } ], 28 | "displayHints" : { 29 | "labelTemplate" : [ { 30 | "attributeKey" : "alias", 31 | "mask" : "{{9999}} {{9999}} {{9999}} {{9999}} {{999}}" 32 | } ], 33 | "logo" : "templates/master/global/css/img/ppimages/pp_logo_1_v1.png" 34 | }, 35 | "id" : 0, 36 | "paymentProductId" : 1 37 | } ], 38 | "allowsRecurring" : true, 39 | "allowsTokenization" : true, 40 | "autoTokenized" : false, 41 | "displayHints" : { 42 | "displayOrder" : 23, 43 | "label" : "Visa", 44 | "logo" : "templates/master/global/css/img/ppimages/pp_logo_1_v1.png" 45 | }, 46 | "fields" : [ { 47 | "dataRestrictions" : { 48 | "isRequired" : true, 49 | "validators" : { 50 | "length" : { 51 | "maxLength" : 19, 52 | "minLength" : 12 53 | }, 54 | "luhn" : { 55 | } 56 | } 57 | }, 58 | "displayHints" : { 59 | "alwaysShow" : false, 60 | "displayOrder" : 10, 61 | "formElement" : { 62 | "type" : "text" 63 | }, 64 | "label" : "Card number", 65 | "mask" : "{{9999}} {{9999}} {{9999}} {{9999}} {{999}}", 66 | "obfuscate" : false, 67 | "placeholderLabel" : "**** **** **** ****", 68 | "preferredInputType" : "IntegerKeyboard" 69 | }, 70 | "id" : "cardNumber", 71 | "type" : "numericstring" 72 | }, { 73 | "dataRestrictions" : { 74 | "isRequired" : true, 75 | "validators" : { 76 | "expirationDate" : { 77 | }, 78 | "length" : { 79 | "maxLength" : 4, 80 | "minLength" : 4 81 | }, 82 | "regularExpression" : { 83 | "regularExpression" : "^(?:0[1-9]|1[0-2])[0-9]{2}$" 84 | } 85 | } 86 | }, 87 | "displayHints" : { 88 | "alwaysShow" : false, 89 | "displayOrder" : 20, 90 | "formElement" : { 91 | "type" : "text" 92 | }, 93 | "label" : "Expiry date", 94 | "mask" : "{{99}}/{{99}}", 95 | "obfuscate" : false, 96 | "placeholderLabel" : "MM/YY", 97 | "preferredInputType" : "IntegerKeyboard" 98 | }, 99 | "id" : "expiryDate", 100 | "type" : "expirydate" 101 | }, { 102 | "dataRestrictions" : { 103 | "isRequired" : false, 104 | "validators" : { 105 | "length" : { 106 | "maxLength" : 4, 107 | "minLength" : 3 108 | }, 109 | "regularExpression" : { 110 | "regularExpression" : "^[0-9]{3}[0-9]?$" 111 | } 112 | } 113 | }, 114 | "displayHints" : { 115 | "alwaysShow" : true, 116 | "displayOrder" : 24, 117 | "formElement" : { 118 | "type" : "text" 119 | }, 120 | "label" : "CVV", 121 | "mask" : "{{9999}}", 122 | "obfuscate" : false, 123 | "placeholderLabel" : "123", 124 | "preferredInputType" : "IntegerKeyboard", 125 | "tooltip" : { 126 | "image" : "templates/master/global/css/img/ppimages/ppf_cvv_v1.png", 127 | "label" : "Please enter your security code as shown in the image" 128 | } 129 | }, 130 | "id" : "cvv", 131 | "type" : "numericstring" 132 | } ], 133 | "id" : 1, 134 | "mobileIntegrationLevel" : "OPTIMISED_SUPPORT", 135 | "paymentMethod" : "card", 136 | "paymentProductGroup" : "cards" 137 | } 138 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/support/EncryptPaymentRequest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.support 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.Util 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.encryption.EncryptData 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.encryption.Encryptor 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.exception.EncryptDataException 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.EncryptedPaymentRequest 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest 14 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PublicKeyResponse 15 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.PaymentProductField 16 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 17 | import io.reactivex.rxjava3.core.Observable 18 | import java.util.* 19 | 20 | internal class EncryptPaymentRequest { 21 | 22 | operator fun invoke( 23 | connectSDKConfiguration: ConnectSDKConfiguration, 24 | paymentRequest: PaymentRequest 25 | ): Observable> { 26 | 27 | return GetPublicKey().invoke( 28 | connectSDKConfiguration 29 | ).map { networkResponse -> 30 | when (networkResponse) { 31 | is NetworkResponse.ApiError -> { 32 | NetworkResponse.ApiError(networkResponse.apiErrorResponse) 33 | } 34 | is NetworkResponse.Success -> { 35 | encryptPublicKey(connectSDKConfiguration, paymentRequest, networkResponse.data) 36 | } 37 | } 38 | } 39 | } 40 | 41 | private fun encryptPublicKey( 42 | connectSDKConfiguration: ConnectSDKConfiguration, 43 | paymentRequest: PaymentRequest, 44 | publicKeyResponse: PublicKeyResponse? 45 | ): NetworkResponse { 46 | 47 | // Format all values based on their paymentproductfield.type and them to the encryptedValues 48 | val formattedPaymentValues: MutableMap = HashMap() 49 | for (field in paymentRequest.paymentProduct.paymentProductFields) { 50 | val value = paymentRequest.getValue(field.id) 51 | 52 | // The date and expirydate are already in the correct format. 53 | // If the masks given by the GC gateway are correct 54 | if (field.type != null && value != null) { 55 | if (field.type == PaymentProductField.Type.NUMERICSTRING) { 56 | formattedPaymentValues[field.id] = value.replace("[^\\d.]".toRegex(), "") 57 | } else { 58 | formattedPaymentValues[field.id] = value 59 | } 60 | } 61 | } 62 | 63 | val encryptDataObject = EncryptData().apply { 64 | paymentValues = formattedPaymentValues 65 | clientSessionId = connectSDKConfiguration.sessionConfiguration.clientSessionId 66 | nonce = UUID.randomUUID().toString() 67 | paymentProductId = paymentRequest.paymentProduct.id.toInt() 68 | tokenize = paymentRequest.tokenize 69 | 70 | if (paymentRequest.accountOnFile != null) accountOnFileId = paymentRequest.accountOnFile.id 71 | } 72 | 73 | val encryptPaymentRequest = Encryptor(publicKeyResponse).encrypt(encryptDataObject)?.let { encryptedData -> 74 | EncryptedPaymentRequest(encryptedData,Util.getBase64EncodedMetadata( 75 | Util.getMetadata( 76 | connectSDKConfiguration.applicationContext, 77 | connectSDKConfiguration.applicationId, 78 | connectSDKConfiguration.ipAddress 79 | ) 80 | )) 81 | } ?: throw EncryptDataException("Error while encrypting fields") 82 | 83 | return NetworkResponse.Success(encryptPaymentRequest) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/model/validation/ValidationRuleBoletoBancarioRequiredness.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.model.validation; 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.Constants; 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentRequest; 9 | 10 | import org.apache.commons.lang3.StringUtils; 11 | 12 | /** 13 | * Validation rule for Boleto Bancario. 14 | */ 15 | public class ValidationRuleBoletoBancarioRequiredness extends AbstractValidationRule { 16 | 17 | private final static String TAG = ValidationRuleBoletoBancarioRequiredness.class.getName(); 18 | 19 | private static final long serialVersionUID = 8128017363108369010L; 20 | 21 | private Integer fiscalNumberLengthToValidate; 22 | 23 | /** 24 | * @deprecated This constructor is for internal use only. 25 | */ 26 | @Deprecated 27 | public ValidationRuleBoletoBancarioRequiredness(Integer fiscalNumberLengthToValidate) { 28 | super("boletobancariorequiredness", ValidationType.BOLETOBANCARIOREQUIREDNESS); 29 | 30 | if (fiscalNumberLengthToValidate == null) { 31 | throw new IllegalArgumentException("Error initialising ValidationRuleBoletoBancarioRequiredness, fiscalNumberLengthToValidate may not be null"); 32 | } 33 | 34 | this.fiscalNumberLengthToValidate = fiscalNumberLengthToValidate; 35 | } 36 | 37 | /** 38 | * @deprecated In a future release, this constructor will be removed. 39 | */ 40 | @Deprecated 41 | public ValidationRuleBoletoBancarioRequiredness(Integer fiscalNumberLengthToValidate, String errorMessage, ValidationType type) { 42 | super(errorMessage, type); 43 | 44 | this.fiscalNumberLengthToValidate = fiscalNumberLengthToValidate; 45 | } 46 | 47 | /** 48 | * Validates that, if the field is required for the current FiscalNumber value, the value is not 49 | * null or empty. 50 | * 51 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 52 | * @param fieldId the ID of the field to which to apply the current validator 53 | * 54 | * @return true if the value in the field with fieldId is required (based on Fiscal Number), and is not empty 55 | */ 56 | @Override 57 | public boolean validate(PaymentRequest paymentRequest, String fieldId) { 58 | if (paymentRequest == null) { 59 | throw new IllegalArgumentException("Error validating Boleto Bancario, paymentRequest may not be null"); 60 | } 61 | if (fieldId == null) { 62 | throw new IllegalArgumentException("Error validating Boleto Bancario, fieldId may not be null"); 63 | } 64 | 65 | // If the field is not required for Boleto, it is definitely valid 66 | if (!isFieldRequired(paymentRequest)) { 67 | return true; 68 | } 69 | 70 | // The field is required, check that it is not empty 71 | String text = paymentRequest.getValue(fieldId); 72 | return StringUtils.isNotEmpty(text); 73 | } 74 | 75 | /** 76 | * Validates if the field is required based on the length of the Fiscal Number field. 77 | * 78 | * @param paymentRequest the fully filled {@link PaymentRequest} that will be used for doing a payment 79 | * 80 | * @return true if the current value in the Fiscal Number field has the length that was specified in 81 | * {@link #ValidationRuleBoletoBancarioRequiredness(Integer)} 82 | */ 83 | public boolean isFieldRequired(PaymentRequest paymentRequest) { 84 | if (paymentRequest == null) { 85 | throw new IllegalArgumentException("Error validating Boleto Bancario, paymentRequest may not be null"); 86 | } 87 | 88 | String fiscalNumber = paymentRequest.getValue(Constants.FISCAL_NUMBER_FIELD_ID); 89 | 90 | int fiscalNumberLength = 0; 91 | if (StringUtils.isNotEmpty(fiscalNumber)) { 92 | fiscalNumberLength = fiscalNumber.length(); 93 | } 94 | 95 | return fiscalNumberLengthToValidate.equals(fiscalNumberLength); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ingenicoconnect-sdk/src/main/java/com/ingenico/connect/gateway/sdk/client/android/sdk/product/RemotePaymentProductRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Global Collect Services B.V 3 | */ 4 | 5 | package com.ingenico.connect.gateway.sdk.client.android.sdk.product 6 | 7 | import com.ingenico.connect.gateway.sdk.client.android.sdk.configuration.ConnectSDKConfiguration 8 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentContext 9 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.PaymentProductDirectoryResponse 10 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.BasicPaymentProducts 11 | import com.ingenico.connect.gateway.sdk.client.android.sdk.model.paymentproduct.PaymentProduct 12 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.NetworkResponse 13 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.OkHttpClientBuilder 14 | import com.ingenico.connect.gateway.sdk.client.android.sdk.network.extension.mapRetrofitResponseToNetworkResponse 15 | import io.reactivex.rxjava3.core.Observable 16 | import retrofit2.Retrofit 17 | import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory 18 | import retrofit2.converter.gson.GsonConverterFactory 19 | 20 | internal class RemotePaymentProductRepository : PaymentProductRepository { 21 | 22 | override fun getPaymentProducts( 23 | paymentContext: PaymentContext, 24 | connectSDKConfiguration: ConnectSDKConfiguration 25 | ): Observable> { 26 | return getPaymentProductService(connectSDKConfiguration).getPaymentProducts( 27 | paymentContext.convertToNetworkRequestParameters() 28 | ) 29 | .flatMap { response -> 30 | mapRetrofitResponseToNetworkResponse(response) 31 | } 32 | } 33 | 34 | override fun getPaymentProduct( 35 | paymentContext: PaymentContext, 36 | connectSDKConfiguration: ConnectSDKConfiguration, 37 | paymentProductId: String 38 | ): Observable> { 39 | return getPaymentProductService(connectSDKConfiguration).getPaymentProduct( 40 | paymentProductId, 41 | paymentContext.convertToNetworkRequestParameters() 42 | ) 43 | .flatMap { response -> 44 | response.body()?.let { paymentProduct -> 45 | for (field in paymentProduct.paymentProductFields) { 46 | field.setValidationRules() 47 | } 48 | } 49 | mapRetrofitResponseToNetworkResponse(response) 50 | } 51 | } 52 | 53 | override fun getPaymentProductDirectory( 54 | paymentContext: PaymentContext, 55 | connectSDKConfiguration: ConnectSDKConfiguration, 56 | paymentProductId: String 57 | ): Observable> { 58 | val parameters: MutableMap = HashMap() 59 | parameters["countryCode"] = paymentContext.countryCode 60 | parameters["currencyCode"] = paymentContext.amountOfMoney.currencyCode 61 | 62 | return getPaymentProductService(connectSDKConfiguration).getPaymentProductDirectory( 63 | paymentProductId, 64 | parameters 65 | ) 66 | .flatMap { response -> 67 | mapRetrofitResponseToNetworkResponse(response) 68 | } 69 | } 70 | 71 | private companion object { 72 | 73 | fun getPaymentProductService(connectSdkConfiguration: ConnectSDKConfiguration): PaymentProductService = 74 | Retrofit.Builder() 75 | .baseUrl( 76 | connectSdkConfiguration.sessionConfiguration.getFormattedClientApiUrl() + 77 | "${connectSdkConfiguration.sessionConfiguration.customerId}/" 78 | ) 79 | .client( 80 | OkHttpClientBuilder.okHttpClient( 81 | connectSdkConfiguration 82 | ) 83 | ) 84 | .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) 85 | .addConverterFactory(GsonConverterFactory.create()) 86 | .build() 87 | .create(PaymentProductService::class.java) 88 | } 89 | } 90 | --------------------------------------------------------------------------------