Java (Desktop)

Requirements

Commerce SDK for Windows is supported on most x86/x64 environments capable of running the Oracle Java Virtual Machine (JVM).  Integrating a card reader and/or a receipt printer solely requires available USB ports or TCP/IP Ethernet for connectivity.  Being an SDK, Commerce processes and functionality (i.e., card reader connectivity, printer connectivity, internet connectivity) all run within the integration application (e.g., a POS system).  As such, the following system requirements apply for the application or framework in which Commerce will be integrated:

  • Windows environment supporting Oracle JVM 1.7 (32-bit ONLY)
  • Internet access (for connectivity to the payment gateway)
  • USB Port access (at least one available port for a card reader and/or receipt printer) or TCP/IP Ethernet access for card reader

In terms of integrating Commerce SDK into an existing application or framework, more information will be provided below.

Installing the card reader and printer drivers

Before you can use the card reader and printer, you’ll need to install some drivers. There are two packages. One is IngenicoUSBDrivers_2.60_setup.exe. Run that and take all the defaults. That will install the card reader drivers.

Next unzip StarMicronicsUsbDrivers.zip and run the approporiate dp_instfile appropriate to the flavor of windows you are running. This will install the printer drivers.

Building the sample application

A sample application package is provided(commerce-windows-sampleapp-x.y.z-release.zip), which includes the following:

  • Java source code for sample application (used to compiled the sample application and use as a fully functioning reference)
  • Pre-compiled Commerce SDK libraries (and required 3rd party dependencies)
  • Pre-compiled sample application executable
  • Developer documentation

The development environment required to build the Commerce SDK Windows Sample Application (as well as develop with Commerce itself) is fairly standard and typically includes the following:

  • Java JDK (1.7 or higher / 32-bit ONLY - but CSDK binaries are compiled for java 7, so make sure to compile for java 7)
  • IDE (IntelliJ works nicely as Commerce includes Gradle scripts, but that is a developer choice)
  • Gradle 2.13 (although later versions may be usable, testing has only been performed using version 2.13.  You are free to use any other build tool desired)

For your convenience, the desktop sample app has been pre-compiled and included in the Getting Started package. Reference the commerce-sampleapp.bat file for more information on how to run the pre-compiled sample application JAR.

The Commerce SDK sample applications package contains the following directories of interest:

  • libs:  Core Commerce SDK libraries and required 3rd party libraries (all JAR files located here - with the exception of desktop-gui-0.1.0.jar - should be considered requirements for)
  • nativeLibs : Native libraries for card reader communication, printer communication, and lower-level Commerce functionality
  • src : Source code for Commerce Sample Application (a fully functional set of source code and functionality, demonstrating all available Commerce functionality)

To preconfigure the sample app to load your Converge credentials, modify the desktop.properties file. These credentials can also be modified from within the sample app by clicking on Settings->Credentials

Using the Microsoft Surface Pro : If you are hoping to build the sample app on a Microsoft Surface Pro, be advised that the JVM may render the font and other GUI elements too small for high-resolution screens. If this happens, navigate to the Windows display settings and reduce the screen resolution to around 1024 x 768. This should allow the sample app to render correctly.

Import and build sample application/gradle project
  1. Extract the sample application project to a directory of your choosing.
  2. Use the file build.gradle included with the sample application to import the sample application project into your IDE.
  3. The following information may be needed to compile/build and run the sample application:

    • Main Class: com.elavon.sample.desktopgui.CommerceSampleApplication
    • Virtual Machine Options:

      • -Djava.library.path=.\nativeLibs
      • -classpath “.\libs\*”;.
    • Virtual Machine: Reminder, you must be running a 32-bit JVM (e.g., Oracle JDK 1.7 32-bit)

The sample application should build and run using the above configuration.  Feel free to browse the sample application source code to learn more on how the Commerce SDK is used to perform transactions and accept payments.

Integrating Commerce SDK into a Windows application

Using the steps below, Commerce SDK may be integrated into a new or existing application for the purpose of accepting payments.

Commerce SDK and third-party code dependencies

The following Commerce SDK libraries are provided pre-compiled for application integration (located in the /libs directory of the Getting Started package):

  • commerce-core-obfuscated-release.jar
  • commerce-datatypes-java-obfuscated-release
  • commerce-converge-obfuscated-release.jar
  • commerce-desktop-converge-obfuscated-release.jar

In addition to the core libraries mentioned above, there are some 3rd party dependencies that are required. If you plan on using the provided gradle build file, they are pulled in automatically.

Referencing and initializing Commerce SDK

Prior to accepting payments and taking full advantage of Commerce functionality, a few steps should must be performed and items considered when coding.

1. Initialize library and gateway account**  

