Giter VIP home page Giter VIP logo

inperson-sdk-android's Introduction

Authorize.Net In-Person Android SDK Integration Guide

The In-Person SDK for Android is deprecated. The BBPOS Chipper 2X hardware is no longer available.

The Authorize.Net In-Person SDK provides a Semi-Integrated Solution for EMV payment processing. For an overview of the semi-integrated environment and the transaction workflow within that environment, see our Authorize.Net In-Person SDK Overview. This SDK builds on the Authorize.Net API for transaction processing. For more in-depth information on the Authorize.Net API, see our API Reference. For frequently asked questions, see the EMV FAQ page.

The merchant's app invokes this SDK to complete an EMV transaction. The SDK handles the complex EMV workflow and securely submits the EMV transaction to Authorize.Net for processing. The merchant's application never touches any EMV data at any point.

To determine which processor you use, you can submit an API call to getMerchantDetailsRequest. The response contains a processors object.

Point of Sale Workflow

  1. Insert the card reader.
  2. Insert a card with an EMV chip.
  3. Select the Application, if prompted. If only a compatible application resides on the card, the application is selected automatically.
  4. Confirm amount.
  5. Do not remove card until the transaction is complete.
  6. If at any time the user cancels the transaction, the EMV transaction is cancelled.

Setting Up Your Project

  1. Confirm that you are using Android Studio 2.3+ with min Android SDK version 21 and Gradle 2.14.1.
  2. Select File > Open > sampleapp to open the project.
  3. Run Sync in Gradle to bring all the dependencies up to date.
  4. Plug in the test reader and run the sample application.

SDK Overview

  1. Using the SDK to Create and Submit an EMV Transaction.
  2. Configuring the UI.
  3. Non-EMV Transaction Processing.
  4. Receipts.
  5. Reporting.
  6. OTA Update.

Using the SDK to Create and Submit an EMV Transaction

Step 1. Import the emv-anet-sdk.aar file as a library module and build.

Step2 . Authenticate the merchant's application and initialize a valid Merchant object with PasswordAuthentication. You may specify the a test environment (SANDBOX) or live environment (PRODUCTION) to use in enum Environment.

PasswordAuthentication passAuth = PasswordAuthentication.createMerchantAuthentication("Username", "Password", "In-person-sdk-tests");
Merchant merchant = Merchant.createMerchant(Environment.SANDBOX, passAuth);

Step 3. Create an EMV transaction.

EMVTransaction emvTransaction = EMVTransactionManager.createEMVTransaction(merchant, amount);

The merchant application must populate all the fields required by a standard payment transaction, as described in sample code, except the payment method. In addition, the EMVTransactionType field must be set; the default value is GOODS.

EMVTransactionType {
GOODS(0),
SERVICES(1),
CASHBACK(2),
INQUIRY(3),
TRANSFER(4),
PAYMENT(5),
REFUND(6);
}

emvTransaction.setEmvTransactionType(EMVTransactionType.GOODS);

Note: Only GOODS, SERVICES, and PAYMENT are supported.

Step 4. Submit the EMV transaction.

EMVTransactionManager.startEMVTransaction(EMVTransaction emvTransaction, final EMVTransactionListener emvTransactionListener, Context context)

EMVTransactionListener is the callback interface of the EMVTransaction object. It must be implemented by the merchant application.

public interface EMVTransactionListener {
void onEMVTransactionSuccessful(Result result);
void onEMVReadError(EMVErrorCode emvError);
void onEMVTransactionError(Result result, EMVErrorCode emvError);
}

Responses

Successful response: onEMVTransactionSuccessful

The EMV transaction was approved.

The Result object is returned to the merchant's app. The Result object contains all the values present in a regular API Result object. In addition, it has the EMV response data in a hash map. Standard EMV tag values can be used as keys to retrieve information from the hash map. For example, to retrieve application ID:

HashMap<String,String> map = result.getEmvTlvMap(); String applicationId= map.get("4f");

Server error: onEMVTransactionError

The transaction was sent to the server, but the server returned an error. For example: Session time out, insufficient balance. The Result object is returned.

EMV Error: onEMVReadError

An error occurred in collecting the EMV encrypted BLOB (Binary Large Object) from the reader. One of the following error codes is returned.

// EMV ERROR Codes
EMVErrorCode {
UNKNOWN(0),
TRANSACTION_CANCELED(1),
READER_INITIALIZATION_ERROR(2),
TIMEOUT(3),
INPUT_INVALID(4),
VOLUME_WARNING_NOT_ACCEPTED(5),
CRITICAL_LOW_BATTERY(6),
TRANSACTION_TERMINATED(7),
TRANSACTION_DECLINED(8),
UNKNOWN_READER_ERROR(9);
}

QuickChip

The In-Person SDK for Android supports Visa's Quick Chip. Here are the entry points in EMVTransactionManager:

//entry points
public static void startQuickChipTransaction(EMVTransaction emvTransaction, final QuickChipTransactionSessionListener quickChipTransactionSessionListener, Context context, boolean  showSignature, boolean isAuthOnlyTransaction)
public static void prepareDataForQuickChipTransaction(final Context context, final QuickChipTransactionSessionListener quickChipTransactionSessionListener)
public static boolean hasStoredQuickChipData()
public static void clearStoredQuickChipData(final QuickChipTransactionSessionListener quickChipTransactionSessionListener)
//interfaces
public interface QuickChipTransactionSessionListener extends EMVTransactionListener{
void onTransactionStatusUpdate(String transactionStatus);
void onPrepareQuickChipDataSuccessful();
void onPrepareQuickChipDataError(EMVErrorCode error, String cause);

//bluetooth connection callbacks
void onReturnBluetoothDevices(List<BluetoothDevice> bluetoothDeviceList);
void onBluetoothDeviceConnected(BluetoothDevice bluetoothDevice);
void onBluetoothDeviceDisConnected();
}

We support Quick Chip with UI and Quick Chip in the background.

Quick Chip with SDK-Provided UI

The startQuickChipTransaction call works in the same way as startEMVTransaction:

  1. Provide the EMVTransaction, QuickChipTransactionSessionListener objects with transaction details and callbacks.
  2. Set Context object to be the calling Android context (mostly Activity).
  3. isAuthOnlyTransaction boolean provides users with a way of doing transaction without capturing it. This can be useful if user wants to authorize for some amount and later on capture with a different one. If you do not plan to use this functionality, simply set it to false.

Here is a code example using these steps:

// Implement your app logic in the following callbacks:

EMVTransactionManager.QuickChipTransactionSessionListener iemvTransaction = new EMVTransactionManager.QuickChipTransactionSessionListener() {
@Override
public void onEMVTransactionSuccessful(net.authorize.aim.emv.Result result) {

}

@Override
public void onEMVReadError(EMVErrorCode emvError) {

}

@Override
public void onEMVTransactionError(net.authorize.aim.emv.Result result, EMVErrorCode emvError) {

}

@Override
public void onTransactionStatusUpdate(String transactionStatus) {

}

@Override
public void onPrepareQuickChipDataSuccessful() {

}

@Override
public void onPrepareQuickChipDataError(EMVErrorCode error, String cause) {

}

@Override
public void onReturnBluetoothDevices(final List<BluetoothDevice> bluetoothDeviceList) {

}

@Override
public void onBluetoothDeviceConnected(BluetoothDevice bluetoothDevice) {

}

@Override
public void onBluetoothDeviceDisConnected() {

}

};

// Construct the transaction object.

Order order = Order.createOrder();
OrderItem oi = OrderItem.createOrderItem();
oi.setItemId("1");
oi.setItemName("name");

oi.setItemQuantity("1");
oi.setItemTaxable(false);
oi.setItemDescription("desc");
oi.setItemDescription("Goods");

order.addOrderItem(oi);
BigDecimal transAmount = new BigDecimal("1.00");
oi.setItemPrice(transAmount);
order.setTotalAmount(transAmount);

// Assume AppManager.merchant is where we keep the singleton merchant object after successful authentication.

EMVTransaction emvTransaction = EMVTransactionManager.createEMVTransaction(AppManager.merchant, transAmount);
emvTransaction.setEmvTransactionType(EMVTransactionType.GOODS);
emvTransaction.setOrder(order);
emvTransaction.setSolutionID("SOLUTION ID");

// Optional fields for tip.

emvTransaction.setTableNumber("TABLE 1");
emvTransaction.setEmployeeId("EMPLOYEE 1");

// Start Quick Chip transaction with your context.

EMVTransactionManager.startQuickChipTransaction(emvTransaction, iemvTransaction, context);

Quick Chip in the Background (No UI)

To use Quick Chip without the UI component, begin the transaction by calling prepareDataForQuickChipTransaction. Here are the steps:

  1. Provide a QuickChipTransactionSessionListener object that listens to SDK status changes as it communicates with the reader. Information and error messages will be shown through QuickChipTransactionSessionListener callbacks.
  2. After a onPrepareQuickChipDataSuccessful callback, card data will be temporarily stored inside the SDK. To finish the transaction, just initiate startQuickChipTransaction with the transaction details and finish the transaction.
  3. You can check if there is any stored card data using hasStoredQuickChipData, or choose to discard that data using clearStoredQuickChipData.

Here is the code snippet for the above section:

// Create the transaction objects in the same way as start Quick Chip
// EMVTransaction emvTransaction;
// Context context;

// Prepare data for quick chip transaction.

EMVTransactionManager.prepareDataForQuickChipTransaction(context, iemvTransaction);

// Callback Methods.

EMVTransactionManager.QuickChipTransactionSessionListener iemvTransaction = new EMVTransactionManager.QuickChipTransactionSessionListener() {
@Override
public void onEMVTransactionSuccessful(net.authorize.aim.emv.Result result) {

}

@Override
public void onEMVReadError(EMVErrorCode emvError) {

}

@Override
public void onEMVTransactionError(net.authorize.aim.emv.Result result, EMVErrorCode emvError) {

}

@Override
public void onTransactionStatusUpdate(String transactionStatus) {

}

@Override
public void onPrepareQuickChipDataSuccessful() {
//should return true
EMVTransactionManager.hasStoredQuickChipData();

}

@Override
public void onPrepareQuickChipDataError(EMVErrorCode error, String cause) {
//clear data if error happens
EMVTransactionManager.clearStoredQuickChipData();
}
};

// Finish transaction by calling startQuickChipTransaction after prepareDataForQuickChipTransaction is completed.

EMVTransactionManager.startQuickChipTransaction(emvTransaction, iemvTransaction, context);

NOTE: To use Quick Chip functionality, the card reader must have the latest firmware version and configuration. Refer to the OTA Update section for more details.

Bluetooth Support

The In-Person SDK for Android now supports a Bluetooth connection mode with AnywhereCommerce Walker C2X BT readers. To enable the Bluetooth connection, follow these steps from class EMVTransactionManager:

  1. Set the connection mode to Bluetooth.
