Java (Windows)

Commerce SDK for Windows is supported on most x64/x86 environments that are capable of running Oracle’s Java Virtual Machine (JVM).

Integrating a payment terminal (card reader) and/or receipt printer solely requires the available USB ports or TCP/IP Ethernet for connectivity.

In this topic:

Requirements

Being a software development kit (SDK), Commerce SDK’s processes and functionality run within the integration application. As such, the following system requirements apply for the application or framework in which Commerce SDK will be integrated:

  • Windows environment supporting Oracle JVM 1.8 (32-bit only)
  • Internet access for connectivity to the payment gateway
  • USB port access, at least one for the card reader and/or receipt printer
  • As an alternate for the USB port, TCP/IP Ethernet access for the card reader

Payment Terminal and Printer Drivers Installation

To install the payment terminal drivers, run IngenicoUSBDrivers_3.14_setup.exe and accept all the installation defaults.

To install the printer drivers, extract the files from StarMicronicsUsbDrivers.zip and run the dp_instfile that is appropriate to your Windows environment.

Commerce SDK Sample Application

The Commerce SDK sample application package (commerce-windows-sampleapp-x.y.z-release.zip) includes the following items:

  • Java source code used to compile the sample application and serves as a fully functional reference
  • Pre-compiled Commerce SDK libraries and the required 3rd party dependencies
  • Pre-compiled sample application executable
  • Developer documentation

The development environment required to build the Commerce SDK Sample Application includes the following items:

  • Java JDK 1.8 or later (32-bit only)

    Commerce SDK binaries are compiled for Java 8.

  • IDE (Integrated Development Environment)

    Intellij works nicely as Commerce SDK includes Gradle scripts.

  • Gradle 5.6.4

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

The Commerce SDK sample application package contains the following directories:

  • libs - Core Commerce SDK libraries and required 3rd party libraries (all the JAR files except for desktop-gui-0.1.0.jar are requirements for building the sample application)
  • nativeLibs - Native libraries for card reader communication, printer communication and lower-level Commerce SDK functionality
  • src - Source code for Commerce SDK sample application

note

To pre-configure the sample application to load your Converge credentials, modify the desktop.properties file. These credentials can also be modified from within the sample application through Settings | Credentials.

Using Microsoft Surface Pro to build the sample application may result in the JVM rendering 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 about 1024 x 768.

To import and build the sample application project (Gradle project), complete these steps:

  1. Extract the sample application project to a directory.
  2. Use the build.gradle file to import the sample application project into the IDE.
  3. You may need the following information 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: Must be running a 32-bit JVM

Integrate Commerce SDK with Windows Application

These Commerce SDK libraries (stored in the libs directory) are pre-compiled for application integration:

  • 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 Commerce SDK libraries, there are some required 3rd party dependencies that are pulled automatically when the Gradle build file is to be used.

To integrate Commerce SDK with a new or existing payment application, complete these steps:

  1. Initialize the Library and Gateway account.

    In addition to loading the Commerce SDK libraries, initialize and load the payment gateway account.

    ECCError error = ECLCommerceDesktop.initialize();
    if (error != null)
    {
        return error;  // Ensure no errors when initializing Commerce SDK
    }
    
  2. Implement the ECLConvergeAccountListener interface.

    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, implement the ECLConvergeAccountListener interface or the ECLCreditCallAccountListener interface.

    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)
        {
            // returns your Converge account's merchant ID
        }
    
        @Override
        public ECCSensitiveData getUserId(ECLAccountInterface eclAccountInterface)
        {
            // returns your Converge account's user ID
        }
    
        @Override
        public ECCSensitiveData getPin(ECLAccountInterface eclAccountInterface)
        {
            // returns your Converge account's PIN
        }
    
        @Override
        public ECCSensitiveData getPartnerAppId(ECLAccountInterface eclAccountInterface)
        {
            // returns your Converge account's partner app ID if you have one
            // this is optional and can be null
        }
    
        @Override
        public ECCSensitiveData getVendorId(ECLAccountInterface eclAccountInterface)
        {
            // returns your vendor ID
        }
    
        @Override
        public ECCSensitiveData getVendorAppName(ECLAccountInterface eclAccountInterface)
        {
            // returns your application name
        }
    
        @Override
        public ECCSensitiveData getVendorAppVersion(ECLAccountInterface eclAccountInterface)
        {
            // returns 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 Commerce SDK chose to use. This is determined to be the closest match to what you specified. Currently, Commerce SDK supports English in US and English and French in Canada.

            ECLLanguageInformation desiredLanguage = ...;
            ECLLanguageInformation finalValue = account.overrideDefaultTerminalLanguage(desiredLanguage);
    
    

    You can override the Commerce SDK 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 are 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
        }
    

    In 5.5, the following methods were added.

    @Override
    public void certificateUpdateRequired(ECLCertificateInfo eclCertificateInfo)
    {
        // do something - look in the sample app code for a concrete example
    }
    
    @Override
    public ECCSensitiveDataInterface getBridgeMaintenanceSystemUsername(ECLAccountInterface eclAccountInterface)
    {
        // return the bmsUsername - each integrator will have unique BMS credentials - get them from your solution engineer
    }
    
    @Override
    public ECCSensitiveDataInterface getBridgeMaintenanceSystemPassword(ECLAccountInterface eclAccountInterface)
    {
        // return the bmsPassword - each integrator will have unique BMS credentials - get them from your solution engineer
    }
    
    @Override
    public void bridgeMaintenanceSystemFailure(ECCError eccError)
    {
        // BMS is the system used to get TMS updates. For example BMS provides updated certificates.
        //
        //                            WARNING WARNING WARNING
        //  !!! Something went wrong when trying to communicate with BMS.                              !!!
        /// !!! If the failure is ECLAccountInvalidCredentials it MUST be addressed.                   !!!
        /// !!! Valid BMS credentials are required in order to keep certificates up to date.           !!!
        /// !!! No transactions will be processed if connecting over IP without valid BMS credentials. !!!
        ///
    }
    
    @Override public void bridgeMaintenanceSystemSuccess()
    {
        // no need to do anything here
    }
    
    @Override
    public ECLProxyInfo getProxyInfo()
    {
        // do something if proxy info is needed - look in the sample app code for a concrete example
    }
    
  3. Create a gateway account.

    Refer to the CommerceAccount class in the sample application.

    Create a Gateway Account Listener Implementation (See Converge account implementation CommerceAccountListener in the sample application). For more information on how to specify account information, as well as using the test environment, see class CommerceSettings in 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, Commerce SDK and the gateway account have been initialized and are ready to process transactions.

  4. Set up a Sale or Pre-Auth transaction.

    Define the baseTransactionAmount (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);
    
  5. Perform a card read and process the Sale or Pre-Auth transaction.

    Refer to the Transaction class in the sample application.

    With the transaction information defined, the card reader can be engaged and collect the card data.

    Create an Instance of ECLTransactionProcessingListener (handles 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);
    

Client Certificate for IP Communication

POS must implement certificateUpdateRequired(). In this method, POS should

  • store the certificate files

    note

    In the sample application code snippet, it is assumed that the client certificates are located in a directory named certificates relative to the working directory.

  • upon connecting, supply information in connection criteria (see [doclink id=“device-connection-criteria” product=“commerce-sdk”]Device Connection Criteria[/doclink])

    • supply certificate files using setConnectionParameters().
    • supply client keystore date using setClientKeyStoreDate().

POS must implement connectWithUpdatedKeystoreInfo(). In this method POS should

  • call ECLCardReaderInterface.connectWithUpdatedKeystoreInfo() passing ECLConnectionParameters.