4.3. mPOS SDK for Android and Java

Introduction

Elecsnet mPOS SDK is a mobile payment software & hardware package that allows to quickly and easily start offering a mobile payment service. Usage of an affordable mobile point of sale (mPOS) terminal allows Connecting party to extend their business with in-person non-cash payments.

@startuml
left to right direction
rectangle "Mobile Device" {
(mPOS SDK)  #ffe6cc;line:black;line.dotted
(Mobile App)
}
(Elecsnet) -- (mPOS SDK)
(Elecsnet) - (Acquirer Bank)
(mPOS SDK) -- (Mobile App)
(mPOS device) - (mPOS SDK)
@enduml

PayneteasyReader SDK provides fast integration with mPOS terminals in mobile apps.

Features

  • Runs both on Android and Java

  • MSR, EMV Contact, EMV Contactless transactions

  • Signature or PIN based transactions

  • Remote key injection

  • Remote firmware update

  • Remote mPOS configuration

  • Certified with OpenWay. The first mobile POS Chip&PIN solution in Russia - https://www.openwaygroup.com/news_card.jsp?dcion=908&rgn=1&lng=1

  • Custom LCD messages for all stages (Miura only)

  • Unified API for all readers

  • Implemented Elecsnet Server API

  • Many transaction types: sale, preauthorization, capture, cancel, reversal, partial reversal and etc.

Note

Requirements: SDK supports target deployment of Android from 2.2 and Oracle JVM (tested on 1.8)

Supported Terminals

Vendor

Model

Connectivity

Miura

M006, M007, M010

Supports MSR, Contact, Contactless transactions. With or without PIN. Remote keys injection, remote configuration and remote MPI and OS update

Spire

SPm2

Bluetooth

Verifone

Vx820

Ethernet, USB, RS232

PAX

SP30

Ethernet, USB, RS232

Note

All terminals support remote configuration and firmware update.

Warning

Deprecated from the 1st of January 2015:
GD Seed: Integrated with the official SDK.
GD Seed: Own SDK. With memory and performance optimization.
ID Tech Unimag II: Integrated with the official SDK.
ID Tech Unimag II: Own SDK. Memory and performance optimization. Extends supported phone models.
Bluebamboo P25.

Warning

Evaluated:
Datecs DRD50, DRD10
Datecs MPED400, Bluepad 50
Wizar POS
BBPOS

Integration

The SDK includes a maven repository - http://paynet-qa.clubber.me/reader/maven/ For Miura Shuttle model: Use TEST on emulators for events.

Setup maven

Android Maven repository can be found here. Add the repository to pom.xml:

<repository>
  id>reader-repo</id>
  <name>reader repo</name>
  <url>http://paynet-qa.clubber.me/reader/maven</url>
</repository>`

Setup gradle

Android Gradle repository can be found here. Add the following to repositories section:

 repositories {
...
   maven { url "https://jitpack.io" }
   maven { url "http://paynet-qa.clubber.me/reader/maven" }
...
 }
  • Add the following to dependencies:

dependencies {
...
  def readerVersion = // check the latest version :ref:`here<https://github.com/payneteasy/reader-example/wiki/Changelog>`
  compile 'com.payneteasy.android.reader:api:' + readerVersion
  compile ('com.payneteasy.android.reader:lib:' + readerVersion)

  compile 'com.payneteasy.android.reader.readers:readers-common-bluetooth:' + readerVersion
  compile ('com.payneteasy.android.reader.readers:readers-miura:' + readerVersion) {
      exclude group:'junit', module:'junit'
  }
...
}

For additional details, please refer to the complete Gradle example available here.

For Bluetooth Readers (Android)

Add the following to AndroidManifest.xml:

<uses-permission android:name="android.permission.BLUETOOTH"/>
   <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

For USB terminals (Android)

  • Add new file res/xml/device_filter.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <!-- 0x1234 / 0x0101  PAX / S80 -->
  <usb-device vendor-id="4660" product-id="257" class="255" subclass="0" protocol="0"/>

  <!-- 0x11CA / 0x0219  VeriFone Inc / Trident USB Device 1.1 / bInterfaceClass = 10 CDC Data -->
  <usb-device vendor-id="4554" product-id="537" class="10" subclass="0" protocol="0"/>