enum EMVDeviceConnectionType {
	AUDIO,
	BLUETOOTH
}
EMVTransactionManager.setDeviceConnectionType(EMVDeviceConnectionType deviceConnectionType);
  1. Start the Bluetooth scan.
EMVTransactionManager.startBTScan(Context context, QuickChipTransactionListener listener);
  1. Connect to the Bluetooth device.
EMVTransactionManager.connectBTDevice(Context context, BluetoothDevice bluetoothDevice, QuickChipTransactionListener listener);
//here the Bluetooth device needs to be imported from android.bluetooth.BluetoothDevice

NOTE: Typically the name of the Bluetooth device is on the back of the reader.

To receive the call-back from the Bluetooth device, implement the following methods in QuickChipTransactionSessionListener

void onReturnBluetoothDevices(List<BluetoothDevice> bluetoothDeviceList);
void onBluetoothDeviceConnected(BluetoothDevice bluetoothDevice);

When you receive the onBluetoothDeviceConnected callback, the connection with the Bluetooth device is successfully established and it is now safe to start EMV transaction.

  1. Start the transaction normally.
EMVTransactionManager.startEMVTransaction(EMVTransaction emvTransaction, final EMVTransactionListener emvTransactionListener, Context context)

NOTE: By default, the In-Person Android SDK will remember the last Bluetooth device that was used, so you do not need to implement this procedure for each session. However, you can reset the last used device by calling:

EMVTransactionManager.clearSavedBTDevice(Context context);

Swipe-Only Mode

When you use a AnywhereCommerce Walker C2X device, EMV/Quick Chip is turned on by default. However, you can choose to use the Magnetic Stripe Reader by calling this before the transaction:

public enum TerminalMode{
	SWIPE_ONLY,
	SWIPE_OR_INSERT
}
EMVTransactionManager.setTerminalMode(TerminalMode terminalMode);

Please contact customer support to determine the supported mode that is associated with your merchant settings.

Tips

The In-Person Android SDK supports tips functionality. Available entry points are:

// Entry points

public static void startQuickChipTransaction(EMVTransaction emvTransaction, final QuickChipTransactionSessionListener quickChipTransactionSessionListener, Context context, double tipAmount)
public static void startQuickChipTransaction(EMVTransaction emvTransaction, final QuickChipTransactionSessionListener quickChipTransactionSessionListener, Context context, TipOptions tipOptions)

// Tip options 

public static class TipOptions {
Integer tipOption1;
Integer tipOption2;
Integer tipOption3;
}

As shown in the above code, we accept two types of tip: one with exact tip amount and the other one with tip percentage that is going to be added on top of the transaction total amount. To use tip amount field, simply specify tip amount in the tipAmount field in the first call; to use tip options, create a TipOptions object with specified options and they will appear in the checkout screen for Quick Chip transactions.

Here is the code snippet for adding tip to an EMVTransaction

// Start Quick Chip with tip options.

EMVTransactionManager.startQuickChipTransaction(emvTransaction, iemvTransaction, context, new EMVTransactionManager.TipOptions(15, 18, 20));

// start Quick Chip with tip value.

EMVTransactionManager.startQuickChipTransaction(emvTransaction, iemvTransaction, context, 1.00);

// Start Quick Chip with an authorization-only transaction. Merchants can settle with different amount later.

EMVTransactionManager.startQuickChipTransaction(emvTransaction, iemvTransaction, context, true, true);

NOTE: Tips functionality is currently only valid for TSYS merchants.

Configuring the UI

You can configure the UI of the In-Person SDK to better match the UI of the merchant application. The merchant application must initialize these values only once when the application starts. If no values are set or null is set for any of the parameters, the SDK defaults to its original theme.

The merchant app can configure the following UI parameters:

SDK font color: EmvSdkUISettings.setFontColorId(R.color.black);

SDK button font color: EmvSdkUISettings.setButtonTextColor(R.color.font_green);

SDK background color: EmvSdkUISettings.setBackgroundColorId(R.color.light_blue);

Banner/top bar background color: EmvSdkUISettings.setBannerBackgroundColor(R.color.white);

For the color properties listed above, the merchant application must define color values and pass the color IDs to the In-Person SDK:

Banner/top bar image: EmvSdkUISettings.setLogoDrawableId(R.drawable.apple);

The merchant application must have a drawable file in the resource file. The drawable ID must be provided to the In-Person SDK.

SDK button color: EmvSdkUISettings.setButtonDrawableId(R.drawable.button_material_style_custom);

The merchant application must define a drawable. SDK supports state list drawables also. The merchant application must provide the drawable ID to the EMV SDK.

You can also customize the signature screen with following APIs:

Signature screen background color: EmvSdkUISettings.setSignViewBackgroundResId(R.color.white);

Signature screen background drawable: EmvSdkUISettings.setSignViewBackgroundResId(R.drawable.apple);

Signature view Border color: EmvSdkUISettings.setSignViewBorderColor(R.color.light_blue)

Signature view background color: EmvSdkUISettings.setSignCaptureBgResId(R.color.white)

Non-EMV Transaction Processing

The SDK supports the following transaction types that can be posted to Authorize.Net gateway:

/**
* The credit card transaction types supported by the payment gateway.
*/
public enum TransactionType {
AUTH_CAPTURE,
AUTH_ONLY,
PRIOR_AUTH_CAPTURE,
CAPTURE_ONLY,
TransactionType.,
UNLINKED_CREDIT,
VOID,
CASH;
}

Non-EMV Code Samples

The following code samples use keyed-in credit card information. To use another transaction type, simply replace TransactionType.AUTH_CAPTURE with the type of transaction you want (shown in the list above). For example, TransactionType.AUTH_ONLY or TransactionType.CREDIT.

//login to gateway to get valid session token
PasswordAuthentication passAuth = PasswordAuthentication.createMerchantAuthentication("Username", "Password", "InpersonSDK-Android-test");
Merchant testMerchant = Merchant.createMerchant(Environment.SANDBOX, passAuth);
testMerchant.setDeviceType(DeviceType.WIRELESS_POS);
testMerchant.setMarketType(MarketType.RETAIL);
net.authorize.aim.Transaction transaction = Transaction.createTransaction(testMerchant, TransactionType.AUTH_CAPTURE, new BigDecimal(1.0));
net.authorize.aim.Result result = (net.authorize.aim.Result)testMerchant.postTransaction(transaction);
//if login succeeded, populate session token in the Merchant object
SessionTokenAuthentication sessionTokenAuthentication = SessionTokenAuthentication.createMerchantAuthentication(testMerchant.getMerchantAuthentication().getName(), loginResult.getSessionToken(), "Test EMV Android");
if ((loginResult.getSessionToken() != null) && (sessionTokenAuthentication != null)) {
testMerchant.setMerchantAuthentication(sessionTokenAuthentication);
}

//create new credit card object with required fields
CreditCard creditCard = CreditCard.createCreditCard();
creditCard.setCreditCardNumber("4111111111111111");
creditCard.setExpirationMonth("11");
creditCard.setExpirationYear("2020");
creditCard.setCardCode("123");

//create order item and add to transaction object
Order order =  Order.createOrder();
OrderItem oi =  OrderItem.createOrderItem();
oi.setItemId("001");
oi.setItemName("testItem");
oi.setItemDescription("Goods");
oi.setItemPrice(new BigDecimal(1.1));
oi.setItemQuantity("1");
oi.setItemTaxable(false);
order.addOrderItem(oi);
order.setTotalAmount(new BigDecimal(1.1));

//post the transaction to Gateway
net.authorize.aim.Result authCaptureResult = (net.authorize.aim.Result) testMerchant.postTransaction(authCaptureTransaction);

Code Sample for Non-EMV Transactions Using Encrypted Swiper Data

//login to gateway to get valid session token
PasswordAuthentication passAuth = PasswordAuthentication.createMerchantAuthentication("Username", "Password", "InpersonSDK-Android-test");
Merchant testMerchant = Merchant.createMerchant(Environment.SANDBOX, passAuth);
testMerchant.setDeviceType(DeviceType.WIRELESS_POS);
testMerchant.setMarketType(MarketType.RETAIL);
net.authorize.aim.Transaction transaction = Transaction.createTransaction(testMerchant, TransactionType.AUTH_CAPTURE, new BigDecimal(1.0));
net.authorize.aim.Result result = (net.authorize.aim.Result)testMerchant.postTransaction(transaction);
//if login succeeded, populate session token in the Merchant object
SessionTokenAuthentication sessionTokenAuthentication = SessionTokenAuthentication.createMerchantAuthentication(testMerchant.getMerchantAuthentication().getName(), loginResult.getSessionToken(), "Test EMV Android");
if ((loginResult.getSessionToken() != null) && (sessionTokenAuthentication != null)) {
testMerchant.setMerchantAuthentication(sessionTokenAuthentication);
}

//create new credit card object and populate it with the encrypted card data coming from the reader
CreditCard creditCard = CreditCard.createCreditCard();
creditCard.setCardPresenseType(net.authorize.data.creditcard.CreditCardPresenceType.CARD_PRESENT_ENCRYPTED);
creditCard.getSwipperData().setMode(SwiperModeType.DATA);
//the following field is the data converted into HEX string coming from the reader
creditCard.getSwipperData().setEncryptedData(IDtechTestBlob);
//the FID for the reader
creditCard.getSwipperData().setDeviceInfo("4649443d4944544543482e556e694d61672e416e64726f69642e53646b7631");
//the Encryption method used by the reader, should be TDES for IDTech
creditCard.getSwipperData().setEncryptionAlgorithm(SwiperEncryptionAlgorithmType.TDES);

//create order item and add to transaction object
Order order =  Order.createOrder();
OrderItem oi =  OrderItem.createOrderItem();
oi.setItemId("001");
oi.setItemName("testItem");
oi.setItemDescription("Goods");
oi.setItemPrice(new BigDecimal(1.1));
oi.setItemQuantity("1");
oi.setItemTaxable(false);
order.addOrderItem(oi);
order.setTotalAmount(new BigDecimal(1.1));

//post the transaction to Gateway
net.authorize.aim.Result authCaptureResult = (net.authorize.aim.Result) testMerchant.postTransaction(authCaptureTransaction);

NOTE: For Non-EMV transaction processing, there is no UI provided by the SDK. The client application is expected to have its own layout and display the response/error message properly.

Fore more details on the supported API call accepted by Authorize.Net gateway, please refer to our Authorize.Net API Documentation.

Creating a Customer Profiles from a Transaction

You can use the information that you capture during a transaction to create a customer profile. The process differs depending on whether you use the provided UI or your own UI.

Creating a Profile Using Your Own UI

The transaction response contains a transaction ID. To create a customer profile, send the transaction ID and the customer profile details taken as input from the customer. Send the Boolean value which decides whether the consent for creating profile is to be taken before or after the transaction. The following example assumes that you use your own UI.

Method Call

