npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

magensa-bluetooth

v1.1.2

Published

Interface between Chromium browser and MagTek devices

Downloads

10

Readme

magensa-bluetooth

npm version
Interface between MagTek® Bluetooth devices, and Chromium based browsers.

Browser Support

Chrome | Opera | Edge | Samsung | --- | --- | --- | --- | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ |

This library utilizes WebBluetooth API.
WebBluetooth compatibility information can be found at the implementation status README and caniuse.com.
Additionally, we have put together detailed compatibility information, as well as initial pair instructions, in our Playground.

Installation

NPM:

npm install magensa-bluetooth

Yarn:

yarn add magensa-bluetooth

Grab your MagTek® device and Get Started

In order to utilize this library, you must have a MagTek® device with Bluetooth capabilities. Currently the compatible devies are

If you have a device, and would like to see this library in action, please head over to our Playground.
If you would like to purchase a device, please head over to the MagTek Store.

Usage

The implementation below will prompt a pair window displaying all MagTek devices in range. Once the end user selects the appropriate device from the pair window, the response to this function call will be a device object.
The device pair window is part of the WebBluetooth API, and is currently mandatory (no bypass exists as of this time).

import { scanForDevices } from 'magensa-bluetooth';

function exampleCallback(dataObj) {
    console.log("data send from device", dataObj);
};

//Using Promises:
scanForDevices(exampleCallback).then( connectedDevice => 
    /*
        'connectedDevice', in this example, is a return object containing device information  
        and the interface needed to interact with your paired device.  
        See Device Object under the 'Return Objects' header below, for more details.  

        Store this device object in a manner that makes sense for your application.  
        This example saves the object to a global namespace:  
    */
    window.MagTekDevice = connectedDevice;
    /*
        Now the device can be acccessed globally. 
        if you wish to limit the scope of the connected device - please do so at your discretion.
    */
).catch(err => console.error(err));

//Using async/await:
const examplePairing = async() => {
    try {
        const connectedDevice = await scanForDevices(exampleCallback);
        /*  
            Now 'connectedDevice' contains the device object.  
            Store this in a manner that makes sense for your application.  
        */
        window.MagTekDevice = connectedDevice;
    }
    catch(error) {
        console.error(error);
    }
}

The callback function(s) provided are the only way the paired device can send data to the host.

  • All data returned to the provided callbacks will be of type object. Please see Return Objects section for more information.
  • Please see the Callbacks section below for more information about user provided callback functions.
  • For single page applications, please ensure that the callback function(s) provided is always "mounted" to receive data.

Device Interface API

All methods are asynchronous (isDeviceOpen being the only synchronous exception). Be sure to catch all exceptions - as any error occured upon invocation of these functions will throw an Error.

| Function | Input Parameters | Output | Notes | |:--------:|:-------:|:-------:|:--------:| | scanForDevices | callbacks [,deviceName[, deviceType]] | Device Object | Please refer to callback examples below. Device name is optional. Device type is optional and supports special cases. Available types listed here | | startTransaction | emvOptions | Success | Initiates EMV transaction. emvOptions is optional - any property supplied will override the default | | cancelTransaction | none | Success | Cancel any transaction that is in progress. | | openDevice | none | Success | Opens paired device to receive commands | | closeDevice | none | Success | Clears session (when applicable) and closes device safely | | clearSession | Number (optional) | Success | Removes previous card data from device's volatile memory. Only PinPad devices have session. Optional input is "Bitmap slot number" for displaying custom display templates | | deviceInfo | none | Device Information | Be aware this call will clear device session prior to returning device information | | requestCardSwipe | swipeOptions | Success | swipeOptions is optional. Any property supplied will override the default| | isDeviceOpen | none | Boolean | synchronous function that returns device's open status | | sendCommand | Hex String or Array<Number> | object | send raw command to device. Output will be an object (if the response has a parser) or array (if returning raw device response) | | forceDisconnect | none | void | Sever device connection, in the case that the device becomes unresponsive | | requestPinEntry | pinOptions | Success | PinPad devices only | | setDisplayMessage | displayOptions | Success | PinPad devices only | | sendUserSelection | Number | Success | SCRA devices only. This command is only used to respond to device's userSelectionRequest | | sendArpcResponse | Hex String or Array<Numbers> | Success | For more information about building ARPC, please see the MagTek® documentation | | setDeviceDateTime | JavaScript Date object | Success | SCRA devices only | | requestTipOrCashback | tipCashbackOptions | Success | DynaPro Go Only |

