# Integrating Peripherals

# General Overview

There is a series of External Peripherals (opens new window) that are supported on GoDaddy Poynt by default. However, there is a large number of other peripherals, accessories, or models that merchants may also want to connect to their terminal. For this reason, we have built an API that allows developers to connect new devices.

An Accessory Provider is an Android application that manages one of the accessories connected to the GoDaddy Poynt device. Some examples of accessories include Cash Drawer, Cash Register, Scale etc.

Once implemented, merchants can connect to the new accessory using GoDaddy Poynt Accessory Manager (opens new window).

# Creating an Accessory Provider

In order to create an accessory provider, please follow the steps outlined below.

  1. Register your application within the accessory manager by providing an XML definition in your AndroidManifest file.

  2. Create an Accessory Broadcast Receiver class to handle the ACCESSORY_ATTACHED and ACCESSORY_DETACHED intent actions.

  3. Create an Accessory Service class that will initialize and talk to the actual accessory when the events mentioned above are received.

  4. Expose Accessory functionality to the rest of the system by implementing a standard service interface.

# Registration

# Registering an Accessory Provider

The first step for providing support and managing an accessory is registering your application and accessory provided with Accessory Manager.

The registration is done using an XML defined in AndroidManifest.xml

<application>
    <!-- meta-data defines the list of accessories this app supports -->
    <!-- Poynt Accessory Manager will look for meta-data with name
    "co.poynt.accessory.resources" to get the list of supported accessories by this app.-->
    <meta-data
        android:name="co.poynt.accessory.resources"
        android:resource="@xml/accessory" />

    <receiver
        android:name=".AccessoryReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="co.poynt.accessory.manager.action.ACCESSORY_ATTACHED" />
            <action android:name="co.poynt.accessory.manager.action.ACCESSORY_DETACHED" />
        </intent-filter>
    </receiver>
</application>

You will also need to register your BroadcastReceiver class and the Intents ACCESSORY_DETACHED and ACCESSORY_ATTACHED as you see above.

Define the information of the accessory in an XML file. You will need to know the vendor id and product id of your accessory device.

<accessories xmlns:android="http://schemas.android.com/apk/res/android">
 <!-- model-name: Name of accessory as understood by user.
     This name should match the model name defined by manufacturer -->
 <!-- category: Defines the category of the device been supported -->
 <!-- package: name of the package designated to handle this accessory -->
 <!-- service_class: name of the service class that will expose interface for this accessory
      this service class could be different that actual accessory service.-->
 <!-- Please refer to AccessoryProvider and AccessoryType in Poynt SDK -->
 <!-- For example in order to expose CashDrawer function to rest of the system accessory
      provider service needs to implement ICashDrawerService interface. -->

 <!-- REQUIRED: application id of this app
      this appid is issued by poynt web portal
      IMPORTANT: Replace this appid with your appid.-->
 <!--<appid>urn:aid:0f39b7a3-b9db-41f1-9cdb-9f04a3620ade</appid>-->
 <appid>urn:aid:d3462a56-737b-4419-b54c-39a59f4dc8d6</appid>

<!--
Supported categories:
- "Printer"
- "Cash Drawer"
- "Scanner"
-->
  <accessory
       category="Cash Drawer"
       model-name="Generic"
       version="1.0"
       service_class="co.poynt.accessory.CashDrawerService"
       type="usb" >
       <usb-device
           product-id="12345"
           vendor-id="1234" />
   </accessory>
</accessories>

# Implementing a Broadcast Receiver

The implementation of a broadcast receiver is necessary to begin receiving accessory events.