//Create customer profile object.
CustomerProfile customerProfile = CustomerProfile.createCustomerProfile(); 
customerProfile.setEmail(email); 
customerProfile.setMerchantCustomerId(merchantCustomerId); 
customerProfile.setDescription(description);
//Create payment profile object.
PaymentProfile paymentProfile = PaymentProfile.createPaymentProfile();
Address address = Address.createAddress(); 
address.setFirstName("abc); 
address.setLastName("def"); 
address.setCity("New york"); 
address.setState("CA"); 
address.setCountry("USA"); 
address.setZipPostalCode("94585"); 
address.setCompany("lmn");
address.setPhoneNumber("02014585485"); 
address.setAddress(Mt street); 
address.setFaxNumber("857458547965);
paymentProfile.setBillTo(address);
// Implement the profile transaction listener which is overridden from QuickChipTransactionSessionListener and send its object as an input parameter.

final EMVTransactionManager.ProfileTransactionListener profileTransactionListener = new EMVTransactionManager.ProfileTransactionListener() {
@Override  public void onTransactionStatusUpdate(String transactionStatus) {}
@Override  public void onPrepareQuickChipDataSuccessful() {}
@Override  public void onPrepareQuickChipDataError(EMVErrorCode error, String cause) {}
@Override  public void onReturnBluetoothDevices(List<BluetoothDevice> bluetoothDeviceList) {}
@Override  public void onBluetoothDeviceConnected(BluetoothDevice bluetoothDevice) {}
@Override  public void onBluetoothDeviceDisConnected() {}
@Override  public void onProfileEMVTransactionSuccessful(net.authorize.aim.emv.Result emvResult,net.authorize.cim.Result custProfileResult) { } 
@Override  public void onProfileTransactionSuccessful(net.authorize.cim.Result result) {}
@Override  public void onEMVTransactionSuccessful(net.authorize.aim.emv.Result result) {}
@Override  public void onEMVReadError(EMVErrorCode emvError) {}
@Override  public void onEMVTransactionError(net.authorize.aim.emv.Result result, EMVErrorCode emvError) {}
public void onProfileEMVTransactionError(final String message,final Exception e, net.authorize.aim.emv.Result result) {}
public void onProfileTransactionError(String errorMessage, Exception e) {}
@Override  public void onProfileTransactionStarted(String message) {}
};
//Call the provided API for creating customer profile as below:

ProfileTransactionManager.getInstance().createCustomerProfileFromTransaction(context, AppManager.merchant, transactionId, customerProfile,paymentProfile, profileTransactionListener);

Method Details

/**
 * @param context: Android component context.
 * @param merchant: Merchant object.
 * @param transactionId: Transaction ID from which user want to create profile.
 * @param customerProfile: Customer profile details object like email, merchant customer ID or description.
 * @param paymentProfile: PaymentProfile profile details objects, such as billing address.
 * @param profileTransactionListener: An interface callback to receive the result after transaction is completed.
*/
 
public void createCustomerProfileFromTransaction(final Context context, final Merchant merchant, String transactionId,final CustomerProfile  customerProfile, final PaymentProfile paymentProfile, final EMVTransactionManager.ProfileTransactionListener profileTransactionListener)

Creating a Profile Using the Included UI

When you create a profile using the included UI, the customer profile is created as soon as the transaction is done. Send the customer profile and payment profile objects with the EMV transaction object while creating the transaction. The transaction is completed the transaction UI is used to create the customer profile within SDK itself. The SDK provides the UI for collecting customer information. When the profile is created, both the payment transaction result and the profile result objects are sent simultaneously to the calling application.

Method Call

//Create customer profile object.
CustomerProfile customerProfile = CustomerProfile.createCustomerProfile(); 
customerProfile.setEmail(email); 
customerProfile.setMerchantCustomerId(merchantCustomerId); 
customerProfile.setDescription(description);
//Create payment profile object.
PaymentProfile paymentProfile = PaymentProfile.createPaymentProfile();
Address address = Address.createAddress(); 
address.setFirstName("abc); 
address.setLastName("def"); 
address.setCity("New york"); 
address.setState("CA"); 
address.setCountry("USA"); 
address.setZipPostalCode("94585"); 
address.setCompany("lmn");
address.setPhoneNumber("02014585485"); 
address.setAddress(Mt street); 
address.setFaxNumber("857458547965);
paymentProfile.setBillTo(address);
// Implement the profile transaction listener which is overridden from QuickChipTransactionSessionListener and send its object as an input parameter.

final EMVTransactionManager.ProfileTransactionListener profileTransactionListener = new EMVTransactionManager.ProfileTransactionListener() {
@Override  public void onTransactionStatusUpdate(String transactionStatus) {}
@Override  public void onPrepareQuickChipDataSuccessful() {}
@Override  public void onPrepareQuickChipDataError(EMVErrorCode error, String cause) {}
@Override  public void onReturnBluetoothDevices(List<BluetoothDevice> bluetoothDeviceList) {}
@Override  public void onBluetoothDeviceConnected(BluetoothDevice bluetoothDevice) {}
@Override  public void onBluetoothDeviceDisConnected() {}
@Override  public void onProfileEMVTransactionSuccessful(net.authorize.aim.emv.Result emvResult,net.authorize.cim.Result custProfileResult) { } 
@Override  public void onProfileTransactionSuccessful(net.authorize.cim.Result result) {}
@Override  public void onEMVTransactionSuccessful(net.authorize.aim.emv.Result result) {}
@Override  public void onEMVReadError(EMVErrorCode emvError) {}
@Override  public void onEMVTransactionError(net.authorize.aim.emv.Result result, EMVErrorCode emvError) {}
public void onProfileEMVTransactionError(final String message,final Exception e, net.authorize.aim.emv.Result result) {}
public void onProfileTransactionError(String errorMessage, Exception e) {}
@Override  public void onProfileTransactionStarted(String message) {}
};
EMVTransactionManager.createCustomerProfileHeadFul(emvTransaction, context, true, IS_BEFORE, profileTransactionListener);

Method Details

 /**
* @param emvTransaction: Details for creating transaction ie amount etc. 
* @param context: Android component context
* @param showSignature: to show signature or not
* @param isConsentBefore: This is related to taking user consent before payment transaction or after payment transaction.
* @param profileEMVTransactionListener: An interface callback to receive the result after transaction is completed
*/
public static void createCustomerProfileHeadFul(EMVTransaction emvTransaction, Context context, boolean showSignature,
boolean isConsentBefore, final ProfileTransactionListener profileEMVTransactionListener)

Creating an Additional Payment from a Transaction Using Your Own UI

After the transaction is completed, you can create an additional payment. Send the payment details object (with details such as billing address), customer profile ID, and the transaction ID of the previous transaction to the SDK. You must create customized UI to collect the customer data.

Method Call

//Create payment profile object.
PaymentProfile paymentProfile = PaymentProfile.createPaymentProfile();
Address address = Address.createAddress(); 
address.setFirstName("abc); 
address.setLastName("def"); 
address.setCity("New york"); 
address.setState("CA"); 
address.setCountry("USA"); 
address.setZipPostalCode("94585"); 
address.setCompany("lmn");
address.setPhoneNumber("02014585485"); 
address.setAddress(Mt street); 
address.setFaxNumber("857458547965);
paymentProfile.setBillTo(address);
// Implement the profile transaction listener which is overridden from QuickChipTransactionSessionListener and send its object as an input parameter.

final EMVTransactionManager.ProfileTransactionListener profileTransactionListener = new EMVTransactionManager.ProfileTransactionListener() {
@Override  public void onTransactionStatusUpdate(String transactionStatus) {}
@Override  public void onPrepareQuickChipDataSuccessful() {}
@Override  public void onPrepareQuickChipDataError(EMVErrorCode error, String cause) {}
@Override  public void onReturnBluetoothDevices(List<BluetoothDevice> bluetoothDeviceList) {}
@Override  public void onBluetoothDeviceConnected(BluetoothDevice bluetoothDevice) {}
@Override  public void onBluetoothDeviceDisConnected() {}
@Override  public void onProfileEMVTransactionSuccessful(net.authorize.aim.emv.Result emvResult,net.authorize.cim.Result custProfileResult) { } 
@Override  public void onProfileTransactionSuccessful(net.authorize.cim.Result result) {}
@Override  public void onEMVTransactionSuccessful(net.authorize.aim.emv.Result result) {}
@Override  public void onEMVReadError(EMVErrorCode emvError) {}
@Override  public void onEMVTransactionError(net.authorize.aim.emv.Result result, EMVErrorCode emvError) {}
public void onProfileEMVTransactionError(final String message,final Exception e, net.authorize.aim.emv.Result result) {}
public void onProfileTransactionError(String errorMessage, Exception e) {}
@Override  public void onProfileTransactionStarted(String message) {}
 };
ProfileTransactionManager.getInstance().createAdditionalPaymentProfile(profileId, transactionId, AppManager.merchant, context, paymentProfile, profileTransactionListener);

Method Details

/**
	* @param profileId: Profile id for which user want to create additional payment profile
	* @param transactionId: Transaction id from which the payment profile is to be created.
	* @param merchant: Logged in Merchant object.
	* @param context: Android component context.
	* @param paymentProfile: Payment profile details object.
	* @param profileTransactionListener: An interface callback to receive the result after transaction is completed
*/
public void createAdditionalPaymentProfile(String profileId, String transactionId, Merchant merchant, Context context, PaymentProfile paymentProfile, final EMVTransactionManager.ProfileTransactionListener profileTransactionListener){final ResultReceiver resultReceiver = new ResultReceiver(new Handler())

Creating an Additional Payment from a Transaction Using the Included UI

To create additional payment profiles, the user has to send the customer profile id with the emv transaction object while submitting the transaction.

// Implement the profile transaction listener which is overridden from QuickChipTransactionSessionListener and send its object as an input parameter.

final EMVTransactionManager.ProfileTransactionListener profileTransactionListener = new EMVTransactionManager.ProfileTransactionListener() {
@Override  public void onTransactionStatusUpdate(String transactionStatus) {}
@Override  public void onPrepareQuickChipDataSuccessful() {}
@Override  public void onPrepareQuickChipDataError(EMVErrorCode error, String cause) {}
@Override  public void onReturnBluetoothDevices(List<BluetoothDevice> bluetoothDeviceList) {}
@Override  public void onBluetoothDeviceConnected(BluetoothDevice bluetoothDevice) {}
@Override  public void onBluetoothDeviceDisConnected() {}
@Override  public void onProfileEMVTransactionSuccessful(net.authorize.aim.emv.Result emvResult,net.authorize.cim.Result custProfileResult) { } 
@Override  public void onProfileTransactionSuccessful(net.authorize.cim.Result result) {}
@Override  public void onEMVTransactionSuccessful(net.authorize.aim.emv.Result result) {}
@Override  public void onEMVReadError(EMVErrorCode emvError) {}
@Override  public void onEMVTransactionError(net.authorize.aim.emv.Result result, EMVErrorCode emvError) {}
public void onProfileEMVTransactionError(final String message,final Exception e, net.authorize.aim.emv.Result result) {}
public void onProfileTransactionError(String errorMessage, Exception e) {}
@Override  public void onProfileTransactionStarted(String message) {}
 };
EMVTransactionManager.createAdditionalPaymentProfileHeadFul(emvTransaction, context, true, IS_BEFORE,profileTransactionListener, customerProfileId);

Method Details

/**
* @param emvTransaction
* @param context
* @param showSignature
* @param isBefore
* @param profileEMVTransactionListener
* @param profileId: Application just has to send the profile id. Payment profile input is taken in the sdk UI.
*/

```java
public static void createAdditionalPaymentProfileHeadFul(EMVTransaction emvTransaction, Context context, boolean showSignature, boolean isBefore, final ProfileTransactionListener profileEMVTransactionListener, String profileId)

Customer Email Receipt

To send the customer a transaction receipt, create a notification transaction and post it to the Authorize.Net gateway. Here is a code sample:

//assume we have MerchantContact Object that stores merchant contact info
MerchantContact contact = getMerchantContact();
if (contact != null) {
StringBuilder sb = new StringBuilder();
if (StringUtils.isNotEmpty(contact.getCompanyName())) {
sb.append(contact.getCompanyName());
}
sb.append("<br/>");
if (StringUtils.isNotEmpty(contact.getAddress())) {
sb.append(contact.getAddress());
}
sb.append("<br/>");
if (StringUtils.isNotEmpty(contact.getCity())) {
sb.append(contact.getCity());
sb.append(", ");
}
if (StringUtils.isNotEmpty(contact.getState())) {
sb.append(contact.getState());
sb.append(" ");
}
if (StringUtils.isNotEmpty(contact.getZip())) {
sb.append(contact.getZip());

}
sb.append("<br/>");
if (StringUtils.isNotEmpty(contact.getPhone())) {
sb.append(contact.getPhone());
}

er.setHeaderEmailReceipt(sb.toString());
}
net.authorize.notification.Transaction t = testMerchant.createNotificationTransaction(net.authorize.notification.TransactionType.CUSTOMER_TRANSACTION_RECEIPT_EMAIL, er);
t.setTransId(transactionId);
t.setCustomerEmailAddress(emailId);
net.authorize.notification.Result result = (net.authorize.notification.Result) testMerchant.postTransaction(t);
//result object has all the result coming from Anet gateway

NOTE: For other supported notification transaction types, refer to the Transaction and Result object in the net.authorize.notification package.

Reporting

Here is the list of supported transaction types for transaction reporting:

GET_SETTLED_BATCH_LIST,
GET_TRANSACTION_LIST,
GET_TRANSACTION_DETAILS,
GET_BATCH_STATISTICS,
GET_UNSETTLED_TRANSACTION_LIST;
GET_SETTLED_BATCH_LIST,
GET_TRANSACTION_LIST,
GET_TRANSACTION_DETAILS,
GET_BATCH_STATISTICS,
GET_UNSETTLED_TRANSACTION_LIST;

These transaction types follow the identical format for posting to Authorize.Net gateway as a payment transaction. For example, here is the code sample for GET_UNSETTLED_TRANSACTION_LIST:

net.authorize.reporting.Result result = null;
net.authorize.reporting.Transaction t = testMerchant.createReportingTransaction(net.authorize.reporting.TransactionType.GET_UNSETTLED_TRANSACTION_LIST);
t.setReportingDetails(ReportingDetails.createReportingDetails());
result = (net.authorize.reporting.Result) AnetHelper.merchant.postTransaction(t);
//you can check reporting details in the ReportingDetails object returned by result.getReportingDetails()

To use other report types, simply change TransactionType to other enum values.

NOTE: For other supported transaction types, refer to the Transaction and Result object in the net.authorize.notification package.

OTA Updates

The In-Person Android SDK has the ability to do an Over-The-Air update for AnywhereCommerce Walker C2X magstripe and chip reader. To use this functionality, initiate the following SDK call:

public static void startOTAUpdate(Context context, boolean demoMode)

where context is the calling Android Context and demoMode is for setting the update to be going to either a demo server or a production server.

In the OTA update page, you have the option to do firmware update, config update, or both. In the option menu, you may get detailed info for the reader that you are currently using.

NOTE: OTA update may take up to 30 min to finish, please make sure reader is fully charged and do not unplug reader while updating.

Error Codes

You can view these error messages at our Reason Response Code Tool by entering the Response Reason Code into the tool. There will be additional information and suggestions there.

Field Order Response Code Response Reason Code Text
3 2 355 An error occurred during the parsing of the EMV data.
3 2 356 EMV-based transactions are not currently supported for this processor and card type.
3 2 357 Opaque Descriptor is required.
3 2 358 EMV data is not supported with this transaction type.
3 2 359 EMV data is not supported with this market type.
3 2 360 An error occurred during the decryption of the EMV data.
3 2 361 The EMV version is invalid.
3 2 362 x_emv_version is required.

Auto Configuration of Audio Readers

Android hardware varies between different manufacturers, and there is a possibility that default audio configuration does not work in all Android devices. For audio jack readers, if we check reader information by getDeviceInfo() API, and the error returned is OTAUpdateManager.HeadlessOTAUpdateError.COMM_ERROR, this implies that default configuration are not working for the attached reader and auto configuration is required to setup it up.

The following API from OTAUpdateManager can be used to start auto configuration:

public static void startAutoConfig(Context context, boolean demoMode, HeadlessOTAUpdateListener listener)

The following interface methods have been added to HeadlessOTAUpdateListener to monitor and update configuration process:

1- void onAudioAutoConfigProgressUpdate(double var1); Return the auto configuration progress in percentage.

2- void onAudioAutoConfigCompleted(boolean isDefaultSettings, String autoConfigSettings); The auto configuration completed. If it is not default settings, the auto configuration settings are returned.

3- void onAudioAutoConfigError(AudioAutoConfigError error); The auto config resulted in some error.

Apart from the three additions to HeadlessOTAUpdateListener for auto configuration, shown above, another interface method is added to notify when bluetooth device gets disconnected.

4- void onBluetoothDeviceDisConnected(); Bluetooth device got disconnected.

At anytime if it is required to cancel the auto configuration, use following API from OTAUpdateManager -

`public static void cancelAutoConfig(Context context, boolean demoMode, HeadlessOTAUpdateListener listener)`

inperson-sdk-android's People

Contributors

amimishr avatar brianmc avatar fezzubair avatar hpreslier avatar ncpga avatar ptaneja avatar scopelan avatar triciasfu avatar ywang7 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

inperson-sdk-android's Issues

An error occurred while decrypting the EMV data.

So I'm trying to access the sdk to make payments. I've been able to login to the sandbox account created at Authorize.Net and the same login are used in this demo app.

But when I try to make a payment I'm getting the following data.

emv data error

Please note that I'm using the AnywhereCommerce C2X EMV Chip Reader to make the transaction.

Please help me in finding out the issue. Any help would be appreciated. Thanks!

Evm Read Error Transaction Declined

I have tested the app in three different devices and getting the below error:
One plus: Transaction always successful
Moto G2: First transaction and continuous second transaction get declined.
Samsung Galaxy S7Edge: Always give the device timeout issue.

How can I resolve this

E00003: Invalid character in the given encoding

I get this error when sending '®' in the OrderItem's name or description. I cannot find a way to specify the encoding of the XML via the SDK. The generated XML always starts with <?xml version="1.0"?>... without any encoding (when I print it with request.toAuthNetPOSTString()).

Is there a way to set the encoding?
Is this a bug on the server side or in the SDK?

//cc @rhldr

TRANSACTION_DECLINED even tho network transaction reports success

Hey

we are using a chip reader from your device loaner program and android in-person SDK.
During development we have noticed a strange SDK behavior, which we would prefer to clear up before going to production.

As mentioned here http://forms.authorize.net/emvDeviceLoanerProgram we only use Visa cards for sandbox requests.

What we have observed is that with the vast majority of Visa cards the first web request the in-person sdk attempts is reported as TRANSACTION_DECLINED in our EMVTransactionListener. onEMVReadError callback, although when we inspect the app network traffic, we can see that the authOnlyTransaction was a success, we get the email receipt, and the transaction is visible in the sandbox website unsettled transactions
list.

We have found some Visa cards that work with no problem, but have no idea what makes them special.

Transaction with transactionId: 60021414341 on sandbox API is an example of the transaction which was a success, but the in-person SDK reported it as a failure.

What may cause the difference in status reported from API and in-person sdk?

Appreciate your help!

Crash on android version 5.0

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.VerifyError: Rejecting class net.authorize.AuthNetField because it failed compile-time verification (declaration of 'net.authorize.AuthNetField' appears in /data/app/com.successive.logicspaybill-1/base.apk)
at net.authorize.xml.XMLTransaction.addAuthentication(:66)
at net.authorize.xml.XMLTransaction.addAuthentication(:55)
at net.authorize.mobile.Transaction.toAuthNetPOSTString(:2142)
at net.authorize.util.HttpClient.ˏ(:79)
at net.authorize.util.HttpClient.executeXML(:280)
at net.authorize.Merchant.postTransaction(:416)
at com.successive.logicspaybill.async.LoginAsync.doInBackground(LoginAsync.java:132)
at com.successive.logicspaybill.async.LoginAsync.doInBackground(LoginAsync.java:32)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:818) 
10-08 10:22:15.859 6386-6451/com.successive.logicspaybill E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.successive.logicspaybill, PID: 6386
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.VerifyError: Rejecting class net.authorize.AuthNetField because it failed compile-time verification (declaration of 'net.authorize.AuthNetField' appears in /data/app/com.successive.logicspaybill-1/base.apk)
at net.authorize.xml.XMLTransaction.addAuthentication(:66)
at net.authorize.xml.XMLTransaction.addAuthentication(:55)
at net.authorize.mobile.Transaction.toAuthNetPOSTString(:2142)
at net.authorize.util.HttpClient.ˏ(:79)
at net.authorize.util.HttpClient.executeXML(:280)
at net.authorize.Merchant.postTransaction(:416)
at com.successive.logicspaybill.async.LoginAsync.doInBackground(LoginAsync.java:132)
at com.successive.logicspaybill.async.LoginAsync.doInBackground(LoginAsync.java:32)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:818) 
10-08 10:22:16.331 6386-6386/com.successive.logicspaybill E/WindowManager: android.view.WindowLeaked: Activity com.successive.logicspaybill.activities.LoginActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{21cd8156 V.E..... R......D 0,0-576,116} that was originally added here
at android.view.ViewRootImpl.(ViewRootImpl.java:363)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:261)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.app.Dialog.show(Dialog.java:298)
at com.successive.logicspaybill.async.LoginAsync.onPreExecute(LoginAsync.java:63)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
at android.os.AsyncTask.execute(AsyncTask.java:535)
at com.successive.logicspaybill.activities.LoginActivity$1.onClick(LoginActivity.java:79)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Device timeout issue.

If the card reader device remains connected to mobile then after one or two successful transactions it gives the timeout error.
How to resolve this?

Implement Payment for End user in Native Android/iOS App

Hello, We are using inperson-sdk-android/iOS and Accept-sdk-android/iOS for Implementing payment Process for Bank Transfer and Credit Card. Please note that we are using Payment Process in Mobile Application in Android/iOS. Is it possible that End User from any where in the World perform Transaction using Authorize.Net in Native Android/iOS Application ?
Can you suggest which sdk we can use for Payment Process ? If possible can you please provide Demo for End User Payment Process ?

Sample Blob not working (KSN is duplicated)

Hi,

While using the sample blob 02e300801f3d23008383252a343736312a2a2a2a2a2a2a2a303037365e4341524420372f5649534120544553545e313731322a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3f2a3b343736312a2a2a2a2a2a2a2a303037363d313731322a2a2a2a2a2a2a2a2a2a2a3f2abdc6bf66f166e542230f16ded5c9d777aceb532e93a34f719a74bb82f10a26ed8492c1e19cd30aaaa366ad4ddc89996b31e0a08293f4048472f7e85019172be48e7fe9b1e8a46ecb740cf2d7e8e2cd2d56b89e693389bf7882286c1454817ded39da65002686d30f34313754303238373430629949010020002002aabf3b03 we are getting the KSN is duplicate error. Please let me know why we are getting this error.
OR send me another blob on my email-id([email protected]) or reply it over here

Thanks
Pawan

Getting Error E00007 - User authentication failed due to invalid authentication values

I keep receiving this error when I try to complete a transaction. I've looked into the sample app code and do not see any part where they specify a transaction key or api login ID when completing the transaction. Am I missing something or does the inperson sdk not need that specified?

And if the inperson sdk doesn't need that specified, any hints as to why I could be receiving that error?

Thanks!

Is it possible to trim the extra libs?

My concern is over the logging and junit libs included in this project. Considering the low method count limit on Android it would be preferable to not include the libs especially on production builds. Is it possible to build jars not requiring these extra libs?

Sanbox login issue

In This code when I try to login with my sandbox credentials it is not allowing me to login. there is one "LoginActivity.java" file which contains "deviceID" field. i don't know from where to get this device id. There is one comment as well like "set your_device_ID. You need to get a registered device id from your MINT account and set the id here"

so my question is what is MINT Account? is there any other parameters we need to set?

Payment issue

During the payment when i insert the credit card in the card reader and it displays "processing..." for some seconds, then it leads me to a signature screen where i need to sign it in order to proceed with the payment. When i sign it and hit the "Authorize" button it displays "processing" and then it returns to the main menu screen without displaying any errors. The transation is not made and doesn't enter to Authorize's panel. What could it possibly be?

Unkown Device Error

I have purchased a Anywhere Commerce Walker C2X reader from the Authorize.net POSPortal.
I have downloaded the demo InPerson EMV app called "sampleapp" from GitHub. I already have an Authorize.net account and have tied the sampleapp to my gateway mobile devices. The device is enable in the Authorize.net back office.
I have no problem logging into the Authorize.net account and obtaining a session token.
When I enter an amount to perform an EMV transaction and press Process Payment, I get a EMV Status, Unknown Device Error. It appears the demo app is not able to communicate with the reader. I am using a Samsung Galaxy Tab A 9.7" tablet which is not an approved device but I have also tried this on a Galaxy Tab E 9.6" tablet with the same result (also not approved).
Has anyone seen this, has any one been able to get their Walker C2x to work on a Galaxy Tab A or E tablet?

How to Login using login Id and Transaction Key ?

Hello,

Currently, I have used Password authentication using the below code.
PasswordAuthentication passAuth = PasswordAuthentication .createMerchantAuthentication(loginId,password, deviceID);

but need to log in using the login Id and Transaction key it is possible using this SDK ?

I have tried the below code :
TransactionKeyAuthentication auth = TransactionKeyAuthentication.createMerchantAuthentication(loginId,transactionkey);

Thanks.

unable to import in eclipse

hi
i am unable to import sdk in eclipse ,its contain sample app which get imported whenever i try to add sdk in eclipse ,please provide me steps.

How to detect user has swiped and now request for payment Authorize.net

I need to process payment using credit card swiper(Like AnywhereCommerce) but I'm not able to understand that how do i know that user has swiped credit card and now i have to request for payment to authorize.net(i.e to call EMVTransactionManager.startEMVTransaction(emvTransaction, this, activity);)

To detect swipe is there any callback method ? if yes then what is the name of that method and how do i use it?

Please guid me guys.

Standard emv tag value

The Result object is returned to the merchant's app. The Result object contains all the values present in a regular API Result object. In addition, it has the EMV response data in a hash map. Standard EMV tag values can be used as keys to retrieve information from the hash map. For example, to retrieve application ID:

HashMap<String,String> map = result.getEmvTlvMap(); String applicationId= map.get("4f");

Where I can see the all map key map list.
And what is the key 9f10.
I always get the value of 9f10 same i.e. 06010A03A0A002, Can you tell me why?
Any help would be appreciated. :)

MSR Head Card Swipe payment Info

AuthorizeNet/inperson-sdk-android => got error like java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.bbpos.emvswipe.ui/settings.txt: open failed: ENOENT (No such file or directory)

we want to use authorize.net sdk in Android application but didn't get any working sample application(demo).
so need your help how to use authorize.net for American Express ,Discover ,JCB ,Diners Club/ Carte Blanch ,Visa ,Master Card and on-line bank transaction so need your help devlope authorize.net sdk in our app for payment.

so we need your help for use authorize.net sdk in our app. which sdk is better AuthorizeNet/inperson-sdk-android or AuthorizeNet/accept-sample-android ? please provide any working sample code (demo)

Also, we are able to see transaction amount and cancel transaction button , in centre of UI we have status textbox but its not changing.Let us know what we need to do here.

Please help us

AnywhereCommerce Walker C2X Tap to pay

We're using the AnywhereCommerce Walker C2X and see that there are only swipe and insert available:
public enum TerminalMode{ SWIPE_ONLY, SWIPE_OR_INSERT }
Is there a plan to support tap to pay or is that available some way that I'm not seeing?

Transaction Reporting

Has anyone done more detailed transaction reporting than what the sample app does in the inperson-sdk-android? I'd like to show more than just the last transaction. For example I'd like to be able to give the user options to see all unsettled transactions or a list of the most recent transactions.

I've seen examples for this in the other authorize.net sdks but I'm not sure how to implement it in the inperson sdk. Does anyone have any tips to help me get started?

Customizing SDK Provided Screens

The SDK handled screens show lack of details. It becomes difficult for users to understand the app flow. Please take a look at the questions below.

signaturescreen
In the above screen the text - "Please Sign", "Cancel" and "Clear" are really small when opened in a Tablet device. I did not find any method to increase text size. We only have parameters to change color and font. Is there any way to increase font size? Please assist.

swipescreen

In the above screen, we wanted to change the text to "Please Insert Chip/Swipe". Is there any possibility to change the text?

Please let me know if these can be handled. Thanks in advance.

Device timeout after 1st successful transaction

Hi, i am facing problem with card reader which only success for first transaction. After that the card reader keep flashing with different colors and my app could not connect to it (Device time out). I have not figured out why this happens. I am using in-person Android sdk and it also happen with the demo as well. Any help would appreciate. I am in rush of fisnishing my company app. Thanks

Hi,

Hi, i am facing problem with card reader which only success for first transaction. After that the card reader keep flashing with different colors and my app could not connect to it (Device time out). I have not figured out why this happens. I am using in-person Android sdk and it also happen with the demo as well. Any help would appreciate. I am in rush of fisnishing my company app. Thanks

Problems migrating to AndroidX

After migrating my project to AndroidX it no longer compiles. I also tried migrating the SDK sample App and same thing happens, it doesn't compile. I got this error:

ERROR: Unable to resolve dependency for ':app@release/compileClasspath': Failed to transform file 'emv-anet-sdk.aar' to match attributes {artifactType=processed-aar} using transform JetifyTransform
Show Details
Affected Modules: app

thanks

How to get terminal ID

How can I get the terminal id in the response?
In the autherize.net merchant account, I can see the terminal number in the transaction.

Below is the result from the SDK after the successful transaction

Account Number: XXXX5887
Account Type: VISA
Auth Code: 026454
Authorized Amount :$1.00
CAVV Result Code :NOT_VALIDATED
Entry Mode: Chip Read
Transaction ID: 41003423119
Transaction Hash: 2CE44C1A083F83C499F124CAAB328F54
Transaction Type:AUTH_ONLY
Response Code: APPROVED
Result Code:APPROVED
XML Response:
OkI00001Successful.oZQ8zGzlXwdM7fZPEinAVNzgaOFBLadJTkRSLTn89v0cXNgh_GuQYZHhyzifzERINRMyYZ9MpbrkybvdzioWxzefhuWqzmZiDYtg7wax$9AZWig1uMlnTYgGkkDuRjj7d5reFW4F3rVoGKJ1WyK2HgAA1026454PP410034231192CE44C1A083F83C499F124CAAB328F540XXXX5887Chip ReadVisa1This transaction has been approved.4F07A0000000031010500B56697361204372656469748A023030910A62660196DC7CDF993030950500800080009B02E8009F100706010A03A0A0024FA0000000031010505669736120437265646974Visa Credit8A3030009162660196DC7CDF9930309500800080009BE8009F1006010A03A0A002

onPrepareQuickChipDataSuccessful not firing

I'm attempting to implement this without the UI according to the instructions. This is my code:

    val l = object : EMVTransactionManager.QuickChipTransactionSessionListener {
      override fun onReturnBluetoothDevices(bluetoothDeviceList: List<BluetoothDevice>) {
      }

      override fun onBluetoothDeviceConnected(bluetoothDevice: BluetoothDevice) {
      }

      override fun onBluetoothDeviceDisConnected() {
      }

      override fun onTransactionStatusUpdate(transactionStatus: String) {
        sendMessage("Transaction Status Update: ${transactionStatus}")
      }

      override fun onPrepareQuickChipDataSuccessful() {
        sendMessage("Chip data saved Successfully")
      }

      override fun onPrepareQuickChipDataError(error: EMVErrorCode, cause: String) {
        sendMessage("onPrepareQuickChipDataError")
        sendMessage(cause)
      }

      override fun onEMVTransactionSuccessful(result: net.authorize.aim.emv.Result) {
      }

      override fun onEMVReadError(emvError: EMVErrorCode) {
        if (emvError != null) {
          sendMessage("EMV Error: ${emvError.errorString}")
        } else sendMessage("EMV Error")
        promise.reject("EMV Read Error", emvError.errorString);
      }

      override fun onEMVTransactionError(result: net.authorize.aim.emv.Result, emvError: EMVErrorCode) {
        sendMessage("onEMVTransactionError")
      }
    }
    
    EMVTransactionManager.prepareDataForQuickChipTransaction(context, l)

I get the message Transaction Status Update: Waiting for device... from the onTransactionStatusUpdate event but never get anything from either onPrepareQuickChipDataSuccessful or onPrepareQuickChipDataError. I've inserted the card into the device and waited for an extended period of time.

I do not see this actually used in the sample app anywhere. Does this work and what might I be doing wrong?

Standard EMV tag key mapping

The Result object is returned to the merchant's app. The Result object contains all the values present in a regular API Result object. In addition, it has the EMV response data in a hash map. Standard EMV tag values can be used as keys to retrieve information from the hash map. For example, to retrieve application ID:

HashMap<String,String> map = result.getEmvTlvMap(); String applicationId= map.get("4f");

Where I can see the all map key map list.
And what is the key 9f10.
I always get the value of 9f10 same i.e. 06010A03A0A002, Can you tell me why?
Any help would be appreciated. :)

Getting error when trying to use httpclient dependency

I am getting an error that says "httpclient defines classes that conflict with classes now provided by Android. Solutions include finding newer versions or alternative libraries that don't have the same problem."

I've tried adding "use Library 'org.apache.http.legacy" in my build.gradle file to fix it but it isn't working. Has anyone else found an alternative to using this dependency or found any other solution?

Here is my build.gradle code pasted below. I'm very new to Android Studio so any help or tips would be greatly appreciated!

plugins {
id 'com.android.application'
}

android {
compileSdkVersion 30
buildToolsVersion "30.0.3"

useLibrary 'org.apache.http.legacy'

defaultConfig {
    applicationId "com.example.startfromscratchinperson"
    minSdkVersion 21
    targetSdkVersion 30
    versionCode 1
    versionName "1.0"

    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions{
    exclude 'META-INF/DEPENDENCIES'
}

}

dependencies {

implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':emv-anet-sdk')
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'org.apache.httpcomponents:httpcore:4.4.1'
implementation 'org.apache.httpcomponents:httpclient:4.5'
implementation 'com.madgag.spongycastle:prov:1.53.0.0'
implementation 'com.google.android.material:material:1.0.0'

}

In Person SDK - Integrating BBPOS Chipper BT 2X with Android app

We have purchased BBPOS Chippier BT 2X from posportal (https://partner.posportal.com/authorizenet/auth/credit-card-readers/anywherecommerce-walker-c2x-for-authorizenet.html). And we would like to integrate this with an Android app. The app is basically going to be used in a Box office kind of setting (to sell tickets), that is our end users are merchants. So as per our understanding, we should be using In-person SDK.
We have gone through the github readme (https://github.com/AuthorizeNet/inperson-sdk-android) as well as the overview doc (https://developer.authorize.net/api/reference/features/in-person.html). However we still have some more questions.

  1. For starters, when we try to create a sample Android application by integrating the emv-anet-sdk as a library module, we are getting into a crash. The crashlog is given below. We use Kotlin, and work on Android studio 3.6.2 . Our app targets API 29 with a minimum supported version of API 26. 
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.companyname.bbposintegrator, PID: 7225
    java.lang.NoClassDefFoundError: Failed resolution of: Lorg/spongycastle/util/encoders/Base64;
        at net.authorize.aim.emv.QuickChipActivity.ॱ(:726)
        at net.authorize.aim.emv.QuickChipActivity.onReturnCheckCardResult(:652)
        at net.authorize.aim.emv.І$ǃ.onReturnCheckCardResult(:157)
        at com.bbpos.bbdevice.BBDeviceController$82.run(:3270)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7076)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "org.spongycastle.util.encoders.Base64" on path: DexPathList[[zip file "/data/app/com.quintetsolutions.bbposintegrator-R5iJPybUY4b3N4RbcgkBkQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.companyname.bbposintegrator-R5iJPybUY4b3N4RbcgkBkQ==/lib/arm64, /system/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at net.authorize.aim.emv.QuickChipActivity.ॱ(:726) 
        at net.authorize.aim.emv.QuickChipActivity.onReturnCheckCardResult(:652) 
        at net.authorize.aim.emv.І$ǃ.onReturnCheckCardResult(:157) 
        at com.bbpos.bbdevice.BBDeviceController$82.run(:3270) 
        at android.os.Handler.handleCallback(Handler.java:873) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7076) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 

And the code is given below. Removed unimportant parts for ease of reading. You can see that we just authenticate using PasswordAuthentication, and on successful authentication, try to search for BBPOS device. If the swiper is found, we will call startQuickChipTransaction. This will open the SDK payment dialog with text "Please swipe card". However, when we swipe any card, the SDK will crash with the error above. 

private fun authenticate() {
        AuthenticationTask().execute()
    }

    inner class AuthenticationTask : AsyncTask<Void, Void, Merchant>() {
        override fun onPostExecute(result: Merchant?) {
            super.onPostExecute(result)
            if (merchant != null) {
                startBTScan()
            }
        }
        override fun doInBackground(vararg params: Void?): Merchant? {
            val deviceID = "Test EMV Android"
            val passAuth = PasswordAuthentication.createMerchantAuthentication(MY_USERNAME, MY_PASSWORD, deviceID)
            merchant = Merchant.createMerchant(environment, passAuth)
            if (merchant != null) {
                val transaction: Transaction = merchant!!.createMobileTransaction(TransactionType.MOBILE_DEVICE_LOGIN)
                val mobileDevice = MobileDevice.createMobileDevice(deviceID,"Device description", "425-555-0000", "Android")
                transaction.mobileDevice = mobileDevice
                val result = merchant?.postTransaction(transaction) as net.authorize.mobile.Result

                if (result.isOk()) {
                    try {
                        val sessionTokenAuthentication = SessionTokenAuthentication.createMerchantAuthentication(merchant!!
                            .getMerchantAuthentication().getName(), result
                            .getSessionToken(), "Test EMV Android")
                        if (result.getSessionToken() != null&& sessionTokenAuthentication != null) {
                            merchant?.setMerchantAuthentication(sessionTokenAuthentication)
                        }
                        return merchant
                    } catch (ex: Exception) {
                        ex.printStackTrace()
                        return null
                    }
                }
            }
            return null
        }
    }

    private fun startBTScan() {
        EMVTransactionManager.setDeviceConnectionType(EMVDeviceConnectionType.BLUETOOTH)
        EMVTransactionManager.setTerminalMode(EMVTransactionManager.TerminalMode.SWIPE_ONLY)
        EMVTransactionManager.startBTScan(this@MainActivity, mListener);
    }

    val mListener = object :EMVTransactionManager.QuickChipTransactionSessionListener {
        override fun onBluetoothDeviceConnected(p0: BluetoothDevice?) {
            appendLog("onBluetoothDeviceConnected " + p0?.name)
            val emvTransaction = EMVTransactionManager.createEMVTransaction(merchant, BigDecimal(0.01))
            emvTransaction.emvTransactionType = EMVTransactionType.PAYMENT
            EMVTransactionManager.startQuickChipTransaction(emvTransaction, this, this@MainActivity)
        }

        override fun onReturnBluetoothDevices(p0: MutableList<BluetoothDevice>?) {
            appendLog("onReturnBluetoothDevices")
            p0?.let { array ->
                for (device in array) {
                    if (isBBPOSSwiper(device)) {
                        EMVTransactionManager.connectBTDevice(this@MainActivity, device, this)
                    }
                }
            }
        }
    }

Let us know if any other information is needed. 

  1. Basically, we are only interested in Swipe transactions for now (not tap or dip). Could you confirm whether we are approaching this right by using startQuickChipTransaction method for non-EMV encrypted swipe transactions, correct? 

  2. In the above code (as well as the SDK sample), we need to pass on the merchant username and password. As we already mentioned, our end users are merchant so the app need to get the username and password for all merchants from the server. Is there any other way for authentication (like any transactionKey) so that we don't have to pass the username/password of the merchant to the mobile app? 

  3. Is there any other documentation other than that I linked above? Where can we see the documentation of individual methods that I used in the code above?

Let us know. 

java.lang.RuntimeException: Method code too large!

I have tried to run the sample code but encountered with this problem:

Error:Execution failed for task ':app:transformClassesWithInstantRunForDebug'.

com.android.build.api.transform.TransformException: java.lang.RuntimeException: java.lang.RuntimeException: Method code too large!

AmericanExpress accountType is not parsed properly

If the transaction was made with an American Express card, getAccountType returns CardType/UNKNOWN, probably because of the space in the value. Works for MasterCard and Visa.

Response XML:

<?xml version="1.0" encoding="UTF-8"?>
<createTransactionResponse xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <refId>1a84d7e9935640f0b123</refId>
  <messages>
    <resultCode>Ok</resultCode>
    <message>
      <code>I00001</code>
      <text>Successful.</text>
    </message>
  </messages>
  <transactionResponse>
    <responseCode>1</responseCode>
    <authCode>B7M93V</authCode>
    <avsResultCode>P</avsResultCode>
    <cvvResultCode />
    <cavvResultCode />
    <transId>2229017123</transId>
    <refTransID>2229017123</refTransID>
    <transHash>2EF2497043C0510A8CC14FB74F7F3123</transHash>
    <testRequest>0</testRequest>
    <accountNumber>XXXX0002</accountNumber>
    <accountType>AmericanExpress</accountType>
    <messages>
      <message>
        <code>1</code>
        <description>This transaction has been approved.</description>
      </message>
    </messages>
  </transactionResponse>
</createTransactionResponse>

Refund Integration

We need to implement refund feature for android from our app as we have integrated inperson-sdk in our app..
We have 2 options for payment, first is, user will manually enter card details and make payment and another option is by attaching c2x card reader to make payment and in both of the cases we are providing refund feature.
We are searching for refund api from android but not able to get things.We need help to integrate refund if anyone has integrated or has some idea about refund...

Error FileNotFoundException

AuthorizeNet/inperson-sdk-android => got error like java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.bbpos.emvswipe.ui/settings.txt: open failed: ENOENT (No such file or directory)

we want to use authorize.net sdk in Android application but didn't get any working sample application(demo).
so need your help how to use authorize.net for American Express ,Discover ,JCB ,Diners Club/ Carte Blanch ,Visa ,Master Card and on-line bank transaction so need your help devlope authorize.net sdk in our app for payment.

so we need your help for use authorize.net sdk in our app. which sdk is better AuthorizeNet/inperson-sdk-android or AuthorizeNet/accept-sample-android ? please provide any working sample code (demo)

Refund Integration Issues

Respected sir,

As per your guidelines(#41) we have implemented code to get transaction details from transaction id and also able to differentiate when to void and refund transaction ... here is a code so that other people can review and implement it..

## Query : But we are not getting how can we implement refund and void feature like to get transaction detail you provided package name net.authorize.reporting.TransactionType.GET_TRANSACTION_DETAILS.
So from package name we're able get how to implement.

Also we unable to get how to pass transaction_id when requesting for refund and void transactions with transaction.So if you can also help us for same.

So please provide us some more detailed picture for same or if any working demo and if there is any correction in below code then please inform us so that we can provide best quality to our client.

//TODO : Get details of particular transaction.
private class GetTransactionDetails extends AsyncTask<String, Integer, net.authorize.reporting.Result> {

    GetTransactionDetails() {
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog.setMessage(getString(R.string.anet_authentication));
        progressDialog.show();
    }

    @Override
    protected net.authorize.reporting.Result doInBackground(String... transactionId) {
        net.authorize.reporting.Result tDetailedResult = null;
        try {
            String deviceId = Build.MANUFACTURER + "_" + Build.MODEL;
            //TODO : First we need to login and Create authentication method based on login, password and device ID
            PasswordAuthentication passAuth = PasswordAuthentication.createMerchantAuthentication(getString(R.string.anet_userName), getString(R.string.anet_password), deviceId);

            //TODO : Create merchant object using authentication method
            Merchant testMerchant = Merchant.createMerchant(Environment.SANDBOX, passAuth);
            testMerchant.createReportingTransaction(TransactionType.GET_TRANSACTION_DETAILS);

            net.authorize.mobile.Transaction loginTransaction = testMerchant.createMobileTransaction(net.authorize.mobile.TransactionType.MOBILE_DEVICE_LOGIN);
            net.authorize.data.mobile.MobileDevice mobileDevice = net.authorize.data.mobile.MobileDevice.createMobileDevice(deviceId, "Device description", "425-555-0000", "Android");
            loginTransaction.setMobileDevice(mobileDevice);

            //TODO : Post login, request to Authorize.net Gateway
            net.authorize.mobile.Result loginResult = (net.authorize.mobile.Result) testMerchant.postTransaction(loginTransaction);
            if (loginResult.isOk()) {
                publishProgress(1);
                Thread.sleep(1000);

                SessionTokenAuthentication sessionTokenAuthentication = SessionTokenAuthentication.createMerchantAuthentication(testMerchant.getMerchantAuthentication().getName(), loginResult.getSessionToken(), "Test EMV Android");//InpersonSDK-Android-test
                if (loginResult.getSessionToken() != null)
                    testMerchant.setMerchantAuthentication(sessionTokenAuthentication);

                publishProgress(2);
                Thread.sleep(1000);

                ReportingDetails details = ReportingDetails.createReportingDetails();
                details.setTransactionId(transactionId[0]);

                net.authorize.reporting.Transaction transaction = Transaction.createTransaction(testMerchant, TransactionType.GET_TRANSACTION_DETAILS);
                transaction.setReportingDetails(details);

                tDetailedResult = (Result) testMerchant.postTransaction(transaction);
            }
        } catch (Exception e) {
            System.out.println("TAG --> " + e.getMessage());
        }
        return tDetailedResult;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        if (values[0] == 1)
            progressDialog.setMessage(getString(R.string.anet_authentication_successfull));
        else if (values[0] == 2)
            progressDialog.setMessage(getString(R.string.anet_request_transaction_details));
    }

    @Override
    protected void onPostExecute(net.authorize.reporting.Result tDetailedResult) {
        super.onPostExecute(tDetailedResult);
        try {
            progressDialog.dismiss();
            if (tDetailedResult != null) {
                System.out.println("TAG -- ANET --> response : " + tDetailedResult.getXmlResponse());
                List<MessageType> mTypeList = tDetailedResult.getMessages();
                if (mTypeList != null && mTypeList.size() > 0) {
                    String rCode = mTypeList.get(0).getValue();
                    System.out.println("TAG -- ANET --> rCode : " + rCode);
                    if (rCode.equals("I00011"))
                        CommonUtility.alert(activity, getString(R.string.cancel_transaction), getString(R.string.anet_merchant_not_activated));
                    else if (rCode.equals("E00001"))
                        CommonUtility.alert(activity, getString(R.string.cancel_transaction), getString(R.string.anet_system_error));
                    else if (rCode.equals("E00011")) //TODO : No permission
                        new AlertDialog.Builder(activity).setTitle(getString(R.string.cancel_transaction)).setMessage(getString(R.string.anet_no_permission_to_get_transaction_details)).create().show();
                    else if (rCode.equals("I00001")) {//TODO : Successfully got details
                        ReportingDetails details = tDetailedResult.getReportingDetails();
                        List<TransactionDetails> list = details.getTransactionDetailList();
                        if (list != null && list.size() > 0) {
                            TransactionDetails tDetails = list.get(0);
                            TransactionStatusType statusType = tDetails.getTransactionStatus();
                            String text = "";
                            if ((statusType == TransactionStatusType.CAPTURED_PENDING_SETTLEMENT))
                                Toast.makeText(activity, text = "Transaction can be voided", Toast.LENGTH_SHORT).show();
                            else if (statusType == TransactionStatusType.SETTLED_SUCCESSFULLY)
                                Toast.makeText(activity, text = "Transaction can request for refund", Toast.LENGTH_SHORT).show();
                            else if (statusType == TransactionStatusType.VOIDED)
                                Toast.makeText(activity, text = "Transaction already voided", Toast.LENGTH_SHORT).show();
                            else if (statusType == TransactionStatusType.REFUND_PENDING_SETTLEMENT)
                                Toast.makeText(activity, text = "Transaction refund already in progress", Toast.LENGTH_SHORT).show();
                            else if (statusType == TransactionStatusType.REFUND_SETTLED_SUCCESSFULLY)
                                Toast.makeText(activity, text = "Transaction already refunded", Toast.LENGTH_SHORT).show();
                            System.out.println("TAG -- ANET --> text : " + text);
                        }
                    }
                }
            } else
                CommonUtility.alert(activity, getString(R.string.cancel_transaction), getString(R.string.anet_null_response));
        } catch (Exception e) {
            System.out.println("TAG --> " + e.getMessage());
        }
    }
}

reading EMV encrypted BLOB android

I'm not able to get EMV encrypted blob which is required for creation of new CrediCard object.
Also i'm not able to get that in README.md file provided code for EMVTrasaction works only for AnywhereCommerce device or for both(AnywhereCommerce and IdTech).
If it works only for AnywhereCommerce then which code i run for IdTech device which also supported by this SDK and additionally how do i get that which card reader device is connected to Android Mobile/tablet and how to get that card reader device detail(Like blob) and Card which is swiped through that device.
Also RECORD_AUDIO and STORAGE READ and WRITE permissions are needed?
Please guid me in proper direction.
When user clicks on pay button following code runs

This is my code :
private class CreateTransaction extends AsyncTask<Integer, Integer, Integer> {

    //String cardNumber = "", expirationMonth = "", expirationYear = "", cvv = "";
      private static final String IDTechTestBlob = "3032434530313830314634413232303030333942252a353435392a2a2a2a2a2a2a2a333830305e504157414e20524157414c20202020202020202020202020202f5e2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a3f2a3b353435392a2a2a2a2a2a2a2a333830303d2a2a2a2a2a2a2a2a2a2a2a2a2a2a3f2a35343843443545353433463145313945313037454145444532434242384246413730423430374633414234323834363330314335453443323137344534453845354130373730303431453037443934443632313531303133383241344342413535354133313434334443353839354341443332393638433338383634383736454645393535464646423344413930423534394342413137413631334345423139373241443539384446453241333437363145463544424241413039414237443043354232434134333835444131354437333230363331433730434238373138323643464345334144334133444434443539433630413732364532464132454530343239313341344232454538354443434135444338413443384533343436313845393935303138303144393745383443304336324437384135354332413545333130323436303031324230333234323030303237373336463033";

    net.authorize.mobile.Result loginResult;

    Order order = null;
    Merchant testMerchant = null;
    Customer customer = null;

    //net.authorize.aim.Result authCaptureResult = null;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        progressDialog = new ProgressDialog(activity);
        progressDialog.setCancelable(false);
        progressDialog.setMessage("Requesting for payment...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.show();
    }

    @Override
    protected Integer doInBackground(Integer... params) {
        try {
            //first we need to login and Create authentication method based on login, password and device ID
            PasswordAuthentication passAuth = PasswordAuthentication.createMerchantAuthentication(getString(R.string.userName), getString(R.string.password), "InpersonSDK-Android-test");

            //Create merchant object using authentication method
            testMerchant = Merchant.createMerchant(Environment.SANDBOX, passAuth);
            testMerchant.setDeviceType(DeviceType.WIRELESS_POS);
            testMerchant.setMarketType(MarketType.RETAIL);

            //Create login request and populate mobile device field
            net.authorize.mobile.Transaction loginTransaction = testMerchant.createMobileTransaction(net.authorize.mobile.TransactionType.MOBILE_DEVICE_LOGIN);
            net.authorize.data.mobile.MobileDevice mobileDevice = net.authorize.data.mobile.MobileDevice.createMobileDevice("InpersonSDK-Android-test", "Device description", "425-555-0000", "Android");
            loginTransaction.setMobileDevice(mobileDevice);
            //post login request to Authorize.net Gateway
            loginResult = (net.authorize.mobile.Result) testMerchant.postTransaction(loginTransaction);

            if (loginResult.isOk()) {
                System.out.println("TAG --> Login Successful");
                //if login succeeded, populate session token in the Merchant object
                SessionTokenAuthentication sessionTokenAuthentication = SessionTokenAuthentication.createMerchantAuthentication(testMerchant.getMerchantAuthentication().getName(), loginResult.getSessionToken(), "InpersonSDK-Android-test");
                if ((loginResult.getSessionToken() != null) && (sessionTokenAuthentication != null)) {
                    testMerchant.setMerchantAuthentication(sessionTokenAuthentication);
                }

                creditCard = CreditCard.createCreditCard();
                creditCard.setCardPresenseType(net.authorize.data.creditcard.
                        CreditCardPresenceType.CARD_PRESENT_ENCRYPTED);
                creditCard.getSwipperData().setMode(SwiperModeType.DATA);
                //the following field is the data converted into HEX string coming from the reader
                creditCard.getSwipperData().setEncryptedData(IDTechTestBlob);
                //the FID for the reader
                creditCard.getSwipperData().setDeviceInfo("4649443d4944544543482e556e694d61672e416e64726f69642e53646b7631");
                //the Encryption method used by the reader, should be TDES for IDTech
                creditCard.getSwipperData().setEncryptionAlgorithm(SwiperEncryptionAlgorithmType.
                        TDES);
                //}

                publishProgress(50);

                //create order item and add to transaction object
                order = Order.createOrder();
                OrderItem oi = OrderItem.createOrderItem();
                oi.setItemId("2");
                oi.setItemName("This is sparta");
                oi.setItemDescription("Goods");
                oi.setItemPrice(new BigDecimal(200.0));  //itemPrice/quantity
                oi.setItemQuantity("2");
                oi.setItemTaxable(false);
                order.addOrderItem(oi);
                order.setTotalAmount(new BigDecimal(1.00));

                customer = Customer.createCustomer();
                customer.setId("12");  //Login user id
                customer.setCustomerId("12");  //Login user id
                customer.setAddress("Raj Wold Mall, XYZ");
                customer.setCompany("ABCD PVT. LTD.");
                customer.setCity("Bangol");
                customer.setCustomerType(CustomerType.INDIVIDUAL);
                customer.setCountry("India");
                customer.setState("Bangol");
                customer.setFirstName("Harshal");
                customer.setLastName("Bhatt");
                customer.setEmail("[email protected]");
                customer.setZipPostalCode("123465");

                Address address = Address.createAddress();
                address.setAddress("ABCD Infotech, D-Mart,Bangol");
                address.setPhoneNumber("1234567890");
                address.setZipPostalCode("123456");
                address.setCompany("ABC Infotech");
                address.setCountry("India");
                address.setState("Bangol");
                address.setCity("Bangol");
                address.setFirstName("Harshal");
                address.setLastName("Bhatt");

                customer.setShipTo(address);
                //customer.setBillTo(address);

                publishProgress(75);

            } else {
                //handle login errors in here
            }
        } catch (Exception e) {
            System.out.println("TAG Exception --> " + e.getMessage());
        }
        return 0;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        if (values[0] == 50) {
            if (progressDialog != null) {
                progressDialog.setMessage("Getting customer details...");
            }
        } else if (values[0] == 75) {
            if (progressDialog != null) {
                progressDialog.setMessage("Please wait ... making transaction");
            }
        }
    }

    @Override
    protected void onPostExecute(Integer response) {
        super.onPostExecute(response);
        try {

            if (creditCard != null && creditCard.getCreditCardNumber() != null) {
                startEMVTransaction(customer, order, testMerchant, creditCard);
            } else {
                if (progressDialog != null) {
                    progressDialog.dismiss();
                }
                Toast.makeText(activity, "Card number : " + creditCard.getCreditCardNumber(),
                        Toast.LENGTH_SHORT).show();
                Toast.makeText(activity, "Card Not Found", Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            System.out.println("TAG Exception --> " + e.getMessage());
        }
    }
}

private void startEMVTransaction(Customer customer, Order order, Merchant merchant,
                                 CreditCard creditCard) {
    EMVTransaction emvTransaction = EMVTransactionManager.createEMVTransaction(merchant,
            order.getTotalAmount());
    emvTransaction.setCustomer(customer);
    emvTransaction.setOrder(order);
    emvTransaction.setCreditCard(creditCard);
    emvTransaction.setEmvTransactionType(EMVTransactionType.GOODS);
    EMVTransactionManager.startEMVTransaction(emvTransaction, this, activity);
}

@OverRide
public void onEMVTransactionSuccessful(Result result) {
if (progressDialog != null) {
progressDialog.dismiss();
}
Toast.makeText(activity, "EMVTransactionSuccessful", Toast.LENGTH_SHORT).show();
if (result != null) {
if (result.isApproved()) {
Toast.makeText(activity, "Payment Successful", Toast.LENGTH_SHORT).show();
HashMap<String,String> map = result.getEmvTlvMap();
Toast.makeText(activity, "4f --> "+map.get("4f"), Toast.LENGTH_SHORT).show();
Toast.makeText(activity, "4f --> "+map.get("4f"), Toast.LENGTH_SHORT).show();
Toast.makeText(activity, "4f --> "+map.get("4f"), Toast.LENGTH_SHORT).show();
Toast.makeText(activity, result.getXmlResponse(), Toast.LENGTH_SHORT).show();
Toast.makeText(activity, result.getResponseText(), Toast.LENGTH_LONG).show();
Toast.makeText(activity, "A/c no. : " + result.getAccountNumber(), Toast.LENGTH_SHORT).
show();
Toast.makeText(activity, "Transaction Id : " + result.getTransId(), Toast.LENGTH_SHORT).
show();
Toast.makeText(activity, "Tip amount : " + result.getTipAmount(), Toast.LENGTH_SHORT).
show();
} else {
Toast.makeText(activity, result.getResponseText(), Toast.LENGTH_LONG).show();
Toast.makeText(activity, result.getTransactionResponseMessages().get(0).getReasonText(),
Toast.LENGTH_SHORT).show();
Toast.makeText(activity, result.getMessages().get(0).getText(), Toast.LENGTH_SHORT).
show();
Toast.makeText(activity, result.getXmlResponse(), Toast.LENGTH_SHORT).show();
}
}
}

@Override
public void onEMVReadError(EMVErrorCode emvErrorCode) {
    if (progressDialog != null) {
        progressDialog.dismiss();
    }
    Toast.makeText(activity, "EMVReadError", Toast.LENGTH_SHORT).show();
    if (emvErrorCode != null) {
        Toast.makeText(activity, "Error Code : " + emvErrorCode.getError(), Toast.LENGTH_LONG).
                show();
        Toast.makeText(activity, "Error String : " + emvErrorCode.getErrorString(),
                Toast.LENGTH_LONG).show();
    }
}

@Override
public void onEMVTransactionError(Result result, EMVErrorCode emvErrorCode) {
    if (progressDialog != null) {
        progressDialog.dismiss();
    }
    Toast.makeText(activity, "EMVTransactionError", Toast.LENGTH_SHORT).show();
    if (result != null) {
        Toast.makeText(activity, result.getResponseText(), Toast.LENGTH_SHORT).show();
        Toast.makeText(activity, result.getXmlResponse(), Toast.LENGTH_SHORT).show();
        if (result.getMessages() != null && result.getMessages().size() > 0) {
            Toast.makeText(activity, "Message : " + result.getMessages().get(0).getText(),
                    Toast.LENGTH_LONG).show();
            Toast.makeText(activity, "Message string : " + result.getMessages().get(0).getValue(),
                    Toast.LENGTH_LONG).show();
        }
        if (result.getTransactionResponseMessages() != null &&
                result.getTransactionResponseMessages().size() > 0) {
            Toast.makeText(activity, "Response Reason : " +
                            result.getTransactionResponseMessages().get(0).getReasonText(),
                    Toast.LENGTH_LONG).show();
        }
    }
}

}

Support for below api 21 in android

Hi sir,

This sample contains .aar file that supports only devices with api 21 and above. Is there any other way to provide support devices running below api 21 ? or any other library for android to support below api 21 by AuthorizeNet .. ?

Communication Link Uninitialized

I am always getting an error "Communication link is not initialized please try again".

Steps:-

  1. create session by authorized merchant.
    2.click on my application payment button and get a Screen of swipe card .
  2. on swipe screen i pressed cancel transaction button.
    4.again start to do payment in this case i got the error message and application hang on this screen.

please help ....

Device not reading EMV nor swipes

Hello,

I'm having trouble processing credit card transactions within the sandbox environment.
So far, while testing only on the sample app, I've been unable to get a successful/error response from the EmvTransactionManager listener. After choosing an amount within the MainActivity, and after selecting the emvButton, I assume the device should begin listening for an EMV insert, however no callback is ever called once an EMV is inserted.

Currently we're sending Auth.net keyed manual entries and CC swipes w/o the inperson-sdk, however for EMV transactions I believe this is the only sdk thats fit the purpose for our terminals.

Could running this sdk on our own terminals be the issue? If so, can we build our own EMV listener and pass the info to Auth.net?

Thanks for reading!

AuthCapture Transaction internal failure

The transaction fails to post and this is the result:
<?xml version="1.0" ?><messages><resultCode>Error</resultCode><message><code>E00000</code><text>Unknown error : Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference</text></message></messages>

My code:

                net.authorize.aim.Transaction authCaptureTransaction = Transaction.createTransaction(merchant, TransactionType.AUTH_CAPTURE, totalAmount);
                authCaptureTransaction.setCreditCard(creditCard);
                authCaptureTransaction.setOrder(order);

                //post the transaction to Gateway
                net.authorize.aim.Result authCaptureTransactionResult = (net.authorize.aim.Result) merchant.postTransaction(authCaptureTransaction);
                if(authCaptureTransactionResult.isOk()){
                    Log.d(TAG, "Transaction Finished");
                    try {
                        ResponseCode responseCode = authCaptureTransactionResult.getResponseCode();
                        Log.d(TAG, responseCode.getCode()+":"+responseCode.getDescription());
                        listener.onNonEMVTransactionFinished(responseCode);
                    } catch (Exception e){
                        e.printStackTrace();
                    }
                } else {
                    Log.e(TAG, "Transaction Failed");
                    listener.onNonEMVTransactionFailed();
                }

I followed the method returns and it seems it fails in the bolded statement internally:

public static String executeXML(Environment environment, ITransaction transaction) {
        DefaultHttpClient httpClient = null;
        String rawResponseString = "";
        if(environment != null && transaction != null) {
            try {
                httpClient = getDefaultHttpClient(environment);
                **HttpPost e = createHttpPost(environment, transaction);**

And then further in the bolded statement here:

private static HttpPost createHttpPost(Environment env, ITransaction transaction) throws Exception {
        URI postUrl = null;
        HttpPost httpPost = null;
        if(!(transaction instanceof Transaction)) {
            postUrl = new URI(env.getXmlBaseUrl() + "/xml/v1/request.api");
            httpPost = new HttpPost(postUrl);
            httpPost.setHeader("Content-Type", "text/xml; charset=utf-8");
            **httpPost.setEntity(new StringEntity(transaction.toAuthNetPOSTString()));**
        }

        return httpPost;
    }

Ill post more code if necessary. I don't know why some string thats not checked for nullity should cause the transaction to fail completely. Please fix this.

Thanks

java.lang.ClassNotFoundException: Didn't find class "com.bbpos.z.e"

The code was working fine, but unfortunately, but without doing any changes it occur with the problem:

java.lang.NoClassDefFoundError: Failed resolution of: Lcom/bbpos/z/e;
at com.bbpos.emvswipe.i$58.run(SourceFile:335)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.bbpos.z.e" on path: DexPathList[[zip file "/data/app/com.successive.logicspaybill-1/base.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_dependencies_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_0_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_1_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_2_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_3_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_4_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_5_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_6_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_7_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_8_apk.apk", zip file "/data/app/com.successive.logicspaybill-1/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.successive.logicspaybill-1/lib/arm, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at com.bbpos.emvswipe.i$58.run(SourceFile:335) 
at android.os.Handler.handleCallback(Handler.java:746) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5443) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
Suppressed: java.lang.ClassNotFoundException: com.bbpos.z.e
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 9 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.