diff --git a/build.gradle b/build.gradle index 2e4c5b6..14fa771 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ ext { siteUrl = 'https://github.com/AuthorizeNet/cybersource-android-sdk' gitUrl = 'https://github.com/AuthorizeNet/cybersource-android-sdk.git' - libraryVersion = '1.0.0' + libraryVersion = '2.0.0' localReleaseDest = "${buildDir}/release/${libraryVersion}" developerId = 'fezzubair' @@ -44,14 +44,19 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 23 - versionCode 1 - versionName "1.0" + versionCode 2 + versionName "2.0" } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } + debug { + minifyEnabled false + shrinkResources false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } } testOptions { unitTests { diff --git a/proguard-rules.pro b/proguard-rules.pro index f0e9eb1..d180a23 100644 --- a/proguard-rules.pro +++ b/proguard-rules.pro @@ -18,14 +18,14 @@ public protected *; } --keep class com.visa.inappsdk.connectors.inapp.InAppGateway +-keep class InAppGateway -keepclassmembernames class * { java.lang.Class class$(java.lang.String); java.lang.Class class$(java.lang.String, boolean); } --keepclassmembers class com.visa.inappsdk.connectors.inapp.InAppSDKApiClient +-keepclassmembers class InAppSDKApiClient -keepclasseswithmembernames,includedescriptorclasses class * { native ; diff --git a/src/main/java/com/cybersource/inappsdk/common/utils/SDKMathUtils.java b/src/main/java/com/cybersource/inappsdk/common/utils/SDKMathUtils.java new file mode 100644 index 0000000..e72b5c9 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/common/utils/SDKMathUtils.java @@ -0,0 +1,84 @@ +package com.cybersource.inappsdk.common.utils; + +import java.math.BigDecimal; + +import static java.math.BigDecimal.ZERO; + +/* + * @author fzubair + */ + +public class SDKMathUtils { + + /** used to calculate the percentage **/ + private static BigDecimal HUNDRED = new BigDecimal("100"); + + /** number of decimals returned **/ + private static int DECIMALS = 2; + + /** + * given an amount and a percentage, the method calculates the percentage + * using BigDecimal numbers + * + * @param amount + * @param percentage + * @return the percentage of the amount input + */ + public static BigDecimal calculatePercentage(BigDecimal amount, BigDecimal percentage) { + if (isZero(percentage) || (amount == null)) { + return ZERO; + } + + BigDecimal fractionalChange = amount.multiply(percentage).divide(HUNDRED); + + return fractionalChange.setScale(DECIMALS, BigDecimal.ROUND_HALF_UP); + } + + /** + * r checks if "number" equals zero + * + * @param number + * @return true if number equals zero, false otherwise + */ + public static boolean isZero(BigDecimal number) { + if (number == null) { + number = BigDecimal.ZERO; + } + return number.compareTo(BigDecimal.ZERO) == 0; + } + + /** + * adds two BigDecimals and returns the total + * + * @param number1 + * @param number2 + * @return total + */ + public static BigDecimal add(BigDecimal number1, BigDecimal number2) { + if (number1 == null) { + number1 = BigDecimal.ZERO; + } + if (number2 == null) { + number2 = BigDecimal.ZERO; + } + return number1.add(number2).setScale(DECIMALS, BigDecimal.ROUND_HALF_UP); + } + + /** + * substracts trwo BigDecimal numbers + * + * @param number1 + * @param number2 + * @return result of the subtraction + */ + public static BigDecimal substract(BigDecimal number1, BigDecimal number2) { + if (number1 == null) { + number1 = BigDecimal.ZERO; + } + if (number2 == null) { + number2 = BigDecimal.ZERO; + } + return number1.subtract(number2).setScale(DECIMALS, BigDecimal.ROUND_HALF_UP); + } + +} diff --git a/src/main/java/com/cybersource/inappsdk/common/utils/SDKUtils.java b/src/main/java/com/cybersource/inappsdk/common/utils/SDKUtils.java index 854cfa4..eab405c 100644 --- a/src/main/java/com/cybersource/inappsdk/common/utils/SDKUtils.java +++ b/src/main/java/com/cybersource/inappsdk/common/utils/SDKUtils.java @@ -1,6 +1,7 @@ package com.cybersource.inappsdk.common.utils; import android.text.TextUtils; +import android.util.Base64; import com.cybersource.inappsdk.common.SDKCore; import com.cybersource.inappsdk.common.SDKCurrency; @@ -20,6 +21,7 @@ import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; +import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; @@ -80,6 +82,10 @@ public class SDKUtils { /** Port: 443 */ private final static int PORT_443 = 443; + /** SEC PUBLIC KEY **/ + public static String PUBLIC_KEY = null; + + /** * This method checks if given class exists basing on its name. If it does * exist it also checks if conforms to a given class type. @@ -240,7 +246,8 @@ public static HttpsURLConnection getHttpsURLConnection(String urlString, String urlConnection.setReadTimeout(RECIEVE_DATA_TIMEOUT); urlConnection.setDoOutput(doOutput); urlConnection.setDoInput(true); - //android.util.Log.d("VMposUtils", "Connection: " + requestMethod + " -to- " + urlString); + android.util.Log.d("SDKUtils", "Connection: " + requestMethod + " -to- " + urlString); + return urlConnection; } @@ -323,36 +330,6 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) } } -/* public static HttpClient getHttpClientWithSSLSupport() { - try { - KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - trustStore.load(null, null); - - SSLSocketFactory sf = new MySSLSocketFactory(trustStore); - sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - - - HttpParams params = new BasicHttpParams(); - params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, CONNECTION_ATTEPTS); - params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(CONNECTION_ATTEPTS)); - params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false); - HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); - HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); - HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT); - HttpConnectionParams.setSoTimeout(params, RECIEVE_DATA_TIMEOUT); - - SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), PORT_80)); - registry.register(new Scheme("https", sf, PORT_443)); - - ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); - - return new DefaultHttpClient(ccm, params); - } catch (Exception e) { - return new DefaultHttpClient(); - } - }*/ - private static class MySSLSocketFactory extends SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"); @@ -486,5 +463,37 @@ public static String getGatewayAmountStringFromBigDecimal(BigDecimal value){ BigDecimal amount = value.setScale(2, RoundingMode.CEILING); return amount.toPlainString(); } + + + public static String getBase64Blob(String token) { + byte[] encodedTokenBytes = Base64.encode(token.getBytes(), Base64.NO_WRAP); + String encodedToken = new String(encodedTokenBytes); + return encodedToken; + } + +/* private String createSecServiceJson(String androidPayBlob){ + String secBlob = "{\"publicKeyHash\": \"" + getPublicKeyHash() + "\"," + + "\"version\": \"1.0\"," + + "\"data\":" + "\"" + androidPayBlob + "\"}"; + return secBlob; + }*/ + + /** + * Uses the public passed in by client code through SDK API Client + * @return hashed sec public key + */ + public static String getPublicKeyHash() { + MessageDigest digest = null; + try { + digest = MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + byte[] publicKeyHash; + byte[] pubKeyBytes = Base64.decode(PUBLIC_KEY, Base64.NO_WRAP); + publicKeyHash = digest.digest(pubKeyBytes); + String publicKeyHashString = new String(Base64.encode(publicKeyHash, Base64.NO_WRAP)); + return publicKeyHashString; + } } \ No newline at end of file diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppConnectionService.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppConnectionService.java index 96e8653..113d28c 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppConnectionService.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppConnectionService.java @@ -7,18 +7,18 @@ import android.os.ResultReceiver; import android.util.Xml; +import com.cybersource.inappsdk.connectors.inapp.envelopes.InAppBaseEnvelope; +import com.cybersource.inappsdk.soap.connection.SDKConnectionConstants; +import com.cybersource.inappsdk.soap.parser.SDKSoapParser; import com.cybersource.inappsdk.common.error.SDKError; import com.cybersource.inappsdk.common.error.SDKGatewayError; import com.cybersource.inappsdk.common.error.SDKInternalError; import com.cybersource.inappsdk.common.utils.SDKUtils; import com.cybersource.inappsdk.connectors.inapp.connection.InAppConnectionData; -import com.cybersource.inappsdk.connectors.inapp.envelopes.InAppBaseEnvelope; import com.cybersource.inappsdk.connectors.inapp.receivers.TransactionResultReceiver; import com.cybersource.inappsdk.connectors.inapp.responses.InAppResponseObject; import com.cybersource.inappsdk.datamodel.SDKGatewayErrorMapping; import com.cybersource.inappsdk.datamodel.response.SDKGatewayResponse; -import com.cybersource.inappsdk.soap.connection.SDKConnectionConstants; -import com.cybersource.inappsdk.soap.parser.SDKSoapParser; import java.io.BufferedWriter; import java.io.IOException; @@ -170,6 +170,7 @@ protected void onPostHandleAction(Object result, ResultReceiver resultReceiver) SDKGatewayResponse response = (SDKGatewayResponse)result; resultData.putParcelable(SERVICE_RESULT_RESPONSE_KEY, response); switch (response.getType()) { + case SDK_ANDROID_PAY: case SDK_ENCRYPTION: resultReceiver.send(SERVICE_RESULT_CODE_SDK_RESPONSE, resultData); break; diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppGateway.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppGateway.java index 2770e56..cefbab6 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppGateway.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppGateway.java @@ -3,13 +3,14 @@ import android.os.Bundle; import android.os.Handler; +import com.cybersource.inappsdk.connectors.inapp.envelopes.InAppAndroidPayEnvelope; +import com.cybersource.inappsdk.connectors.inapp.transaction.client.InAppTransaction; +import com.cybersource.inappsdk.datamodel.SDKGateway; +import com.cybersource.inappsdk.datamodel.transaction.callbacks.SDKApiConnectionCallback; import com.cybersource.inappsdk.common.error.SDKError; import com.cybersource.inappsdk.connectors.inapp.envelopes.InAppEncryptEnvelope; import com.cybersource.inappsdk.connectors.inapp.receivers.TransactionResultReceiver; -import com.cybersource.inappsdk.datamodel.SDKGateway; import com.cybersource.inappsdk.datamodel.response.SDKGatewayResponse; -import com.cybersource.inappsdk.datamodel.transaction.SDKTransactionObject; -import com.cybersource.inappsdk.datamodel.transaction.callbacks.SDKApiConnectionCallback; /** * Created by fzubair on 10/6/2015. @@ -30,7 +31,7 @@ public static InAppGateway getGateway() { } @Override - protected boolean performEncryption(SDKTransactionObject transactionObject, SDKApiConnectionCallback applicationConnectionCallback) { + protected boolean performEncryption(InAppTransaction transactionObject, SDKApiConnectionCallback applicationConnectionCallback) { if(transactionInProgress) return transactionInProgress; if (transactionObject == null) @@ -47,6 +48,24 @@ protected boolean performEncryption(SDKTransactionObject transactionObject, SDKA return transactionInProgress; } + @Override + protected boolean performAndroidPayTransaction(InAppTransaction transactionObject, SDKApiConnectionCallback applicationConnectionCallback) { + if(transactionInProgress) + return transactionInProgress; + if (transactionObject == null) + return false; + + registerResultReceiver(); + transactionInProgress = true; + this.connectionCallback = applicationConnectionCallback; + InAppAndroidPayEnvelope envelope = new InAppAndroidPayEnvelope(transactionObject, merchantId, + messageSignature); + if (envelope == null) + return false; + InAppConnectionService.startActionConnect(InAppSDKApiClient.getContext().get(), envelope, resultReceiver); + return transactionInProgress; + } + private InAppGateway() { } diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppSDKApiClient.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppSDKApiClient.java index 88d1e8f..dcb3e5f 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppSDKApiClient.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/InAppSDKApiClient.java @@ -3,8 +3,9 @@ import android.content.Context; import com.cybersource.inappsdk.common.SDKCore; +import com.cybersource.inappsdk.common.utils.SDKUtils; +import com.cybersource.inappsdk.connectors.inapp.transaction.client.InAppTransaction; import com.cybersource.inappsdk.connectors.inapp.connection.InAppConnectionData; -import com.cybersource.inappsdk.datamodel.transaction.SDKTransactionObject; import com.cybersource.inappsdk.datamodel.transaction.callbacks.SDKApiConnectionCallback; import java.lang.ref.WeakReference; @@ -20,10 +21,11 @@ public class InAppSDKApiClient { public enum Environment {ENV_TEST, ENV_PROD}; private final Environment environment; private final String merchantID; + private String publicKey = null; private final SDKApiConnectionCallback connectionCallback; // endpoint API to be used once the 'performApi' method is invoked - public enum Api {API_ENCRYPTION} + public enum Api {API_ENCRYPTION, API_ANDROID_PAY} private InAppSDKApiClient(Builder builder) { this.context = builder.context; @@ -39,6 +41,8 @@ private InAppSDKApiClient(Builder builder) { if(builder.apiTestEndpoint != null) configureTestEndpoint(builder.apiTestEndpoint); setActiveCurrentUrl(); + SDKUtils.PUBLIC_KEY = builder.publicKey; + this.publicKey = builder.publicKey; configureConnectionTimeout(builder.connectionTimeout); } @@ -75,20 +79,27 @@ public static void dispose() { InAppGateway.dispose(); } - public boolean performApi(Api api, SDKTransactionObject transactionObject, String messageSignature){ + public boolean performApi(Api api, InAppTransaction transactionObject, String messageSignature){ if(api == null) throw new NullPointerException("API must not be null"); if(transactionObject == null) throw new NullPointerException("Transaction Object must not be null"); - if(transactionObject.getCardData() == null) - throw new NullPointerException("Missing fields: Card Data must not be null"); if(messageSignature == null || messageSignature.isEmpty()) throw new NullPointerException("Invalid Message Signature"); InAppGateway.getGateway().setMessageSignature(messageSignature); switch (api){ case API_ENCRYPTION: + if(transactionObject.getCardData() == null) + throw new NullPointerException("Missing fields: Card Data must not be null"); return InAppGateway.getGateway().performEncryption(transactionObject, this.connectionCallback); + case API_ANDROID_PAY: + if(transactionObject.getPurchaseOrder() == null) + throw new NullPointerException("Missing fields: Purchase Order must not be null"); + if(this.publicKey == null) + throw new NullPointerException("Missing fields: Public Key must not be null"); + return InAppGateway.getGateway().performAndroidPayTransaction(transactionObject, + this.connectionCallback); default: return false; } @@ -102,6 +113,7 @@ public static class Builder { private String transactionNamespace = null; private String apiProdEndpoint = null; private String apiTestEndpoint = null; + private String publicKey = null; private int connectionTimeout; public Builder(Context context, Environment environment, String merchantID){ @@ -134,6 +146,11 @@ public InAppSDKApiClient.Builder sdkApiTestEndpoint(String apiTestEndpoint) { return this; } + public InAppSDKApiClient.Builder publicKey(String publicKey) { + this.publicKey = publicKey; + return this; + } + public InAppSDKApiClient.Builder sdkConnectionTimeout(int timeoutMillis) { this.connectionTimeout = timeoutMillis; return this; diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppBillTo.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppBillTo.java index b22d7a2..6b5a795 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppBillTo.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppBillTo.java @@ -11,21 +11,47 @@ public class InAppBillTo implements InAppBaseModel { public final String FIRST_NAME = "firstName"; public final String LAST_NAME = "lastName"; + public final String EMAIL = "email"; public final String POSTAL_CODE = "postalCode"; + public final String STREET1 = "street1"; + public final String STREET2 = "street2"; + public final String CITY = "city"; + public final String STATE = "state"; + public final String COUNTRY = "country"; public String firstName; public String lastName; + public String email; public String postalCode; + public String street1; + public String street2; + public String city; + public String state; + public String country; /** * @param firstName * @param lastName + * @param email * @param postalCode + * @param street1 + * @param street2 + * @param city + * @param state + * @param country */ - public InAppBillTo(String firstName, String lastName, String postalCode) { + public InAppBillTo(String firstName, String lastName, String email, + String postalCode, String street1, String street2, + String city, String state, String country) { this.firstName = firstName; this.lastName = lastName; this.postalCode = postalCode; + this.email = email; + this.street1 = street1; + this.street2 = street2; + this.city = city; + this.state = state; + this.country = country; } @Override @@ -37,8 +63,26 @@ public void updateEnvelope(SDKXMLParentNode request) { if (this.lastName != null) { billTo.addTextNode(billTo.getNamespace(), LAST_NAME, this.lastName); } + if (this.street1 != null) { + billTo.addTextNode(billTo.getNamespace(), STREET1, this.street1); + } + if (this.street2 != null) { + billTo.addTextNode(billTo.getNamespace(), STREET2, this.street2); + } + if (this.city != null) { + billTo.addTextNode(billTo.getNamespace(), CITY, this.city); + } + if (this.state != null) { + billTo.addTextNode(billTo.getNamespace(), STATE, this.state); + } if (this.postalCode != null) { billTo.addTextNode(billTo.getNamespace(), POSTAL_CODE, this.postalCode); } + if (this.country != null) { + billTo.addTextNode(billTo.getNamespace(), COUNTRY, this.country); + } + if (this.email != null) { + billTo.addTextNode(billTo.getNamespace(), EMAIL, this.email); + } } } diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppEncryptedPayment.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppEncryptedPayment.java new file mode 100644 index 0000000..322c11f --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppEncryptedPayment.java @@ -0,0 +1,44 @@ +package com.cybersource.inappsdk.connectors.inapp.datamodel; + +import com.cybersource.inappsdk.soap.model.SDKXMLParentNode; + +/** + * Created by fzubair on 11/18/2015. + */ +public class InAppEncryptedPayment implements InAppBaseModel { + + public final String OBJECT_NAME = "encryptedPayment"; + public final String DESCRIPTOR = "descriptor"; + public final String DATA = "data"; + + public String descriptor; + public String data; + + /** + * All fields in constructor are required + * + * @param descriptor the FID + * @param data encrypted payment data as a blob + */ + public InAppEncryptedPayment(String descriptor, String data) { + this.descriptor = descriptor; + this.data = data; + } + + @Override + public void updateEnvelope(SDKXMLParentNode request) { + if (validateObject()) { + SDKXMLParentNode purchase = request.addNode(request.getNamespace(), OBJECT_NAME); + // if (this.descriptor != null) { + // purchase.addTextNode(purchase.getNamespace(), DESCRIPTOR, this.descriptor); + // } + if (this.data != null) { + purchase.addTextNode(null, DATA, this.data); + } + } + } + + private boolean validateObject() { + return !(this.descriptor == null && this.data == null); + } +} diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppItem.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppItem.java new file mode 100644 index 0000000..b3a0628 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/datamodel/InAppItem.java @@ -0,0 +1,81 @@ +package com.cybersource.inappsdk.connectors.inapp.datamodel; + +import com.cybersource.inappsdk.soap.model.SDKXMLParentNode; + +/** + * Describes fields in "item" object in WebService request + * + * @author fzubair + */ +public class InAppItem implements InAppBaseModel { + + public final String OBJECT_NAME = "item"; + public final String ID = "id"; + public final String UNIT_PRICE = "unitPrice"; + public final String QUANTITY = "quantity"; + public final String PRODUCT_CODE = "productCode"; + public final String PRODUCT_NAME = "productName"; + public final String PRODUCT_SKU = "productSKU"; + public final String TAX_AMOUNT = "taxAmount"; + + public String unitPrice; + public String quantity; + public String id; + public String productCode; + public String productName; + public String productSKU; + public String taxAmount; + + /** + * @param id + * @param unitPrice + * @param quantity + * @param productCode + * @param productName + * @param productSKU + * @param taxAmount + */ + public InAppItem(String id, String unitPrice, String quantity, String productCode, String productName, + String productSKU, String taxAmount) { + this.id = id; + this.unitPrice = unitPrice; + this.quantity = quantity; + this.productCode = productCode; + this.productName = productName; + this.productSKU = productSKU; + this.taxAmount = taxAmount; + } + + @Override + public void updateEnvelope(SDKXMLParentNode request) { + if (validateObject()) { + SDKXMLParentNode item = request.addNode(request.getNamespace(), OBJECT_NAME); + if (this.id != null) { + item.addAttribute(null, ID, this.id); + } + if (this.unitPrice != null) { + item.addTextNode(item.getNamespace(), UNIT_PRICE, this.unitPrice); + } + if (this.quantity != null) { + item.addTextNode(item.getNamespace(), QUANTITY, this.quantity); + } + if (this.productCode != null) { + item.addTextNode(item.getNamespace(), PRODUCT_CODE, this.productCode); + } + if (this.productName != null) { + item.addTextNode(item.getNamespace(), PRODUCT_NAME, this.productName); + } + if (this.productSKU != null) { + item.addTextNode(item.getNamespace(), PRODUCT_SKU, this.productSKU); + } + if (this.taxAmount != null) { + item.addTextNode(item.getNamespace(), TAX_AMOUNT, this.taxAmount); + } + } + } + + private boolean validateObject() { + return !(this.id == null && this.unitPrice == null && this.quantity == null && this.productCode == null + && this.productName == null && this.productSKU == null && this.taxAmount == null); + } +} \ No newline at end of file diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppAndroidPayEnvelope.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppAndroidPayEnvelope.java new file mode 100644 index 0000000..7a7dea7 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppAndroidPayEnvelope.java @@ -0,0 +1,138 @@ +package com.cybersource.inappsdk.connectors.inapp.envelopes; + +import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppBillTo; +import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppItem; +import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppPurchaseTotals; +import com.cybersource.inappsdk.connectors.inapp.services.InAppAuthService; +import com.cybersource.inappsdk.connectors.inapp.transaction.client.InAppTransaction; +import com.cybersource.inappsdk.datamodel.response.SDKGatewayResponseType; +import com.cybersource.inappsdk.common.error.SDKError; +import com.cybersource.inappsdk.common.utils.SDKUtils; +import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppEncryptedPayment; +import com.cybersource.inappsdk.connectors.inapp.responses.InAppResponseObject; +import com.cybersource.inappsdk.connectors.inapp.transaction.InAppEnvelopeAndroidPayTransactionObject; +import com.cybersource.inappsdk.datamodel.transaction.fields.SDKBillTo; +import com.cybersource.inappsdk.datamodel.transaction.fields.SDKLineItem; +import com.cybersource.inappsdk.datamodel.transaction.fields.SDKPurchaseOrder; +import com.cybersource.inappsdk.soap.model.SDKXMLParentNode; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by fzubair on 11/18/2015. + */ +public class InAppAndroidPayEnvelope extends InAppBaseEnvelope{ + + public static final String PUBLIC_KEY_HASH = "publicKeyHash"; + public static final String VERSION = "version"; + public static final String VERSION_NUMBER = "1.0"; + public static final String DATA = "data"; + + InAppAndroidPayEnvelope() { + } + + public InAppAndroidPayEnvelope(InAppTransaction transactionObject, String merchantId, String messageSignature) { + createEnvelopeHeader(merchantId, messageSignature); + InAppEnvelopeAndroidPayTransactionObject androidPayTransactionObject = convertTransactionObject(transactionObject, merchantId); + createEnvelopeBody(androidPayTransactionObject); + } + + private void createEnvelopeBody(InAppEnvelopeAndroidPayTransactionObject paymentObject) { + SDKXMLParentNode request = this.createRequestMessage(); + paymentObject.updateEnvelope(request); + } + + private InAppEnvelopeAndroidPayTransactionObject convertTransactionObject(InAppTransaction transactionObject, + String merchantId) { + String merchantReferenceCode = transactionObject.getMerchantReferenceCode(); + + SDKBillTo billTo = transactionObject.getBillTo(); + InAppBillTo bill = null; + if (billTo != null) { + bill = new InAppBillTo(billTo.getFirstName(), billTo.getLastName(), + billTo.getEmail(), billTo.getPostalCode(), billTo.getStreet1(), + billTo.getStreet2(), billTo.getCity(), billTo.getState(), + billTo.getCountry()); + } + + InAppAuthService inAppAuthService = new InAppAuthService(true, false); + + SDKPurchaseOrder purchaseOrder = transactionObject.getPurchaseOrder(); + List items = null; + InAppPurchaseTotals purchaseTotals = null; + if(purchaseOrder != null) { + purchaseTotals = new InAppPurchaseTotals( + purchaseOrder.getCurrency().name(), + SDKUtils.getGatewayAmountStringFromBigDecimal + (purchaseOrder.getGrandTotalAmount()) + ); + List lineItems = purchaseOrder.getLineItems(); + if (lineItems != null) { + items = new ArrayList<>(); + int id = 0; + for (SDKLineItem item : lineItems) { + String itemId = String.valueOf(id); + + InAppItem newItem = new InAppItem(itemId, String.valueOf(item.getUnitPrice()), + String.valueOf(item.getQuantity()), null, item.getProductName(), null, + String.valueOf(item.getTaxAmount())); + items.add(newItem); + id++; + } + } + } + + String encryptedPaymentData = transactionObject.getEncryptedPaymentData(); + // TODO: CREATE SEC BLOB OUT OF THIS ANDROID PAY BLOB + String secBlobEncryptedPayment = createSecServiceJson(encryptedPaymentData); + secBlobEncryptedPayment = SDKUtils.getBase64Blob(secBlobEncryptedPayment); + + InAppEncryptedPayment inAppEncryptedPayment = new InAppEncryptedPayment + (DESCRIPTOR_FID, secBlobEncryptedPayment); + + InAppEnvelopeAndroidPayTransactionObject inAppEnvelopeAndroidPayTransactionObject = + new InAppEnvelopeAndroidPayTransactionObject(merchantId, merchantReferenceCode, + bill, items, purchaseTotals, inAppAuthService, PAYMENT_SOLUTION, CLIENT_LIBRARY, + inAppEncryptedPayment); + return inAppEnvelopeAndroidPayTransactionObject; + } + + private String createSecServiceJson(String androidPayBlob){ + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put(PUBLIC_KEY_HASH, SDKUtils.getPublicKeyHash()); + jsonObject.put(VERSION, VERSION_NUMBER); + jsonObject.put(DATA, androidPayBlob); + } catch (JSONException e) { + e.printStackTrace(); + } + + return jsonObject.toString(); + } + + + @Override + protected void createEnvelopeHeader(String merchantID, String messageSignature) { + super.createEnvelopeHeader(merchantID, messageSignature); + } + + @Override + public SDKError parseGatewayError(InputStream inputStream) { + return super.parseGatewayError(inputStream); + } + + @Override + public InAppResponseObject parseResponse(InputStream inputStream) { + return InAppResponseObject.createAndroidPayAuthResponse(inputStream, getResponseType()); + } + + @Override + public SDKGatewayResponseType getResponseType() { + return SDKGatewayResponseType.SDK_ANDROID_PAY; + } +} diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppBaseEnvelope.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppBaseEnvelope.java index e8b3854..808db04 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppBaseEnvelope.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppBaseEnvelope.java @@ -1,12 +1,12 @@ package com.cybersource.inappsdk.connectors.inapp.envelopes; +import com.cybersource.inappsdk.datamodel.response.SDKGatewayResponseType; +import com.cybersource.inappsdk.soap.model.SDKXMLTextNode; import com.cybersource.inappsdk.common.error.SDKError; import com.cybersource.inappsdk.connectors.inapp.InAppSDKApiClient; import com.cybersource.inappsdk.connectors.inapp.responses.InAppResponseObject; -import com.cybersource.inappsdk.datamodel.response.SDKGatewayResponseType; import com.cybersource.inappsdk.soap.envelope.SDKBaseSoapEnvelope; import com.cybersource.inappsdk.soap.model.SDKXMLParentNode; -import com.cybersource.inappsdk.soap.model.SDKXMLTextNode; import java.io.InputStream; @@ -39,7 +39,10 @@ public abstract class InAppBaseEnvelope extends SDKBaseSoapEnvelope { protected static final String HEADER_PASSWORD_TYPE_VALUE_DIGEST = "PasswordDigest"; // -- Faizan -- added this field to provide uniqueness for the sdk identity // TODO: always update this version of client library with every new version release of the SDK - protected static final String CLIENT_LIBRARY = "InAppSDK Android v1.0.0"; + protected static final String CLIENT_LIBRARY = "InAppSDK Android v2.0.0"; + protected static final String PAYMENT_SOLUTION = "006"; // 006 for Android Pay + + public final static String DESCRIPTOR_FID = "RklEPUNPTU1PTi5BTkRST0lELklOQVBQLlBBWU1FTlQ="; protected String merchantId; protected String messageSignature; diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppEncryptEnvelope.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppEncryptEnvelope.java index 540acc5..a0a9ec8 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppEncryptEnvelope.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/envelopes/InAppEncryptEnvelope.java @@ -5,9 +5,9 @@ import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppCard; import com.cybersource.inappsdk.connectors.inapp.responses.InAppResponseObject; import com.cybersource.inappsdk.connectors.inapp.services.InAppEncryptPaymentDataService; -import com.cybersource.inappsdk.connectors.inapp.transaction.InAppEncryptionTransactionObject; +import com.cybersource.inappsdk.connectors.inapp.transaction.InAppEnvelopeEncryptionTransactionObject; +import com.cybersource.inappsdk.connectors.inapp.transaction.client.InAppTransaction; import com.cybersource.inappsdk.datamodel.response.SDKGatewayResponseType; -import com.cybersource.inappsdk.datamodel.transaction.SDKTransactionObject; import com.cybersource.inappsdk.datamodel.transaction.fields.SDKBillTo; import com.cybersource.inappsdk.datamodel.transaction.fields.SDKCardData; import com.cybersource.inappsdk.soap.model.SDKXMLParentNode; @@ -22,18 +22,18 @@ public class InAppEncryptEnvelope extends InAppBaseEnvelope { InAppEncryptEnvelope() { } - public InAppEncryptEnvelope(SDKTransactionObject transactionObject, String merchantId, String messageSignature) { + public InAppEncryptEnvelope(InAppTransaction transactionObject, String merchantId, String messageSignature) { createEnvelopeHeader(merchantId, messageSignature); - InAppEncryptionTransactionObject encryptionTransactionObject = convertTransactionObject(transactionObject, merchantId); + InAppEnvelopeEncryptionTransactionObject encryptionTransactionObject = convertTransactionObject(transactionObject, merchantId); createEnvelopeBody(encryptionTransactionObject); } - private void createEnvelopeBody(InAppEncryptionTransactionObject paymentObject) { + private void createEnvelopeBody(InAppEnvelopeEncryptionTransactionObject paymentObject) { SDKXMLParentNode request = this.createRequestMessage(); paymentObject.updateEnvelope(request); } - private InAppEncryptionTransactionObject convertTransactionObject(SDKTransactionObject transactionObject, + private InAppEnvelopeEncryptionTransactionObject convertTransactionObject(InAppTransaction transactionObject, String merchantId) { String merchantReferenceCode = transactionObject.getMerchantReferenceCode(); @@ -50,22 +50,15 @@ private InAppEncryptionTransactionObject convertTransactionObject(SDKTransaction InAppBillTo bill = null; if (billTo != null) { bill = new InAppBillTo(billTo.getFirstName(), billTo.getLastName(), - billTo.getPostalCode()); + billTo.getEmail(), billTo.getPostalCode(), billTo.getStreet1(), + billTo.getStreet2(), billTo.getCity(), billTo.getState(), + billTo.getCountry()); } InAppEncryptPaymentDataService inAppEncryptPaymentDataService = new InAppEncryptPaymentDataService(true, null); - /*transactionObject.getPurchaseDetails().getCommerceIndicator());*/ - // Faizan -- added the encrypted payment part - //VMposEncryptedPayment encryptedPayment = transactionObject.getEncryptedPayment(); - -/* VMposEncryptedPayment encryptedPayment = new VMposEncryptedPayment(); - encryptedPayment.setEncodedData(getIDTechTestBlob()); - encryptedPayment.setEncodedMetaData(VMposMessageSignature.MetadataEncodedValue); - encryptedPayment.setPaymentSolution(VMposMessageSignature.PAYMENT_SOLUTION_DEFAULT_VALUE);*/ - - InAppEncryptionTransactionObject inAppEncryptionTransactionObject = new InAppEncryptionTransactionObject( - merchantId, merchantReferenceCode, card, bill, inAppEncryptPaymentDataService, CLIENT_LIBRARY/*, encryptedPayment*/); + InAppEnvelopeEncryptionTransactionObject inAppEncryptionTransactionObject = new InAppEnvelopeEncryptionTransactionObject( + merchantId, merchantReferenceCode, card, bill, inAppEncryptPaymentDataService, CLIENT_LIBRARY); return inAppEncryptionTransactionObject; } diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppCcAndroidPayAuthReply.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppCcAndroidPayAuthReply.java new file mode 100644 index 0000000..2faaa35 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppCcAndroidPayAuthReply.java @@ -0,0 +1,61 @@ +package com.cybersource.inappsdk.connectors.inapp.responses; + +/** + * Object InAppCcAuthReply stores all possible data of object + * ccAuthReplay from gateway responses (most of fields are optional, so they + * will be 'null', this object appears only in Authorize and Sale Methods) + * + * @author fzubair + */ + public class InAppCcAndroidPayAuthReply { + + public String accountBalance; + public String accountBalanceCurrency; + public String accountBalanceSign; + public String affluenceIndicator; + public String amount; + public String authorizationCode; + public String authorizedDateTime; + public String avsCode; + public String avsCodeRaw; + public String cardCategory; + public String cardCommercial; + public String cardGroup; + public String cardHealthcare; + public String cardIssuerCountry; + public String cardLevel3Eligible; + public String cardPayroll; + public String cardPINlessDebit; + public String cardPrepaid; + public String cardRegulated; + public String cardSignatureDebit; + public String cavvResponseCode; + public String cavvResponseCodeRaw; + public String cvCode; + public String cvCodeRaw; + public String evEmail; + public String evEmailRaw; + public String evName; + public String evNameRaw; + public String evPhoneNumber; + public String evPhoneNumberRaw; + public String evPostalCode; + public String evPostalCodeRaw; + public String evStreet; + public String evStreetRaw; + public String forwardCode; + public String merchantAdviceCode; + public String merchantAdviceCodeRaw; + public String ownerMerchantID; + public String paymentNetworkTransactionID; + public String personalIDCode; + public String posData; + public String processorResponse; + public String processorTransactionID; + public String reasonCode; + public String reconciliationID; + public String referralResponseNumber; + public String requestAmount; + public String requestCurrency; + public String transactionID; +} diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppPurchaseTotalsReply.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppPurchaseTotalsReply.java new file mode 100644 index 0000000..7d07dcf --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppPurchaseTotalsReply.java @@ -0,0 +1,13 @@ +package com.cybersource.inappsdk.connectors.inapp.responses; + +/** + * Object VMposCyberSourcePurchaseTotalsReplay appears in every type of response + * except of VoidReplay + * + * @author fzubair + */ +public class InAppPurchaseTotalsReply { + + public String currency; + +} diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppResponseFields.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppResponseFields.java index f88a47f..604ff38 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppResponseFields.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppResponseFields.java @@ -45,60 +45,60 @@ public class InAppResponseFields { // ccCreditReply // EMV Reply - protected static final String EMV_REPLAY = "c:emvReply"; - protected static final String EMV_REPLAY_COMBINED_TAGS = "c:combinedTags"; // ccAuthReply + protected static final String EMV_REPLY = "c:emvReply"; + protected static final String EMV_REPLY_COMBINED_TAGS = "c:combinedTags"; // ccAuthReply // Auth Reply Fields - protected static final String CC_AUTH_REPLAY = "c:ccAuthReply"; - protected static final String CC_AUTH_REPLAY_ACCOUNT_BALANCE = "c:accountBalance"; - protected static final String CC_AUTH_REPLAY_ACCOUNT_BALANCE_CURRENCY = "c:accountBalanceCurrency"; - protected static final String CC_AUTH_REPLAY_ACCOUNT_BALANCE_SIGN = "c:accountBalanceSign"; - protected static final String CC_AUTH_REPLAY_AFFLUENCE_INDICATOR = "c:affluenceIndicator"; - protected static final String CC_AUTH_REPLAY_AMOUNT = "c:amount"; - protected static final String CC_AUTH_REPLAY_AUTHORIZATION_CODE = "c:authorizationCode"; - protected static final String CC_AUTH_REPLAY_AUTHORIZED_DATE_TIME = "c:authorizedDateTime"; - protected static final String CC_AUTH_REPLAY_AVS_CODE = "c:avsCode"; - protected static final String CC_AUTH_REPLAY_AVS_CODE_RAW = "c:avsCodeRaw"; - protected static final String CC_AUTH_REPLAY_CARD_CATEGORY = "c:cardCategory"; - protected static final String CC_AUTH_REPLAY_CARD_COMMERCIAL = "c:cardCommercial"; - protected static final String CC_AUTH_REPLAY_CARD_GROUP = "c:cardGroup"; - protected static final String CC_AUTH_REPLAY_CARD_HEALTHCARE = "c:cardHealthcare"; - protected static final String CC_AUTH_REPLAY_CARD_ISSUER_COUNTRY = "c:cardIssuerCountry"; - protected static final String CC_AUTH_REPLAY_CARD_LEVEL_3_ELIGIBLE = "c:cardLevel3Eligible"; - protected static final String CC_AUTH_REPLAY_CARD_PAYROLL = "c:cardPayroll"; - protected static final String CC_AUTH_REPLAY_CARD_PINLESS_DEBIT = "c:cardPINlessDebit"; - protected static final String CC_AUTH_REPLAY_CARD_PREPAID = "c:cardPrepaid"; - protected static final String CC_AUTH_REPLAY_CARD_REGULATED = "c:cardRegulated"; - protected static final String CC_AUTH_REPLAY_CARD_SIGNATURE_DEBIT = "c:cardSignatureDebit"; - protected static final String CC_AUTH_REPLAY_CAVV_RESPONSE_CODE = "c:cavvResponseCode"; - protected static final String CC_AUTH_REPLAY_CAVV_RESPONSE_CODE_RAW = "c:cavvResponseCodeRaw"; - protected static final String CC_AUTH_REPLAY_CV_CODE = "c:cvCode"; - protected static final String CC_AUTH_REPLAY_CV_CODE_RAW = "c:cvCodeRaw"; - protected static final String CC_AUTH_REPLAY_EV_EMAIL = "c:evEmail"; - protected static final String CC_AUTH_REPLAY_EV_EMAIL_RAW = "c:evEmailRaw"; - protected static final String CC_AUTH_REPLAY_EV_NAME = "c:evName"; - protected static final String CC_AUTH_REPLAY_EV_NAME_RAW = "c:evNameRaw"; - protected static final String CC_AUTH_REPLAY_EV_PHONE_NUMBER = "c:evPhoneNumber"; - protected static final String CC_AUTH_REPLAY_EV_PHONE_NUMBER_RAW = "c:evPhoneNumberRaw"; - protected static final String CC_AUTH_REPLAY_EV_POSTAL_CODE = "c:evPostalCode"; - protected static final String CC_AUTH_REPLAY_EV_POSTAL_CODE_RAW = "c:evPostalCodeRaw"; - protected static final String CC_AUTH_REPLAY_EV_STREET = "c:evStreet"; - protected static final String CC_AUTH_REPLAY_EV_STREET_RAW = "c:evStreetRaw"; - protected static final String CC_AUTH_REPLAY_FORWARD_CODE = "c:forwardCode"; - protected static final String CC_AUTH_REPLAY_MERCHANT_ADVICE_CODE = "c:merchantAdviceCode"; - protected static final String CC_AUTH_REPLAY_MERCHANT_ADVICE_CODE_RAW = "c:merchantAdviceCodeRaw"; - protected static final String CC_AUTH_REPLAY_OWNER_MERCHANT_ID = "c:ownerMerchantID"; - protected static final String CC_AUTH_REPLAY_PAYMENT_NETWORK_TRANSACTION_ID = "c:paymentNetworkTransactionID"; - protected static final String CC_AUTH_REPLAY_PERSONAL_ID_CODE = "c:personalIDCode"; - protected static final String CC_AUTH_REPLAY_POS_DATE = "c:posData"; - protected static final String CC_AUTH_REPLAY_PROCESSOR_RESPONSE = "c:processorResponse"; - protected static final String CC_AUTH_REPLAY_PROCESSOR_TRANSACTION_ID = "c:processorTransactionID"; - protected static final String CC_AUTH_REPLAY_REASON_CODE = REASON_CODE; - protected static final String CC_AUTH_REPLAY_RECONCILATION_ID = "c:reconciliationID"; - protected static final String CC_AUTH_REPLAY_REFERRAL_RESPONSE_NUMBER = "c:referralResponseNumber"; - protected static final String CC_AUTH_REPLAY_REQUEST_AMOUNT = "c:requestAmount"; - protected static final String CC_AUTH_REPLAY_REQUEST_CURRENCY = "c:requestCurrency"; - protected static final String CC_AUTH_REPLAY_TRANSACTION_ID = "c:transactionID"; + protected static final String CC_AUTH_REPLY = "c:ccAuthReply"; + protected static final String CC_AUTH_REPLY_ACCOUNT_BALANCE = "c:accountBalance"; + protected static final String CC_AUTH_REPLY_ACCOUNT_BALANCE_CURRENCY = "c:accountBalanceCurrency"; + protected static final String CC_AUTH_REPLY_ACCOUNT_BALANCE_SIGN = "c:accountBalanceSign"; + protected static final String CC_AUTH_REPLY_AFFLUENCE_INDICATOR = "c:affluenceIndicator"; + protected static final String CC_AUTH_REPLY_AMOUNT = "c:amount"; + protected static final String CC_AUTH_REPLY_AUTHORIZATION_CODE = "c:authorizationCode"; + protected static final String CC_AUTH_REPLY_AUTHORIZED_DATE_TIME = "c:authorizedDateTime"; + protected static final String CC_AUTH_REPLY_AVS_CODE = "c:avsCode"; + protected static final String CC_AUTH_REPLY_AVS_CODE_RAW = "c:avsCodeRaw"; + protected static final String CC_AUTH_REPLY_CARD_CATEGORY = "c:cardCategory"; + protected static final String CC_AUTH_REPLY_CARD_COMMERCIAL = "c:cardCommercial"; + protected static final String CC_AUTH_REPLY_CARD_GROUP = "c:cardGroup"; + protected static final String CC_AUTH_REPLY_CARD_HEALTHCARE = "c:cardHealthcare"; + protected static final String CC_AUTH_REPLY_CARD_ISSUER_COUNTRY = "c:cardIssuerCountry"; + protected static final String CC_AUTH_REPLY_CARD_LEVEL_3_ELIGIBLE = "c:cardLevel3Eligible"; + protected static final String CC_AUTH_REPLY_CARD_PAYROLL = "c:cardPayroll"; + protected static final String CC_AUTH_REPLY_CARD_PINLESS_DEBIT = "c:cardPINlessDebit"; + protected static final String CC_AUTH_REPLY_CARD_PREPAID = "c:cardPrepaid"; + protected static final String CC_AUTH_REPLY_CARD_REGULATED = "c:cardRegulated"; + protected static final String CC_AUTH_REPLY_CARD_SIGNATURE_DEBIT = "c:cardSignatureDebit"; + protected static final String CC_AUTH_REPLY_CAVV_RESPONSE_CODE = "c:cavvResponseCode"; + protected static final String CC_AUTH_REPLY_CAVV_RESPONSE_CODE_RAW = "c:cavvResponseCodeRaw"; + protected static final String CC_AUTH_REPLY_CV_CODE = "c:cvCode"; + protected static final String CC_AUTH_REPLY_CV_CODE_RAW = "c:cvCodeRaw"; + protected static final String CC_AUTH_REPLY_EV_EMAIL = "c:evEmail"; + protected static final String CC_AUTH_REPLY_EV_EMAIL_RAW = "c:evEmailRaw"; + protected static final String CC_AUTH_REPLY_EV_NAME = "c:evName"; + protected static final String CC_AUTH_REPLY_EV_NAME_RAW = "c:evNameRaw"; + protected static final String CC_AUTH_REPLY_EV_PHONE_NUMBER = "c:evPhoneNumber"; + protected static final String CC_AUTH_REPLY_EV_PHONE_NUMBER_RAW = "c:evPhoneNumberRaw"; + protected static final String CC_AUTH_REPLY_EV_POSTAL_CODE = "c:evPostalCode"; + protected static final String CC_AUTH_REPLY_EV_POSTAL_CODE_RAW = "c:evPostalCodeRaw"; + protected static final String CC_AUTH_REPLY_EV_STREET = "c:evStreet"; + protected static final String CC_AUTH_REPLY_EV_STREET_RAW = "c:evStreetRaw"; + protected static final String CC_AUTH_REPLY_FORWARD_CODE = "c:forwardCode"; + protected static final String CC_AUTH_REPLY_MERCHANT_ADVICE_CODE = "c:merchantAdviceCode"; + protected static final String CC_AUTH_REPLY_MERCHANT_ADVICE_CODE_RAW = "c:merchantAdviceCodeRaw"; + protected static final String CC_AUTH_REPLY_OWNER_MERCHANT_ID = "c:ownerMerchantID"; + protected static final String CC_AUTH_REPLY_PAYMENT_NETWORK_TRANSACTION_ID = "c:paymentNetworkTransactionID"; + protected static final String CC_AUTH_REPLY_PERSONAL_ID_CODE = "c:personalIDCode"; + protected static final String CC_AUTH_REPLY_POS_DATE = "c:posData"; + protected static final String CC_AUTH_REPLY_PROCESSOR_RESPONSE = "c:processorResponse"; + protected static final String CC_AUTH_REPLY_PROCESSOR_TRANSACTION_ID = "c:processorTransactionID"; + protected static final String CC_AUTH_REPLY_REASON_CODE = REASON_CODE; + protected static final String CC_AUTH_REPLY_RECONCILATION_ID = "c:reconciliationID"; + protected static final String CC_AUTH_REPLY_REFERRAL_RESPONSE_NUMBER = "c:referralResponseNumber"; + protected static final String CC_AUTH_REPLY_REQUEST_AMOUNT = "c:requestAmount"; + protected static final String CC_AUTH_REPLY_REQUEST_CURRENCY = "c:requestCurrency"; + protected static final String CC_AUTH_REPLY_TRANSACTION_ID = "c:transactionID"; // NVP Reply Fields protected static final String NVP_DECISION = "decision"; diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppResponseObject.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppResponseObject.java index 31084fc..deecb50 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppResponseObject.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/responses/InAppResponseObject.java @@ -1,13 +1,16 @@ package com.cybersource.inappsdk.connectors.inapp.responses; -import com.cybersource.inappsdk.common.error.SDKError; +import android.text.TextUtils; +import android.util.Log; + import com.cybersource.inappsdk.common.error.SDKGatewayError; import com.cybersource.inappsdk.common.error.SDKInternalError; import com.cybersource.inappsdk.common.utils.SDKUtils; -import com.cybersource.inappsdk.datamodel.response.SDKGatewayResponse; import com.cybersource.inappsdk.datamodel.response.SDKGatewayResponseType; import com.cybersource.inappsdk.datamodel.response.SDKResponseDecision; import com.cybersource.inappsdk.datamodel.response.SDKResponseReasonCode; +import com.cybersource.inappsdk.common.error.SDKError; +import com.cybersource.inappsdk.datamodel.response.SDKGatewayResponse; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -18,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; +import java.math.BigDecimal; import java.util.HashMap; import javax.xml.parsers.DocumentBuilder; @@ -29,7 +33,7 @@ import javax.xml.transform.stream.StreamResult; /** - * Provides parsers for responses from CyberSouce Gateway and also is an Object that store parsed data. + * Provides parsers for responses from CyberSource Gateway and also is an Object that store parsed data. * * Created by fzubair on 10/8/2015. */ @@ -42,9 +46,6 @@ public final class InAppResponseObject extends InAppResponseFields { private final static String DECISION_REJECT = "REJECT"; private final static String DECISION_REVIEW = "REVIEW"; - // Describes if response decision returns success - // public VMposCyberSourceResponseDec success; - // Main Fields public String additionalData; // ccAuthReply public SDKResponseDecision decision; // all @@ -60,6 +61,8 @@ public final class InAppResponseObject extends InAppResponseFields { // Objects public InAppCcEncryptedPaymentDataReply ccEncryptedPaymentReply; + public InAppCcAndroidPayAuthReply ccAuthReply; + public InAppPurchaseTotalsReply purchaseTotals; // Response type public SDKGatewayResponseType type; @@ -92,23 +95,11 @@ private static HashMap parseNVPResponseString(String nvpResponse * @param type - type of response * @return */ -/* public static InAppResponseObject createAuthorizationResponse(InputStream inputStream, + public static InAppResponseObject createAndroidPayAuthResponse(InputStream inputStream, SDKGatewayResponseType type) { Document doc = parseResponse(inputStream); - DOMSource domSource = new DOMSource(doc); - StringWriter writer = new StringWriter(); - StreamResult streamResult = new StreamResult(writer); - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer transformer = null; - try { - transformer = tf.newTransformer(); - transformer.transform(domSource, streamResult); - } catch (Exception e) { - e.printStackTrace(); - } - - Log.d("Encrypt Response", writer.toString()); + getResponseStringWriter(doc); if (doc != null) { @@ -117,26 +108,26 @@ private static HashMap parseNVPResponseString(String nvpResponse NodeList nl = doc.getElementsByTagName(REPLY_MESSAGE); - Element replay = (Element)(nl.item(0)); - setDefaultFields(result, replay); - result.additionalData = getValue(replay, ADDITIONAL_DATA); - result.receiptNumber = getValue(replay, RECEIPT_NUMBER); + Element reply = (Element)(nl.item(0)); + setDefaultFields(result, reply); + result.additionalData = getValue(reply, ADDITIONAL_DATA); + result.receiptNumber = getValue(reply, RECEIPT_NUMBER); - Element pTotals = (Element)(replay.getElementsByTagName(PURCHASE_TOTALS).item(0)); + Element pTotals = (Element)(reply.getElementsByTagName(PURCHASE_TOTALS).item(0)); if (pTotals != null) { result.purchaseTotals = getPurchaseTotalsReply(pTotals); } - Element ccAuthReplay = (Element)(replay.getElementsByTagName(CC_AUTH_REPLAY).item(0)); + Element ccAuthReplay = (Element)(reply.getElementsByTagName(CC_AUTH_REPLY).item(0)); if (ccAuthReplay != null) { - result.ccAuthReply = getAuthReply(ccAuthReplay); + result.ccAuthReply = getAndroidPayAuthReply(ccAuthReplay); } return result; } else { return null; } - }*/ + } /** * Parse EncryptionResponse to InAppResponseObject @@ -219,16 +210,16 @@ public static SDKError createErrorResponse(InputStream inputStream) { return error; } - private static void setDefaultFields(InAppResponseObject result, Element replay) { - result.decision = getDecisionType(getValue(replay, DECISION)); - result.invalidField = getValue(replay, INVALID_FIELD); - result.merchantReferenceCode = getValue(replay, MERCHANT_REFERENCE_CODE); - result.missingField = getValue(replay, MISSING_FIELD); - result.reasonCode = getValue(replay, REASON_CODE); - result.requestID = getValue(replay, REQUEST_ID); - result.requestToken = getValue(replay, REQUEST_TOKEN); + private static void setDefaultFields(InAppResponseObject result, Element reply) { + result.decision = getDecisionType(getValue(reply, DECISION)); + result.invalidField = getValue(reply, INVALID_FIELD); + result.merchantReferenceCode = getValue(reply, MERCHANT_REFERENCE_CODE); + result.missingField = getValue(reply, MISSING_FIELD); + result.reasonCode = getValue(reply, REASON_CODE); + result.requestID = getValue(reply, REQUEST_ID); + result.requestToken = getValue(reply, REQUEST_TOKEN); - Element icsMsg = (Element)(replay.getElementsByTagName(ICS_MESSAGE).item(0)); + Element icsMsg = (Element)(reply.getElementsByTagName(ICS_MESSAGE).item(0)); if (icsMsg != null) { result.icsMessage = getICSMessageReply(icsMsg); } @@ -263,63 +254,69 @@ private static InAppIcsMessageReply getICSMessageReply(Element element) { return icsMessageReply; } + private static InAppPurchaseTotalsReply getPurchaseTotalsReply(Element element) { + InAppPurchaseTotalsReply result = new InAppPurchaseTotalsReply(); + result.currency = getValue(element, PURCHASE_TOTALS_CURRENCY); + return result; + } -/* private static InAppCcAuthReply getAuthReply(Element element) { - - InAppCcAuthReply ccAuthReply = new InAppCcAuthReply(); - - ccAuthReply.accountBalance = getValue(element, CC_AUTH_REPLAY_ACCOUNT_BALANCE); - ccAuthReply.accountBalanceCurrency = getValue(element, CC_AUTH_REPLAY_ACCOUNT_BALANCE_CURRENCY); - ccAuthReply.accountBalanceSign = getValue(element, CC_AUTH_REPLAY_ACCOUNT_BALANCE_SIGN); - ccAuthReply.affluenceIndicator = getValue(element, CC_AUTH_REPLAY_AFFLUENCE_INDICATOR); - ccAuthReply.amount = getValue(element, CC_AUTH_REPLAY_AMOUNT); - ccAuthReply.authorizationCode = getValue(element, CC_AUTH_REPLAY_AUTHORIZATION_CODE); - ccAuthReply.authorizedDateTime = getValue(element, CC_AUTH_REPLAY_AUTHORIZED_DATE_TIME); - ccAuthReply.avsCode = getValue(element, CC_AUTH_REPLAY_AVS_CODE); - ccAuthReply.avsCodeRaw = getValue(element, CC_AUTH_REPLAY_AVS_CODE_RAW); - ccAuthReply.cardCategory = getValue(element, CC_AUTH_REPLAY_CARD_CATEGORY); - ccAuthReply.cardCommercial = getValue(element, CC_AUTH_REPLAY_CARD_COMMERCIAL); - ccAuthReply.cardGroup = getValue(element, CC_AUTH_REPLAY_CARD_GROUP); - ccAuthReply.cardHealthcare = getValue(element, CC_AUTH_REPLAY_CARD_HEALTHCARE); - ccAuthReply.cardIssuerCountry = getValue(element, CC_AUTH_REPLAY_CARD_ISSUER_COUNTRY); - ccAuthReply.cardLevel3Eligible = getValue(element, CC_AUTH_REPLAY_CARD_LEVEL_3_ELIGIBLE); - ccAuthReply.cardPayroll = getValue(element, CC_AUTH_REPLAY_CARD_PAYROLL); - ccAuthReply.cardPINlessDebit = getValue(element, CC_AUTH_REPLAY_CARD_PINLESS_DEBIT); - ccAuthReply.cardPrepaid = getValue(element, CC_AUTH_REPLAY_CARD_PREPAID); - ccAuthReply.cardRegulated = getValue(element, CC_AUTH_REPLAY_CARD_REGULATED); - ccAuthReply.cardSignatureDebit = getValue(element, CC_AUTH_REPLAY_CARD_SIGNATURE_DEBIT); - ccAuthReply.cavvResponseCode = getValue(element, CC_AUTH_REPLAY_CAVV_RESPONSE_CODE); - ccAuthReply.cavvResponseCodeRaw = getValue(element, CC_AUTH_REPLAY_CAVV_RESPONSE_CODE_RAW); - ccAuthReply.cvCode = getValue(element, CC_AUTH_REPLAY_CV_CODE); - ccAuthReply.cvCodeRaw = getValue(element, CC_AUTH_REPLAY_CV_CODE_RAW); - ccAuthReply.evEmail = getValue(element, CC_AUTH_REPLAY_EV_EMAIL); - ccAuthReply.evEmailRaw = getValue(element, CC_AUTH_REPLAY_EV_EMAIL_RAW); - ccAuthReply.evName = getValue(element, CC_AUTH_REPLAY_EV_NAME); - ccAuthReply.evNameRaw = getValue(element, CC_AUTH_REPLAY_EV_NAME_RAW); - ccAuthReply.evPhoneNumber = getValue(element, CC_AUTH_REPLAY_EV_PHONE_NUMBER); - ccAuthReply.evPhoneNumberRaw = getValue(element, CC_AUTH_REPLAY_EV_PHONE_NUMBER_RAW); - ccAuthReply.evPostalCode = getValue(element, CC_AUTH_REPLAY_EV_POSTAL_CODE); - ccAuthReply.evPostalCodeRaw = getValue(element, CC_AUTH_REPLAY_EV_POSTAL_CODE_RAW); - ccAuthReply.evStreet = getValue(element, CC_AUTH_REPLAY_EV_STREET); - ccAuthReply.evStreetRaw = getValue(element, CC_AUTH_REPLAY_EV_STREET_RAW); - ccAuthReply.forwardCode = getValue(element, CC_AUTH_REPLAY_FORWARD_CODE); - ccAuthReply.merchantAdviceCode = getValue(element, CC_AUTH_REPLAY_MERCHANT_ADVICE_CODE); - ccAuthReply.merchantAdviceCodeRaw = getValue(element, CC_AUTH_REPLAY_MERCHANT_ADVICE_CODE_RAW); - ccAuthReply.ownerMerchantID = getValue(element, CC_AUTH_REPLAY_OWNER_MERCHANT_ID); - ccAuthReply.paymentNetworkTransactionID = getValue(element, CC_AUTH_REPLAY_PAYMENT_NETWORK_TRANSACTION_ID); - ccAuthReply.personalIDCode = getValue(element, CC_AUTH_REPLAY_PERSONAL_ID_CODE); - ccAuthReply.posData = getValue(element, CC_AUTH_REPLAY_POS_DATE); - ccAuthReply.processorResponse = getValue(element, CC_AUTH_REPLAY_PROCESSOR_RESPONSE); - ccAuthReply.processorTransactionID = getValue(element, CC_AUTH_REPLAY_PROCESSOR_TRANSACTION_ID); - ccAuthReply.reasonCode = getValue(element, CC_AUTH_REPLAY_REASON_CODE); - ccAuthReply.reconciliationID = getValue(element, CC_AUTH_REPLAY_RECONCILATION_ID); - ccAuthReply.referralResponseNumber = getValue(element, CC_AUTH_REPLAY_REFERRAL_RESPONSE_NUMBER); - ccAuthReply.requestAmount = getValue(element, CC_AUTH_REPLAY_REQUEST_AMOUNT); - ccAuthReply.requestCurrency = getValue(element, CC_AUTH_REPLAY_REQUEST_CURRENCY); - ccAuthReply.transactionID = getValue(element, CC_AUTH_REPLAY_TRANSACTION_ID); + + private static InAppCcAndroidPayAuthReply getAndroidPayAuthReply(Element element) { + + InAppCcAndroidPayAuthReply ccAuthReply = new InAppCcAndroidPayAuthReply(); + + ccAuthReply.accountBalance = getValue(element, CC_AUTH_REPLY_ACCOUNT_BALANCE); + ccAuthReply.accountBalanceCurrency = getValue(element, CC_AUTH_REPLY_ACCOUNT_BALANCE_CURRENCY); + ccAuthReply.accountBalanceSign = getValue(element, CC_AUTH_REPLY_ACCOUNT_BALANCE_SIGN); + ccAuthReply.affluenceIndicator = getValue(element, CC_AUTH_REPLY_AFFLUENCE_INDICATOR); + ccAuthReply.amount = getValue(element, CC_AUTH_REPLY_AMOUNT); + ccAuthReply.authorizationCode = getValue(element, CC_AUTH_REPLY_AUTHORIZATION_CODE); + ccAuthReply.authorizedDateTime = getValue(element, CC_AUTH_REPLY_AUTHORIZED_DATE_TIME); + ccAuthReply.avsCode = getValue(element, CC_AUTH_REPLY_AVS_CODE); + ccAuthReply.avsCodeRaw = getValue(element, CC_AUTH_REPLY_AVS_CODE_RAW); + ccAuthReply.cardCategory = getValue(element, CC_AUTH_REPLY_CARD_CATEGORY); + ccAuthReply.cardCommercial = getValue(element, CC_AUTH_REPLY_CARD_COMMERCIAL); + ccAuthReply.cardGroup = getValue(element, CC_AUTH_REPLY_CARD_GROUP); + ccAuthReply.cardHealthcare = getValue(element, CC_AUTH_REPLY_CARD_HEALTHCARE); + ccAuthReply.cardIssuerCountry = getValue(element, CC_AUTH_REPLY_CARD_ISSUER_COUNTRY); + ccAuthReply.cardLevel3Eligible = getValue(element, CC_AUTH_REPLY_CARD_LEVEL_3_ELIGIBLE); + ccAuthReply.cardPayroll = getValue(element, CC_AUTH_REPLY_CARD_PAYROLL); + ccAuthReply.cardPINlessDebit = getValue(element, CC_AUTH_REPLY_CARD_PINLESS_DEBIT); + ccAuthReply.cardPrepaid = getValue(element, CC_AUTH_REPLY_CARD_PREPAID); + ccAuthReply.cardRegulated = getValue(element, CC_AUTH_REPLY_CARD_REGULATED); + ccAuthReply.cardSignatureDebit = getValue(element, CC_AUTH_REPLY_CARD_SIGNATURE_DEBIT); + ccAuthReply.cavvResponseCode = getValue(element, CC_AUTH_REPLY_CAVV_RESPONSE_CODE); + ccAuthReply.cavvResponseCodeRaw = getValue(element, CC_AUTH_REPLY_CAVV_RESPONSE_CODE_RAW); + ccAuthReply.cvCode = getValue(element, CC_AUTH_REPLY_CV_CODE); + ccAuthReply.cvCodeRaw = getValue(element, CC_AUTH_REPLY_CV_CODE_RAW); + ccAuthReply.evEmail = getValue(element, CC_AUTH_REPLY_EV_EMAIL); + ccAuthReply.evEmailRaw = getValue(element, CC_AUTH_REPLY_EV_EMAIL_RAW); + ccAuthReply.evName = getValue(element, CC_AUTH_REPLY_EV_NAME); + ccAuthReply.evNameRaw = getValue(element, CC_AUTH_REPLY_EV_NAME_RAW); + ccAuthReply.evPhoneNumber = getValue(element, CC_AUTH_REPLY_EV_PHONE_NUMBER); + ccAuthReply.evPhoneNumberRaw = getValue(element, CC_AUTH_REPLY_EV_PHONE_NUMBER_RAW); + ccAuthReply.evPostalCode = getValue(element, CC_AUTH_REPLY_EV_POSTAL_CODE); + ccAuthReply.evPostalCodeRaw = getValue(element, CC_AUTH_REPLY_EV_POSTAL_CODE_RAW); + ccAuthReply.evStreet = getValue(element, CC_AUTH_REPLY_EV_STREET); + ccAuthReply.evStreetRaw = getValue(element, CC_AUTH_REPLY_EV_STREET_RAW); + ccAuthReply.forwardCode = getValue(element, CC_AUTH_REPLY_FORWARD_CODE); + ccAuthReply.merchantAdviceCode = getValue(element, CC_AUTH_REPLY_MERCHANT_ADVICE_CODE); + ccAuthReply.merchantAdviceCodeRaw = getValue(element, CC_AUTH_REPLY_MERCHANT_ADVICE_CODE_RAW); + ccAuthReply.ownerMerchantID = getValue(element, CC_AUTH_REPLY_OWNER_MERCHANT_ID); + ccAuthReply.paymentNetworkTransactionID = getValue(element, CC_AUTH_REPLY_PAYMENT_NETWORK_TRANSACTION_ID); + ccAuthReply.personalIDCode = getValue(element, CC_AUTH_REPLY_PERSONAL_ID_CODE); + ccAuthReply.posData = getValue(element, CC_AUTH_REPLY_POS_DATE); + ccAuthReply.processorResponse = getValue(element, CC_AUTH_REPLY_PROCESSOR_RESPONSE); + ccAuthReply.processorTransactionID = getValue(element, CC_AUTH_REPLY_PROCESSOR_TRANSACTION_ID); + ccAuthReply.reasonCode = getValue(element, CC_AUTH_REPLY_REASON_CODE); + ccAuthReply.reconciliationID = getValue(element, CC_AUTH_REPLY_RECONCILATION_ID); + ccAuthReply.referralResponseNumber = getValue(element, CC_AUTH_REPLY_REFERRAL_RESPONSE_NUMBER); + ccAuthReply.requestAmount = getValue(element, CC_AUTH_REPLY_REQUEST_AMOUNT); + ccAuthReply.requestCurrency = getValue(element, CC_AUTH_REPLY_REQUEST_CURRENCY); + ccAuthReply.transactionID = getValue(element, CC_AUTH_REPLY_TRANSACTION_ID); return ccAuthReply; - }*/ + } private static InAppCcEncryptedPaymentDataReply getEncryptedPaymentReply(Element element) { @@ -341,33 +338,50 @@ private static InAppCcEncryptedPaymentDataReply getEncryptedPaymentReply(Element return ccEncryptedPaymentReply; } -/* public SDKGatewayResponse convertAuthorizationToGatewayResponse() { + public SDKGatewayResponse convertToGatewayResponse() { + if(ccAuthReply != null) + return convertAuthorizationToGatewayResponse(); + else + return convertEncryptionToGatewayResponse(); + } + + private SDKGatewayResponse convertAuthorizationToGatewayResponse() { String dateTime = null; - if (ccAuthReply != null && ccAuthReply.authorizedDateTime != null) { + if (ccAuthReply != null) { dateTime = ccAuthReply.authorizedDateTime; } - String date = null; - String time = null; + String date = null, time = null; if (dateTime != null) { date = SDKUtils.convertToLocalDate(dateTime); time = SDKUtils.convertToLocalTime(dateTime); } String authCode = (ccAuthReply != null) ? ccAuthReply.authorizationCode : null; - BigDecimal authorizedAmount = BigDecimal.ZERO; + BigDecimal authorizedAmount = BigDecimal.ZERO; - if (!TextUtils.isEmpty(ccAuthReply.amount)) { - authorizedAmount = new BigDecimal(ccAuthReply.amount); + if (ccAuthReply != null && !TextUtils.isEmpty(ccAuthReply.amount)) { + authorizedAmount = new BigDecimal(ccAuthReply.amount); } - return new SDKGatewayResponse(decision, requestID, - SDKResponseReasonCode.getResponseReasonCodeByValueMapping(reasonCode), type, authorizedAmount, - authCode, date, time, ""); - }*/ + SDKResponseReasonCode sdkResponseReasonCode = SDKResponseReasonCode + .getResponseReasonCodeByValueMapping(reasonCode); + + return new SDKGatewayResponse.Builder + (type, sdkResponseReasonCode, requestID, requestToken) + .decision(decision) + .date(date) + .time(time) + .authorizationCode(authCode) + .authorizedAmount(authorizedAmount) + .build(); + } + + private SDKGatewayResponse convertEncryptionToGatewayResponse() { + String dateTime = null; + if(ccEncryptedPaymentReply != null) + dateTime = ccEncryptedPaymentReply.requestDateTime; - public SDKGatewayResponse convertToGatewayResponse() { - String dateTime = ccEncryptedPaymentReply.requestDateTime; String date = null, time = null; if (dateTime != null) { date = SDKUtils.convertToLocalDate(dateTime); @@ -379,10 +393,10 @@ public SDKGatewayResponse convertToGatewayResponse() { return new SDKGatewayResponse.Builder (type, sdkResponseReasonCode, requestID, requestToken) - .setDecision(decision) - .setDate(date) - .setTime(time) - .setEncryptedPaymentData(ccEncryptedPaymentReply.data) + .decision(decision) + .date(date) + .time(time) + .encryptedPaymentData(ccEncryptedPaymentReply.data) .build(); } @@ -392,7 +406,7 @@ public SDKGatewayResponse convertNVPToGatewayResponse(InAppResponseObject result SDKGatewayResponse response = new SDKGatewayResponse.Builder (type, sdkResponseReasonCode, result.requestID, result.requestToken) - .setDecision(result.decision) + .decision(result.decision) .build(); return response; } diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/services/InAppAuthService.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/services/InAppAuthService.java new file mode 100644 index 0000000..d784e7a --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/services/InAppAuthService.java @@ -0,0 +1,49 @@ +package com.cybersource.inappsdk.connectors.inapp.services; + +import com.cybersource.inappsdk.soap.model.SDKXMLParentNode; + +/** + * Describes fields of "ccAuthService" object in WebService request + * + * Created by fzubair on 11/18/2015. + */ +public class InAppAuthService extends InAppBaseService { + + public final String OBJECT_NAME = "ccAuthService"; + public final String RUN = "run"; + public final String PARTIAL_AUTH_INDICATOR = "partialAuthIndicator"; + + public String run; + public String partialAuthIndicator; + + /** + * All fields in constructor are required + * + * @param run + */ + public InAppAuthService(boolean run, boolean partialAuthIndicator) { + this.run = String.valueOf(run); + this.partialAuthIndicator = String.valueOf(partialAuthIndicator); + } + + @Override + public void updateEnvelope(SDKXMLParentNode request) { + if (validateObject()) { + SDKXMLParentNode creditService = request.addNode(request.getNamespace(), OBJECT_NAME); + if (this.run != null) { + creditService.addAttribute(null, RUN, this.run); + } + if (this.partialAuthIndicator != null) { + creditService.addTextNode(creditService.getNamespace(), PARTIAL_AUTH_INDICATOR, partialAuthIndicator); + } + } + } + + private boolean validateObject() { + if (this.run == null) { + return false; + } else { + return true; + } + } +} diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/services/InAppEncryptPaymentDataService.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/services/InAppEncryptPaymentDataService.java index ee1d9d5..1afad7d 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/services/InAppEncryptPaymentDataService.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/services/InAppEncryptPaymentDataService.java @@ -13,7 +13,6 @@ public class InAppEncryptPaymentDataService extends InAppBaseService { public final String RUN = "run"; public String run; - String commerceIndicator; /** * All fields in constructor are required @@ -22,7 +21,6 @@ public class InAppEncryptPaymentDataService extends InAppBaseService { */ public InAppEncryptPaymentDataService(boolean run, String commerceIndicator) { this.run = String.valueOf(run); - this.commerceIndicator = commerceIndicator; } @Override diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEnvelopeAndroidPayTransactionObject.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEnvelopeAndroidPayTransactionObject.java new file mode 100644 index 0000000..5a9c0d0 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEnvelopeAndroidPayTransactionObject.java @@ -0,0 +1,82 @@ +package com.cybersource.inappsdk.connectors.inapp.transaction; + +import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppBillTo; +import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppItem; +import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppPurchaseTotals; +import com.cybersource.inappsdk.connectors.inapp.services.InAppAuthService; +import com.cybersource.inappsdk.soap.model.SDKXMLParentNode; +import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppEncryptedPayment; + +import java.util.List; + +/** + * Contains payment data that will be send to WebService in request body; + * + * @author fzubair + */ +public class InAppEnvelopeAndroidPayTransactionObject extends InAppEnvelopeTransactionObject { + + public List items; + public InAppPurchaseTotals purchaseTotals; + public InAppBillTo billTo; + public InAppAuthService ccAuthService; + private String paymentSolution; + + public final String PAYMENT_SOLUTION = "paymentSolution"; + + public InAppEncryptedPayment encryptedPayment; + + /** + * All fields in constructor are required + * + * @param merchantId + * @param merchantReferenceCode + * @param inAppBillTo + * @param inAppItems + * @param inAppPurchaseTotals + * @param inAppAuthService + * @param paymentSolution + * @param clientLibrary + * @param encryptedPayment + */ + public InAppEnvelopeAndroidPayTransactionObject(String merchantId, String merchantReferenceCode, + InAppBillTo inAppBillTo, List inAppItems, + InAppPurchaseTotals inAppPurchaseTotals, + InAppAuthService inAppAuthService, String paymentSolution, + String clientLibrary, InAppEncryptedPayment encryptedPayment) { + this.merchantID = merchantId; + this.merchantReferenceCode = merchantReferenceCode; + this.items = inAppItems; + this.purchaseTotals = inAppPurchaseTotals; + this.billTo = inAppBillTo; + this.clientLibrary = clientLibrary; + this.ccAuthService = inAppAuthService; + this.paymentSolution = paymentSolution; + this.encryptedPayment = encryptedPayment; + } + + @Override + public void updateEnvelope(SDKXMLParentNode request) { + createMerchantData(request); + if (this.billTo != null) { + this.billTo.updateEnvelope(request); + } + if (this.items != null) { + for (InAppItem item : this.items) { + item.updateEnvelope(request); + } + } + if (this.purchaseTotals != null) { + this.purchaseTotals.updateEnvelope(request); + } + if (this.encryptedPayment != null) { + this.encryptedPayment.updateEnvelope(request); + } + if (this.ccAuthService != null) { + this.ccAuthService.updateEnvelope(request); + } + if (this.paymentSolution != null) { + request.addTextNode(request.getNamespace(), PAYMENT_SOLUTION, this.paymentSolution); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEncryptionTransactionObject.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEnvelopeEncryptionTransactionObject.java similarity index 67% rename from src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEncryptionTransactionObject.java rename to src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEnvelopeEncryptionTransactionObject.java index 16460ab..90bfbd1 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEncryptionTransactionObject.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEnvelopeEncryptionTransactionObject.java @@ -2,28 +2,23 @@ import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppBillTo; import com.cybersource.inappsdk.connectors.inapp.datamodel.InAppCard; -import com.cybersource.inappsdk.connectors.inapp.services.InAppEncryptPaymentDataService; import com.cybersource.inappsdk.soap.model.SDKXMLParentNode; +import com.cybersource.inappsdk.connectors.inapp.services.InAppEncryptPaymentDataService; /** * Contains payment data that will be send to WebService in request body; * * Created by fzubair on 10/8/2015. */ -public class InAppEncryptionTransactionObject extends InAppTransactionObject { +public class InAppEnvelopeEncryptionTransactionObject extends InAppEnvelopeTransactionObject { - public InAppCard card; - public InAppBillTo billTo; - public String clientLibrary; + private InAppCard card; + private InAppBillTo billTo; public InAppEncryptPaymentDataService encryptPaymentDataService; - private final String CLIENT_LIBRARY = "clientLibrary"; public final String PAYMENT_SOLUTION = "paymentSolution"; - //public VMposEncryptedPayment encryptedPayment; - //public String clientLibrary; - /** * All fields in constructor are required * @@ -32,12 +27,12 @@ public class InAppEncryptionTransactionObject extends InAppTransactionObject { * @param inAppWebServiceCard * @param inAppBillTo * @param encryptPaymentDataService - * @param //shipTo + * @param clientLibrary */ - public InAppEncryptionTransactionObject(String merchantId, String merchantReferenceCode, - InAppCard inAppWebServiceCard, InAppBillTo inAppBillTo, - InAppEncryptPaymentDataService encryptPaymentDataService, - String clientLibrary) { + public InAppEnvelopeEncryptionTransactionObject(String merchantId, String merchantReferenceCode, + InAppCard inAppWebServiceCard, InAppBillTo inAppBillTo, + InAppEncryptPaymentDataService encryptPaymentDataService, + String clientLibrary) { this.merchantID = merchantId; this.merchantReferenceCode = merchantReferenceCode; this.clientLibrary = clientLibrary; @@ -49,9 +44,6 @@ public InAppEncryptionTransactionObject(String merchantId, String merchantRefere @Override public void updateEnvelope(SDKXMLParentNode request) { createMerchantData(request); - if(this.clientLibrary != null){ - request.addTextNode(request.getNamespace(), CLIENT_LIBRARY, this.clientLibrary); - } if (this.billTo != null) { this.billTo.updateEnvelope(request); } diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppTransactionObject.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEnvelopeTransactionObject.java similarity index 78% rename from src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppTransactionObject.java rename to src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEnvelopeTransactionObject.java index 5f54995..a13a531 100644 --- a/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppTransactionObject.java +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/InAppEnvelopeTransactionObject.java @@ -9,13 +9,15 @@ * * @author fzubair */ -public abstract class InAppTransactionObject { +public abstract class InAppEnvelopeTransactionObject { public final String MERCHANT_ID = "merchantID"; public final String MERCHANT_REFERENCE_CODE = "merchantReferenceCode"; + private final String CLIENT_LIBRARY = "clientLibrary"; - public String merchantID; - public String merchantReferenceCode; + protected String merchantID; + protected String merchantReferenceCode; + protected String clientLibrary; /** * Updates request with fields needed in WebService request. @@ -39,5 +41,8 @@ protected void createMerchantData(SDKXMLParentNode request) { if (this.merchantReferenceCode != null) { request.addTextNode(request.getNamespace(), MERCHANT_REFERENCE_CODE, this.merchantReferenceCode); } + if(this.clientLibrary != null){ + request.addTextNode(request.getNamespace(), CLIENT_LIBRARY, this.clientLibrary); + } } } \ No newline at end of file diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppAndroidPayTransactionObject.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppAndroidPayTransactionObject.java new file mode 100644 index 0000000..0e72157 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppAndroidPayTransactionObject.java @@ -0,0 +1,35 @@ +package com.cybersource.inappsdk.connectors.inapp.transaction.client; + +import static com.cybersource.inappsdk.connectors.inapp.transaction.client.InAppTransactionType.IN_APP_TRANSACTION_ANDROID_PAY; + +/** + * Provides data for Android Pay transaction + * + * Created by fzubair on 11/18/2015. + */ +final class InAppAndroidPayTransactionObject extends InAppTransaction { + + private InAppAndroidPayTransactionObject(Builder builder) + { + this.transactionType = builder.transactionType; + this.merchantReferenceCode = builder.merchantReferenceCode; + this.transactionTime = builder.transactionTime; + this.transactionDate = builder.transactionDate; + this.billTo = builder.billTo; + this.encryptedPaymentData = builder.encryptedPaymentData; + this.purchaseOrder = builder.purchaseOrder; + } + + public static class Builder extends InAppTransaction.Builder{ + + public Builder(){ + this.transactionType = IN_APP_TRANSACTION_ANDROID_PAY; + this.merchantReferenceCode = Long.toString(System.currentTimeMillis()); + } + + @Override + public InAppAndroidPayTransactionObject build(){ + return new InAppAndroidPayTransactionObject(this); + } + } +} diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppEncryptTransactionObject.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppEncryptTransactionObject.java new file mode 100644 index 0000000..f79d50a --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppEncryptTransactionObject.java @@ -0,0 +1,32 @@ +package com.cybersource.inappsdk.connectors.inapp.transaction.client; + +/** + * Provides data for Encrypt transaction + * + * Created by fzubair on 11/18/2015. + */ +final class InAppEncryptTransactionObject extends InAppTransaction { + + private InAppEncryptTransactionObject(Builder builder) + { + this.transactionType = builder.transactionType; + this.merchantReferenceCode = builder.merchantReferenceCode; + this.transactionTime = builder.transactionTime; + this.transactionDate = builder.transactionDate; + this.cardData = builder.cardData; + this.billTo = builder.billTo; + } + + public static class Builder extends InAppTransaction.Builder{ + + public Builder(){ + this.transactionType = InAppTransactionType.IN_APP_TRANSACTION_ENCRYPTION; + this.merchantReferenceCode = Long.toString(System.currentTimeMillis()); + } + + @Override + public InAppEncryptTransactionObject build(){ + return new InAppEncryptTransactionObject(this); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppTransaction.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppTransaction.java new file mode 100644 index 0000000..0a871e4 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppTransaction.java @@ -0,0 +1,127 @@ +package com.cybersource.inappsdk.connectors.inapp.transaction.client; + +import com.cybersource.inappsdk.datamodel.transaction.fields.SDKBillTo; +import com.cybersource.inappsdk.datamodel.transaction.fields.SDKCardData; +import com.cybersource.inappsdk.datamodel.transaction.fields.SDKPurchaseOrder; + +/** + * This class represents a transaction that is sent to the server. + * + * Created by fzubair on 11/18/2015. + */ +public abstract class InAppTransaction { + + protected String merchantReferenceCode; + protected InAppTransactionType transactionType; + protected String transactionTime; + protected String transactionDate; + protected SDKCardData cardData; + protected SDKBillTo billTo; + protected String encryptedPaymentData; + protected SDKPurchaseOrder purchaseOrder; + + InAppTransaction(Builder builder) { + } + + InAppTransaction() { + } + + public String getMerchantReferenceCode() { + return merchantReferenceCode; + } + + public final String getTransactionTime() { + return transactionTime; + } + + public final String getTransactionDate() { + return transactionDate; + } + + public SDKCardData getCardData() { + return cardData; + } + + public SDKBillTo getBillTo() { + return billTo; + } + + public SDKPurchaseOrder getPurchaseOrder() { + return purchaseOrder; + } + + public InAppTransactionType getTransactionType() { + return transactionType; + } + + public String getEncryptedPaymentData() { + return encryptedPaymentData; + } + + /** + * A factory method for creating proper transaction object. + * + * @param type transaction type + * @return one of transaction objects + */ + public static InAppTransaction.Builder createTransactionObject(InAppTransactionType type) { + + switch (type) { + case IN_APP_TRANSACTION_ENCRYPTION: + return new InAppEncryptTransactionObject.Builder(); + case IN_APP_TRANSACTION_ANDROID_PAY: + return new InAppAndroidPayTransactionObject.Builder(); + default: + return new InAppEncryptTransactionObject.Builder(); + } + } + + public static abstract class Builder { + protected String merchantReferenceCode; + protected InAppTransactionType transactionType; + protected String transactionTime; + protected String transactionDate; + protected SDKCardData cardData; + protected SDKBillTo billTo; + protected String encryptedPaymentData; + protected SDKPurchaseOrder purchaseOrder; + + public InAppTransaction.Builder merchantReferenceCode(String merchantReferenceCode) { + this.merchantReferenceCode = merchantReferenceCode; + return this; + } + + public InAppTransaction.Builder cardData(SDKCardData cardData) { + this.cardData = cardData; + return this; + } + + public InAppTransaction.Builder billTo(SDKBillTo billTo) { + this.billTo = billTo; + return this; + } + + public InAppTransaction.Builder purchaseOrder(SDKPurchaseOrder purchaseOrder) { + this.purchaseOrder = purchaseOrder; + return this; + } + + public InAppTransaction.Builder transactionDate(String transactionDate) { + this.transactionDate = transactionDate; + return this; + } + + public InAppTransaction.Builder transactionTime(String transactionTime) { + this.transactionTime = transactionTime; + return this; + } + + public InAppTransaction.Builder encryptedPaymentData(String encryptedPaymentData) { + this.encryptedPaymentData = encryptedPaymentData; + return this; + } + + public abstract InAppTransaction build(); + + } +} diff --git a/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppTransactionType.java b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppTransactionType.java new file mode 100644 index 0000000..c3d4b73 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/connectors/inapp/transaction/client/InAppTransactionType.java @@ -0,0 +1,14 @@ +package com.cybersource.inappsdk.connectors.inapp.transaction.client; + +/** + * Enumeration used to indicate the transaction type. Possible states: + *
    + *
  • IN_APP_TRANSACTION_ENCRYPTION
  • + *
  • IN_APP_TRANSACTION_ANDROID_PAY
  • + *
+ * + * Created by fzubair on 11/18/2015. + */ +public enum InAppTransactionType { + IN_APP_TRANSACTION_ENCRYPTION, IN_APP_TRANSACTION_ANDROID_PAY +} diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/SDKGateway.java b/src/main/java/com/cybersource/inappsdk/datamodel/SDKGateway.java index 48f3511..14325a7 100644 --- a/src/main/java/com/cybersource/inappsdk/datamodel/SDKGateway.java +++ b/src/main/java/com/cybersource/inappsdk/datamodel/SDKGateway.java @@ -1,6 +1,6 @@ package com.cybersource.inappsdk.datamodel; -import com.cybersource.inappsdk.datamodel.transaction.SDKTransactionObject; +import com.cybersource.inappsdk.connectors.inapp.transaction.client.InAppTransaction; import com.cybersource.inappsdk.datamodel.transaction.callbacks.SDKApiConnectionCallback; /** @@ -34,14 +34,23 @@ protected static void setGateway(SDKGateway gatewayInstance) { /** - * Performs payment Authorization for the transaction object + * Performs encryption for the provided credit card data object * - * during operation * @return true if a transaction is already in progress */ - protected abstract boolean performEncryption(SDKTransactionObject transactionObject, + protected abstract boolean performEncryption(InAppTransaction transactionObject, SDKApiConnectionCallback applicationConnectionCallback); + /** + * Performs Transaction using the Android pay encrypted payment data provided with + * the transaction object + * + * @return true if a transaction is already in progress + */ + protected abstract boolean performAndroidPayTransaction(InAppTransaction transactionObject, + SDKApiConnectionCallback applicationConnectionCallback); + + /** * Cleans the gateway instance. */ diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/SDKGatewayErrorMapping.java b/src/main/java/com/cybersource/inappsdk/datamodel/SDKGatewayErrorMapping.java index ce45af8..be51b10 100644 --- a/src/main/java/com/cybersource/inappsdk/datamodel/SDKGatewayErrorMapping.java +++ b/src/main/java/com/cybersource/inappsdk/datamodel/SDKGatewayErrorMapping.java @@ -3,7 +3,7 @@ import com.cybersource.inappsdk.common.error.SDKGatewayError; /** - * Allows to get @VMposGatewayError from error code. + * Allows to get @SDKGatewayError from error code. * * @author fzubair */ diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/response/SDKGatewayResponse.java b/src/main/java/com/cybersource/inappsdk/datamodel/response/SDKGatewayResponse.java index e1b1b92..3d1bc10 100644 --- a/src/main/java/com/cybersource/inappsdk/datamodel/response/SDKGatewayResponse.java +++ b/src/main/java/com/cybersource/inappsdk/datamodel/response/SDKGatewayResponse.java @@ -3,6 +3,8 @@ import android.os.Parcel; import android.os.Parcelable; +import java.math.BigDecimal; + /** * Response object of gateway requests * @@ -16,6 +18,7 @@ public class SDKGatewayResponse implements Parcelable{ private final String requestToken; private final SDKGatewayResponseType type; private final String authorizationCode; + private final BigDecimal authorizedAmount; private final String date; private final String time; private final String encryptedPaymentData; @@ -27,6 +30,7 @@ private SDKGatewayResponse(Builder builder) { this.requestToken = builder.requestToken; this.type = builder.type; this.authorizationCode = builder.authorizationCode; + this.authorizedAmount = builder.authorizedAmount; this.date = builder.date; this.time = builder.time; this.encryptedPaymentData = builder.encryptedPaymentData; @@ -80,6 +84,7 @@ private SDKGatewayResponse(Parcel in){ this.requestToken = in.readString(); this.type = (SDKGatewayResponseType) in.readSerializable(); this.authorizationCode = in.readString(); + this.authorizedAmount = BigDecimal.valueOf(in.readDouble()); this.date = in.readString(); this.time = in.readString(); this.encryptedPaymentData = in.readString(); @@ -98,6 +103,7 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeString(requestToken); dest.writeSerializable(type); dest.writeString(authorizationCode); + dest.writeDouble(authorizedAmount.doubleValue()); dest.writeString(date); dest.writeString(time); dest.writeString(encryptedPaymentData); @@ -123,6 +129,7 @@ public static class Builder { private final String requestToken; private SDKResponseDecision decision; private String authorizationCode; + private BigDecimal authorizedAmount; private String date; private String time; private String encryptedPaymentData; @@ -134,27 +141,32 @@ public Builder(SDKGatewayResponseType type, SDKResponseReasonCode reasonCode, St this.requestToken = requestToken; } - public SDKGatewayResponse.Builder setTime(String time) { + public SDKGatewayResponse.Builder time(String time) { this.time = time; return this; } - public SDKGatewayResponse.Builder setAuthorizationCode(String authorizationCode) { + public SDKGatewayResponse.Builder authorizedAmount(BigDecimal authorizedAmount) { + this.authorizedAmount = authorizedAmount; + return this; + } + + public SDKGatewayResponse.Builder authorizationCode(String authorizationCode) { this.authorizationCode = authorizationCode; return this; } - public SDKGatewayResponse.Builder setDate(String date) { + public SDKGatewayResponse.Builder date(String date) { this.date = date; return this; } - public SDKGatewayResponse.Builder setDecision(SDKResponseDecision decision) { + public SDKGatewayResponse.Builder decision(SDKResponseDecision decision) { this.decision = decision; return this; } - public SDKGatewayResponse.Builder setEncryptedPaymentData(String data) { + public SDKGatewayResponse.Builder encryptedPaymentData(String data) { this.encryptedPaymentData = data; return this; } diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/response/SDKGatewayResponseType.java b/src/main/java/com/cybersource/inappsdk/datamodel/response/SDKGatewayResponseType.java index 28eed06..9af9acf 100644 --- a/src/main/java/com/cybersource/inappsdk/datamodel/response/SDKGatewayResponseType.java +++ b/src/main/java/com/cybersource/inappsdk/datamodel/response/SDKGatewayResponseType.java @@ -7,7 +7,7 @@ */ public enum SDKGatewayResponseType { - SDK_ENCRYPTION; + SDK_ENCRYPTION, SDK_ANDROID_PAY; } \ No newline at end of file diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/SDKEncryptTransactionObject.java b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/SDKEncryptTransactionObject.java deleted file mode 100644 index 2d5e883..0000000 --- a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/SDKEncryptTransactionObject.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.cybersource.inappsdk.datamodel.transaction; - -import static com.cybersource.inappsdk.datamodel.transaction.SDKTransactionType.SDK_TRANSACTION_ENCRYPTION; - -/** - * Provides data for refund transaction - * - * @author fzubair - */ -final class SDKEncryptTransactionObject extends SDKTransactionObject { - - private SDKEncryptTransactionObject(Builder builder) - { - this.transactionType = builder.transactionType; - this.merchantReferenceCode = builder.merchantReferenceCode; - this.transactionTime = builder.transactionTime; - this.transactionDate = builder.transactionDate; - this.cardData = builder.cardData; - this.billTo = builder.billTo; - } - - public static class Builder extends SDKTransactionObject.Builder{ - - public Builder(){ - this.transactionType = SDK_TRANSACTION_ENCRYPTION; - this.merchantReferenceCode = Long.toString(System.currentTimeMillis()); - } - - @Override - public SDKEncryptTransactionObject build(){ - return new SDKEncryptTransactionObject(this); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/SDKTransactionObject.java b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/SDKTransactionObject.java deleted file mode 100644 index 821247b..0000000 --- a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/SDKTransactionObject.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.cybersource.inappsdk.datamodel.transaction; - -import com.cybersource.inappsdk.datamodel.transaction.fields.SDKBillTo; -import com.cybersource.inappsdk.datamodel.transaction.fields.SDKCardData; - -/** - * This class represents a transaction that is sent to a reader and then received back from it. - * - * @author fzubair - */ -public abstract class SDKTransactionObject { - - protected String merchantReferenceCode; - protected SDKTransactionType transactionType; - protected String transactionTime; - protected String transactionDate; - protected SDKCardData cardData; - protected SDKBillTo billTo; - - SDKTransactionObject(Builder builder) { - } - - SDKTransactionObject() { - } - - public String getMerchantReferenceCode() { - return merchantReferenceCode; - } - - public final String getTransactionTime() { - return transactionTime; - } - - public final String getTransactionDate() { - return transactionDate; - } - - public SDKCardData getCardData() { - return cardData; - } - - public SDKBillTo getBillTo() { - return billTo; - } - - public SDKTransactionType getTransactionType() { - return transactionType; - } - - /** - * A factory method for creating proper transaction object. - * - * @param type transaction type - * @return one of transaction objects - */ - public static SDKTransactionObject.Builder createTransactionObject(SDKTransactionType type) { - - switch (type) { - case SDK_TRANSACTION_ENCRYPTION: - return new SDKEncryptTransactionObject.Builder(); - default: - return new SDKEncryptTransactionObject.Builder(); - } - } - - public static abstract class Builder { - protected String merchantReferenceCode; - protected SDKTransactionType transactionType; - protected String transactionTime; - protected String transactionDate; - protected SDKCardData cardData; - protected SDKBillTo billTo; - - public SDKTransactionObject.Builder merchantReferenceCode(String merchantReferenceCode) { - this.merchantReferenceCode = merchantReferenceCode; - return this; - } - - public SDKTransactionObject.Builder cardData(SDKCardData cardData) { - this.cardData = cardData; - return this; - } - - public SDKTransactionObject.Builder billTo(SDKBillTo billTo) { - this.billTo = billTo; - return this; - } - - public SDKTransactionObject.Builder transactionDate(String transactionDate) { - this.transactionDate = transactionDate; - return this; - } - - public SDKTransactionObject.Builder transactionTime(String transactionTime) { - this.transactionTime = transactionTime; - return this; - } - - public abstract SDKEncryptTransactionObject build(); - - } -} diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/SDKTransactionType.java b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/SDKTransactionType.java deleted file mode 100644 index 801f1b9..0000000 --- a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/SDKTransactionType.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.cybersource.inappsdk.datamodel.transaction; - -/** - * Enumeration used to indicate the transaction type. Possible states: - *
    - *
  • SDK_TRANSACTION_ENCRYPTION
  • - *
- * - * @author fzubair - */ -public enum SDKTransactionType { - SDK_TRANSACTION_ENCRYPTION -} diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKBillTo.java b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKBillTo.java index 7d79df5..93ee517 100644 --- a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKBillTo.java +++ b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKBillTo.java @@ -4,12 +4,19 @@ * Created by fzubair on 11/16/2015. */ public final class SDKBillTo { + // required - private String firstName; - private String lastName; - private String postalCode; + private final String firstName; + private final String lastName; // optional + private final String email; + private final String postalCode; + private final String street1; + private final String street2; + private final String city; + private final String state; + private final String country; /** * Creates an instance of object to store keyed card data. Also it sets a @@ -17,7 +24,13 @@ public final class SDKBillTo { private SDKBillTo(Builder builder){ this.firstName = builder.firstName; this.lastName = builder.lastName; + this.email = builder.email; this.postalCode = builder.postalCode; + this.street1 = builder.street1; + this.street2 = builder.street2; + this.city = builder.city; + this.state = builder.state; + this.country = builder.country; } public String getFirstName() { @@ -32,6 +45,30 @@ public String getPostalCode() { return postalCode; } + public String getStreet2() { + return street2; + } + + public String getCity() { + return city; + } + + public String getCountry() { + return country; + } + + public String getEmail() { + return email; + } + + public String getState() { + return state; + } + + public String getStreet1() { + return street1; + } + /* * (non-Javadoc) * @see java.lang.Object#hashCode() @@ -42,6 +79,7 @@ public int hashCode() { int result = super.hashCode(); result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); + result = prime * result + ((email == null) ? 0 : email.hashCode()); result = prime * result + ((postalCode == null) ? 0 : postalCode.hashCode()); return result; } @@ -76,6 +114,13 @@ public boolean equals(Object obj) { } else if (!lastName.equals(other.lastName)) { return false; } + if (email == null) { + if (other.email != null) { + return false; + } + } else if (!email.equals(other.email)) { + return false; + } if (postalCode == null) { if (other.postalCode != null) { return false; @@ -88,27 +133,56 @@ public boolean equals(Object obj) { public static class Builder { // required - private String firstName; - private String lastName; - private String postalCode; + private final String firstName; + private final String lastName; // optional + private String email; + private String postalCode; + private String street1; + private String street2; + private String city; + private String state; + private String country; + + // TODO: change documentation on github + public Builder(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } - public Builder() { + public SDKBillTo.Builder email(String email) { + this.email = email; + return this; } - public SDKBillTo.Builder firstName(String firstName) { - this.firstName = firstName; + public SDKBillTo.Builder postalCode(String postalCode) { + this.postalCode = postalCode; return this; } - public SDKBillTo.Builder lastName(String lastName) { - this.lastName = lastName; + public SDKBillTo.Builder street1(String street1) { + this.street1 = street1; return this; } - public SDKBillTo.Builder postalCode(String postalCode) { - this.postalCode = postalCode; + public SDKBillTo.Builder street2(String street2) { + this.street2 = street2; + return this; + } + + public SDKBillTo.Builder city(String city) { + this.city = city; + return this; + } + + public SDKBillTo.Builder state(String state) { + this.state = state; + return this; + } + + public SDKBillTo.Builder country(String country) { + this.country = country; return this; } diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKCardData.java b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKCardData.java index 3383230..bef91cd 100644 --- a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKCardData.java +++ b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKCardData.java @@ -1,7 +1,7 @@ package com.cybersource.inappsdk.datamodel.transaction.fields; -import com.cybersource.inappsdk.common.exceptions.SDKInvalidCardException; import com.cybersource.inappsdk.common.utils.SDKCardUtils; +import com.cybersource.inappsdk.common.exceptions.SDKInvalidCardException; /** * This class represents the manual card entry. diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKLineItem.java b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKLineItem.java new file mode 100644 index 0000000..11d1af9 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKLineItem.java @@ -0,0 +1,70 @@ +package com.cybersource.inappsdk.datamodel.transaction.fields; + +import java.math.BigDecimal; + +/** + * Contains fields that describes basket item. + * + * Created by fzubair on 11/19/2015. + */ +public final class SDKLineItem { + + private final String productName; + private final BigDecimal unitPrice; + private final int quantity; + private final BigDecimal taxAmount; + + private SDKLineItem(Builder builder){ + this.productName = builder.productName; + this.unitPrice = builder.unitPrice; + this.quantity = builder.quantity; + this.taxAmount = builder.taxAmount; + } + + public String getProductName() { + return productName; + } + + public int getQuantity() { + return quantity; + } + + public BigDecimal getTaxAmount() { + return taxAmount; + } + + public BigDecimal getUnitPrice() { + return unitPrice; + } + + public static class Builder{ + private final String productName; + private final BigDecimal unitPrice; + private final int quantity; + private BigDecimal taxAmount = BigDecimal.ZERO; + + public Builder(String productName, BigDecimal unitPrice, int quantity) { + this.productName = productName; + this.unitPrice = unitPrice; + this.quantity = quantity; + } + + public SDKLineItem.Builder taxAmount(BigDecimal taxAmount) { + if(taxAmount != null) + this.taxAmount = taxAmount; + return this; + } + + public SDKLineItem build(){ + return new SDKLineItem(this); + } + } + + /** + * @return price of all items based on quantity and individual price + */ + public BigDecimal getLineItemsPriceForQuantity() { + return unitPrice.multiply(new BigDecimal(quantity)); + } + +} \ No newline at end of file diff --git a/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKPurchaseOrder.java b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKPurchaseOrder.java new file mode 100644 index 0000000..34b1209 --- /dev/null +++ b/src/main/java/com/cybersource/inappsdk/datamodel/transaction/fields/SDKPurchaseOrder.java @@ -0,0 +1,121 @@ +package com.cybersource.inappsdk.datamodel.transaction.fields; + +import com.cybersource.inappsdk.common.SDKCurrency; +import com.cybersource.inappsdk.common.utils.SDKMathUtils; + +import java.math.BigDecimal; +import java.util.List; + + +/** + * This class represents purchase and contains purchase data which are required + * for transaction. + * + * Created by fzubair on 11/19/2015. + */ +public final class SDKPurchaseOrder { + + private final List items; + private final SDKCurrency currency; + + private BigDecimal grandTotalAmount; + private BigDecimal subtotalAmount; + private BigDecimal shippingAmount; + private BigDecimal totalTax; + + private SDKPurchaseOrder(Builder builder){ + this.items = builder.items; + this.grandTotalAmount = builder.grandTotalAmount; + this.subtotalAmount = builder.subtotalAmount; + this.shippingAmount = builder.shippingAmount; + this.totalTax = builder.totalTax; + this.currency = builder.currency; + updateTotals(); + } + + public BigDecimal getTotalTax() { + return totalTax; + } + + public SDKCurrency getCurrency() { + return currency; + } + + public BigDecimal getGrandTotalAmount() { + return grandTotalAmount; + } + + public List getLineItems() { + return items; + } + + public BigDecimal getSubtotalAmount() { + return subtotalAmount; + } + + + public static class Builder{ + private List items; + private BigDecimal grandTotalAmount = BigDecimal.ZERO; + private BigDecimal subtotalAmount = BigDecimal.ZERO; + private BigDecimal shippingAmount = BigDecimal.ZERO; + private BigDecimal totalTax = BigDecimal.ZERO; + private SDKCurrency currency = SDKCurrency.USD; + + public Builder() { + } + + public SDKPurchaseOrder.Builder items(List items) { + this.items = items; + return this; + } + public SDKPurchaseOrder.Builder grandTotalAmount(BigDecimal grandTotalAmount) { + this.grandTotalAmount = grandTotalAmount; + return this; + } + public SDKPurchaseOrder.Builder subtotalAmount(BigDecimal subtotalAmount) { + this.subtotalAmount = subtotalAmount; + return this; + } + public SDKPurchaseOrder.Builder shippingAmount(BigDecimal shippingAmount) { + this.shippingAmount = shippingAmount; + return this; + } + public SDKPurchaseOrder.Builder totalTax(BigDecimal totalTax) { + this.totalTax = totalTax; + return this; + } + public SDKPurchaseOrder.Builder currency(SDKCurrency currency) { + this.currency = currency; + return this; + } + + public SDKPurchaseOrder build(){ + return new SDKPurchaseOrder(this); + } + } + + /** + * Calculates totalAmount and subtotalAmount. + */ + public void updateTotals() { + + if(items != null) { + for (SDKLineItem item : items) { + subtotalAmount = SDKMathUtils.add(subtotalAmount, + item.getLineItemsPriceForQuantity()); + totalTax = SDKMathUtils.add(totalTax, item.getTaxAmount()); + } + } + grandTotalAmount = subtotalAmount; + + if (shippingAmount.compareTo(BigDecimal.ZERO) > 0) { + grandTotalAmount = SDKMathUtils.add(grandTotalAmount, shippingAmount); + } + + if (totalTax.compareTo(BigDecimal.ZERO) > 0) { + grandTotalAmount = SDKMathUtils.add(grandTotalAmount, totalTax); + } + } + +} diff --git a/src/main/java/com/cybersource/inappsdk/soap/envelope/SDKBaseSoapEnvelope.java b/src/main/java/com/cybersource/inappsdk/soap/envelope/SDKBaseSoapEnvelope.java index a364b1d..b0f7567 100644 --- a/src/main/java/com/cybersource/inappsdk/soap/envelope/SDKBaseSoapEnvelope.java +++ b/src/main/java/com/cybersource/inappsdk/soap/envelope/SDKBaseSoapEnvelope.java @@ -135,9 +135,9 @@ public void writeToParcel(Parcel dest, int flags) { } public void readFromParcel(Parcel in) { - body = in.readParcelable(com.visa.inappsdk.soap.model.SDKXMLBase.class.getClassLoader()); - header = in.readParcelable(com.visa.inappsdk.soap.model.SDKXMLBase.class.getClassLoader()); - envelopeNode = in.readParcelable(com.visa.inappsdk.soap.model.SDKXMLBase.class.getClassLoader()); + body = in.readParcelable(SDKXMLBase.class.getClassLoader()); + header = in.readParcelable(SDKXMLBase.class.getClassLoader()); + envelopeNode = in.readParcelable(SDKXMLBase.class.getClassLoader()); encoding = in.readString(); } diff --git a/src/main/java/com/cybersource/inappsdk/soap/model/SDKXMLNVPNode.java b/src/main/java/com/cybersource/inappsdk/soap/model/SDKXMLNVPNode.java index 58f519f..625c985 100644 --- a/src/main/java/com/cybersource/inappsdk/soap/model/SDKXMLNVPNode.java +++ b/src/main/java/com/cybersource/inappsdk/soap/model/SDKXMLNVPNode.java @@ -16,8 +16,6 @@ public SDKXMLNVPNode(String namespace, String name) { super(namespace, name); } - //private VMposCyberSourceNameValuePair nameValuePair; - /** * Creates a new XML Element. * @@ -30,13 +28,6 @@ public SDKXMLNVPNode(String namespace, String name) { } - *//** - * @return Text value of this text node XML element. - *//* - public VMposCyberSourceNameValuePair getNameValuePair() { - return nameValuePair; - }*/ - /* protected SDKXMLNVPNode(Parcel in){ super(in); } diff --git a/src/main/java/com/cybersource/inappsdk/soap/parser/SDKSoapParser.java b/src/main/java/com/cybersource/inappsdk/soap/parser/SDKSoapParser.java index 4c2127c..8ac0657 100644 --- a/src/main/java/com/cybersource/inappsdk/soap/parser/SDKSoapParser.java +++ b/src/main/java/com/cybersource/inappsdk/soap/parser/SDKSoapParser.java @@ -1,11 +1,13 @@ package com.cybersource.inappsdk.soap.parser; +import android.util.Log; + +import com.cybersource.inappsdk.soap.model.SDKXMLNVPNode; +import com.cybersource.inappsdk.soap.model.SDKXMLTextNode; import com.cybersource.inappsdk.soap.envelope.SDKBaseSoapEnvelope; import com.cybersource.inappsdk.soap.model.SDKXMLAttribute; -import com.cybersource.inappsdk.soap.model.SDKXMLNVPNode; import com.cybersource.inappsdk.soap.model.SDKXMLNode; import com.cybersource.inappsdk.soap.model.SDKXMLParentNode; -import com.cybersource.inappsdk.soap.model.SDKXMLTextNode; import java.util.ArrayList; import java.util.Collection; diff --git a/src/test/java/com/cybersource/inappsdk/common/utils/SDKCardUtilsTest.java b/src/test/java/com/cybersource/inappsdk/common/utils/SDKCardUtilsTest.java index 6ea8255..9800ce2 100644 --- a/src/test/java/com/cybersource/inappsdk/common/utils/SDKCardUtilsTest.java +++ b/src/test/java/com/cybersource/inappsdk/common/utils/SDKCardUtilsTest.java @@ -2,6 +2,7 @@ import com.cybersource.inappsdk.common.SDKCardBrandType; import com.cybersource.inappsdk.common.exceptions.SDKInvalidCardException; +import com.cybersource.inappsdk.common.utils.SDKCardUtils; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/com/cybersource/inappsdk/connectors/inapp/InAppSDKApiClientTest.java b/src/test/java/com/cybersource/inappsdk/connectors/inapp/InAppSDKApiClientTest.java index 9bc9e90..281fbc2 100644 --- a/src/test/java/com/cybersource/inappsdk/connectors/inapp/InAppSDKApiClientTest.java +++ b/src/test/java/com/cybersource/inappsdk/connectors/inapp/InAppSDKApiClientTest.java @@ -3,10 +3,13 @@ import android.content.Context; import android.test.mock.MockContext; +import com.cybersource.inappsdk.common.SDKCurrency; import com.cybersource.inappsdk.common.exceptions.SDKInvalidCardException; -import com.cybersource.inappsdk.datamodel.transaction.SDKTransactionObject; -import com.cybersource.inappsdk.datamodel.transaction.SDKTransactionType; +import com.cybersource.inappsdk.connectors.inapp.InAppSDKApiClient; +import com.cybersource.inappsdk.connectors.inapp.transaction.client.InAppTransaction; +import com.cybersource.inappsdk.connectors.inapp.transaction.client.InAppTransactionType; import com.cybersource.inappsdk.datamodel.transaction.fields.SDKCardData; +import com.cybersource.inappsdk.datamodel.transaction.fields.SDKPurchaseOrder; import org.junit.After; import org.junit.Assert; @@ -92,16 +95,16 @@ public void testGetEnvironment() throws Exception { assertNotNull(apiClient.getEnvironment()); } - @Test +/* @Test public void testDispose() throws Exception { InAppSDKApiClient.dispose(); assertNull(InAppGateway.getGateway()); - } + }*/ @Test public void testConnect() throws Exception { /* assertTrue(apiClient.performApi(InAppSDKApiClient.Api.API_ENCRYPTION, SDKTransactionObject. - createTransactionObject(SDKTransactionType.SDK_TRANSACTION_ENCRYPTION) // type of transaction object + createTransactionObject(SDKTransactionType.IN_APP_TRANSACTION_ENCRYPTION) // type of transaction object .merchantReferenceCode("Android_Sample_Code" + "_" + Long.toString(System.currentTimeMillis())) // you can set it to anything meaningful .cardData(prepareDummyCardData()) // card data to be encrypted .build(), "sdfskjdfs"));*/ @@ -133,10 +136,12 @@ public void testApiClientConnectThrowsNullTransactionObjectException() throws Ex } } + // ************* Encryption API Tests ************* // + @Test public void testApiClientConnectThrowsNullCardDataException() throws Exception { - SDKTransactionObject transactionObject = SDKTransactionObject. - createTransactionObject(SDKTransactionType.SDK_TRANSACTION_ENCRYPTION) // type of transaction object + InAppTransaction transactionObject = InAppTransaction. + createTransactionObject(InAppTransactionType.IN_APP_TRANSACTION_ENCRYPTION) // type of transaction object .cardData(null) // card data to be encrypted .build(); try @@ -150,10 +155,65 @@ public void testApiClientConnectThrowsNullCardDataException() throws Exception { } } + // ************* END Encryption API Tests ************* // + + // ************* Android Pay API Tests ************* // + + @Test + public void testApiClientConnectThrowsNullPurchaseOrderException() throws Exception { + InAppTransaction transactionObject = InAppTransaction. + createTransactionObject(InAppTransactionType.IN_APP_TRANSACTION_ANDROID_PAY) // type of transaction object + .purchaseOrder(null) // purchase order + .build(); + try + { + apiClient.performApi(InAppSDKApiClient.Api.API_ANDROID_PAY, transactionObject, "DUMMY_MESSAGE_SIGNATURE"); + Assert.fail("Should have thrown Null Purchase Order Exception"); + } + catch(NullPointerException e) + { + assertEquals("Missing fields: Purchase Order must not be null", e.getMessage()); + } + } + + @Test + public void testApiClientConnectThrowsNullPublicKeyException() throws Exception { + + apiClient = new InAppSDKApiClient.Builder + (context, InAppSDKApiClient.Environment.ENV_TEST, apiLoginID) + .sdkConnectionCallback(null) // receive callbacks for connection results + .publicKey(null) + .build(); + + InAppTransaction transactionObject = InAppTransaction. + createTransactionObject(InAppTransactionType.IN_APP_TRANSACTION_ANDROID_PAY) // type of transaction object + .purchaseOrder(preparePurchaseOrder()) // purchase order + .build(); + try + { + apiClient.performApi(InAppSDKApiClient.Api.API_ANDROID_PAY, transactionObject, "DUMMY_MESSAGE_SIGNATURE"); + Assert.fail("Should have thrown Null Public Key Exception"); + } + catch(NullPointerException e) + { + assertEquals("Missing fields: Public Key must not be null", e.getMessage()); + } + } + + private SDKPurchaseOrder preparePurchaseOrder(){ + SDKPurchaseOrder purchaseOrder = new SDKPurchaseOrder.Builder() + .currency(SDKCurrency.USD) + .items(null) + .build(); + return purchaseOrder; + } + + // ************* END Android Pay API Tests ************* // + @Test public void testApiClientConnectThrowsInvalidMessageSignatureException() throws Exception { - SDKTransactionObject transactionObject = SDKTransactionObject. - createTransactionObject(SDKTransactionType.SDK_TRANSACTION_ENCRYPTION) // type of transaction object + InAppTransaction transactionObject = InAppTransaction. + createTransactionObject(InAppTransactionType.IN_APP_TRANSACTION_ENCRYPTION) // type of transaction object .cardData(prepareTestCardData()) // card data to be encrypted .build(); try