EMV Options Object

Emv Options object is the input object for the startTransaction function. All property values have default values. Any property supplied will override the default value, while any not supplied will use default values.
There are some differences between devices - so this section will be broken down into four parts:

  1. Properties that are shared by both device types
  2. Properties for SCRA devices only
  3. PinPad properties only
  4. DynaPro Go properties only

Shared Properties:


| Property Name | Description | Type | Acceptable Values | Default Value | |:------------:|:-----------:|:--------------:|:---------------:|:---------------:| | timeout | time, in seconds, before transaction timeout | Number | 1 - 255 | 60 | | cardType | types of cards to accept for transaction | String | 'msr', 'chip', 'chipMsr', 'contactless', 'contactlessChip', 'all' | chipMsr | | cashBack | amount to process as cashback transaction. For transactionType 'refund', this value must be 0 | Number or Array<Numbers> | Number or 6 'byte' n12 format representation of number Number type has limitations, please plan accordingly | 0 | | currencyCode | type of currency. 'default' uses device's application terminal setting (usually USA dollar) | String | 'dollar', 'euro', 'pound', 'default'| 'dollar' | | authorizedAmount | amount to authorize for transaction. For transactionType 'refund', this value must be 0 | Number or Array<Numbers> | Number or 6 'byte' n12 format representation of number Number type has limitations, please plan accordingly | 100 |

SCRA properties only:


| Property Name | Description | Type | Acceptable Values | Default Value | |:------------:|:-----------:|:--------------:|:---------------:|:---------------:| | emvOptions | online EMV options | String | 'normal', 'byPassPin', 'forceOnline', 'quickChip', 'pinByPassQuickChip', 'forceOnlineQuickChip' |'quickChip' | | transactionType | type of transaction to process | String | 'purchase', 'cashback', 'refund', 'contactlessCashback' | 'purchase' | | reportVerbosity | EMV Transaction Status/Progress messaging level | String | 'minimum', 'medium', 'verbose' | 'minimum' |

PinPad properties only:


| Property Name | Description | Type | Acceptable Values | Default Value | |:------------:|:-----------:|:--------------:|:---------------:|:---------------:| | emvOptions | online EMV options | String | 'normal', 'byPassPin', 'forceOnline', 'acquirerNotAvailable' | 'normal' | | transactionType | type of transaction to process | String | 'purchase', 'cashAdvance', 'cashback', 'purchaseGoods', 'purchaseServices', 'cashManual', 'refund', 'chipOnlyPayment' | 'purchase' | | pinTimeout | wait time in seconds for cardholder to enter PIN | Number | 1 -255 |20 | | toneChoice | Select device beep behavior | String | 'noSound', 'oneBeep', 'twoBeeps' | 'oneBeep' | | isQuickChip | arm in QuickChip mode, or not | Boolean | true or false | true |

DynaPro Go properties only:


| Property Name | Description | Type | Acceptable Values | Default Value | Notes | |:------------:|:-----------:|:--------------:|:---------------:|:---------------:|:---------------:| | taxAmount | Total tax amount | Number or Array<Numbers> | Number or 6 'byte' n12 format representation of number | 0 | No decimal points. Number type has limitations, please plan accordingly | | taxPercent | Tax percentage rate | Number or Array<Numbers> | Number or 4 'byte' (n6 format x 100) representation of number | 0 - 99 |This number is for display purposes only - device does not perform tax calculations | | tipAmount | Total tip amount | Number or Array<Numbers> | Number or 6 'byte' n12 format representation of number | 0 | No decimal points. Number type has limitations, please plan accordingly | | balanceBeforeGenAC | (Contactless Only) Balance Read Before Gen AC (EMV Tag DF8104) | Number or Array<Numbers> | Number or 6 'byte' n12 format representation of number | 0 | No decimal points. Number type has limitations, please plan accordingly | | balanceAfterGenAC | (Contactless Only) Balance Read After Gen AC (EMV Tag DF8105) | Number or Array<Numbers> | Number or 6 'byte' n12 format representation of number | 0 | No decimal points. Number type has limitations, please plan accordingly | | trxCategoryCode | (PayPass/MCL Tag 9F53) | Number | N/A | 0 | Optional value |