In addition to loading the Commerce libraries, a payment gateway account (e.g., Converge account) should be provided.  Code to initialize and load the account information may look like the following:

// Initialize Core Commerce SDK
ECCError error = ECLCommerceDesktop.initialize();
if (error != null)
{
    return error;  // Ensure no errors when initializing Commerce SDK
}

2. Implement the ECLConvergeAccountListener interface (See class CommerceAccountListenerin the sample application).

The ECLConvergeAccountListener interface defines the methods where specific properties can be overridden for a gateway account. Depending on the backend server application needs to communicate to, either interface ECLConvergeAccountListener or interface ECLCreditCallAccountListener should be implemented.

public class CommerceAccountListener implements ECLConvergeAccountListener
{
    @Override
    public Context getApplicationContext()
    {
        // do something - look in the sample app code for a concrete example
    }

    @Override
    public ECCSensitiveData getMerchantId(ECLAccountInterface eclAccountInterface)
    {
        // return your converge account's merchant ID
    }

    @Override
    public ECCSensitiveData getUserId(ECLAccountInterface eclAccountInterface)
    {
        // return your converge account's user ID
    }

    @Override
    public ECCSensitiveData getPin(ECLAccountInterface eclAccountInterface)
    {
        // return your converge account's PIN
    }

    @Override
    public ECCSensitiveData getVendorId(ECLAccountInterface eclAccountInterface)
    {
        // return your vendor ID
    }

    @Override
    public ECCSensitiveData getVendorAppName(ECLAccountInterface eclAccountInterface)
    {
        // return your application name
    }

    @Override
    public ECCSensitiveData getVendorAppVersion(ECLAccountInterface eclAccountInterface)
    {
        // return your application version
    }

    @Override 
    public ECLProxyInfo getProxyInfo()
    {
        // do something - look in the sample app code for a concrete example
    }

    @Override 
    public ECLPersistentSettingsInterface getPersistentSettings()
    {
        // do something - look in the sample app code for a concrete example
    }

    @Override
    public void accountDidInitialize(ECLAccountInterface account)
    {
        // Once the account is initialized, you can override certain properties associated with it, like terminal language or
        // US common debit preferences.
        // You also have the chance to setup listeners for different events associated with the account,
        // like get notifications when a key update occurs

        account.setUpdateKeysListener(new ECLUpdateKeysListener()
        {
            @Override
            public void updateKeysFailed(ECCError eccError)
            {
                // do something - look in the sample app code for a concrete example
            }

            @Override
            public void updateKeysCompleted()
            {
                // do something - look in the sample app code for a concrete example
            }

            @Override
            public void updateKeysProgress(ECLTransactionProgress eclTransactionProgress)
            {
                // do something - look in the sample app code for a concrete example
            }
        });

        // set up listener to be notified when a scheduled reboot is about to occur - for V4 pin pads
        account.setCardReaderDailyRebootNotificationListener(new ECLCardReaderDailyRebootNotificationListener()
        {
            @Override
            public void cardReaderWillPerformDailyReboot(long millisUntilReboot)
            {
                // do something - look in the sample app code for a concrete example
            }
        });

        // The language used for transaction can be overridden.
        // This applies to RBA pinpads only and will have no effect for other pinpads.
        // This is completely optional. If not used, a possibly server supplied language preference info is going to be used.
        // You can specify a pair of (language, country) to determine the language to be used on pinpad during a transaction.
        // If the pair you supplied is not supported, the return value will indicate the language CSDK chose to use.
        // This is determined to be the closest match to what you specified.
        // Currently, CSDK supports English in US and English and French in Canada.
        ECLLanguageInformation desiredLanguage = ...;
        ECLLanguageInformation finalValue = account.overrideDefaultTerminalLanguage(desiredLanguage);

        // You can override the CSDK setting for the debit network preference in the US.
        // This applies to US RBA pinpads only and will have no effect for other pinpads.
        // This is completely optional. If not used, a possibly server supplied value is going to be used.
        // The possible choices are: global debit network, us common debit network or no preference at all,
        // in which case the user will be asked to do the selection on the pinpad, if applicable.
        // Be advised that in case of contactless transactions, the pinpad will not ask the user for a selection,
        // but it will select the AID with the highest priority remaining after filtering them based on the setting.
        // For example, if the choice is to use the global network and there 2 global AIDS on the card,
        // RBA will automatically select the one with the highest priority.
        ECLDebitNetworkPreferences debitNetworkPreferences = ...;
        account.overrideDebitNetworkPreferences(debitNetworkPreferences);
    }

    @Override
    public void accountDidFailToInitialize(ECLAccountInterface eclAccountInterface, ECCError eccError)
    {
        // do something - look in the sample app code for a concrete example
    }