public class AccessoryReceiver extends BroadcastReceiver {
    public static final String TAG = "AccessoryReceiver";
    public static final String ACCESSORY_ATTACHED = "co.poynt.accessory.manager.action.ACCESSORY_ATTACHED";
    public static final String ACCESSORY_DETACHED = "co.poynt.accessory.manager.action.ACCESSORY_DETACHED";
    public static final String EXTRA_USB_DEVICE = "co.poynt.accessory.manager.extra.USB_DEVICE";
    public static final String EXTRA_MODEL_NAME = "co.poynt.accessory.manager.extra.MODEL_NAME";
    public static final String EXTRA_MODEL_CATEGORY = "co.poynt.accessory.manager.extra.MODEL_CATEGORY";
    public static final String EXTRA_MODEL_VERSION = "co.poynt.accessory.manager.extra.MODEL_VERSION";
    public static final String CATEGORY_CASH_REGISTER = "Cash Register";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (ACCESSORY_ATTACHED.equals(intent.getAction())) {
            UsbDevice device = (UsbDevice) intent.getParcelableExtra(EXTRA_USB_DEVICE);
            String category = intent.getStringExtra(EXTRA_MODEL_CATEGORY);
            if (device != null) {
                Intent service_intent = null;
                if (CATEGORY_CASH_REGISTER.equals(category)) {
                    service_intent = new Intent(context, CashRegisterService.class);
                } // other device type if supported.
                if (service_intent != null){
                    service_intent.setAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
                    service_intent.putExtra(EXTRA_MODEL_NAME, intent.getStringExtra(EXTRA_MODEL_NAME));
                    service_intent.putExtra(EXTRA_MODEL_CATEGORY, intent.getStringExtra(EXTRA_MODEL_CATEGORY));
                    service_intent.putExtra(UsbManager.EXTRA_DEVICE, device);
                    context.startService(service_intent);
                }
            }

        } else if (ACCESSORY_DETACHED.equals(intent.getAction())) {
            UsbDevice device = (UsbDevice) intent.getParcelableExtra(EXTRA_USB_DEVICE);
            if (device != null) {
                String category = intent.getStringExtra(EXTRA_MODEL_CATEGORY);
                Intent service_intent = null;
                if (CATEGORY_CASH_REGISTER.equals(category)) {
                    service_intent = new Intent(context, CashRegisterService.class);
                }// other device type if supported.
                if (service_intent != null){
                    service_intent.setAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
                    service_intent.putExtra(EXTRA_MODEL_NAME, intent.getStringExtra(EXTRA_MODEL_NAME));
                    service_intent.putExtra(EXTRA_MODEL_CATEGORY, intent.getStringExtra(EXTRA_MODEL_CATEGORY));
                    service_intent.putExtra(UsbManager.EXTRA_DEVICE, device);
                    context.startService(service_intent);
                }
            }
        }
    }
}

Implement the Accessory Service that will initialize the accessory and will implement an accessory service interface to expose the functionality of its accessory to the rest of the system.

public class CashDrawerService extends Service {
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        lastAccessoryModelName = intent.getStringExtra(AccessoryReceiver.EXTRA_MODEL_NAME);
        lastAccessoryCategory = intent.getStringExtra(AccessoryReceiver.EXTRA_MODEL_CATEGORY);
        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
            lastAttachedUsbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            onCashDrawerAttached(lastAttachedUsbDevice,
                    lastAccessoryModelName, lastAccessoryCategory);
        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
            UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            onCashDrawerDetached(device, lastAccessoryModelName,
                    lastAccessoryCategory);
            if (device.getProductId() == lastAttachedUsbDevice.getProductId()
                    && device.getVendorId() == lastAttachedUsbDevice.getVendorId()) {
                lastAttachedUsbDevice = null;
            }
        }
        return START_STICKY;
    }
    /**
     * Implements interface to provide draw open command to the client via service api.
     */
    private final IPoyntCashDrawerService.Stub mBinder = new IPoyntCashDrawerService.Stub() {
        @Override
        public void openDrawer(String referenceId, IPoyntCashDrawerServiceListener callback) throws RemoteException {
            Log.d("openDrawer()");
            if(open()){
                CashDrawerStatus drawerStatus = new CashDrawerStatus(CashDrawerStatus.Code.OPENED, "Cash Drawer opened");
                callback.onResponse(drawerStatus, requestId);
            }else{
                CashDrawerStatus drawerStatus = new CashDrawerStatus(CashDrawerStatus.Code.ERROR, "Failed to open cash drawer");
                callback.onResponse(drawerStatus, requestId);
            }
        }

        public void getDrawerStatus(String referenceId, IPoyntCashDrawerServiceListener callback) throws RemoteException{
             //TODO handle
        }

        public void getDrawerStatusByName(String name, String referenceId, IPoyntCashDrawerServiceListener callback) throws RemoteException{
            //TODO handle
        }

        public void openDrawerByName(String name, String referenceId, IPoyntCashDrawerServiceListener callback) throws RemoteException{
            //TODO handle
        }

    };

    public boolean open(){
        //TODO Implement your "open()" method that communicates with the cash drawer
    }
}

Once you install your accessory application and connect the peripheral, you should get a notification from the GoDaddy Poynt Accessory Manager.

This notification will only show once.

Launcher selection

If you follow the path Settings > Accessory, you should see your accessory there, which you can remove or disable if needed.

Launcher selection

To create an accessory application for a printer, you will need to implement IPoyntPrinterService (opens new window) and IPoyntScannerService (opens new window) for a scanner.

Last Updated: 9/4/2023, 1:28:22 PM