Swipe Options Object

Swipe options are only valid for PinPad devices. Swipe options passed to a SCRA device will be ignored.

| Property Name | Description | Type | Acceptable Values | Default Value | |:------------:|:-----------:|:--------------:|:---------------:|:---------------:| | timeout | time, in seconds, before transaction timeout | Number | 1 - 255 (0 for infinite wait) | 60 | | displayType | choose which display customer will see on device display | | 'swipeIdleAlternate', 'swipeCard', 'pleaseSwipe', 'pleaseSwipeAgain', 'chipErrorUseSwipe' | 'pleaseSwipe' | | toneChoice | Select device beep behavior | String | 'noSound', 'oneBeep', 'twoBeeps' | 'oneBeep' | | isFallback | execute swipe with fallback flag. Be aware this will set displayType to 'chipErrorUseSwipe' | Boolean | true or false | false |

PIN Options Object

| Property Name | Description | Type | Acceptable Values | Default Value | Notes | |:------------:|:-----------:|:--------------:|:---------------:|:---------------:|:---------------:| | languageSelection | Define language prompt behavior | String | 'disabled', 'englishFrench', 'allSpecified' | 'disabled' | 'allSpecified' uses tag DFDF2D to define available languages | | displayType | Define prompt template for PIN entry | String | 'enterPin', 'enterPinAmount', 'reEnterPin', 'reEnterPinAmount', 'verifyPin' | 'enterPin' | | | timeout | time, in seconds, before requestPin timeout | Number | 0 - 255 (0 for 256 seconds) | 30 | | | toneChoice | Select device beep behavior | String | 'noSound', 'oneBeep', 'twoBeeps' | 'oneBeep' | | | pinBlockFormat | Define Pin Block Format | String | 'iso0', 'iso3' | 'iso0' | This value is only respected if device is sent a PAN. If device has no PAN, device creates EPB using ISO Format 1 | | verifyPin | Should device prompt for PIN verification | Boolean | true, false | true | | | waitMessage | Display wait message | Boolean | true, false | true | | | maxPinLength | Specify maximum PIN length | Number | <=12 && >= minPinLength | 12 | Value must be <=12 and >= minPinLength | | minPinLength | Specify minimum PIN length| Number | >=4 && <= maxPinLength | 4 | Value must be >=4 and <= maxPinLength |

Tip Cashback Options Object

| Property Name | Description | Type | Acceptable Values | Default Value | Notes | |:------------:|:-----------:|:--------------:|:---------------:|:---------------:|:---------------:| | timeout | time (in seconds) before operation timeout | Number | 1 - 60 | 30 | | | commandType | Tip or Cashback Mode | String | 'tip', 'cashback' | N/A | commandType is required | | toneChoice | Select device beep behavior | String | 'noSound', 'oneBeep', 'twoBeeps' | 'oneBeep' | | | transactionAmount | Subtotal amount for transaction | Number or Array<Numbers> | Number or 6 'byte' n12 format representation of number | N/A | No decimal points. Number type has limitations, please plan accordingly | | calculatedTaxAmount | Total tax amount | Number or Array<Numbers> | Number or 6 'byte' n12 format representation of number | N/A | No decimal points. Number type has limitations, please plan accordingly | | taxRate | Tax percentage rate | Number or Array<Numbers> | Number or 4 'byte' (n6 format x 100) representation of number | 0 - 99 | This number is for display purposes only - device does not perform tax calculations. taxRate is required | | tipSelectionMode | Preset tip amount type | String | 'percent', 'amount' | N/A | This value is only mandatory in Tip mode. N/A for Cashback Mode | | leftAmount | Fixed Percent or Amount for left display | Number | 0-99 | 0 | N/A for Cashback Mode | | middleAmount | Fixed Percent or Amount for middle display | Number | 0-99 | 0 | N/A for Cashback Mode | | rightAmount | Fixed Percent or Amount for right display | Number | 0-99 | 0 | N/A for Cashback Mode |