    @Override
    public void accountDefaultCurrencyDidChange(ECLAccountInterface eclAccountInterface, ECLCurrencyCode currencyCode)
    {
        // do something - look in the sample app code for a concrete example
    }

    @Override
    public ECLServerType getServerType()
    {
        // do something - look in the sample app code for a concrete example
    }
}

3. Create gateway account (See class CommerceAccount in the sample application)

Create a gateway account listener implementation (See Converge account implementation CommerceAccountListenerin the sample application) For more information on how to specify account information, as well as using the test environment, see class CommerceSettingsin the sample application)

CommerceAccountListener commerceConvergeAccountListener = new CommerceAccountListener(this, commerceSettings);

Load the account information into the Commerce SDK instance

ECLCommerce.createAccount(commerceConvergeAccountListener, new ECLDispatcher(new DesktopHandler()));

At this point, barring any errors, Commerce SDK and the gateway account is initialized, ready to being processing transactions.

4. Setup a simple sale/auth transaction (See class Transaction in the sample application)

Various options, such as gratuity-on-the-PIN Pad, tax, partial approval, pre-auth, and more are available when performing a sale/auth transaction (and included as examples).  For the purpose of this example, a basic sale/auth is setup to process as a card (i.e. credit/debit) transaction.

Define the base Transaction AMOUNT (using Currency Code and Amount in minor units.

For this example, the amount $19.95 is used.

ECLMoney baseTransactionAmount = new ECLMoney(ECLCurrencyCode.USD, 1995);

Retrieve an instance of ECLCardTenderInterface (implementation used for performing card-based operations)

ECLCardTenderInterface cardTenderInterface = yourInstanceOfECLAccountInterface.getTransactionProcessor().createCardTender();

Create an instance of ECLCurrencyTransactionInterface (implementation used for card-based operations where money is changing hands)

For reference a non-currency transaction is similar to a balance inquiry or loyalty program operation.

ECLCurrencyTransactionInterface currencyTransactionInterface = yourInstanceOfECLAccountInterface.getTransactionProcessor().createSaleTransactionWithSubtotal(baseTransactionAmount);

Performing the above steps defines the base set of information needed to process a transaction.  Using the above information, transaction processing can start.

5. Perform a card read and process the simple sale/auth transaction (See class Transaction in the sample application)

With the transaction information defined, the card reader can be engaged and card data collected for the purpose of taking payment.

Create an instance of ECLTransactionProcessingListener (handle all callbacks and any requests for information during transaction processing)

ECLTransactionProcessingListener transactionListener = new ECLTransactionProcessingListener()
{
    @Override
    public void uponSearchingDevice(ECLConnectionMethod eclConnectionMethod)
    {
        // do something - look in the sample app code for a concrete example
    }

    @Override
    public void transactionDidComplete(ECLTransactionInterface transaction, ECLTenderInterface tender,
        final ECLTransactionOutcome outcome)
    {
        // do something - look in the sample app code for a concrete example
    }

    @Override
    public void transactionDidCancel(ECLTransactionInterface transaction, ECLTenderInterface tender)
    {
        // do something - look in the sample app code for a concrete example
    }

    @Override
    public void transactionDidFail(ECLTransactionInterface transaction, ECLTenderInterface tender, List<ECCError> errors)
    {
        // do something - look in the sample app code for a concrete example
    }

    @Override
    public void shouldProvideInformation(final ECLTransactionInterface transaction, final ECLTenderInterface tender,
        final ECLTransactionRequirementsInterface transactionRequires, final ECLTenderRequirementsInterface tenderRequires)
    {
        // We need more information to process the transaction!        
        // During transaction processing, this callback may be executed one or more times for the purpose
        // of collecting more information to continue processing the transaction.
        // Look in the sample app code for a concrete example
    }

    @Override
    public void shouldSetCardReaderToUse(ECLTransactionInterface transaction, ECLTenderInterface tender,
        List<String> cardReadersReadyForUse)
    {
        // Commerce detected more than one card reader so you need to let the user choose which one from the list should be used
        // Should this scenario arise, provide a mechanism to select the appropriate card reader.
        // Look in the sample app code for a concrete example
    }

    public void transactionProgress(final ECLTransactionProgress progress, final ECLTransactionInterface transaction,
        final ECLTenderInterface tender)
    {
        // Always good to know what is happening while the transaction is processing!        
        // Use this callback to provide status information (i.e. "progress" messages)
        // Look in the sample app code for a concrete example
    }
};

// Initiate Transaction Processing!
yourInstanceOfECLAccountInterface.getTransactionProcessor().processTransaction(currencyTransactionInterface, cardTenderInterface, transactionListener);