├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── net │ └── authorize │ └── acceptsdk │ └── ApplicationTest.java ├── main ├── AndroidManifest.xml ├── java │ └── net │ │ └── authorize │ │ └── acceptsdk │ │ ├── AcceptSDKApiClient.java │ │ ├── ValidationCallback.java │ │ ├── ValidationManager.java │ │ ├── datamodel │ │ ├── common │ │ │ ├── Message.java │ │ │ └── ResponseMessages.java │ │ ├── error │ │ │ └── SDKErrorCode.java │ │ ├── merchant │ │ │ ├── AbstractMerchantAuthentication.java │ │ │ ├── ClientKeyBasedMerchantAuthentication.java │ │ │ ├── FingerPrintBasedMerchantAuthentication.java │ │ │ ├── FingerPrintData.java │ │ │ └── MerchantAuthenticationType.java │ │ └── transaction │ │ │ ├── CardData.java │ │ │ ├── EncryptTransactionObject.java │ │ │ ├── TransactionObject.java │ │ │ ├── TransactionType.java │ │ │ ├── callbacks │ │ │ └── EncryptTransactionCallback.java │ │ │ └── response │ │ │ ├── EncryptTransactionResponse.java │ │ │ ├── ErrorTransactionResponse.java │ │ │ └── TransactionResponse.java │ │ ├── internal │ │ └── AcceptSDKCore.java │ │ ├── network │ │ ├── AcceptService.java │ │ ├── ConnectionData.java │ │ └── TransactionResultReceiver.java │ │ ├── parser │ │ ├── AcceptSDKParser.java │ │ └── JSONConstants.java │ │ └── util │ │ ├── LogUtil.java │ │ ├── SDKCurrency.java │ │ └── SDKUtils.java └── res │ └── values │ └── strings.xml └── test └── java └── net └── authorize └── acceptsdk ├── AcceptSDKApiClientTest.java ├── ExampleUnitTest.java ├── datamodel ├── merchant │ ├── ClientKeyBasedMerchantAuthenticationTest.java │ ├── FingerPrintBasedMerchantAuthenticationTest.java │ └── FingerPrintDataTest.java └── transaction │ ├── CardDataTest.java │ └── EncryptTransactionObjectTest.java ├── network └── AcceptServiceTest.java └── parser └── AcceptSDKParserTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | 39 | # Keystore files 40 | *.jks 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Authorize.Net 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Authorize.Net Accept Mobile SDK for Android 3 | 4 | 5 | This SDK allows mobile developers to accept payments on a customer's mobile device from within their Android applications without having to pass sensitive card data back to their application backend servers. For more information on including payments in your mobile application see our [In-App Payments Guide](http://developer.authorize.net/api/reference/features/in-app.html) 6 | 7 | 8 | ## Contents 9 | 10 | 1. [Installation](#installation-one-step) 11 | 1. [Getting Started](#getting-started-four-steps) 12 | 1. [Sample Application](#sample-application) 13 | 14 | ## Installation (One Step) 15 | Add the dependency from jCenter to your app's (not project's) `build.gradle` file. 16 | 17 | ```groovy 18 | repositories { 19 | jcenter() 20 | } 21 | 22 | dependencies { 23 | compile 'net.authorize:accept-sdk-android:1.0.2' 24 | } 25 | ``` 26 | 27 | ## Getting Started (Four Steps) 28 | 29 | ### Prerequisites 30 | Android API 14+ is required as the `minSdkVersion` in your build.gradle 31 | 32 | 33 | ### 1. Initialize AcceptSDKApiClient 34 | All SDK API's will be accessed through `AcceptSDKApiClient` Object, which can be created as follows: 35 | 36 | ```java 37 | // Parameters: 38 | // 1) Context - Activity context 39 | // 2) AcceptSDKApiClient.Environment - AUTHORIZE.NET ENVIRONMENT 40 | apiClient = new AcceptSDKApiClient.Builder (getActivity(), 41 | AcceptSDKApiClient.Environment.SANDBOX) 42 | .connectionTimeout(5000) // optional connection time out in milliseconds 43 | .build(); 44 | ``` 45 | 46 | ### 2. Prepare Objects required to call Token API 47 | Fetch token API requires `EncryptTransactionObject`, which can be created as follows: 48 | 49 | ```java 50 | EncryptTransactionObject transactionObject = TransactionObject. 51 | createTransactionObject(TransactionType.SDK_TRANSACTION_ENCRYPTION)// type of transaction object 52 | .cardData(prepareCardDataFromFields()) // card data to be encrypted 53 | .merchantAuthentication(prepareMerchantAuthentication()) //Merchant authentication 54 | .build(); 55 | ``` 56 | 57 | `EncryptTransactionObject` requires `cardData` object, which can be created as follows: 58 | 59 | ```java 60 | CardData cardData = new CardData.Builder(CARD_NUMBER, 61 | EXPIRATION_MONTH, // MM 62 | EXPIRATION_YEAR) // YYYY 63 | .cvvCode(CARD_CVV) // Optional 64 | .zipCode(ZIP_CODE)// Optional 65 | .cardHolderName(CARD_HOLDER_NAME)// Optional 66 | .build(); 67 | ``` 68 | 69 | `EncryptTransactionObject` requires `merchantAuthentication` object, which can be created as follows: 70 | 71 | ```java 72 | ClientKeyBasedMerchantAuthentication merchantAuthentication = ClientKeyBasedMerchantAuthentication. 73 | createMerchantAuthentication(API_LOGIN_ID, CLIENT_KEY); 74 | ``` 75 | 76 | Check out the "Obtaining a Public Client Key" section in [Accept Mobile](http://developer.authorize.net/api/reference/features/in-app.html) 77 | for more information on getting CLIENT_KEY. 78 | 79 | ### 3. Calling Token API 80 | When transaction information is ready, you can make the following call to fetch token: 81 | 82 | ```java 83 | // Parameters: 84 | // 1. EncryptTransactionObject - The transaction object for current transaction 85 | // 2. transaction response callback. 86 | apiClient.getTokenWithRequest(transactionObject, callback); 87 | ``` 88 | 89 | ### 4. Implement `EncryptTransactionCallback` Interface. 90 | To get a response back, the activity/fragment should implement the `EncryptTransactionCallback` interface. It has thefollowing methods: 91 | 92 | > [`onEncryptionFinished()`](#onEncryption-Finished) 93 | 94 | > [`onErrorReceived()`](#onError-Received) 95 | 96 | #### `onEncryptionFinished()` 97 | This method will be called when token is successfully generated.`EncryptTransactionResponse` object has Data Descriptor and Data Value details which will be used to perform the payment transaction. 98 | 99 | ```java 100 | @Override 101 | public void onEncryptionFinished(EncryptTransactionResponse response) 102 | { 103 | Toast.makeText(getActivity(), 104 | response.getDataDescriptor() + " : " + response.getDataValue(), 105 | Toast.LENGTH_LONG) 106 | .show(); 107 | } 108 | ``` 109 | 110 | #### `onErrorReceived()` 111 | This method will be called in three scenarios, 112 | 113 | > Validation of information is failed. 114 | > Network related errors. 115 | > API error response. 116 | 117 | `ErrorTransactionResponse` may contain one or more error messages. 118 | 119 | ```java 120 | @Override 121 | public void onErrorReceived(ErrorTransactionResponse errorResponse) 122 | { 123 | Message error = errorResponse.getFirstErrorMessage(); 124 | Toast.makeText(getActivity(), 125 | error.getMessageCode() + " : " + error.getMessageText() , 126 | Toast.LENGTH_LONG) 127 | .show(); 128 | } 129 | ``` 130 | 131 | ## Sample Application 132 | We have a sample application which demonstrates the SDK usage: 133 | https://github.com/AuthorizeNet/accept-sample-android 134 | 135 | 136 | ## Google Play In-App Billing API 137 | Google’s developer terms require that purchases related to the app, such as premium features or credits, are made via their native Google Play In-app Billing API. See https://play.google.com/about/developer-content-policy.html for more details. 138 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | dependencies { 7 | classpath 'com.android.tools.build:gradle:4.1.1' 8 | } 9 | } 10 | 11 | apply plugin: 'com.android.library' 12 | 13 | ext { 14 | PUBLISH_GROUP_ID = 'net.authorize' 15 | PUBLISH_ARTIFACT_ID = 'accept-android-sdk' 16 | PUBLISH_VERSION = '1.0.4' 17 | // COMMENT : If publish version changes change "version name" in "defaultconfig" below 18 | } 19 | 20 | 21 | android { 22 | compileSdkVersion 29 23 | buildToolsVersion "29.0.3" 24 | 25 | defaultConfig { 26 | minSdkVersion 26 27 | targetSdkVersion 29 28 | versionCode 4 29 | versionName "1.0.4" 30 | buildConfigField("String", "SDK_VERSION", "\"1.0.4\"") 31 | } 32 | // compileOptions { 33 | // sourceCompatibility JavaVersion.VERSION_1_7 34 | // targetCompatibility JavaVersion.VERSION_1_7 35 | // } 36 | buildTypes { 37 | release { 38 | minifyEnabled false 39 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 40 | } 41 | } 42 | testOptions { 43 | unitTests { 44 | returnDefaultValues = true 45 | } 46 | } 47 | 48 | lintOptions { 49 | abortOnError false 50 | } 51 | } 52 | 53 | repositories { 54 | google() 55 | jcenter() 56 | mavenCentral() 57 | } 58 | 59 | dependencies { 60 | implementation fileTree(dir: 'libs', include: ['*.jar']) 61 | implementation 'com.android.support:support-compat:28.0.0' 62 | testImplementation 'junit:junit:4.12' 63 | testImplementation 'org.mockito:mockito-core:1.10.19' 64 | } 65 | 66 | apply from: 'https://raw.githubusercontent.com/blundell/release-android-library/master/android-release-aar.gradle' 67 | -------------------------------------------------------------------------------- /proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Kiran\Softwares\AndroidSdk/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 | -------------------------------------------------------------------------------- /src/androidTest/java/net/authorize/acceptsdk/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/AcceptSDKApiClient.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk; 2 | 3 | import android.content.Context; 4 | import java.lang.ref.WeakReference; 5 | import net.authorize.acceptsdk.datamodel.transaction.EncryptTransactionObject; 6 | import net.authorize.acceptsdk.datamodel.transaction.callbacks.EncryptTransactionCallback; 7 | import net.authorize.acceptsdk.internal.AcceptSDKCore; 8 | import net.authorize.acceptsdk.network.ConnectionData; 9 | 10 | /** 11 | * API client class. 12 | * 13 | * Created by kbollepa on 7/7/2016. 14 | */ 15 | public class AcceptSDKApiClient { 16 | 17 | //COMMENT: context is needed to start service. 18 | private static WeakReference sContext; 19 | 20 | public enum Environment {SANDBOX, PRODUCTION} 21 | 22 | ; 23 | 24 | private final Environment mEnvironment; 25 | 26 | public AcceptSDKApiClient(Builder builder) { 27 | sContext = builder.context; 28 | mEnvironment = builder.environment; 29 | configureConnectionTimeout(builder.connectionTimeout); 30 | setActiveEndPointUrl(); 31 | } 32 | 33 | public Environment getEnvironment() { 34 | return mEnvironment; 35 | } 36 | 37 | public static WeakReference getContext() { 38 | return sContext; 39 | } 40 | 41 | private void configureConnectionTimeout(int timeoutMillis) { 42 | ConnectionData.setConnectionTimeout(timeoutMillis); 43 | } 44 | 45 | /** 46 | * Method to set end point url based on Environment {@link Environment} 47 | */ 48 | private void setActiveEndPointUrl() { 49 | String url = (this.mEnvironment == Environment.PRODUCTION) ? ConnectionData.ENDPOINT_PRODUCTION 50 | : ConnectionData.ENDPOINT_SANDBOX; 51 | ConnectionData.setActiveEndPointUrl(url); 52 | } 53 | 54 | /** 55 | * API to get Encrypted token for given payment information. 56 | * 57 | * @param transactionObject encryption transaction object. In case of null,Throws {@link 58 | * NullPointerException} 59 | * @param callback callback for response of transaction 60 | * @return boolean, false if another transaction is already in progress. 61 | */ 62 | public boolean getTokenWithRequest(EncryptTransactionObject transactionObject, 63 | EncryptTransactionCallback callback) { 64 | if (transactionObject == null) { 65 | throw new NullPointerException("Transaction Object must not be null"); 66 | } 67 | 68 | if (callback == null) { 69 | throw new NullPointerException("Transaction Callback must not be null"); 70 | } 71 | return AcceptSDKCore.getInstance().performEncryption(transactionObject, callback); 72 | } 73 | 74 | /** 75 | * Builder pattern to create ApiClient. 76 | */ 77 | public static class Builder { 78 | private final WeakReference context; 79 | private final Environment environment; 80 | private int connectionTimeout; 81 | 82 | /** 83 | * API to build AcceptSDKpiClient 84 | * 85 | * @param context activity from where api is getting called. 86 | * @param environment sandbox or production. If this parameter is null by default environment 87 | * is sandbox. 88 | */ 89 | 90 | public Builder(Context context, Environment environment) { 91 | if (context == null) throw new NullPointerException("Context must not be null"); 92 | this.context = new WeakReference<>(context); 93 | this.environment = (environment == null) ? Environment.SANDBOX : environment; 94 | } 95 | 96 | /** 97 | * API to set ConnectionTimeout for Network calls 98 | * 99 | * @param timeout, time in milli seconds 100 | * @return AcceptSDKApiClient.Builder 101 | */ 102 | public AcceptSDKApiClient.Builder connectionTimeout(int timeout) { 103 | this.connectionTimeout = timeout; 104 | return this; 105 | } 106 | 107 | public AcceptSDKApiClient build() { 108 | return new AcceptSDKApiClient(this); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/ValidationCallback.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk; 2 | 3 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 4 | 5 | /** 6 | * Validation Callback for Transaction Data. 7 | * 8 | * Created by Kiran Bollepalli on 20,July,2016. 9 | * kbollepa@visa.com 10 | */ 11 | public interface ValidationCallback { 12 | 13 | /** 14 | * Callback method for successful validation. 15 | */ 16 | void OnValidationSuccessful(); 17 | 18 | /** 19 | * Callback method for failed validation. 20 | * 21 | * @param errorTransactionResponse {@link ErrorTransactionResponse} 22 | */ 23 | void OnValidationFailed(ErrorTransactionResponse errorTransactionResponse); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/ValidationManager.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk; 2 | 3 | import java.util.Calendar; 4 | 5 | /** 6 | * Class contains utility methods to validate card details. 7 | * 8 | * Created by kbollepa on 7/7/2016. 9 | */ 10 | public class ValidationManager { 11 | 12 | /* ----------------- Validations related to Card data -------------------------*/ 13 | 14 | /** 15 | * Method validates given card number is valid w.r.t Luhn formula 16 | * 17 | * @param cardNumber String 18 | * @return true if card is valid and false for invalid card. 19 | */ 20 | public static boolean isValidCardNumber(String cardNumber) { 21 | if (cardNumber == null) { 22 | return false; 23 | } 24 | cardNumber = cardNumber.trim(); 25 | if (cardNumber.length() < 6) { 26 | return false; 27 | } 28 | if (!cardNumber.matches("\\d+")) { 29 | return false; 30 | } 31 | 32 | // reversing the string 33 | String reversedNumber = new StringBuilder(cardNumber).reverse().toString(); 34 | 35 | String mutilatedString = ""; 36 | 37 | // Even digits are doubled, odd digits are not modified 38 | for (int i = 0; i < reversedNumber.length(); i++) { 39 | int c = Integer.parseInt(String.valueOf(reversedNumber.charAt(i))); 40 | if (i % 2 != 0) { 41 | c *= 2; 42 | } 43 | mutilatedString += c; 44 | } 45 | 46 | int sumOfDigits = 0; 47 | 48 | // summing up all digits 49 | for (int i = 0; i < mutilatedString.length(); i++) { 50 | int c = Integer.parseInt(String.valueOf(mutilatedString.charAt(i))); 51 | sumOfDigits += c; 52 | } 53 | 54 | if (sumOfDigits > 0 && sumOfDigits % 10 == 0) { 55 | return true; 56 | } else { 57 | return false; 58 | } 59 | } 60 | 61 | /** 62 | * Method validates expiration month of card 63 | * 64 | * @param month a string in two-digit format 65 | * @return true if expiration month is valid and false if invalid. 66 | */ 67 | public static boolean isValidExpirationMonth(String month) { 68 | 69 | if (month == null || month.length() != 2 || (!month.matches("\\d+"))) { 70 | return false; 71 | } 72 | 73 | int checkMonth = Integer.parseInt(month); 74 | if (checkMonth < 1 || checkMonth > 12) { 75 | return false; 76 | } 77 | 78 | return true; 79 | } 80 | 81 | /** 82 | * Method validates expiration month of card 83 | * 84 | * @param year a string in 4-digit format 85 | * @return true if expiration month is valid and false if invalid. 86 | */ 87 | public static boolean isValidExpirationYear(String year) { 88 | if (year == null || (year.length() != 4)) { 89 | return false; 90 | } 91 | if (!year.matches("\\d+")) return false; 92 | return true; 93 | } 94 | 95 | /** 96 | * Validation for Past date 97 | * 98 | * @param month two digit string 99 | * @param year four digit string 100 | * @return true if validation is success, false if fails. 101 | */ 102 | 103 | public static boolean isValidExpirationDate(String month, String year) { 104 | int currentYear = Calendar.getInstance().get(Calendar.YEAR); 105 | int currentMonth = 106 | Calendar.getInstance().get(Calendar.MONTH) + 1; // since JANUARY = 0 for Calendar class 107 | int checkYear = Integer.parseInt(year); 108 | int checkMonth = Integer.parseInt(month); 109 | 110 | if (checkYear < currentYear) { 111 | return false; 112 | } else if ((checkYear == currentYear) && (checkMonth < currentMonth)) { 113 | return false; 114 | } 115 | return true; 116 | } 117 | 118 | /** 119 | * Method validates cvv code of card. 120 | * CVV code should be numeric string and length should be 3 or 4. 121 | * 122 | * @param cvvCode a string 123 | * @return true if validation is success, false if fails. 124 | */ 125 | public static boolean isValidCVV(String cvvCode) { 126 | if (cvvCode == null || (cvvCode.length() < 3 || cvvCode.length() > 4)) { 127 | return false; 128 | } 129 | 130 | if (!cvvCode.matches("\\d+")) { 131 | return false; 132 | } 133 | return true; 134 | } 135 | 136 | /** 137 | * Method validates zip code of card. 138 | * zip code length should be between 1 & 20. 139 | * 140 | * @param zipCode a string 141 | * @return true if validation is success, false if fails. 142 | */ 143 | public static boolean isValidZipCode(String zipCode) { 144 | if (zipCode == null || (zipCode.length() < 1 || zipCode.length() > 20)) { 145 | return false; 146 | } 147 | return true; 148 | } 149 | 150 | /** 151 | * Method validates card holder name. 152 | * Card holder name length should be between 1 & 64. 153 | * 154 | * @param fullName a string 155 | * @return true if validation is success, false if fails. 156 | */ 157 | 158 | public static boolean isValidCardHolderName(String fullName) { 159 | if (fullName == null || (fullName.length() < 1 || fullName.length() > 64)) { 160 | return false; 161 | } 162 | return true; 163 | } 164 | 165 | /* ----------------- Validations related to Finger Print -------------------------*/ 166 | 167 | /** 168 | * Method validates amount. 169 | * Amount should be positive numbers with 1-2 digit fraction. 170 | * 171 | * @param amount as double 172 | * @return true if validation is success, false if fails. 173 | */ 174 | public static boolean isValidAmount(double amount) { 175 | if (amount <= 0) return false; 176 | return true; 177 | } 178 | 179 | /* ----------------- Validations related to Finger Print -------------------------*/ 180 | 181 | /** 182 | * Method validates Time stamp. 183 | * Amount should be positive numbers. 184 | * 185 | * @param timestamp as long 186 | * @return true if validation is success, false if fails. 187 | */ 188 | public static boolean isValidTimeStamp(long timestamp) { 189 | if (timestamp < 0) { 190 | return false; 191 | } 192 | return true; 193 | } 194 | 195 | /* ----------------- Common Validations-------------------------*/ 196 | public static boolean isValidString(String string) { 197 | if (string == null || (string.isEmpty())) { 198 | return false; 199 | } 200 | return true; 201 | } 202 | } -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/common/Message.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.common; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * POJO Class of message section from server response. 8 | * 9 | * Created by Kiran Bollepalli on 12,July,2016. 10 | * kbollepa@visa.com 11 | */ 12 | public class Message implements Parcelable { 13 | 14 | String mMessageCode; 15 | String mMessageText; 16 | 17 | public Message() { 18 | } 19 | 20 | public Message(Parcel in) { 21 | readFromParcel(in); 22 | } 23 | 24 | public Message(String mMessageCode, String mMessageText) { 25 | this.mMessageCode = mMessageCode; 26 | this.mMessageText = mMessageText; 27 | } 28 | 29 | 30 | 31 | public String getMessageCode() { 32 | return mMessageCode; 33 | } 34 | 35 | public void setMessageCode(String mMessageCode) { 36 | this.mMessageCode = mMessageCode; 37 | } 38 | 39 | public String getMessageText() { 40 | return mMessageText; 41 | } 42 | 43 | public void setMessageText(String mMessageText) { 44 | this.mMessageText = mMessageText; 45 | } 46 | 47 | @Override public String toString() { 48 | return "Message{" + 49 | "Code='" + mMessageCode + '\'' + 50 | ", MessageText='" + mMessageText + '\'' + 51 | '}'; 52 | } 53 | 54 | // ---------- Code for Parcelable interface ---------- 55 | 56 | public void readFromParcel(Parcel in) { 57 | mMessageCode = in.readString(); 58 | mMessageText = in.readString(); 59 | } 60 | @Override public void writeToParcel(Parcel dest, int flags) { 61 | dest.writeString(mMessageCode); 62 | dest.writeString(mMessageText); 63 | } 64 | 65 | @Override public int describeContents() { 66 | return 0; 67 | } 68 | 69 | public static final Creator CREATOR = new Creator() { 70 | @Override public Message createFromParcel(Parcel in) { 71 | return new Message(in); 72 | } 73 | 74 | @Override public Message[] newArray(int size) { 75 | return new Message[size]; 76 | } 77 | }; 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/common/ResponseMessages.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.common; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import net.authorize.acceptsdk.parser.JSONConstants; 8 | 9 | /** 10 | * POJO Class of messages section from server response. 11 | * Created by Kiran Bollepalli on 12,July,2016. 12 | * kbollepa@visa.com 13 | */ 14 | public class ResponseMessages implements Parcelable { 15 | 16 | /** 17 | * Result code is either Ok or Error. 18 | * Also see{@link JSONConstants.ResultCode} 19 | */ 20 | private String mResultCode; 21 | 22 | private List mMessageList; 23 | 24 | public ResponseMessages(String mResultCode) { 25 | this.mResultCode = mResultCode; 26 | this.mMessageList = new ArrayList<>(); 27 | } 28 | 29 | public ResponseMessages(Parcel in) { 30 | readFromParcel(in); 31 | } 32 | 33 | /** 34 | * Get Result code of Transaction. 35 | * 36 | * @return String, returns "Ok" if successful or "Error" in case of failure. 37 | */ 38 | public String getResultCode() { 39 | return mResultCode; 40 | } 41 | 42 | public void setResultCode(String mResultCode) { 43 | this.mResultCode = mResultCode; 44 | } 45 | 46 | public List getMessageList() { 47 | return mMessageList; 48 | } 49 | 50 | public void setMessageList(List mMessageList) { 51 | this.mMessageList = mMessageList; 52 | } 53 | 54 | public boolean addMessage(Message message) { 55 | if (mMessageList == null) return false; 56 | mMessageList.add(message); 57 | return true; 58 | } 59 | 60 | // ---------- Code for Parcelable interface ---------- 61 | 62 | public void readFromParcel(Parcel in) { 63 | mResultCode = in.readString(); 64 | mMessageList = in.createTypedArrayList(Message.CREATOR); 65 | } 66 | 67 | @Override public void writeToParcel(Parcel dest, int flags) { 68 | dest.writeString(mResultCode); 69 | dest.writeTypedList(mMessageList); 70 | } 71 | 72 | @Override public int describeContents() { 73 | return 0; 74 | } 75 | 76 | public static final Creator CREATOR = new Creator() { 77 | @Override public ResponseMessages createFromParcel(Parcel in) { 78 | return new ResponseMessages(in); 79 | } 80 | 81 | @Override public ResponseMessages[] newArray(int size) { 82 | return new ResponseMessages[size]; 83 | } 84 | }; 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/error/SDKErrorCode.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.error; 2 | 3 | /** 4 | * Class contains all Error codes for mapping validation errors, Network errors and API errors. 5 | * 6 | * Created by Kiran Bollepalli on 15,July,2016. 7 | * kbollepa@visa.com 8 | */ 9 | public enum SDKErrorCode { 10 | 11 | E_WC_02("E_WC_02", "A HTTPS connection is required."), 12 | E_WC_04("E_WC_04", "Please provide mandatory field to library."), 13 | E_WC_05("E_WC_05", "Please provide valid credit card number."), 14 | E_WC_06("E_WC_06", "Please provide valid expiration month."), 15 | E_WC_07("E_WC_07", "Please provide valid expiration year."), 16 | E_WC_08("E_WC_08", "Expiration date must be in the future."), 17 | E_WC_09("E_WC_09", "Fingerprint hash should not be blank."), 18 | E_WC_10("E_WC_10", "Please provide valid api login id."), 19 | E_WC_11("E_WC_11", "Please provide valid timestamp in utc."), 20 | E_WC_12("E_WC_12", "Sequence attribute should not be blank."), 21 | E_WC_13("E_WC_13", "Invalid Fingerprint."), 22 | E_WC_14("E_WC_14", "Accept encryption failed."), 23 | E_WC_15("E_WC_15", "Please provide valid CVV."), 24 | E_WC_16("E_WC_16", "Please provide valid Zip code."), 25 | E_WC_17("E_WC_17", "Please provide valid card holder name."), 26 | E_WC_18("E_W_18", "Client key is required."); 27 | 28 | private String errorCode; 29 | private String errorMessage; 30 | 31 | SDKErrorCode(String errorCode, String errorMessage) { 32 | this.errorCode = errorCode; 33 | this.errorMessage = errorMessage; 34 | } 35 | 36 | public String getErrorCode() { 37 | return errorCode; 38 | } 39 | 40 | public String getErrorMessage() { 41 | return errorMessage; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/merchant/AbstractMerchantAuthentication.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.merchant; 2 | 3 | import java.io.Serializable; 4 | import net.authorize.acceptsdk.ValidationCallback; 5 | 6 | /** 7 | * A common class used to represent Merchant Authentication. 8 | * 9 | * Created by Kiran Bollepalli on 08,July,2016. 10 | * kbollepa@visa.com 11 | */ 12 | public abstract class AbstractMerchantAuthentication implements Serializable { 13 | private static final long serialVersionUID = 2L; 14 | 15 | protected String mApiLoginID; 16 | protected MerchantAuthenticationType merchantAuthenticationType; 17 | 18 | public MerchantAuthenticationType getMerchantAuthenticationType() { 19 | return this.merchantAuthenticationType; 20 | } 21 | 22 | public String getApiLoginID() { 23 | return this.mApiLoginID; 24 | } 25 | 26 | /** 27 | * Validates Merchant Authentication. 28 | * 29 | * @param callback {@link ValidationCallback} 30 | * @return boolean true, if it is success. false if validation fails. 31 | */ 32 | public abstract boolean validateMerchantAuthentication(ValidationCallback callback); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/merchant/ClientKeyBasedMerchantAuthentication.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.merchant; 2 | 3 | import net.authorize.acceptsdk.ValidationCallback; 4 | import net.authorize.acceptsdk.ValidationManager; 5 | import net.authorize.acceptsdk.datamodel.error.SDKErrorCode; 6 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 7 | 8 | /** 9 | * ClientKey based Merchant Authentication 10 | */ 11 | public class ClientKeyBasedMerchantAuthentication extends AbstractMerchantAuthentication { 12 | 13 | private String mClientKey; 14 | 15 | private ClientKeyBasedMerchantAuthentication() { 16 | } 17 | 18 | /** 19 | * Creates a client key authenticator. 20 | * 21 | * @param loginId API login id of merchant. 22 | * @param clientKey public client key of merchant 23 | * @return ClientKeyBasedMerchantAuthentication Object 24 | */ 25 | public static ClientKeyBasedMerchantAuthentication createMerchantAuthentication(String loginId, 26 | String clientKey) { 27 | ClientKeyBasedMerchantAuthentication authenticator = new ClientKeyBasedMerchantAuthentication(); 28 | 29 | if (loginId != null) loginId = loginId.trim(); 30 | if (clientKey != null) clientKey = clientKey.trim(); 31 | 32 | authenticator.mApiLoginID = loginId; 33 | authenticator.mClientKey = clientKey; 34 | authenticator.merchantAuthenticationType = MerchantAuthenticationType.CLIENT_KEY; 35 | 36 | return authenticator; 37 | } 38 | 39 | public String getClientKey() { 40 | return mClientKey; 41 | } 42 | 43 | /** 44 | * Validates Client key based Merchant Authentication. 45 | * 46 | * @param callback {@link ValidationCallback} 47 | * @return boolean true, if it is success. false if validation fails. 48 | */ 49 | @Override public boolean validateMerchantAuthentication(ValidationCallback callback) { 50 | if (!ValidationManager.isValidString(mApiLoginID)) { 51 | callback.OnValidationFailed( 52 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_10)); 53 | return false; 54 | } 55 | 56 | if (!ValidationManager.isValidString(mClientKey)) { 57 | callback.OnValidationFailed( 58 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_18)); 59 | return false; 60 | } 61 | 62 | return true; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/merchant/FingerPrintBasedMerchantAuthentication.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.merchant; 2 | 3 | import net.authorize.acceptsdk.ValidationCallback; 4 | import net.authorize.acceptsdk.ValidationManager; 5 | import net.authorize.acceptsdk.datamodel.error.SDKErrorCode; 6 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 7 | 8 | /** 9 | * Fingerprint based Merchant Authentication. 10 | */ 11 | public class FingerPrintBasedMerchantAuthentication extends AbstractMerchantAuthentication { 12 | 13 | private FingerPrintData mFingerPrintData; 14 | 15 | private FingerPrintBasedMerchantAuthentication() { 16 | } 17 | 18 | /** 19 | * Creates a client key authenticator. 20 | * 21 | * @param loginId API login id of merchant. 22 | * @param fingerPrintData {@link FingerPrintData} 23 | * @return FingerPrintBasedMerchantAuthentication container 24 | */ 25 | public static FingerPrintBasedMerchantAuthentication createMerchantAuthentication(String loginId, 26 | FingerPrintData fingerPrintData) { 27 | FingerPrintBasedMerchantAuthentication authenticator = 28 | new FingerPrintBasedMerchantAuthentication(); 29 | 30 | if (loginId != null) loginId = loginId.trim(); 31 | 32 | authenticator.mApiLoginID = loginId; 33 | authenticator.mFingerPrintData = fingerPrintData; 34 | authenticator.merchantAuthenticationType = MerchantAuthenticationType.FINGERPRINT; 35 | 36 | return authenticator; 37 | } 38 | 39 | public FingerPrintData getFingerPrintData() { 40 | return mFingerPrintData; 41 | } 42 | 43 | public void setFingerPrintData(FingerPrintData fingerPrintData) { 44 | mFingerPrintData = fingerPrintData; 45 | } 46 | 47 | /** 48 | * Validates Fingerprint based Merchant Authentication. 49 | * 50 | * @param callback {@link ValidationCallback} 51 | * @return boolean true, if it is success. false if validation fails. 52 | */ 53 | 54 | @Override public boolean validateMerchantAuthentication(ValidationCallback callback) { 55 | if (!ValidationManager.isValidString(mApiLoginID)) { 56 | callback.OnValidationFailed( 57 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_10)); 58 | return false; 59 | } 60 | 61 | if (mFingerPrintData == null) { 62 | callback.OnValidationFailed( 63 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_04)); 64 | return false; 65 | } 66 | 67 | if (!mFingerPrintData.validateFingerPrint(callback)) { 68 | return false; 69 | } 70 | return true; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/merchant/FingerPrintData.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.merchant; 2 | 3 | import java.io.Serializable; 4 | import net.authorize.acceptsdk.ValidationCallback; 5 | import net.authorize.acceptsdk.ValidationManager; 6 | import net.authorize.acceptsdk.datamodel.error.SDKErrorCode; 7 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 8 | 9 | /** 10 | * Class of FingerPrint Data 11 | * 12 | * 13 | * Created by Kiran Bollepalli on 07,July,2016. 14 | * kbollepa@visa.com 15 | */ 16 | public class FingerPrintData implements Serializable { 17 | 18 | private final double DEFAULT_AMOUNT = -99999.99; 19 | 20 | //Mandatory 21 | private String hashValue; 22 | private long timestamp; 23 | 24 | //Optional 25 | private String sequence; 26 | private String currencyCode; 27 | private double amount = DEFAULT_AMOUNT; 28 | 29 | public FingerPrintData(Builder builder) { 30 | 31 | this.hashValue = builder.hashValue; 32 | if (hashValue != null) hashValue = hashValue.trim(); 33 | 34 | this.timestamp = builder.timestamp; 35 | 36 | this.sequence = builder.sequence; 37 | if (sequence != null) sequence = sequence.trim(); 38 | 39 | this.currencyCode = builder.currencyCode; 40 | if (currencyCode != null) currencyCode = currencyCode.trim(); 41 | 42 | this.amount = builder.amount; 43 | } 44 | 45 | /** 46 | * Validates Finger Print details 47 | * 48 | * @param callback {@link ValidationCallback} 49 | * @return boolean true, if it is success. false if validation fails. 50 | */ 51 | public boolean validateFingerPrint(ValidationCallback callback) { 52 | if (!ValidationManager.isValidString(hashValue)) { 53 | callback.OnValidationFailed( 54 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_09)); 55 | return false; 56 | } 57 | 58 | if (!ValidationManager.isValidTimeStamp(timestamp)) { 59 | callback.OnValidationFailed( 60 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_11)); 61 | return false; 62 | } 63 | 64 | /*COMMENT: Since Currency code, amount and sequence are optional, 65 | validate only if value is not null(i.e., provided by client app). 66 | */ 67 | if (sequence != null && sequence.isEmpty()) { 68 | callback.OnValidationFailed( 69 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_12)); 70 | return false; 71 | } 72 | 73 | //FIXME : currency code and amount don't have validation error mapping. 74 | 75 | if (currencyCode != null && currencyCode.isEmpty()) { 76 | callback.OnValidationFailed( 77 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_13)); 78 | return false; 79 | } 80 | 81 | if (amount != DEFAULT_AMOUNT && !ValidationManager.isValidAmount(amount)) { 82 | callback.OnValidationFailed( 83 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_13)); 84 | return false; 85 | } 86 | 87 | return true; 88 | } 89 | 90 | public String getHashValue() { 91 | return hashValue; 92 | } 93 | 94 | public void setHashValue(String hashValue) { 95 | this.hashValue = hashValue; 96 | } 97 | 98 | public double getAmount() { 99 | return amount; 100 | } 101 | 102 | public String getAmountString() { 103 | return String.valueOf(amount); 104 | } 105 | 106 | public void setAmount(double amount) { 107 | this.amount = amount; 108 | } 109 | 110 | public long getTimestamp() { 111 | return timestamp; 112 | } 113 | 114 | public void setTimestamp(long timestamp) { 115 | this.timestamp = timestamp; 116 | } 117 | 118 | public String getTimestampString() { 119 | return String.valueOf(timestamp); 120 | } 121 | 122 | public String getSequence() { 123 | return sequence; 124 | } 125 | 126 | public void setSequence(String sequence) { 127 | this.sequence = sequence; 128 | } 129 | 130 | public String getCurrencyCode() { 131 | return currencyCode; 132 | } 133 | 134 | public void setCurrencyCode(String currencyCode) { 135 | this.currencyCode = currencyCode; 136 | } 137 | 138 | /** 139 | * Builder class for FingerPrint Class 140 | */ 141 | public static class Builder { 142 | private String hashValue; 143 | private long timestamp; 144 | private String sequence; 145 | private String currencyCode; 146 | private double amount; 147 | 148 | /** 149 | * Builder constructor 150 | * 151 | * @param hashValue hash value of Fingerprint 152 | * @param timestamp Time stamp 153 | */ 154 | public Builder(String hashValue, long timestamp) { 155 | this.timestamp = timestamp; 156 | this.hashValue = hashValue; 157 | } 158 | 159 | public FingerPrintData.Builder setSequence(String sequence) { 160 | this.sequence = sequence; 161 | return this; 162 | } 163 | 164 | public FingerPrintData.Builder setCurrencyCode(String currencyCode) { 165 | this.currencyCode = currencyCode; 166 | return this; 167 | } 168 | 169 | public FingerPrintData.Builder setAmount(double amount) { 170 | this.amount = amount; 171 | return this; 172 | } 173 | 174 | public FingerPrintData build() { 175 | return new FingerPrintData(this); 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/merchant/MerchantAuthenticationType.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.merchant; 2 | 3 | /** 4 | * Defines the type of merchant authentication mechanisms that are supported. 5 | */ 6 | public enum MerchantAuthenticationType { 7 | /** 8 | * For ClientKey based Authentication. 9 | */ 10 | CLIENT_KEY, 11 | /** 12 | * For Finger Print based Authentication. 13 | */ 14 | FINGERPRINT 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/transaction/CardData.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction; 2 | 3 | import java.io.Serializable; 4 | import net.authorize.acceptsdk.ValidationCallback; 5 | import net.authorize.acceptsdk.ValidationManager; 6 | import net.authorize.acceptsdk.datamodel.error.SDKErrorCode; 7 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 8 | 9 | /** 10 | * Created by Kiran Bollepalli on 07,July,2016. 11 | * kbollepa@visa.com 12 | */ 13 | public class CardData implements Serializable { 14 | 15 | private static final long serialVersionUID = 2L; 16 | private static final String MONTH_PREFIX = "0"; 17 | private static final String YEAR_PREFIX = "20"; 18 | 19 | //Required 20 | private String cardNumber; 21 | private String expirationMonth; 22 | private String expirationYear; 23 | 24 | //Optional 25 | private String cvvCode; 26 | private String zipCode; 27 | private String cardHolderName; 28 | 29 | /** 30 | * Creates an instance of object to store keyed card data. Also it sets a 31 | */ 32 | private CardData(Builder builder) { 33 | this.cardNumber = trimString(builder.cardNumber); 34 | this.expirationMonth = prefixMonth(builder.expirationMonth); 35 | this.expirationYear = prefixYear(builder.expirationYear); 36 | this.cvvCode = trimString(builder.cvvCode); 37 | this.zipCode = trimString(builder.zipCode); 38 | this.cardHolderName = trimString(builder.cardHolderName); 39 | } 40 | 41 | private String trimString(String data) { 42 | if (ValidationManager.isValidString(data)) { 43 | data = data.trim(); 44 | } 45 | return data; 46 | } 47 | 48 | private String prefixMonth(String month) { 49 | if (ValidationManager.isValidString(month)) { 50 | month = month.trim(); 51 | if (month.length() == 1) month = MONTH_PREFIX + month; 52 | } 53 | 54 | return month; 55 | } 56 | 57 | private String prefixYear(String year) { 58 | if (ValidationManager.isValidString(year)) { 59 | year = year.trim(); 60 | if (year.length() == 2) year = YEAR_PREFIX + year; 61 | } 62 | 63 | return year; 64 | } 65 | 66 | public boolean validateCardData(ValidationCallback callback) { 67 | boolean result = false; 68 | if (!ValidationManager.isValidCardNumber(cardNumber)) { 69 | callback.OnValidationFailed( 70 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_05)); 71 | return result; 72 | } 73 | if (!ValidationManager.isValidExpirationMonth(expirationMonth)) { 74 | callback.OnValidationFailed( 75 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_06)); 76 | return result; 77 | } 78 | 79 | if (!ValidationManager.isValidExpirationYear(expirationYear)) { 80 | callback.OnValidationFailed( 81 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_07)); 82 | return result; 83 | } 84 | 85 | if (!ValidationManager.isValidExpirationDate(expirationMonth, expirationYear)) { 86 | 87 | callback.OnValidationFailed( 88 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_08)); 89 | return result; 90 | } 91 | 92 | //COMMENT: since cvv,zip and card Holder name are optional, validate only if client 93 | // application provides value 94 | if (cvvCode != null && !ValidationManager.isValidCVV(cvvCode)) { 95 | callback.OnValidationFailed( 96 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_15)); 97 | return result; 98 | } 99 | 100 | if (zipCode != null && !ValidationManager.isValidZipCode(zipCode)) { 101 | callback.OnValidationFailed( 102 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_16)); 103 | return result; 104 | } 105 | if (cardHolderName != null && !ValidationManager.isValidCardHolderName(cardHolderName)) { 106 | callback.OnValidationFailed( 107 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_17)); 108 | return result; 109 | } 110 | 111 | // callback.OnValidationSuccessful(); 112 | return true; 113 | } 114 | 115 | public String getCvvCode() { 116 | return cvvCode; 117 | } 118 | 119 | public void setCvvCode(String cvvCode) { 120 | this.cvvCode = cvvCode; 121 | } 122 | 123 | public String getZipCode() { 124 | return zipCode; 125 | } 126 | 127 | public void setZipCode(String zipCode) { 128 | this.zipCode = zipCode; 129 | } 130 | 131 | public String getCardHolderName() { 132 | return cardHolderName; 133 | } 134 | 135 | public void setCardHolderName(String cardHolderName) { 136 | this.cardHolderName = cardHolderName; 137 | } 138 | 139 | public String getCardNumber() { 140 | return cardNumber; 141 | } 142 | 143 | public void setCardNumber(String cardNumber) { 144 | this.cardNumber = cardNumber; 145 | } 146 | 147 | public String getExpirationMonth() { 148 | return expirationMonth; 149 | } 150 | 151 | public void setExpirationMonth(String expirationMonth) { 152 | this.expirationMonth = expirationMonth; 153 | } 154 | 155 | public String getExpirationYear() { 156 | return expirationYear; 157 | } 158 | 159 | public void setExpirationYear(String expirationYear) { 160 | this.expirationYear = expirationYear; 161 | } 162 | 163 | public String getExpirationInFormatMMYYYY() { 164 | return expirationMonth + expirationYear; 165 | } 166 | 167 | public static class Builder { 168 | // required 169 | private final String cardNumber; 170 | private final String expirationMonth; 171 | private final String expirationYear; 172 | private String cvvCode; 173 | private String zipCode; 174 | private String cardHolderName; 175 | 176 | public Builder(String cardNumber, String expirationMonth, String expirationYear) { 177 | this.cardNumber = cardNumber; 178 | this.expirationMonth = expirationMonth; 179 | this.expirationYear = expirationYear; 180 | } 181 | 182 | public CardData.Builder cvvCode(String cvvCode) { 183 | this.cvvCode = cvvCode; 184 | return this; 185 | } 186 | 187 | public CardData.Builder zipCode(String zipCode) { 188 | this.zipCode = zipCode; 189 | return this; 190 | } 191 | 192 | public CardData.Builder cardHolderName(String cardHolderName) { 193 | this.cardHolderName = cardHolderName; 194 | return this; 195 | } 196 | 197 | public CardData build() { 198 | return new CardData(this); 199 | } 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/transaction/EncryptTransactionObject.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction; 2 | 3 | import net.authorize.acceptsdk.ValidationCallback; 4 | import net.authorize.acceptsdk.datamodel.error.SDKErrorCode; 5 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 6 | 7 | /** 8 | * Created by Kiran Bollepalli on 07,July,2016. 9 | * kbollepa@visa.com 10 | */ 11 | public class EncryptTransactionObject extends TransactionObject { 12 | 13 | private EncryptTransactionObject(Builder builder) { 14 | mTransactionType = builder.transactionType; 15 | this.mCardData = builder.cardData; 16 | this.mMerchantAuthentication = builder.merchantAuthentication; 17 | } 18 | 19 | @Override public boolean validateTransactionObject(final ValidationCallback callback) { 20 | if (mMerchantAuthentication == null) { 21 | callback.OnValidationFailed( 22 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_04)); 23 | return false; 24 | } 25 | if (mCardData == null) { 26 | callback.OnValidationFailed( 27 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_04)); 28 | return false; 29 | } 30 | if (mMerchantAuthentication.validateMerchantAuthentication(callback) 31 | && mCardData.validateCardData(callback)) { 32 | callback.OnValidationSuccessful(); 33 | return true; 34 | } else { 35 | return false; 36 | } 37 | } 38 | 39 | public static class Builder extends TransactionObject.Builder { 40 | 41 | public Builder() { 42 | transactionType = TransactionType.SDK_TRANSACTION_ENCRYPTION; 43 | } 44 | 45 | @Override public EncryptTransactionObject build() { 46 | return new EncryptTransactionObject(this); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/transaction/TransactionObject.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction; 2 | 3 | import java.io.Serializable; 4 | import java.util.UUID; 5 | import net.authorize.acceptsdk.ValidationCallback; 6 | import net.authorize.acceptsdk.datamodel.merchant.AbstractMerchantAuthentication; 7 | 8 | /** 9 | * Created by Kiran Bollepalli on 07,July,2016. 10 | * kbollepa@visa.com 11 | */ 12 | public abstract class TransactionObject implements Serializable { 13 | 14 | private static final long serialVersionUID = 2L; 15 | 16 | AbstractMerchantAuthentication mMerchantAuthentication; 17 | CardData mCardData; 18 | TransactionType mTransactionType; 19 | String mGuid; 20 | 21 | public TransactionObject() { 22 | //FIXME : Need to revisit this code 23 | mGuid = UUID.randomUUID().toString(); 24 | } 25 | 26 | public AbstractMerchantAuthentication getMerchantAuthentication() { 27 | return mMerchantAuthentication; 28 | } 29 | 30 | public void setGuid(String guid) { 31 | mGuid = guid; 32 | } 33 | 34 | public String getGuid() { 35 | return mGuid; 36 | } 37 | 38 | public void setMerchantAuthentication(AbstractMerchantAuthentication mMerchantAuthentication) { 39 | 40 | this.mMerchantAuthentication = mMerchantAuthentication; 41 | } 42 | 43 | public CardData getCardData() { 44 | return mCardData; 45 | } 46 | 47 | public void setCardData(CardData mCardData) { 48 | this.mCardData = mCardData; 49 | } 50 | 51 | public TransactionType getTransactionType() { 52 | return mTransactionType; 53 | } 54 | 55 | public void setTransactionType(TransactionType mTransactionType) { 56 | this.mTransactionType = mTransactionType; 57 | } 58 | 59 | public abstract boolean validateTransactionObject(ValidationCallback callback); 60 | 61 | /** 62 | * A factory method for creating proper transaction object. 63 | * 64 | * @param type transaction type 65 | * @return one of transaction objects 66 | */ 67 | public static TransactionObject.Builder createTransactionObject(TransactionType type) 68 | throws IllegalArgumentException { 69 | 70 | if (type == null) throw new IllegalArgumentException("TransactionType must not be null"); 71 | switch (type) { 72 | case SDK_TRANSACTION_ENCRYPTION: 73 | return new EncryptTransactionObject.Builder(); 74 | default: 75 | return new EncryptTransactionObject.Builder(); 76 | } 77 | } 78 | 79 | public static abstract class Builder { 80 | CardData cardData; 81 | AbstractMerchantAuthentication merchantAuthentication; 82 | TransactionType transactionType; 83 | 84 | public TransactionObject.Builder cardData(CardData cardData) { 85 | this.cardData = cardData; 86 | return this; 87 | } 88 | 89 | public TransactionObject.Builder merchantAuthentication( 90 | AbstractMerchantAuthentication merchantAuthentication) { 91 | this.merchantAuthentication = merchantAuthentication; 92 | return this; 93 | } 94 | 95 | public abstract EncryptTransactionObject build(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/transaction/TransactionType.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Enumeration used to indicate the transaction type. Possible states: 7 | *
    8 | *
  • SDK_TRANSACTION_ENCRYPTION
  • 9 | *