Display Options Object

| Property Name | Description | Type | Acceptable Values | Default Value | Notes | |:------------:|:-----------:|:--------------:|:---------------:|:---------------:|:---------------:| | messageId | Id for message to display | Number | Acceptable IDs are listed here | N/A | No default value - ID is required | | displayTime | How long the display message will display on screen | Number | 0 (infinite) - 255 | 15 seconds | |

Callbacks

User defined callback functions can be as granular as desired. For this purpose - there is only one callback that is mandatory to provide to the scanForDevices method. The remaining callbacks are subscription based. In reference to the return objects for the below callbacks - please see the Return Objects section for object structures.

errorCallback is the only special case. Please see description for behavior. For all other callbacks - if one is not provided - data will be sent to the main callback (transactionCallback). This can sometimes clutter the callback data, and become problematic, so please plan callback structure according to your specific needs.

| Callback | Return object | Notes | |:--------:|:-------------:|:-----:| | transactionCallback | Transaction Result Object | Transaction data. Object structure will depend on which type of transaction was requested. This is the only mandatory callback, as it serves as the main/default callback. | | errorCallback | Error Object | If provided, all internal errors that cannot be thrown to a caller will be piped to this callback. If not provided, internal errors will log to JavaScript console. All errors pertaining to functions invoked via the deviceInterface will always be thrown back to the caller | | displayCallback | Display Message Object | Message to display directly to the end user. This callback is only used by SCRA devices. PinPad devices will display messages directly on the device | | transactionStatusCallback | Transaction Status Object | Status, Progress, Messages, and Codes will all be piped to this callback. You can throttle reportVerbosity on SCRA devices | | disconnectHandler | Disconnect Event | Disconnect Event inherits from Event. Disconnect events are emitted every time a device disconnects (closes) | | userSelectionCallback | userSelectionRequest | SCRA devices that have multiple applications, and process a card with multiple applications will send this report. User must select item from the menu items listed in the report and respond using the sendUserSelection function with the menu selection number |

Callback Examples

This is the most basic example - using Promises.

let exampleCallback = responseObj => {
    /*
        For a single callback, all responses will be passed to this callback.
        You can filter by properties in the responseObj, if desired.
        For example...
    */

    if ('swipeData' in responseObj) {
        //process swipe data.
    }
}

scanForDevices(exampleCallback)
    .then( device => {
        window.MagTekDevice = device
    })
    .catch( errObj => {
        console.log(errObj)
    });

This is the most basic example - using async/await.

let exampleCallback = responseObj => {
    /*
        For a single callback, all responses will be passed to this callback.
        You can filter by properties in the responseObj, if desired.
        For example...
    */

   const { swipeData } = responseObj;

   if (swipeData) {
       //process swipe data.
   }
}

const connectDevice = async() => {
    try {
        let deviceResp = await scanForDevices(exampleCallback)

        window.MagTekDevice = devicedeviceResp
    }
    catch(error) {
        console.log(error)
    }
}

These are two examples of the most granular way to interact with this library:

Structure callbacks using function property assignment:


const callbacks = (function() {
    const allCallbacks = responseObj => {
        /*
            This will be the main callback, also known as the 'transactionCallback'.
            Since we are using an IIFE to structure callbacks, we don't need to explicitly assign this value.
        */

        if ('swipeData' in responseObj) {
            //Handle swipe data.
        }
    }

    allCallbacks.errorCallback = errObj => {
        /*
            Handle all internal errors that cannot be thrown back to a caller.
            If this callback is not provided - internal errors will be logged to the JavaScript console.
        */
    }

    allCallbacks.transactionStatusCallback = statusObj => {
        /*
            Handle or log all transaction status, progress, codes and messages.
            This callback is great for debugging and device visibility.
        */
    }

    allCallbacks.displayCallback = ({ displayMessage }) => {
        /*
            Handle all user display messages.
            For SCRA devices - EMV standards state this message must be displayed directly to the user.
            PinPad devices will not use this callback, and will instead use the device display.
            The message language is determined by device configuration.
        */
        document.getElementById('display-to-user').innerText = displayMessage;
    }

    allCallbacks.userSelectionCallback = ({ userSelectionRequest }) => {
        /*
            Respond to any User Selection Request Notifications.
            SCRA devices with multiple applications only.
        */
    }

    allCallbacks.disconnectHandler = event => {
        //Handle device disconnect events.
        let message = `Device: ${event.target.name} has disconnected`;
    }

    return allCallbacks;
})();