</resources>
  • Add any activity element to AndroidManifest.xml:

<intent-filter>
      <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
  </intent-filter>
  <meta-data  android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />`
  • Add to the activity:

public class MainActivity extends Activity {

   private final UsbPermissionResolver usbPermissionResolver = new UsbPermissionResolver();

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       ...
       usbPermissionResolver.checkPermission(getIntent(), this);
   }

   @Override
   protected void onNewIntent(Intent intent) {
       super.onNewIntent(intent);
       usbPermissionResolver.checkPermission(intent, this);
   }

   @Override
   protected void onDestroy() {
       super.onDestroy();
       usbPermissionResolver.unregister(this);
   }

   ...

   }

Note

Please see this commit for more information.

For Miura (Java)

Please see the example app-2 how to run and assemble the application for Miura Readers to run on JVM.

app-3-webstart shows how to run the application from a browser via Java WebStart:

Sample Code

Implement the IReaderPresenter interface:

@Override
  public ProcessingContinuation onCard(BankCard bankCard) {

      setStatus("onCard: %s", bankCard);

      return ProcessingContinuation.Builder
              .startSaleOnline()
              .processingBaseUrl  ( Config.SERVER_BASE_URL)
              .merchantLogin      ( Config.MERCHANT_LOGIN )
              .merchantControlKey ( Config.MERCHANT_KEY   )
              .merchantEndPointId ( Config.END_POINT_ID   )
              .orderDescription   ( "test description"    )
              .orderInvoiceNumber ( "invoice-"+System.currentTimeMillis())
              .orderMerchantData  ( "custom merchant data for a internal use")
              .customerPhone      ( "+7 499 918-64-41"    )
              .customerEmail      ( "info@payneteasy.com" )
              .customerCountry    ( "RUS"                 )
              .listener(new IProcessingStageListener() {
                  @Override
                  public void onStageChanged(ProcessingStageEvent aEvent) {
                      setStatus("processing: %s", aEvent);
                  }
              })
              .build();

  }

  @Override
  public void onReaderSerialNumber(String aKsn) {
      setStatus("onReaderSerialNumber: %s", aKsn);
  }

  @Override
  public void cardReaderStateChanged(CardReaderEvent cardReaderEvent) {
      setStatus("cardReaderStateChanged: %s", cardReaderEvent);
  }

  @Override
  public void onCardError(CardError cardError) {
      setStatus("onCardError: %s", cardError);
  }

  @Override
  public void onReaderNotSupported(CardReaderProblem aProblem) {
      setStatus("onReaderNotSupported: %s", aProblem);
  }

  @Override
  public void onAudioData(short[] shorts, int i) {
      // for visualization
  }

  @Override
  public ConfigurationContinuation onConfiguration() {
      return new ConfigurationContinuation.Builder()
              .configDir              ( new File(activity.getFilesDir(), "miura-config"))
              .configurationBaseUrl   ( Config.SERVER_CONFIG_URL  )
              .merchantLogin          ( Config.MERCHANT_LOGIN     )
              .merchantControlKey     ( Config.MERCHANT_KEY       )
              .merchantEndPointId     ( Config.END_POINT_ID       )
              .build();
  }

Note

Fill the Config.MERCHANT_LOGIN, Config.MERCHANT_KEY, Config.END_POINT_ID with your own values.

Starts the Reader Manager:

CardReaderInfo cardReader = CardReaderInfo.TEST;
BigDecimal amount = new BigDecimal(1);
String currency = "RUB";

SimpleCardReaderPresenter presenter = new SimpleCardReaderPresenter(this, statusView);
cardReaderManager = CardReaderFactory.findManager(this, cardReader, presenter, amount, currency, null);`

Deal with cardReaderManager:

  • ICardReaderManager.startSaleSession() starts a sale session

  • ICardReaderManager.stopSession() stops a session and releases resources