10 | * 11 | * @author Kiran bollepalli 12 | */ 13 | public enum TransactionType implements Serializable { 14 | SDK_TRANSACTION_ENCRYPTION 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/transaction/callbacks/EncryptTransactionCallback.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction.callbacks; 2 | 3 | import net.authorize.acceptsdk.datamodel.transaction.response.EncryptTransactionResponse; 4 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 5 | 6 | /** 7 | * Callback Interface for Encrypt Transaction 8 | * 9 | * Created by Kiran Bollepalli on 07,July,2016. 10 | * kbollepa@visa.com 11 | */ 12 | public interface EncryptTransactionCallback { 13 | 14 | /** 15 | * Called when an error occurred caused by sending/receiving a request. It 16 | * might be an error returned by the gateway as well as by the gateway 17 | * driver (e.g connection problems, missing request parameters) 18 | * 19 | * @param error 20 | */ 21 | public abstract void onErrorReceived(ErrorTransactionResponse error); 22 | 23 | /** 24 | * Called when transaction request completed. 25 | */ 26 | public abstract void onEncryptionFinished(EncryptTransactionResponse response); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/transaction/response/EncryptTransactionResponse.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction.response; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Response Object of Encrypt Transaction. 8 | * 9 | * Created by Kiran Bollepalli on 07,July,2016. 10 | * kbollepa@visa.com 11 | */ 12 | public class EncryptTransactionResponse extends TransactionResponse { 13 | 14 | private String mDataDescriptor; 15 | private String mDataValue; 16 | 17 | public EncryptTransactionResponse() { 18 | super(); 19 | } 20 | 21 | 22 | /** 23 | * Returns Data descriptor .Used as "dataDescriptor" to perform payment transaction. 24 | * 25 | * @return String 26 | */ 27 | public String getDataDescriptor() { 28 | return mDataDescriptor; 29 | } 30 | 31 | public void setDataDescriptor(String mDataDescriptor) { 32 | this.mDataDescriptor = mDataDescriptor; 33 | } 34 | 35 | /** 36 | * Returns Encrypted Payment Token.Used as "dataValue" to perform payment transaction. 37 | * 38 | * @return String Encrypted Payment Token 39 | */ 40 | public String getDataValue() { 41 | return mDataValue; 42 | } 43 | 44 | public void setDataValue(String mDataValue) { 45 | this.mDataValue = mDataValue; 46 | } 47 | 48 | 49 | // ---------- Code for Parcelable interface ---------- 50 | 51 | public EncryptTransactionResponse(Parcel in) { 52 | super(in); 53 | readFromParcel(in); 54 | } 55 | 56 | 57 | @Override public int describeContents() { 58 | return 0; 59 | } 60 | 61 | 62 | 63 | public void readFromParcel(Parcel in) { 64 | mDataDescriptor = in.readString(); 65 | mDataValue = in.readString(); 66 | } 67 | 68 | @Override public void writeToParcel(Parcel dest, int flags) { 69 | super.writeToParcel(dest, flags); 70 | dest.writeString(mDataDescriptor); 71 | dest.writeString(mDataValue); 72 | } 73 | 74 | public static final Parcelable.Creator CREATOR = 75 | new Parcelable.Creator() { 76 | 77 | @Override public EncryptTransactionResponse createFromParcel(Parcel in) { 78 | return new EncryptTransactionResponse(in); 79 | } 80 | 81 | @Override public EncryptTransactionResponse[] newArray(int size) { 82 | return new EncryptTransactionResponse[size]; 83 | } 84 | }; 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/transaction/response/ErrorTransactionResponse.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction.response; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.List; 8 | import net.authorize.acceptsdk.datamodel.common.Message; 9 | import net.authorize.acceptsdk.datamodel.common.ResponseMessages; 10 | import net.authorize.acceptsdk.datamodel.error.SDKErrorCode; 11 | import net.authorize.acceptsdk.parser.JSONConstants; 12 | import net.authorize.acceptsdk.util.LogUtil; 13 | import net.authorize.acceptsdk.util.SDKUtils; 14 | 15 | /** 16 | * ErrorTransactionResponse class. 17 | * 18 | * Created by Kiran Bollepalli on 15,July,2016. 19 | * kbollepa@visa.com 20 | */ 21 | public class ErrorTransactionResponse extends TransactionResponse { 22 | 23 | public ErrorTransactionResponse(ResponseMessages responseMessages) { 24 | super(responseMessages); 25 | } 26 | 27 | /** 28 | * Create Error Response from {@link Message} object. 29 | * 30 | * @param errorMessage Message Object. 31 | * @return ErrorTransactionResponse {@link ErrorTransactionResponse} 32 | */ 33 | public static ErrorTransactionResponse createErrorResponse(Message errorMessage) { 34 | ResponseMessages responseMessages = new ResponseMessages(JSONConstants.ResultCode.ERROR); 35 | responseMessages.addMessage(errorMessage); 36 | return new ErrorTransactionResponse(responseMessages); 37 | } 38 | 39 | /** 40 | * Create Error Response from Error Stream 41 | * 42 | * @param errorCode error Message code. 43 | * @param errorStream error stream. 44 | * @return ErrorTransactionResponse {@link ErrorTransactionResponse} 45 | * @throws IOException parsing exception. 46 | */ 47 | public static ErrorTransactionResponse createErrorResponse(String errorCode, 48 | InputStream errorStream) throws IOException { 49 | 50 | String errorString = SDKUtils.convertStreamToString(errorStream); 51 | LogUtil.log(LogUtil.LOG_LEVEL.INFO, errorString); 52 | Message message = new Message(errorCode, errorString); 53 | return ErrorTransactionResponse.createErrorResponse(message); 54 | } 55 | 56 | /** 57 | * Create Error Response 58 | * 59 | * @param {@link SDKErrorCode} error code. 60 | * @param errorMessage error message. 61 | * @return ErrorTransactionResponse {@link ErrorTransactionResponse} 62 | */ 63 | public static ErrorTransactionResponse createErrorResponse(SDKErrorCode errorCode, 64 | String errorMessage) { 65 | Message message = new Message(errorCode.getErrorCode(), errorMessage); 66 | return ErrorTransactionResponse.createErrorResponse(message); 67 | } 68 | 69 | /** 70 | * Create Error Response 71 | * 72 | * @param {@link SDKErrorCode} error code. 73 | * @return ErrorTransactionResponse {@link ErrorTransactionResponse} 74 | */ 75 | public static ErrorTransactionResponse createErrorResponse(SDKErrorCode errorCode) { 76 | Message message = new Message(errorCode.getErrorCode(), errorCode.getErrorMessage()); 77 | return ErrorTransactionResponse.createErrorResponse(message); 78 | } 79 | 80 | public Message getFirstErrorMessage() { 81 | Message message = null; 82 | if (responseMessages == null) return message; 83 | 84 | List messageList = responseMessages.getMessageList(); 85 | if (messageList != null && messageList.size() > 0) message = messageList.get(0); 86 | 87 | return message; 88 | } 89 | 90 | // ---------- Code for Parcelable interface ---------- 91 | 92 | public ErrorTransactionResponse(Parcel in) { 93 | super(in); 94 | } 95 | 96 | @Override public int describeContents() { 97 | return 0; 98 | } 99 | 100 | @Override public void writeToParcel(Parcel dest, int flags) { 101 | super.writeToParcel(dest, flags); 102 | } 103 | 104 | public static final Parcelable.Creator CREATOR = 105 | new Parcelable.Creator() { 106 | 107 | @Override public ErrorTransactionResponse createFromParcel(Parcel in) { 108 | return new ErrorTransactionResponse(in); 109 | } 110 | 111 | @Override public ErrorTransactionResponse[] newArray(int size) { 112 | return new ErrorTransactionResponse[size]; 113 | } 114 | }; 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/datamodel/transaction/response/TransactionResponse.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction.response; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import java.util.List; 6 | import net.authorize.acceptsdk.datamodel.common.Message; 7 | import net.authorize.acceptsdk.datamodel.common.ResponseMessages; 8 | 9 | /** 10 | * Base Transaction Response Object. 11 | * 12 | * Created by Kiran Bollepalli on 12,July,2016. 13 | * kbollepa@visa.com 14 | */ 15 | public class TransactionResponse implements Parcelable { 16 | 17 | ResponseMessages responseMessages; 18 | 19 | public TransactionResponse() { 20 | } 21 | 22 | protected TransactionResponse(Parcel in) { 23 | readFromParcel(in); 24 | } 25 | 26 | public TransactionResponse(ResponseMessages responseMessages) { 27 | this.responseMessages = responseMessages; 28 | } 29 | 30 | public ResponseMessages getResponseMessages() { 31 | return responseMessages; 32 | } 33 | 34 | public void setResponseMessages(ResponseMessages responseMessages) { 35 | this.responseMessages = responseMessages; 36 | } 37 | 38 | public String getResultCode() { 39 | return responseMessages.getResultCode(); 40 | } 41 | 42 | public List getMessageList() { 43 | return responseMessages.getMessageList(); 44 | } 45 | // ---------- Code for Parcelable interface ---------- 46 | 47 | public void readFromParcel(Parcel in) { 48 | responseMessages = in.readParcelable(ResponseMessages.class.getClassLoader()); 49 | } 50 | 51 | @Override public void writeToParcel(Parcel dest, int flags) { 52 | dest.writeParcelable(responseMessages, flags); 53 | } 54 | 55 | @Override public int describeContents() { 56 | return 0; 57 | } 58 | 59 | public static final Creator CREATOR = new Creator() { 60 | @Override public TransactionResponse createFromParcel(Parcel in) { 61 | return new TransactionResponse(in); 62 | } 63 | 64 | @Override public TransactionResponse[] newArray(int size) { 65 | return new TransactionResponse[size]; 66 | } 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/internal/AcceptSDKCore.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.internal; 2 | 3 | import android.os.Bundle; 4 | import android.os.Handler; 5 | import net.authorize.acceptsdk.AcceptSDKApiClient; 6 | import net.authorize.acceptsdk.ValidationCallback; 7 | import net.authorize.acceptsdk.datamodel.transaction.EncryptTransactionObject; 8 | import net.authorize.acceptsdk.datamodel.transaction.callbacks.EncryptTransactionCallback; 9 | import net.authorize.acceptsdk.datamodel.transaction.response.EncryptTransactionResponse; 10 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 11 | import net.authorize.acceptsdk.network.AcceptService; 12 | import net.authorize.acceptsdk.network.TransactionResultReceiver; 13 | 14 | /** 15 | * Core class has implementation of API's. 16 | * Created by Kiran Bollepalli on 07,July,2016. 17 | * kbollepa@visa.com 18 | */ 19 | public class AcceptSDKCore implements TransactionResultReceiver.Receiver { 20 | 21 | //COMMENT: Single instance 22 | private static AcceptSDKCore sInstance = new AcceptSDKCore(); 23 | 24 | /** Flag to indicate that a transaction is in progress. */ 25 | private static boolean sTransactionInProgress = false; 26 | private TransactionResultReceiver mResultReceiver = null; 27 | EncryptTransactionCallback mEncryptTransactionCallback; 28 | 29 | private AcceptSDKCore() { 30 | 31 | } 32 | 33 | /** 34 | * Method returns AcceptSDKCore object. 35 | * 36 | * @return AcceptSDKCore 37 | */ 38 | public static AcceptSDKCore getInstance() { 39 | return sInstance; 40 | } 41 | 42 | /** 43 | * @param transactionObject encryption transaction object. 44 | * @param callback callback for response of transaction 45 | * @return boolean, false if another transaction is already in progress. 46 | */ 47 | public boolean performEncryption(final EncryptTransactionObject transactionObject, 48 | final EncryptTransactionCallback callback) { 49 | if (sTransactionInProgress) return sTransactionInProgress; 50 | mEncryptTransactionCallback = callback; 51 | 52 | transactionObject.validateTransactionObject(new ValidationCallback() { 53 | @Override public void OnValidationSuccessful() { 54 | registerResultReceiver(); 55 | sTransactionInProgress = true; 56 | AcceptService.startActionEncrypt(AcceptSDKApiClient.getContext().get(), transactionObject, 57 | mResultReceiver); 58 | } 59 | 60 | @Override public void OnValidationFailed(ErrorTransactionResponse errorTransactionResponse) { 61 | mEncryptTransactionCallback.onErrorReceived(errorTransactionResponse); 62 | sTransactionInProgress = false; 63 | } 64 | }); 65 | 66 | return sTransactionInProgress; 67 | } 68 | 69 | private void registerResultReceiver() { 70 | if (mResultReceiver != null) return; 71 | mResultReceiver = new TransactionResultReceiver(new Handler()); 72 | mResultReceiver.setReceiver(this); 73 | } 74 | 75 | @Override public void onReceiveResult(int resultCode, Bundle resultData) { 76 | 77 | sTransactionInProgress = false; 78 | switch (resultCode) { 79 | case AcceptService.SERVICE_RESULT_CODE_SDK_RESPONSE: 80 | EncryptTransactionResponse response = 81 | resultData.getParcelable(AcceptService.SERVICE_RESULT_RESPONSE_KEY); 82 | mEncryptTransactionCallback.onEncryptionFinished(response); 83 | break; 84 | case AcceptService.SERVICE_RESULT_CODE_SDK_ERROR: 85 | ErrorTransactionResponse error = 86 | resultData.getParcelable(AcceptService.SERVICE_RESULT_ERROR_KEY); 87 | mEncryptTransactionCallback.onErrorReceived(error); 88 | break; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/network/AcceptService.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.network; 2 | 3 | import android.app.IntentService; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.os.ResultReceiver; 8 | import android.util.Xml; 9 | import java.io.BufferedWriter; 10 | import java.io.IOException; 11 | import java.io.OutputStream; 12 | import java.io.OutputStreamWriter; 13 | import java.net.SocketTimeoutException; 14 | import javax.net.ssl.HttpsURLConnection; 15 | import net.authorize.acceptsdk.datamodel.error.SDKErrorCode; 16 | import net.authorize.acceptsdk.datamodel.transaction.EncryptTransactionObject; 17 | import net.authorize.acceptsdk.datamodel.transaction.response.EncryptTransactionResponse; 18 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 19 | import net.authorize.acceptsdk.datamodel.transaction.response.TransactionResponse; 20 | import net.authorize.acceptsdk.parser.AcceptSDKParser; 21 | import net.authorize.acceptsdk.util.LogUtil; 22 | import net.authorize.acceptsdk.util.SDKUtils; 23 | import org.json.JSONException; 24 | 25 | import static net.authorize.acceptsdk.parser.JSONConstants.ResultCode; 26 | import static net.authorize.acceptsdk.util.LogUtil.LOG_LEVEL; 27 | 28 | /** 29 | * Handling asynchronous task requests in 30 | * a service on a separate handler thread for Accept 31 | * 32 | * Created by Kiran Bollepalli on 07,July,2016. 33 | * kbollepa@visa.com 34 | */ 35 | public class AcceptService extends IntentService { 36 | 37 | private final static String POST = "POST"; 38 | 39 | public static final String ACTION_ENCRYPT = "net.authorize.action.ENCRYPT"; 40 | 41 | private static final String EXTRA_PARAM_TRANSACTION_OBJECT = 42 | "net.authorize.extra.TRANSACTION_OBJECT"; 43 | private static final String EXTRA_PARAM_RESULT_RECEIVER = "net.authorize.extra.RESULT_RECEIVER"; 44 | 45 | public static final String SERVICE_RESULT_RESPONSE_KEY = "SERVICE_RESULT_RESPONSE_KEY"; 46 | public static final String SERVICE_RESULT_ERROR_KEY = "SERVICE_RESULT_ERROR_KEY"; 47 | public static final int SERVICE_RESULT_CODE_SDK_RESPONSE = 100; 48 | public static final int SERVICE_RESULT_CODE_SDK_ERROR = 200; 49 | 50 | /** 51 | * Starts this service to perform action ENCRYPT with the given parameters. If 52 | * the service is already performing a task this action will be queued. 53 | * 54 | * @param context Activity context 55 | * @param transactionObject - Envelope that will be send to Gateway 56 | * @param resultReceiver - result receiver to notify the gateway when the service has a result 57 | * @see IntentService 58 | */ 59 | public static void startActionEncrypt(Context context, 60 | final EncryptTransactionObject transactionObject, TransactionResultReceiver resultReceiver) { 61 | Intent intent = new Intent(context, AcceptService.class); 62 | intent.setAction(ACTION_ENCRYPT); 63 | Bundle bundle = new Bundle(); 64 | bundle.putSerializable(EXTRA_PARAM_TRANSACTION_OBJECT, transactionObject); 65 | bundle.putParcelable(EXTRA_PARAM_RESULT_RECEIVER, resultReceiver); 66 | intent.putExtras(bundle); 67 | context.startService(intent); 68 | } 69 | 70 | public AcceptService() { 71 | super("InAppConnectionService"); 72 | } 73 | 74 | @Override protected void onHandleIntent(Intent intent) { 75 | if (intent != null) { 76 | final String action = intent.getAction(); 77 | 78 | switch (action) { 79 | case ACTION_ENCRYPT: 80 | final EncryptTransactionObject transactionObject = 81 | (EncryptTransactionObject) intent.getSerializableExtra( 82 | EXTRA_PARAM_TRANSACTION_OBJECT); 83 | final ResultReceiver resultReceiver = 84 | intent.getParcelableExtra(EXTRA_PARAM_RESULT_RECEIVER); 85 | Object result = handleActionEncrypt(transactionObject); 86 | onPostHandleAction(result, resultReceiver); 87 | break; 88 | } 89 | } 90 | } 91 | 92 | /** 93 | * Handles action Encrypt in the provided background thread with the provided 94 | * parameters. 95 | */ 96 | private Object handleActionEncrypt(EncryptTransactionObject transactionObject) { 97 | Object resultObject = null; 98 | String url = ConnectionData.getActiveEndPointUrl(); 99 | try { 100 | 101 | HttpsURLConnection urlConnection = SDKUtils.getHttpsURLConnection(url, POST, true); 102 | urlConnection.setRequestProperty(ConnectionData.CONTENT_TYPE_LABEL, 103 | ConnectionData.CONTENT_TYPE_APPLICATION_JSON); 104 | urlConnection.setConnectTimeout(ConnectionData.getConnectionTimeout()); 105 | 106 | OutputStream os = urlConnection.getOutputStream(); 107 | BufferedWriter writer = 108 | new BufferedWriter(new OutputStreamWriter(os, Xml.Encoding.UTF_8.name())); 109 | writer.write( 110 | AcceptSDKParser.getOrderedJsonFromEncryptTransaction(transactionObject)); //Json data 111 | writer.flush(); 112 | writer.close(); 113 | os.close(); 114 | 115 | int responseCode = urlConnection.getResponseCode(); 116 | if (responseCode == HttpsURLConnection.HTTP_OK 117 | || responseCode == HttpsURLConnection.HTTP_CREATED) { 118 | 119 | String responseString = SDKUtils.convertStreamToString(urlConnection.getInputStream()); 120 | LogUtil.log(LOG_LEVEL.INFO, " response string :" + responseString); 121 | TransactionResponse response = 122 | AcceptSDKParser.createEncryptionTransactionResponse(responseString); 123 | /* COMMENT: Check Result code. 124 | * > If it is "Ok" that means transaction is successful. 125 | * > If it is "Error" that means transaction is failed. 126 | */ 127 | if (response.getResultCode().equals(ResultCode.OK)) { 128 | resultObject = response; 129 | } else { //Error case 130 | resultObject = response; 131 | } 132 | } else if (responseCode == HttpsURLConnection.HTTP_INTERNAL_ERROR) { 133 | resultObject = 134 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_02.getErrorCode(), 135 | urlConnection.getErrorStream()); 136 | } else { 137 | //COMMENT: Handles other HTTP errors. 138 | resultObject = ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_02); 139 | } 140 | } catch (SocketTimeoutException e) { 141 | resultObject = 142 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_02, e.getMessage()); 143 | } catch (IOException e) { 144 | resultObject = 145 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_02, e.getMessage()); 146 | } catch (JSONException e) { 147 | resultObject = 148 | ErrorTransactionResponse.createErrorResponse(SDKErrorCode.E_WC_14, e.getMessage()); 149 | } 150 | return resultObject; 151 | } 152 | 153 | protected void onPostHandleAction(Object result, ResultReceiver resultReceiver) { 154 | Bundle resultData = new Bundle(); 155 | if (result instanceof EncryptTransactionResponse) { 156 | EncryptTransactionResponse response = (EncryptTransactionResponse) result; 157 | resultData.putParcelable(SERVICE_RESULT_RESPONSE_KEY, response); 158 | resultReceiver.send(SERVICE_RESULT_CODE_SDK_RESPONSE, resultData); 159 | } else if (result instanceof ErrorTransactionResponse) { 160 | ErrorTransactionResponse response = (ErrorTransactionResponse) result; 161 | resultData.putParcelable(SERVICE_RESULT_ERROR_KEY, response); 162 | resultReceiver.send(SERVICE_RESULT_CODE_SDK_ERROR, resultData); 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/network/ConnectionData.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.network; 2 | 3 | /** 4 | * Class contains constants and methods related to Network connection. 5 | * 6 | * Created by Kiran Bollepalli on 08,July,2016. 7 | * kbollepa@visa.com 8 | */ 9 | public class ConnectionData { 10 | 11 | /** 12 | * End point url for Sandbox. 13 | */ 14 | public static final String ENDPOINT_SANDBOX = "https://apitest.authorize.net/xml/v1/request.api "; 15 | 16 | /** 17 | * End point url for Production. 18 | */ 19 | public static final String ENDPOINT_PRODUCTION = "https://api.authorize.net/xml/v1/request.api "; 20 | 21 | /** 22 | * Label for content-type header. 23 | */ 24 | public static final String CONTENT_TYPE_LABEL = "Content-type"; 25 | /** 26 | * Value for COntent-type header = application/json. 27 | */ 28 | public static final String CONTENT_TYPE_APPLICATION_JSON = "application/json"; 29 | 30 | /** 31 | * Timeout for making a connection. 32 | */ 33 | public static final int DEFAULT_CONN_TIMEOUT = 5000; 34 | /** 35 | * Timeout for receiving data. 36 | */ 37 | public static final int DEFAULT_SOCKET_TIMEOUT = 20000; 38 | 39 | /** 40 | * API current endpoint address. 41 | */ 42 | private static String sActiveEndPointUrl; 43 | 44 | private static int sConnectionTimeout = DEFAULT_CONN_TIMEOUT; 45 | 46 | public static int getConnectionTimeout() { 47 | return sConnectionTimeout; 48 | } 49 | 50 | public static void setConnectionTimeout(int timeout) { 51 | sConnectionTimeout = timeout; 52 | } 53 | 54 | public static void setActiveEndPointUrl(String url) { 55 | sActiveEndPointUrl = url; 56 | } 57 | 58 | public static String getActiveEndPointUrl() { 59 | return sActiveEndPointUrl; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/network/TransactionResultReceiver.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.network; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.os.Bundle; 5 | import android.os.Handler; 6 | import android.os.ResultReceiver; 7 | 8 | /** 9 | * Result Receiver for {@link AcceptService} 10 | */ 11 | @SuppressLint("ParcelCreator") 12 | public class TransactionResultReceiver extends ResultReceiver { 13 | 14 | private Receiver mReceiver; 15 | 16 | public TransactionResultReceiver(Handler handler) { 17 | super(handler); 18 | } 19 | 20 | public interface Receiver { 21 | void onReceiveResult(int resultCode, Bundle resultData); 22 | } 23 | 24 | public void setReceiver(Receiver receiver) { 25 | mReceiver = receiver; 26 | } 27 | 28 | @Override protected void onReceiveResult(int resultCode, Bundle resultData) { 29 | 30 | if (mReceiver != null) { 31 | mReceiver.onReceiveResult(resultCode, resultData); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/parser/AcceptSDKParser.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.parser; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import net.authorize.acceptsdk.datamodel.common.Message; 6 | import net.authorize.acceptsdk.datamodel.common.ResponseMessages; 7 | import net.authorize.acceptsdk.datamodel.error.SDKErrorCode; 8 | import net.authorize.acceptsdk.datamodel.merchant.ClientKeyBasedMerchantAuthentication; 9 | import net.authorize.acceptsdk.datamodel.merchant.FingerPrintBasedMerchantAuthentication; 10 | import net.authorize.acceptsdk.datamodel.merchant.FingerPrintData; 11 | import net.authorize.acceptsdk.datamodel.merchant.MerchantAuthenticationType; 12 | import net.authorize.acceptsdk.datamodel.transaction.CardData; 13 | import net.authorize.acceptsdk.datamodel.transaction.EncryptTransactionObject; 14 | import net.authorize.acceptsdk.datamodel.transaction.response.EncryptTransactionResponse; 15 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 16 | import net.authorize.acceptsdk.datamodel.transaction.response.TransactionResponse; 17 | import net.authorize.acceptsdk.util.LogUtil; 18 | import net.authorize.acceptsdk.util.LogUtil.LOG_LEVEL; 19 | import org.json.JSONArray; 20 | import org.json.JSONException; 21 | import org.json.JSONObject; 22 | import org.json.JSONStringer; 23 | import org.json.JSONTokener; 24 | 25 | import static net.authorize.acceptsdk.parser.JSONConstants.Authentication; 26 | import static net.authorize.acceptsdk.parser.JSONConstants.CLIENT_ID; 27 | import static net.authorize.acceptsdk.parser.JSONConstants.CLIENT_ID_VALUE; 28 | import static net.authorize.acceptsdk.parser.JSONConstants.CONTAINER_REQUEST; 29 | import static net.authorize.acceptsdk.parser.JSONConstants.Card; 30 | import static net.authorize.acceptsdk.parser.JSONConstants.DATA; 31 | import static net.authorize.acceptsdk.parser.JSONConstants.DATA_DESCRIPTOR; 32 | import static net.authorize.acceptsdk.parser.JSONConstants.DATA_VALUE; 33 | import static net.authorize.acceptsdk.parser.JSONConstants.FingerPrint; 34 | import static net.authorize.acceptsdk.parser.JSONConstants.ID; 35 | import static net.authorize.acceptsdk.parser.JSONConstants.MERCHANT_AUTHENTICATION; 36 | import static net.authorize.acceptsdk.parser.JSONConstants.MESSAGE; 37 | import static net.authorize.acceptsdk.parser.JSONConstants.MESSAGES_LIST; 38 | import static net.authorize.acceptsdk.parser.JSONConstants.MESSAGE_CODE; 39 | import static net.authorize.acceptsdk.parser.JSONConstants.MESSAGE_TEXT; 40 | import static net.authorize.acceptsdk.parser.JSONConstants.OPAQUE_DATA; 41 | import static net.authorize.acceptsdk.parser.JSONConstants.RESULT_CODE; 42 | import static net.authorize.acceptsdk.parser.JSONConstants.TOKEN; 43 | import static net.authorize.acceptsdk.parser.JSONConstants.TYPE; 44 | import static net.authorize.acceptsdk.parser.JSONConstants.TYPE_VALUE_TOKEN; 45 | 46 | /** 47 | * This is utility class for Json Parsing.It creates Json and parse Json. 48 | * 49 | * Created by Kiran Bollepalli on 08,July,2016. 50 | * kbollepa@visa.com 51 | */ 52 | public class AcceptSDKParser { 53 | 54 | /** 55 | * Method create Json Object for Encryption API call. Using this method order of insertion is 56 | * preserved. 57 | * 58 | * @param transactionObject encryption transaction Object. Also see {@link 59 | * EncryptTransactionObject} 60 | * @return String json String 61 | * @throws JSONException, exception will be thrown when creation of Json fails. 62 | */ 63 | public static String getOrderedJsonFromEncryptTransaction( 64 | EncryptTransactionObject transactionObject) throws JSONException { 65 | 66 | // Json related to token section 67 | CardData cardData = transactionObject.getCardData(); 68 | 69 | JSONStringer stringer = new JSONStringer().object(); 70 | stringer.key(CONTAINER_REQUEST).object(); 71 | prepareJsonForAuthenticationSection(stringer, transactionObject); 72 | stringer.key(CLIENT_ID).value(CLIENT_ID_VALUE); 73 | stringer.key(DATA).object(); //Data section 74 | stringer.key(TYPE).value(TYPE_VALUE_TOKEN); 75 | stringer.key(ID).value(transactionObject.getGuid()); 76 | prepareJsonForTokenSection(stringer, cardData); 77 | stringer.endObject(); 78 | stringer.endObject(); 79 | stringer.endObject(); 80 | 81 | LogUtil.log(LOG_LEVEL.INFO, "getJsonFromEncryptTransaction : " + stringer.toString()); 82 | return stringer.toString(); 83 | } 84 | 85 | public static void prepareJsonForTokenSection(JSONStringer stringer, CardData cardData) 86 | throws JSONException { 87 | stringer.key(TOKEN).object(); 88 | stringer.key(Card.CARD_NUMBER).value(cardData.getCardNumber()); 89 | stringer.key(Card.EXPIRATION_DATE).value(cardData.getExpirationInFormatMMYYYY()); 90 | if (cardData.getCvvCode() != null) stringer.key(Card.CARD_CODE).value(cardData.getCvvCode()); 91 | if (cardData.getZipCode() != null) stringer.key(Card.ZIP).value(cardData.getZipCode()); 92 | if (cardData.getCardHolderName() != null) { 93 | stringer.key(Card.CARD_HOLDER_NAME).value(cardData.getCardHolderName()); 94 | } 95 | stringer.endObject(); 96 | } 97 | 98 | public static void prepareJsonForAuthenticationSection(JSONStringer stringer, 99 | EncryptTransactionObject transactionObject) throws JSONException { 100 | String clientKey = null; 101 | FingerPrintData fData = null; 102 | String apiLoginId = transactionObject.getMerchantAuthentication().getApiLoginID(); 103 | MerchantAuthenticationType authenticationType = 104 | transactionObject.getMerchantAuthentication().getMerchantAuthenticationType(); 105 | if (authenticationType == MerchantAuthenticationType.CLIENT_KEY) { 106 | ClientKeyBasedMerchantAuthentication clientKeyAuth = 107 | (ClientKeyBasedMerchantAuthentication) transactionObject.getMerchantAuthentication(); 108 | clientKey = clientKeyAuth.getClientKey(); 109 | } else if (authenticationType == MerchantAuthenticationType.FINGERPRINT) { 110 | FingerPrintBasedMerchantAuthentication fingerPrintAuth = 111 | (FingerPrintBasedMerchantAuthentication) transactionObject.getMerchantAuthentication(); 112 | fData = fingerPrintAuth.getFingerPrintData(); 113 | } 114 | stringer.key(MERCHANT_AUTHENTICATION).object(); //Merchant Authentication section 115 | stringer.key(Authentication.NAME).value(apiLoginId); 116 | if (clientKey != null) { 117 | stringer.key(Authentication.CLIENT_KEY).value(clientKey); 118 | } else if (fData != null) { 119 | prepareJsonForFingerPrintSection(stringer, fData); 120 | } 121 | 122 | stringer.endObject(); 123 | } 124 | 125 | public static void prepareJsonForFingerPrintSection(JSONStringer stringer, FingerPrintData fData) 126 | throws JSONException { 127 | stringer.key(Authentication.FINGER_PRINT).object(); //Fingerprint section 128 | stringer.key(FingerPrint.HASH_VALUE).value(fData.getHashValue()); 129 | if (fData.getSequence() != null) stringer.key(FingerPrint.SEQUENCE).value(fData.getSequence()); 130 | stringer.key(FingerPrint.TIME_STAMP).value(fData.getTimestampString()); 131 | if (fData.getCurrencyCode() != null) { 132 | stringer.key(FingerPrint.CURRENCY_CODE).value(fData.getCurrencyCode()); 133 | } 134 | if (fData.getAmountString() != null) { 135 | stringer.key(FingerPrint.AMOUNT).value(fData.getAmountString()); 136 | } 137 | stringer.endObject(); 138 | } 139 | 140 | /** 141 | * Method parses Json response and creates Transaction Response Object. 142 | * If transaction is successful, It creates {@link EncryptTransactionResponse} object. 143 | * If transaction is unsuccessful, it creates {@link TransactionResponse} Object which contains 144 | * error messages. 145 | * 146 | * @param json jsonString 147 | * @return TransactionResponse 148 | * @throws JSONException Json Parsing exception. 149 | */ 150 | public static TransactionResponse createEncryptionTransactionResponse(String json) 151 | throws JSONException { 152 | /* 153 | //COMMENT: Sample Json section 154 | 155 | { 156 | "opaqueData": { 157 | "dataDescriptor": "COMMON.ACCEPT.INAPP.PAYMENT", 158 | "dataValue": "9468313632506051305001" 159 | }, 160 | "messages": { 161 | "resultCode": "Ok", 162 | "message": [ 163 | { 164 | "code": "I00001", 165 | "text": "Successful." 166 | } 167 | ] 168 | } 169 | } 170 | */ 171 | 172 | JSONObject responseObject = (JSONObject) new JSONTokener(json).nextValue(); 173 | if (responseObject.has(OPAQUE_DATA)) { 174 | EncryptTransactionResponse encryptTransactionResponse = new EncryptTransactionResponse(); 175 | parseOpaqueSection(encryptTransactionResponse, responseObject.getJSONObject(OPAQUE_DATA)); 176 | encryptTransactionResponse.setResponseMessages( 177 | parseResponseMessagesSection(responseObject.getJSONObject(MESSAGES_LIST))); 178 | return encryptTransactionResponse; 179 | } else { 180 | ResponseMessages responseMessages = 181 | parseResponseMessagesSection(responseObject.getJSONObject(MESSAGES_LIST)); 182 | ErrorTransactionResponse response = new ErrorTransactionResponse(responseMessages); 183 | return response; 184 | } 185 | } 186 | 187 | private static void parseOpaqueSection(EncryptTransactionResponse response, JSONObject json) 188 | throws JSONException { 189 | /* 190 | //COMMENT: Sample Json section 191 | 192 | "opaqueData": { 193 | "dataDescriptor": "COMMON.ACCEPT.INAPP.PAYMENT", 194 | "dataValue": "9468313632506051305001" 195 | } 196 | */ 197 | response.setDataDescriptor(json.getString(DATA_DESCRIPTOR)); 198 | response.setDataValue(json.getString(DATA_VALUE)); 199 | } 200 | 201 | private static ResponseMessages parseResponseMessagesSection(JSONObject json) 202 | throws JSONException { 203 | /* 204 | //COMMENT: Sample Json section 205 | "messages": { 206 | "resultCode": "Ok", 207 | "message": [ 208 | { 209 | "code": "I00001", 210 | "text": "Successful." 211 | } 212 | ] 213 | } 214 | */ 215 | 216 | String resultCode = json.getString(RESULT_CODE); 217 | boolean isErrorResponse = false; 218 | if (resultCode.equals(JSONConstants.ResultCode.ERROR)) isErrorResponse = true; 219 | ResponseMessages responseMessages = new ResponseMessages(json.getString(RESULT_CODE)); 220 | responseMessages.setMessageList(parseMessagesList(isErrorResponse, json.getJSONArray(MESSAGE))); 221 | return responseMessages; 222 | } 223 | 224 | private static List parseMessagesList(boolean isErrorResponse, JSONArray jsonArray) 225 | throws JSONException { 226 | 227 | int arrayLength = jsonArray.length(); 228 | List messageList = new ArrayList(arrayLength); 229 | for (int index = 0; index < arrayLength; index++) { 230 | Message message = parseMessage(jsonArray.getJSONObject(index)); 231 | if (isErrorResponse) { //COMMENT: if response is of error change api error code to E_WC_14. 232 | message.setMessageCode(SDKErrorCode.E_WC_14.getErrorCode()); 233 | } else { //COMMENT: if response is of error change api error code to I_WC_01. 234 | message.setMessageCode("I_WC_01"); 235 | } 236 | messageList.add(message); 237 | } 238 | return messageList; 239 | } 240 | 241 | private static Message parseMessage(JSONObject json) throws JSONException { 242 | Message message = new Message(); 243 | message.setMessageCode(json.getString(MESSAGE_CODE)); 244 | message.setMessageText(json.getString(MESSAGE_TEXT)); 245 | return message; 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/parser/JSONConstants.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.parser; 2 | 3 | import net.authorize.acceptsdk.BuildConfig; 4 | 5 | /** 6 | * Describes all Json strings, which are used in API's. 7 | * 8 | * Created by Kiran Bollepalli on 12,July,2016. 9 | * kbollepa@visa.com 10 | */ 11 | public final class JSONConstants { 12 | 13 | 14 | /* 15 | Sample Request : 16 | { 17 | "securePaymentContainerRequest": { 18 | "merchantAuthentication": { 19 | "name": "5KP3u95bQpv", 20 | "clientKey": "5FcB6WrfHGS76gHW3v7btBCE3HuuBuke9Pj96Ztfn5R32G5ep42vne7MCWZtAucY" 21 | }, 22 | "data": { 23 | "type": "TOKEN", 24 | "id": "ac210aef-cf2d-656c-69a5-a8e145d8f1fc", 25 | "token": { 26 | "cardNumber": "378282246310005", 27 | "expirationDate": "122021" 28 | } 29 | } 30 | } 31 | } 32 | 33 | Sample Success Response : 34 | 35 | { 36 | "opaqueData": { 37 | "dataDescriptor": "COMMON.ACCEPT.INAPP.PAYMENT", 38 | "dataValue": "9468313632506051305001" 39 | }, 40 | "messages": { 41 | "resultCode": "Ok", 42 | "message": [ 43 | { 44 | "code": "I00001", 45 | "text": "Successful." 46 | } 47 | ] 48 | } 49 | } 50 | 51 | */ 52 | 53 | /* Request related JSON Strings */ 54 | public static final String CONTAINER_REQUEST = "securePaymentContainerRequest"; 55 | public static final String MERCHANT_AUTHENTICATION = "merchantAuthentication"; 56 | public static final String DATA = "data"; 57 | public static final String TYPE = "type"; 58 | public static final String TYPE_VALUE_TOKEN = "TOKEN"; 59 | public static final String CLIENT_ID = "clientId"; 60 | public static final String CLIENT_ID_VALUE = "accept-sdk-android" + BuildConfig.SDK_VERSION; 61 | 62 | 63 | public static final String ID = "id"; 64 | public static final String TOKEN = "token"; 65 | 66 | public interface Authentication { 67 | String NAME = "name"; 68 | String CLIENT_KEY = "clientKey"; 69 | String FINGER_PRINT = "fingerPrint"; 70 | } 71 | 72 | public interface Card { 73 | String CARD_NUMBER = "cardNumber"; 74 | String EXPIRATION_DATE = "expirationDate"; 75 | String CARD_CODE = "cardCode"; 76 | String ZIP = "zip"; 77 | String CARD_HOLDER_NAME = "fullName"; 78 | } 79 | 80 | public interface FingerPrint { 81 | String HASH_VALUE = "hashValue"; 82 | String SEQUENCE = "sequence"; 83 | String TIME_STAMP = "timestamp"; 84 | String CURRENCY_CODE = "currencyCode"; 85 | String AMOUNT = "amount"; 86 | } 87 | 88 | /* Response related JSON Strings */ 89 | public static final String RESULT_CODE = "resultCode"; 90 | 91 | public interface ResultCode { 92 | String OK = "Ok"; 93 | String ERROR = "Error"; 94 | } 95 | 96 | public static final String OPAQUE_DATA = "opaqueData"; 97 | public static final String DATA_DESCRIPTOR = "dataDescriptor"; 98 | public static final String DATA_VALUE = "dataValue"; 99 | public static final String MESSAGES_LIST = "messages"; 100 | public static final String MESSAGE = "message"; 101 | public static final String MESSAGE_CODE = "code"; 102 | public static final String MESSAGE_TEXT = "text"; 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/util/LogUtil.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.util; 2 | 3 | import android.util.Log; 4 | import net.authorize.acceptsdk.BuildConfig; 5 | 6 | /** 7 | * Utility class for Logging. 8 | * 9 | * Created by Kiran Bollepalli on 12,July,2016. 10 | * kbollepa@visa.com 11 | */ 12 | public final class LogUtil { 13 | 14 | public static final String LOG_TAG = "Accept SDK"; 15 | 16 | public enum LOG_LEVEL { 17 | VERBOSE, 18 | DEBUG, 19 | INFO, 20 | WARN, 21 | ERROR 22 | } 23 | 24 | ; 25 | 26 | public static void log(LOG_LEVEL level, String message) { 27 | 28 | 29 | if (!BuildConfig.DEBUG) return; 30 | 31 | if (level == LOG_LEVEL.VERBOSE) { 32 | Log.v(LOG_TAG, message); 33 | } else if (level == LOG_LEVEL.DEBUG) { 34 | Log.d(LOG_TAG, message); 35 | } else if (level == LOG_LEVEL.INFO) { 36 | Log.i(LOG_TAG, message); 37 | } else if (level == LOG_LEVEL.WARN) { 38 | Log.w(LOG_TAG, message); 39 | } else if (level == LOG_LEVEL.ERROR) { 40 | Log.e(LOG_TAG, message); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/util/SDKCurrency.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.util; 2 | 3 | /** 4 | * Enumeration describing available currencies: 5 | * 6 | * Available currencies: 7 | *
    8 | *
  • CAD ( $ )
  • 9 | *
  • EUR ( € )
  • 10 | *
  • GBP ( £ )
  • 11 | *
  • USD ( $ )
  • 12 | *
13 | */ 14 | public enum SDKCurrency { 15 | 16 | CAD("\u0024"), EUR("\u20AC"), GBP("\u00A3"), USD("\u0024"); 17 | 18 | private SDKCurrency(String symbol) { 19 | this.symbol = symbol; 20 | } 21 | 22 | private String symbol; 23 | 24 | public String symbol() { 25 | return symbol; 26 | } 27 | 28 | public static String[] names() { 29 | SDKCurrency[] currency = values(); 30 | String[] names = new String[currency.length]; 31 | 32 | for (int i = 0; i < currency.length; i++) { 33 | names[i] = currency[i].name(); 34 | } 35 | 36 | return names; 37 | } 38 | 39 | public static String[] symbols() { 40 | SDKCurrency[] currency = values(); 41 | String[] symbols = new String[currency.length]; 42 | 43 | for (int i = 0; i < currency.length; i++) { 44 | symbols[i] = currency[i].symbol(); 45 | } 46 | 47 | return symbols; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/authorize/acceptsdk/util/SDKUtils.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.util; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.text.TextUtils; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.math.BigDecimal; 8 | import java.math.RoundingMode; 9 | import java.net.URL; 10 | import java.security.KeyManagementException; 11 | import java.security.NoSuchAlgorithmException; 12 | import java.text.ParseException; 13 | import java.text.SimpleDateFormat; 14 | import java.util.Date; 15 | import java.util.GregorianCalendar; 16 | import java.util.Scanner; 17 | import java.util.TimeZone; 18 | import javax.net.ssl.HttpsURLConnection; 19 | import javax.net.ssl.SSLContext; 20 | import javax.net.ssl.SSLSocketFactory; 21 | 22 | /** 23 | * This class provides static common methods to be used by other classes in the 24 | * project. 25 | */ 26 | 27 | public class SDKUtils { 28 | 29 | /** Format of 'date': yyyy-MM-dd */ 30 | private final static String DATE_FORMAT = "yyyy-MM-dd"; 31 | 32 | /** Format of 'time': HH:mm AM/PM */ 33 | private final static String TIME_FORMAT = "hh:mm a"; 34 | 35 | private final static String DEFAULT_TIMEZONE = "America/Los_Angeles"; 36 | 37 | private final static String UTC_TIMEZONE = "UTC"; 38 | 39 | private final static String BASIC_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; 40 | 41 | /** Max connection attempts = 5 */ 42 | private final static int CONNECTION_ATTEPTS = 5; 43 | 44 | /** Connection timeout = 10000ms */ 45 | private final static int CONNECTION_TIMEOUT = 10000; 46 | 47 | /** Connection timeout = 30000ms */ 48 | private final static int RECIEVE_DATA_TIMEOUT = 30000; 49 | 50 | /** Port: 80 */ 51 | private final static int PORT_80 = 80; 52 | 53 | /** Port: 443 */ 54 | private final static int PORT_443 = 443; 55 | 56 | /** 57 | * Converts given InputStream to String 58 | * 59 | * @param is InputStream 60 | * @return String from InputStream 61 | */ 62 | public static String convertStreamToString(InputStream is) { 63 | Scanner s = new Scanner(is); 64 | s.useDelimiter("\\A"); 65 | String result = s.hasNext() ? s.next() : ""; 66 | s.close(); 67 | return result; 68 | } 69 | 70 | public static String convertTimeInMilisToDate(String timeStamp, String timezone) { 71 | return getTime(timeStamp, timezone, DATE_FORMAT); 72 | } 73 | 74 | public static String convertTimeInMilisToTime(String timeStamp, String timezone) { 75 | return getTime(timeStamp, timezone, TIME_FORMAT); 76 | } 77 | 78 | private static String getTime(String timeStamp, String timezone, String format) { 79 | TimeZone utc = TimeZone.getTimeZone(UTC_TIMEZONE); 80 | long time = stringToLong(timeStamp); 81 | TimeZone timeZone; 82 | if (!TextUtils.isEmpty(timezone)) { 83 | timeZone = TimeZone.getTimeZone(timezone); 84 | } else { 85 | timeZone = TimeZone.getTimeZone(DEFAULT_TIMEZONE); 86 | } 87 | @SuppressLint("SimpleDateFormat") SimpleDateFormat sdf = 88 | new SimpleDateFormat(BASIC_DATE_FORMAT); 89 | sdf.setTimeZone(timeZone); 90 | Date date = new Date(time); 91 | String input = sdf.format(date); // here we have UTC time 92 | GregorianCalendar cal = new GregorianCalendar(utc); 93 | // now we try to parse it to local time 94 | try { 95 | @SuppressLint("SimpleDateFormat") SimpleDateFormat s = 96 | new SimpleDateFormat(BASIC_DATE_FORMAT); 97 | s.setTimeZone(utc); 98 | cal.setTime(s.parse(input)); 99 | Date date2 = new Date(cal.getTime().getTime()); 100 | @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDate = new SimpleDateFormat(format); 101 | return simpleDate.format(date2); 102 | } catch (ParseException e) { 103 | // return UTC time if parse failed 104 | return input; 105 | } 106 | } 107 | 108 | public static String convertToLocalTime(String input) { 109 | return getTime(input, TIME_FORMAT); 110 | } 111 | 112 | public static String convertToLocalDate(String input) { 113 | return getTime(input, DATE_FORMAT); 114 | } 115 | 116 | private static String getTime(String input, String format) { 117 | TimeZone utc = TimeZone.getTimeZone(UTC_TIMEZONE); 118 | @SuppressLint("SimpleDateFormat") SimpleDateFormat f = new SimpleDateFormat(BASIC_DATE_FORMAT); 119 | f.setTimeZone(utc); 120 | GregorianCalendar cal = new GregorianCalendar(utc); 121 | try { 122 | cal.setTime(f.parse(input)); 123 | Date date = new Date(cal.getTime().getTime()); 124 | @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDate = new SimpleDateFormat(format); 125 | return simpleDate.format(date); 126 | } catch (ParseException e) { 127 | return input; 128 | } 129 | } 130 | 131 | public static long stringToLong(String value) { 132 | long result = 0; 133 | if (value != null) { 134 | try { 135 | result = Long.parseLong(value); 136 | } catch (NumberFormatException exception) { 137 | exception.printStackTrace(); 138 | } 139 | } 140 | return result; 141 | } 142 | 143 | public static HttpsURLConnection getHttpsURLConnection(String urlString, String requestMethod, 144 | boolean doOutput) throws IOException { 145 | URL url = new URL(urlString); 146 | HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); 147 | SSLSocketFactory socketFactory = getSSLSocketFactory(); 148 | if (socketFactory != null) { 149 | urlConnection.setSSLSocketFactory(getSSLSocketFactory()); 150 | } 151 | 152 | if (requestMethod != null) { 153 | urlConnection.setRequestMethod(requestMethod); 154 | } 155 | urlConnection.setConnectTimeout(CONNECTION_TIMEOUT); 156 | urlConnection.setReadTimeout(RECIEVE_DATA_TIMEOUT); 157 | urlConnection.setDoOutput(doOutput); 158 | urlConnection.setDoInput(true); 159 | return urlConnection; 160 | } 161 | 162 | 163 | public static SSLSocketFactory getSSLSocketFactory() { 164 | SSLContext context; 165 | try { 166 | context = SSLContext.getInstance("TLSv1.2"); 167 | context.init(null, null, new java.security.SecureRandom()); 168 | return context.getSocketFactory(); 169 | } catch (NoSuchAlgorithmException | KeyManagementException e) { 170 | return null; 171 | } 172 | } 173 | 174 | public static SDKCurrency getSDKCurrencyFromString(String currencyString) { 175 | 176 | switch (currencyString) { 177 | case "USD": 178 | return SDKCurrency.USD; 179 | case "CAD": 180 | return SDKCurrency.CAD; 181 | case "EUR": 182 | return SDKCurrency.EUR; 183 | case "GBP": 184 | return SDKCurrency.GBP; 185 | default: 186 | return null; 187 | } 188 | } 189 | 190 | /** 191 | * Convert BigDecimal amount value to String 192 | * 193 | * @param value the amount in Big Decimal to be converted 194 | * @return String, Amount in string format. 195 | */ 196 | public static String getAmountStringFromBigDecimal(BigDecimal value) { 197 | BigDecimal amount = value.setScale(2, RoundingMode.CEILING); 198 | return amount.toPlainString(); 199 | } 200 | } -------------------------------------------------------------------------------- /src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Accept-Android-SDK 3 | 4 | -------------------------------------------------------------------------------- /src/test/java/net/authorize/acceptsdk/AcceptSDKApiClientTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk; 2 | 3 | import android.content.Context; 4 | import junit.framework.Assert; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.mockito.Mock; 10 | import org.mockito.runners.MockitoJUnitRunner; 11 | /** 12 | * Created by Kiran Bollepalli on 14,July,2016. 13 | * kbollepa@visa.com 14 | */ 15 | @RunWith(MockitoJUnitRunner.class) 16 | public class AcceptSDKApiClientTest { 17 | 18 | 19 | private final String API_LOGIN_ID = "6AB64hcB"; 20 | 21 | AcceptSDKApiClient apiClient; 22 | @Mock 23 | Context context; 24 | String apiLoginID; 25 | 26 | @Before public void setUp() throws Exception { 27 | apiLoginID = API_LOGIN_ID; 28 | apiClient = 29 | new AcceptSDKApiClient.Builder(context, AcceptSDKApiClient.Environment.SANDBOX).build(); 30 | } 31 | 32 | @After public void tearDown() throws Exception { 33 | context = null; 34 | apiClient = null; 35 | } 36 | 37 | @Test public void testGetContext() throws Exception { 38 | Assert.assertNotNull(AcceptSDKApiClient.getContext().get()); 39 | } 40 | } -------------------------------------------------------------------------------- /src/test/java/net/authorize/acceptsdk/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test public void addition_isCorrect() throws Exception { 12 | assertEquals(4, 2 + 2); 13 | } 14 | } -------------------------------------------------------------------------------- /src/test/java/net/authorize/acceptsdk/datamodel/merchant/ClientKeyBasedMerchantAuthenticationTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.merchant; 2 | 3 | import junit.framework.Assert; 4 | import net.authorize.acceptsdk.ValidationCallback; 5 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | /** 10 | * Created by Kiran Bollepalli on 14,July,2016. 11 | * kbollepa@visa.com 12 | */ 13 | public class ClientKeyBasedMerchantAuthenticationTest { 14 | 15 | private String mClientKey; 16 | private String mApiLoginId; 17 | ValidationCallback callBack; 18 | 19 | @Before public void setUp() { 20 | mApiLoginId = "6AB64hcB"; 21 | mClientKey = "6gSuV295YD86Mq4d86zEsx8C839uMVVjfXm9N4wr6DRuhTHpDU97NFyKtfZncUq8"; 22 | callBack = new ValidationCallback() { 23 | @Override public void OnValidationSuccessful() { 24 | 25 | } 26 | 27 | @Override public void OnValidationFailed(ErrorTransactionResponse errorTransactionResponse) { 28 | 29 | } 30 | }; 31 | } 32 | 33 | @Test public void testCreateMerchantAuthentication() { 34 | ClientKeyBasedMerchantAuthentication merchantAuthentication = 35 | ClientKeyBasedMerchantAuthentication.createMerchantAuthentication(mApiLoginId, mClientKey); 36 | Assert.assertEquals(true, merchantAuthentication.validateMerchantAuthentication(callBack)); 37 | } 38 | 39 | @Test public void testApiLoginIDForNull() { 40 | mApiLoginId = null; 41 | mClientKey = "6gSuV295YD86Mq4d86zEsx8C839uMVVjfXm9N4wr6DRuhTHpDU97NFyKtfZncUq8"; 42 | ClientKeyBasedMerchantAuthentication merchantAuthentication = 43 | ClientKeyBasedMerchantAuthentication.createMerchantAuthentication(mApiLoginId, mClientKey); 44 | Assert.assertEquals(false, merchantAuthentication.validateMerchantAuthentication(callBack)); 45 | } 46 | 47 | @Test public void testApiLoginIDForError() { 48 | mApiLoginId = " "; 49 | mClientKey = "6gSuV295YD86Mq4d86zEsx8C839uMVVjfXm9N4wr6DRuhTHpDU97NFyKtfZncUq8"; 50 | ClientKeyBasedMerchantAuthentication merchantAuthentication = 51 | ClientKeyBasedMerchantAuthentication.createMerchantAuthentication(mApiLoginId, mClientKey); 52 | Assert.assertEquals(false, merchantAuthentication.validateMerchantAuthentication(callBack)); 53 | 54 | } 55 | 56 | @Test public void testClientKeyForError() { 57 | mApiLoginId = "6AB64hcB"; 58 | mClientKey = ""; 59 | ClientKeyBasedMerchantAuthentication merchantAuthentication = 60 | ClientKeyBasedMerchantAuthentication.createMerchantAuthentication(mApiLoginId, mClientKey); 61 | Assert.assertEquals(false, merchantAuthentication.validateMerchantAuthentication(callBack)); 62 | } 63 | 64 | @Test public void testClientKeyForNull() { 65 | mApiLoginId = "6AB64hcB"; 66 | mClientKey = null; 67 | ClientKeyBasedMerchantAuthentication merchantAuthentication = 68 | ClientKeyBasedMerchantAuthentication.createMerchantAuthentication(mApiLoginId, mClientKey); 69 | Assert.assertEquals(false, merchantAuthentication.validateMerchantAuthentication(callBack)); 70 | 71 | } 72 | } -------------------------------------------------------------------------------- /src/test/java/net/authorize/acceptsdk/datamodel/merchant/FingerPrintBasedMerchantAuthenticationTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.merchant; 2 | 3 | import junit.framework.Assert; 4 | import net.authorize.acceptsdk.ValidationCallback; 5 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | /** 10 | * Created by Kiran Bollepalli on 14,July,2016. 11 | * kbollepa@visa.com 12 | */ 13 | public class FingerPrintBasedMerchantAuthenticationTest { 14 | 15 | private FingerPrintData fingerPrintData; 16 | private String mApiLoginId; 17 | ValidationCallback callBack; 18 | 19 | @Before public void setUp() { 20 | mApiLoginId = "6AB64hcB"; 21 | fingerPrintData = 22 | new FingerPrintData.Builder("37072f4703346059fbde79b4c8babdcd", 1468821505).setSequence( 23 | "abc").setAmount(12344.52).build(); 24 | callBack = new ValidationCallback() { 25 | @Override public void OnValidationSuccessful() { 26 | 27 | } 28 | 29 | @Override public void OnValidationFailed(ErrorTransactionResponse errorTransactionResponse) { 30 | 31 | } 32 | }; 33 | } 34 | 35 | @Test public void testCreateMerchantAuthentication() { 36 | FingerPrintBasedMerchantAuthentication merchantAuthentication = 37 | FingerPrintBasedMerchantAuthentication.createMerchantAuthentication(mApiLoginId, 38 | fingerPrintData); 39 | Assert.assertEquals(true, merchantAuthentication.validateMerchantAuthentication(callBack)); 40 | } 41 | 42 | @Test public void testApiLoginIDForNull() { 43 | mApiLoginId = null; 44 | FingerPrintBasedMerchantAuthentication merchantAuthentication = 45 | FingerPrintBasedMerchantAuthentication.createMerchantAuthentication(mApiLoginId, 46 | fingerPrintData); 47 | Assert.assertEquals(false, merchantAuthentication.validateMerchantAuthentication(callBack)); 48 | } 49 | 50 | @Test public void testFingerPrintForNull() { 51 | mApiLoginId = "6AB64hcB"; 52 | fingerPrintData = null; 53 | FingerPrintBasedMerchantAuthentication merchantAuthentication = 54 | FingerPrintBasedMerchantAuthentication.createMerchantAuthentication(mApiLoginId, 55 | fingerPrintData); 56 | Assert.assertEquals(false, merchantAuthentication.validateMerchantAuthentication(callBack)); 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/test/java/net/authorize/acceptsdk/datamodel/merchant/FingerPrintDataTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.merchant; 2 | 3 | import junit.framework.Assert; 4 | import net.authorize.acceptsdk.ValidationCallback; 5 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | /** 10 | * Created by Kiran Bollepalli on 18,July,2016. 11 | * kbollepa@visa.com 12 | */ 13 | public class FingerPrintDataTest { 14 | 15 | ValidationCallback callBack; 16 | private FingerPrintData fingerPrintData; 17 | 18 | @Before public void setUp() throws Exception { 19 | fingerPrintData = 20 | new FingerPrintData.Builder("37072f4703346059fbde79b4c8babdcd", 1468821505) 21 | .setSequence("abc") 22 | .setCurrencyCode("USD") 23 | .setAmount(12344.52).build(); 24 | 25 | callBack = new ValidationCallback() { 26 | @Override public void OnValidationSuccessful() { 27 | 28 | } 29 | 30 | @Override public void OnValidationFailed(ErrorTransactionResponse errorTransactionResponse) { 31 | 32 | } 33 | }; 34 | } 35 | 36 | @Test public void testFingerPrintData() { 37 | Assert.assertEquals(true,fingerPrintData.validateFingerPrint(callBack)); 38 | } 39 | 40 | @Test public void testHashValueForError() { 41 | FingerPrintData data = 42 | new FingerPrintData.Builder(null, 111) 43 | .setSequence(null) 44 | .setCurrencyCode(null) 45 | .setAmount(0) 46 | .build(); 47 | Assert.assertEquals(false,data.validateFingerPrint(callBack)); 48 | } 49 | 50 | @Test public void testTimeStampForError() { 51 | FingerPrintData data = 52 | new FingerPrintData.Builder("37072f4703346059fbde79b4c8babdcd", -111) 53 | .setSequence(null) 54 | .setCurrencyCode(null) 55 | .setAmount(0) 56 | .build(); 57 | Assert.assertEquals(false,data.validateFingerPrint(callBack)); 58 | } 59 | 60 | 61 | @Test public void testAmountForError() { 62 | FingerPrintData data = 63 | new FingerPrintData.Builder("37072f4703346059fbde79b4c8babdcd", 111) 64 | .setSequence(null) 65 | .setCurrencyCode(null) 66 | .setAmount(-111.123) 67 | .build(); 68 | Assert.assertEquals(false,data.validateFingerPrint(callBack)); 69 | } 70 | } -------------------------------------------------------------------------------- /src/test/java/net/authorize/acceptsdk/datamodel/transaction/CardDataTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction; 2 | 3 | import junit.framework.Assert; 4 | import net.authorize.acceptsdk.ValidationCallback; 5 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | /** 10 | * Created by Kiran Bollepalli on 14,July,2016. 11 | * kbollepa@visa.com 12 | */ 13 | public class CardDataTest { 14 | 15 | private String cardNumber = "4111111111111111"; 16 | private String month = "11"; 17 | private String year = "2050"; 18 | private String cvvCode = "111"; 19 | private String zipCode = "bangalore"; 20 | private String cardHolderName = "kiran bollepalli"; 21 | 22 | ValidationCallback callBack; 23 | 24 | @Before public void setUp() throws Exception { 25 | callBack = new ValidationCallback() { 26 | @Override public void OnValidationSuccessful() { 27 | 28 | } 29 | 30 | @Override public void OnValidationFailed(ErrorTransactionResponse errorTransactionResponse) { 31 | 32 | } 33 | }; 34 | } 35 | 36 | @Test public void testCardNumberForSuccess() { 37 | cardNumber = "4111111111111111"; 38 | month = "11"; 39 | year = "2050"; 40 | CardData card = new CardData.Builder(cardNumber, month, year).cvvCode("111") 41 | .zipCode("abc") 42 | .cardHolderName("kiran") 43 | .build(); 44 | Assert.assertEquals(true, card.validateCardData(callBack)); 45 | } 46 | 47 | @Test public void testCardNumberForSuccess2() { 48 | cardNumber = "4111111111111111"; 49 | month = "11"; 50 | year = "50"; 51 | CardData card = new CardData.Builder(cardNumber, month, year).build(); 52 | Assert.assertEquals(true, card.validateCardData(callBack)); 53 | } 54 | 55 | @Test public void testCardNumberForSuccess3() { 56 | cardNumber = "4111111111111111"; 57 | month = "1"; 58 | year = "50"; 59 | CardData card = new CardData.Builder(cardNumber, month, year).build(); 60 | Assert.assertEquals(true, card.validateCardData(callBack)); 61 | } 62 | 63 | @Test public void testCardNumberForNull() { 64 | cardNumber = null; 65 | month = "11"; 66 | year = "2050"; 67 | CardData card = new CardData.Builder(cardNumber, month, year).build(); 68 | Assert.assertEquals(false, card.validateCardData(callBack)); 69 | } 70 | 71 | @Test public void testMonthForNull() { 72 | cardNumber = "4111111111111111"; 73 | month = null; 74 | year = "2050"; 75 | CardData card = new CardData.Builder(cardNumber, month, year).build(); 76 | Assert.assertEquals(false, card.validateCardData(callBack)); 77 | } 78 | 79 | @Test public void testYearForNull() { 80 | cardNumber = "4111111111111111"; 81 | month = "1"; 82 | year = null; 83 | CardData card = new CardData.Builder(cardNumber, month, year).build(); 84 | Assert.assertEquals(false, card.validateCardData(callBack)); 85 | } 86 | 87 | @Test public void testCardNumberMinimumLength() { 88 | cardNumber = "4111"; 89 | month = "11"; 90 | year = "2050"; 91 | CardData card = new CardData.Builder(cardNumber, month, year).build(); 92 | Assert.assertEquals(false, card.validateCardData(callBack)); 93 | } 94 | 95 | @Test public void testCardNumberMaximumLength() { 96 | cardNumber = "411111111111111111111111111111111111111"; 97 | month = "11"; 98 | year = "2050"; 99 | CardData card = new CardData.Builder(cardNumber, month, year).build(); 100 | Assert.assertEquals(false, card.validateCardData(callBack)); 101 | } 102 | 103 | @Test public void testCardNumberForError() { 104 | cardNumber = "41111AAAAA"; 105 | month = "11"; 106 | year = "2050"; 107 | CardData card = new CardData.Builder(cardNumber, month, year).build(); 108 | Assert.assertEquals(false, card.validateCardData(callBack)); 109 | } 110 | 111 | @Test public void testExpirationMonth() { 112 | cardNumber = "4111111111111111"; 113 | month = "aa"; 114 | year = "2050"; 115 | CardData card = new CardData.Builder(cardNumber, month, year).build(); 116 | Assert.assertEquals(false, card.validateCardData(callBack)); 117 | } 118 | 119 | @Test public void testCVVForError() { 120 | cardNumber = "4111111111111111"; 121 | month = "11"; 122 | year = "2050"; 123 | cvvCode = "111a"; 124 | CardData card = new CardData.Builder(cardNumber, month, year).cvvCode(cvvCode).build(); 125 | Assert.assertEquals(false, card.validateCardData(callBack)); 126 | } 127 | 128 | @Test public void testZip() { 129 | cardNumber = "4111111111111111"; 130 | month = "11"; 131 | year = "2050"; 132 | cvvCode = "111"; 133 | zipCode = "b"; 134 | CardData card = new CardData.Builder(cardNumber, month, year).cvvCode(cvvCode) 135 | .zipCode(zipCode) 136 | .build(); 137 | Assert.assertEquals(true, card.validateCardData(callBack)); 138 | } 139 | 140 | @Test public void testZipForError() { 141 | cardNumber = "4111111111111111"; 142 | month = "11"; 143 | year = "2050"; 144 | cvvCode = "111"; 145 | zipCode = " "; 146 | CardData card = new CardData.Builder(cardNumber, month, year).cvvCode(cvvCode) 147 | .zipCode(zipCode) 148 | .build(); 149 | Assert.assertEquals(false, card.validateCardData(callBack)); 150 | } 151 | 152 | @Test public void testCardHolderName() { 153 | cardNumber = "4111111111111111"; 154 | month = "11"; 155 | year = "2050"; 156 | cvvCode = "111"; 157 | zipCode = "bangalore"; 158 | cardHolderName = "kiran bollepalli"; 159 | CardData card = new CardData.Builder(cardNumber, month, year).cvvCode(cvvCode) 160 | .zipCode(zipCode) 161 | .cardHolderName(cardHolderName) 162 | .build(); 163 | Assert.assertEquals(true, card.validateCardData(callBack)); 164 | } 165 | 166 | @Test public void testCardHolderNameForError() { 167 | cardNumber = "4111111111111111"; 168 | month = "11"; 169 | year = "2050"; 170 | cvvCode = "111"; 171 | zipCode = "bangalore"; 172 | cardHolderName = 173 | "kiran bollepalli afafakfhaskjfadjsfjasdfhasdfadsjfdasjfhasdfhasdhfjhadsfhadfhfjadfn" 174 | + " sdfadffasdfadsfasdfasdfa adsfasdfadsfdasfa"; 175 | CardData card = new CardData.Builder(cardNumber, month, year).cvvCode(cvvCode) 176 | .zipCode(zipCode) 177 | .cardHolderName(cardHolderName) 178 | .build(); 179 | Assert.assertEquals(false, card.validateCardData(callBack)); 180 | } 181 | } -------------------------------------------------------------------------------- /src/test/java/net/authorize/acceptsdk/datamodel/transaction/EncryptTransactionObjectTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.datamodel.transaction; 2 | 3 | import junit.framework.Assert; 4 | import net.authorize.acceptsdk.ValidationCallback; 5 | import net.authorize.acceptsdk.datamodel.merchant.ClientKeyBasedMerchantAuthentication; 6 | import net.authorize.acceptsdk.datamodel.transaction.response.ErrorTransactionResponse; 7 | import org.junit.Before; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.rules.ExpectedException; 11 | 12 | /** 13 | * Created by Kiran Bollepalli on 14,July,2016. 14 | * kbollepa@visa.com 15 | */ 16 | public class EncryptTransactionObjectTest { 17 | private final String CLIENT_KEY = 18 | "6gSuV295YD86Mq4d86zEsx8C839uMVVjfXm9N4wr6DRuhTHpDU97NFyKtfZncUq8"; 19 | private final String API_LOGIN_ID = "6AB64hcB"; 20 | ClientKeyBasedMerchantAuthentication clientKeyBasedMerchantAuthentication; 21 | private final String CARD_NUMBER = "4111111111111111"; 22 | private final String EXPIRATION_MONTH = "11"; 23 | private final String EXPIRATION_YEAR = "2050"; 24 | private final String CVV = "256"; 25 | CardData cardData; 26 | ValidationCallback callBack; 27 | 28 | @Before public void setUp() { 29 | clientKeyBasedMerchantAuthentication = ClientKeyBasedMerchantAuthentication. 30 | createMerchantAuthentication(API_LOGIN_ID, CLIENT_KEY); 31 | cardData = new CardData.Builder(CARD_NUMBER, EXPIRATION_MONTH, EXPIRATION_YEAR).build(); 32 | callBack = new ValidationCallback() { 33 | @Override public void OnValidationSuccessful() { 34 | 35 | } 36 | 37 | @Override public void OnValidationFailed(ErrorTransactionResponse errorTransactionResponse) { 38 | 39 | } 40 | }; 41 | } 42 | 43 | @Test public void testEncryptTransactionObjectInstantiation() { 44 | TransactionObject transactionObject = TransactionObject. 45 | createTransactionObject(TransactionType.SDK_TRANSACTION_ENCRYPTION) 46 | .cardData(cardData) 47 | .merchantAuthentication(clientKeyBasedMerchantAuthentication).build(); 48 | Assert.assertEquals(true,transactionObject.validateTransactionObject(callBack)); 49 | } 50 | 51 | @Test public void testCardDataForError() { 52 | TransactionObject transactionObject = TransactionObject. 53 | createTransactionObject(TransactionType.SDK_TRANSACTION_ENCRYPTION) 54 | .cardData(null) 55 | .merchantAuthentication(clientKeyBasedMerchantAuthentication).build(); 56 | Assert.assertEquals(false,transactionObject.validateTransactionObject(callBack)); 57 | } 58 | 59 | @Test public void testAuthenticationForError() { 60 | TransactionObject transactionObject = TransactionObject. 61 | createTransactionObject(TransactionType.SDK_TRANSACTION_ENCRYPTION) 62 | .cardData(cardData) 63 | .merchantAuthentication(null).build(); 64 | Assert.assertEquals(false,transactionObject.validateTransactionObject(callBack)); 65 | } 66 | } -------------------------------------------------------------------------------- /src/test/java/net/authorize/acceptsdk/network/AcceptServiceTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.network; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Handler; 6 | import net.authorize.acceptsdk.datamodel.merchant.ClientKeyBasedMerchantAuthentication; 7 | import net.authorize.acceptsdk.datamodel.transaction.CardData; 8 | import net.authorize.acceptsdk.datamodel.transaction.EncryptTransactionObject; 9 | import net.authorize.acceptsdk.datamodel.transaction.TransactionType; 10 | import org.junit.Before; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | import org.mockito.Mock; 14 | import org.mockito.runners.MockitoJUnitRunner; 15 | 16 | /** 17 | * Created by Kiran Bollepalli on 14,July,2016. 18 | * kbollepa@visa.com 19 | */ 20 | @RunWith(MockitoJUnitRunner.class) 21 | public class AcceptServiceTest { 22 | private final String CARD_NUMBER = "4111111111111111"; 23 | private final String CARD_EXPIRATION_MONTH = "11"; 24 | private final String CARD_EXPIRATION_YEAR = "2017"; 25 | private final String CARD_ZIP = "98001"; 26 | private final String CARD_CVV = "256"; 27 | private final String CLIENT_KEY = 28 | "6gSuV295YD86Mq4d86zEsx8C839uMVVjfXm9N4wr6DRuhTHpDU97NFyKtfZncUq8"; 29 | private final String API_LOGIN_ID = "6AB64hcB"; 30 | TransactionResultReceiver mResultReceiver; 31 | @Mock 32 | Context context; 33 | 34 | @Before 35 | public void initiate() { 36 | registerResultReceiver(); 37 | } 38 | 39 | private void registerResultReceiver() { 40 | if (mResultReceiver != null) return; 41 | mResultReceiver = new TransactionResultReceiver(new Handler()); 42 | } 43 | 44 | @Test 45 | public void testStartActionEncrypt() throws Exception { 46 | AcceptService.startActionEncrypt(context, prepareTransactionObject(), mResultReceiver); 47 | //assertNotNull(getService()); 48 | } 49 | 50 | @Test 51 | public void testOnHandleIntent() throws Exception { 52 | Intent intent = new Intent(context, AcceptService.class); 53 | intent.setAction(AcceptService.ACTION_ENCRYPT); 54 | context.startService(intent); 55 | //assertNotNull(getService()); 56 | } 57 | 58 | private EncryptTransactionObject prepareTransactionObject() { 59 | ClientKeyBasedMerchantAuthentication merchantAuthentication = 60 | ClientKeyBasedMerchantAuthentication. 61 | createMerchantAuthentication(API_LOGIN_ID, CLIENT_KEY); 62 | 63 | // create a transaction object by calling the predefined api for creation 64 | return EncryptTransactionObject. 65 | createTransactionObject( 66 | TransactionType.SDK_TRANSACTION_ENCRYPTION) // type of transaction object 67 | .cardData(prepareTestCardData()) // card data to be encrypted 68 | .merchantAuthentication(merchantAuthentication).build(); 69 | } 70 | 71 | private CardData prepareTestCardData() { 72 | CardData cardData = 73 | new CardData.Builder(CARD_NUMBER, CARD_EXPIRATION_MONTH, CARD_EXPIRATION_YEAR).build(); 74 | 75 | return cardData; 76 | } 77 | } -------------------------------------------------------------------------------- /src/test/java/net/authorize/acceptsdk/parser/AcceptSDKParserTest.java: -------------------------------------------------------------------------------- 1 | package net.authorize.acceptsdk.parser; 2 | 3 | import net.authorize.acceptsdk.datamodel.merchant.ClientKeyBasedMerchantAuthentication; 4 | import net.authorize.acceptsdk.datamodel.merchant.FingerPrintBasedMerchantAuthentication; 5 | import net.authorize.acceptsdk.datamodel.merchant.FingerPrintData; 6 | import net.authorize.acceptsdk.datamodel.transaction.CardData; 7 | import net.authorize.acceptsdk.datamodel.transaction.EncryptTransactionObject; 8 | import net.authorize.acceptsdk.datamodel.transaction.TransactionType; 9 | import org.junit.Before; 10 | 11 | /** 12 | * Created by Kiran Bollepalli on 08,July,2016. 13 | * kbollepa@visa.com 14 | */ 15 | public class AcceptSDKParserTest { 16 | 17 | EncryptTransactionObject transactionObject; 18 | 19 | private final String ACCOUNT_NUMBER = "4111111111111111"; 20 | private final String EXPIRATION_MONTH = "11"; 21 | private final String EXPIRATION_YEAR = "2017"; 22 | private final String CLIENT_KEY = 23 | "6gSuV295YD86Mq4d86zEsx8C839uMVVjfXm9N4wr6DRuhTHpDU97NFyKtfZncUq8"; 24 | private final String API_LOGIN_ID = "6AB64hcB"; 25 | 26 | @Before public void setUp() throws Exception { 27 | transactionObject = prepareTransactionObject(); 28 | } 29 | 30 | private EncryptTransactionObject prepareTransactionObject() { 31 | ClientKeyBasedMerchantAuthentication merchantAuthentication = 32 | ClientKeyBasedMerchantAuthentication. 33 | createMerchantAuthentication(API_LOGIN_ID, CLIENT_KEY); 34 | 35 | // create a transaction object by calling the predefined api for creation 36 | return EncryptTransactionObject. 37 | createTransactionObject( 38 | TransactionType.SDK_TRANSACTION_ENCRYPTION) // type of transaction object 39 | .cardData(prepareTestCardData()) // card data to be encrypted 40 | .merchantAuthentication(merchantAuthentication).build(); 41 | } 42 | 43 | private CardData prepareTestCardData() { 44 | CardData cardData = null; 45 | 46 | cardData = new CardData.Builder(ACCOUNT_NUMBER, EXPIRATION_MONTH, EXPIRATION_YEAR).build(); 47 | 48 | return cardData; 49 | } 50 | 51 | private EncryptTransactionObject prepareTransactionObjectForFingerPrintTest() { 52 | FingerPrintData fData = 53 | new FingerPrintData.Builder("37072f4703346059fbde79b4c8babdcd", 1468821505).build(); 54 | 55 | FingerPrintBasedMerchantAuthentication merchantAuthentication = 56 | FingerPrintBasedMerchantAuthentication. 57 | createMerchantAuthentication(API_LOGIN_ID, fData); 58 | 59 | // create a transaction object by calling the predefined api for creation 60 | return EncryptTransactionObject. 61 | createTransactionObject( 62 | TransactionType.SDK_TRANSACTION_ENCRYPTION) // type of transaction object 63 | .cardData(prepareTestCardData()) // card data to be encrypted 64 | .merchantAuthentication(merchantAuthentication).build(); 65 | } 66 | 67 | //COMMENT: JSONStringer is not mocked due to that unit testing failed. 68 | //@Test public void testGetJsonFromEncryptTransaction() throws Exception { 69 | // String result = AcceptSDKParser.getOrderedJsonFromEncryptTransaction(transactionObject); 70 | //} 71 | // 72 | //@Test public void testGetJsonFromEncryptTransactionForFingerPrint() throws Exception { 73 | // String result = AcceptSDKParser.getOrderedJsonFromEncryptTransaction(prepareTransactionObjectForFingerPrintTest()); 74 | //} 75 | } --------------------------------------------------------------------------------