//Using Promises
scanForDevices(callbacks)
    .then( device => {
        window.MagTekDevice = device
    })
    .catch( errObj => {
        console.error("Caught Error: ", errObj);
    });
    

//Using async/await
const pairDevice = async() => {
    try {
        const deviceResp = await scanForDevices(callbacks);
        window.MagTekDevice = deviceResp;
    }
    catch(error) {
        console.error("Caught Error: ", errObj);
    }
}

Structure callbacks using an Object:

const exampleErrorHandler = errObj => {
    /*
        Handle all internal errors that cannot be thrown back to a caller.
        If this callback is not provided - internal errors will be logged to the JavaScript console.
    */
}

const exampleTransactionHandler = dataObj => {
    //Handle all transaction/card data.
}

const exampleTransactionStatusHandler = statusObj => {
    /*
        Handle or log all transaction status, progress, codes and messages.
        This callback is great for debugging and device visibility.
    */
}

const exampleDisplayMessageHandler = ({ displayMessage }) => {
    /*
        Handle all user display messages.
        For SCRA devices - EMV standards state this message must be displayed directly to the user.
        PinPad devices will not use this callback, and will instead use the device display.
        The message language is determined by device configuration.
    */
    document.getElementById('display-to-user').innerText = displayMessage;
}

const exampleDisconnectHandler = event => {
    //Handle device disconnect events.
    let message = `Device: ${event.target.name} has disconnected`;
}

const exampleUserSelectionCallback = ({ userSelectionRequest }) => {
     /*
        Respond to any User Selection Request Notifications.
        SCRA devices with multiple applications only.
    */
}

//Note that when structuring multiple callbacks in an object - 'transactionCallback' becomes mandatory.

let callBackObject = {
    transactionCallback: exampleTransactionHandler,
    errorCallback: exampleErrorHandler,
    displayCallback: exampleDisplayMessageHandler,
    transactionStatusCallback: exampleTransactionStatusHandler,
    disconnectHandler: exampleDisconnectHandler,
    userSelectionCallback: exampleUserSelectionCallback
}

//Using Promises
scanForDevices(callBackObject)
    .then( device => {
        window.MagTekDevice = device
    })
    .catch( errObj => {
        console.error("Caught Error: ", errObj);
    });
    

//Using async/await
const connectDevice = async() => {
    try {
        const deviceResp = await scanForDevices(callBackObject);
        window.MagTekDevice = deviceResp;
    }
    catch(error) {
        console.error("Caught Error: ", errObj);
    }
}

Return Objects

1. Device Object

{
    id: String,
    name: String,
    deviceType: String,
    deviceInterface: {
        openDevice: Function
        startTransaction: Function
        cancelTransaction: Function
        sendCommand: Function
        clearSession: Function
        closeDevice: Function
        deviceInfo: Function
        requestCardSwipe: Function
        isDeviceOpen: Function
        forceDisconnect: Function
        requestPinEntry: Function
        setDisplayMessage: Function
        sendUserSelection: Function
        sendArpcResponse: Function
        setDeviceDateTime: Function
        requestTipOrCashback: Function
    }
}

2. Transaction Result Object:

arqcData and batchData are hex strings that are unparsed, and contain the same data as the parsed objects.

{
    arqcData: String,
    arqcDataParsed: [
        { tag: String, length: Number, value: String }, 
        { tag: String, length: Number, value: String }
    ],
    batchData: String,
    batchDataParsed: [
        { tag: String, length: Number, value: String },
        { tag: String, length: Number, value: String }
    ],
    swipeData: {
        ksn: String,
        Last4: String,
        encSessionId: String,
        expirationDate: String, // MM/DD format
        magnePrint: String,
        magnePrintStatus: String,
        maskedPAN: String,
        serialNumber: String,
        track1: String,
        track1Masked: String,
        track1DecodeStatus: Number,
        track2: String,
        track2DecodeStatus: Number,
        track2Masked: String,
        track3: String,
        track3DecodeStatus: Number,
        track3Masked: String
    },
    signatureRequired: Boolean
}

3. Display Message Object:

{
    displayMessage: String
}

4. Transaction Status Object:

{
    transactionStatus: {
        statusCode: Number,
        statusMsg: String,
        progressCode: Number,
        progressMsg: String
    }
}

5. Error Object

There are many error objects, depending on what layer threw the error. All errors extend JavaScript's Error. All have the following properties.

{
    Error: {
        code: Number,
        name: String,
        message: String
    }
}

6. Success Object

{
    code: 0,
    message: String
}

7. Device Information

{
    deviceName: String,
    deviceType: String,
    isConnected: Boolean,
    serialNumber: String,
    batteryLevel: Number //Scra devices only - Pin devices display battery level
}

8. Tip Cashback Report

{
    tipCashbackReport: {
        operationStatus: String,
        reportMode: String,
        amount: Array<Number>,
        tax: Array<Number>,
        taxRate: Array<Number>,
        tipOrCashbackAmount: Array<Number>
    }
}

9. Pin Data Report

{
    pinData: {
        operationStatus: String,
        pinKsn: String,
        encryptedPinBlock: String
    }
}

10. User Selection Request

{
    userSelectionRequest: {
        selectionType: String,
        timeRemaining:  Number,
        menuItems: Array<Number>
    }
}

Playground and Additional Information

Please visit our Playground for an interactive demo.

  • The Playground also offers detailed compatibility information, as well as first time pairing instructions for all compatible browsers and operating systems.
  • The Playground source code is also available as an example implementation.

Debug Event

For added visibility during development, this library has a debug event emitter (deviceLog) that will log verbose details for all device interactions.
This can be especially useful when a bad command is sent - or to see the behavior when a device begins to refuse commands.
If you wish to subscribe to the event, you may do so:

const debugLogger = logInfo => console.log(logInfo.detail);

window.addEventListener('deviceLog', debugLogger, { passive: true});
//Be sure to remove it when unmounting to avoid memory leaks:
window.removeEventListener('deviceLog', debugLogger, { passive: true});

WebBluetooth Info

There are some WebBluetooth issues that users of this library should be made aware of:

  • The initial pairing process (wherin the Chromium browser, and the Operating System coincide the Bluetooth Pair) can be a bit challenging at times. To that end, a comprehensive list of pairing instructions, based upon browser choice and operating system, has been put together in our Playground.
    • Select a browser, operating system, expand the panel and click "Specific Details".
    • Most all users that have trouble getting this library started, need to follow the instructions to the letter.
      • Also, following the instructions to the letter, in addition to a device power cycle, will solve most all initial pairing issues.
    • Remember this initial pair is one-time only, and does not need to be repeated to utilize the library (or any WebBluetooth solution) in the future.
  • There is a simple check that can be included in the web application that consumes this library, to see if the client is using a compatible browser. That check is as follows:
        if (navigator && navigator.bluetooth) { 
            //Compatible
        }
        else {
            //Not Compatible browser
        }
    • It is important to note that compatible browsers will fail this check if the site is not deployed through secure context (valid https:// domain).
      • localhost will work for development purposes, but it's important to note that 192.168.0.1: and 127.0.0.1 will both fail the secure context check.
        • This is especially important to consider for active mobile development.
      • When a compatible browser fails the secure context check - the bluetooth property is removed from the navigator object. No other error or warning is emitted.

Transaction Amount Limitations

Please be aware that there are limitations on maximum amounts for transactions:
The maximum length of Transaction Amount, Calculated Tax Amount, Tip dollar amount, and Cash Back dollar amount is 10 digits. If the Tip calculated by percentage equals or exceeds $42,949,672.95, the device shows 0.

Device Types

Under very rare circumstances, it is possible this library will fail to identify a valid device type.
In this case, there is a third parameter for scanForDevices function that accepts a deviceType. The available types are:

  • tDynamo
  • eDynamo
  • dynaProGo
  • DynaPro Mini

MagTek® is a registered trademark of MagTek, Inc.
Magensa™ is a trademark of MagTek, Inc.