All pages
Powered by GitBook
1 of 6

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Appendix A - Status Codes

public enum StatusCode
{
    SUCCESS = 0,
    TIMEOUT = 1,
    ERROR = 2,
    UNAVAILABLE = 3
}
Enum
Description

SUCCESS

The operation completed successfully.

TIMEOUT

The operation timed out.

ERROR

Error attempting the operation.

UNAVAILABLE

Status currently unavailable.

Appendix D - Apple VAS

These instructions are for preparing Apple VAS (value-added service) transactions.

Merchant ID and URL Slots

  • Set the Apple VAS Merchant ID and URL property for each slot 1 to 6 using IDeviceControl --> setConfigInfo().

POS Capabilities

  • Set the POS capabilities property using IDeviceControl à setConfigInfo().

Start Transaction

  • Set the PaymentMethods to include PaymentMethod.AppleVAS.

  • Set AppleVASMode to: VASMode.Single, VASMode.Dual, or VASMode.VASOnly.

  • Set AppleVASProtocol to: VASProtocol.Full or VASProtocol.URL.

  • Data from an Apple VAS (9F27 and 9F2A) is returned in separate Apple VAS slot containers.

  • FE — var — VAS Data Container

    • FF01

—
var
— Apple VAS Container Slot 1 Container
  • 9F27 — var — VAS Data. Up to 128 bytes.

  • 9F2A — var — Mobile Token. Up to 36 bytes.

  • FF02 — var — Apple VAS Container Slot 2 Container

    • 9F27 — var — VAS Data. Up to 128 bytes.

    • 9F2A — var — Mobile Token. Up to 36 bytes.

  • FF03 — var — Apple VAS Container Slot 3 Container

    • 9F27 — var — VAS Data. Up to 128 bytes.

    • 9F2A — var — Mobile Token. Up to 36 bytes.

  • FF04 — var — Apple VAS Container Slot 4 Container

    • 9F27 — var — VAS Data. Up to 128 bytes.

    • 9F2A — var — Mobile Token. Up to 36 bytes.

  • FF05 — var — Apple VAS Container Slot 5 Container

    • 9F27 — var — VAS Data. Up to 128 bytes.

    • 9F2A — var — Mobile Token. Up to 36 bytes.

  • FF06 — var — Apple VAS Container Slot 6 Container

    • 9F27 — var — VAS Data. Up to 128 bytes.

    • 9F2A — var — Mobile Token. Up to 36 bytes.

  • Transaction Response

    Appendix E - Google Wallet Smart Tap VAS

    These instructions are for preparing Google Wallet Smart Tap VAS (value-added service) transactions.

    • Configure the mobile device for Google Wallet Smart Tap Pass.

    • Load the LTPK protection key (Long Term Private Key) into the MagTek device.

    • Upload a Public Key to the Google Pay & Wallet Console for the issuer account associate with the Google Wallet Pass.

    Set the Google Smart Tap Collector ID property for each slot 1 to 6 using IDeviceControl à setConfigInfo().

    • Set the POS capabilities property using IDeviceControl à setConfigInfo().

    • Set the PaymentMethods to include PaymentMethod.GoogleVAS.

    • Set AppleVASMode to: VASMode.Single, VASMode.Dual, or VASMode.VASOnly.

    • Data from a Google Wallet Smart Tap (DF7B) is returned in separate Collector ID slot containers associated with the Google Wallet Pass.

    Tag
    Length
    Value / Description

    FF41

    var

    Google Smart Tap Container

    //FF01

    var

    Mobile Device

    Load Key

    Collector ID Slots

    POS Capabilities

    Start Transaction

    Transaction Response

    Collector ID Slot 1 Container

    ///DF7B

    var

    Service Response NDEF Record

    //FF02

    var

    Collector ID Slot 2 Container

    ///DF7B

    var

    Service Response NDEF Record

    //FF03

    var

    Collector ID Slot 3 Container

    ///DF7B

    var

    Service Response NDEF Record

    //FF04

    var

    Collector ID Slot 4 Container

    ///DF7B

    var

    Service Response NDEF Record

    //FF05

    var

    Collector ID Slot 5 Container

    ///DF7B

    var

    Service Response NDEF Record

    //FF06

    var

    Collector ID Slot 6 Container

    ///DF7B

    var

    Service Response NDEF Record

    Appendix B - API Walk Through

    CoreAPI Walk Trough

    The following walks through how to create instances of devices.

    • CoreAPI.createDevice à IDevice

    • CoreAPI.getDeviceList à List

    • CoreAPI.createPPSCRA à MTPPSCRA

    These examples demonstrate methods for creating an IDevice to be used in the MagTek Universal SDK. This also shows how to establish a device specific API, which is not used with the MagTek Universal SDK.

    Here, a single IDevice is established.

    Here, a list of IDevice is established. The first device is accessed at index 0.

    The following walks through how to make use of IDevice.

    • Implement device events within the class to receive events.

    • CoreAPI à IDevice.

    • IDevice à subscribeAll().

    • IDevice à other functions.

    Example

    Application Main window may extent the

    Static
    Member
    Value
    Description

    These constructors initialize a PersonalInfoEntry object.

    • Call startPersonalInfoEntry().

    • At OnEvent():TouchscreenPersonalInfoEntry, build the object.

    Member
    Description

    Return Value:

    Returns an instance of PersonalInfoEntry.

    IEventSubscriber Delegates or can be extended by a separate class. This example uses a separate class and demonstrates how to parse for the various event types.

    Example

    Various events are separately shown below

    The following walks through how to make use of IDeviceControl.

    • IDevice --> IDeviceControl.· IDeviceControl à open().

    • IDeviceControl --> other functions.

    • IDeviceControl --> close().

    Example

    The following walks through how to make use of ConnectionInfo.

    • IDevice --> ConnectionInfo.

    • ConnectionInfo --> getAddress()

    • ConnectionInfo --> getConnectionType()

    • ConnectionInfo --> getDeviceType() Example

    Example

    The following walks through how to make use of IDeviceCapabilities.

    • IDevice à IDeviceCapabilities.

    • IDeviceCapabilities à BatteryBackedClock() to check if date/time should be set.

    • IDeviceCapabilities à PaymentMethods() to check card types supported.

    • IDeviceCapabilities à other functions.

    The following walks through how to make use of IDeviceConfiguration.

    • IDevice --> getDeviceConfiguration().

    • IDeviceConfiguration --> updateFirmware().

    • IDeviceConfiguration --> getConfiguration().

    • IDeviceConfiguration --> setConfiguration().

    Example

    Application Main window may extent the IConfigurationCallback Delegates or can be extended by a separate class. This example uses a separate class and demonstrates how to parse for the various events.

    Example

    Appendices

    Supplementary reference material for the MagTek Universal SDK, including the full status-code list, a step-by-step API walk-through, the EMV transaction flow, and integration guidance for mobile-wallet value-added services (Apple VAS and Google Wallet Smart Tap).

    IDevice à startTransaction().

    IDeviceConfiguration --> other functions.

    // Access MMS with Universal SDK using createDevice()
    
    IDevice mtmms = CoreAPI.createDevice( 
        context,
        DeviceType.MMS, 
        ConnectionType.USB, "",
        "",
        "DynaFlex", 
        "");
    mtmms.requestSignature();
    // Acess MMS with Universal SDK using getDeviceList()
    
    List<IDevice> mtmms = CoreAPI.getDeviceList( 
        context,
        DeviceType.MMS, 
        deviceListCallback);
    mtmms[0].requestSignature();
    import com.magtek.mobile.android.mtusdk.*;
    
    
    // Extend the main window to receive events.
    public class MainWindow implements IEventSubscriber, 
    IConfigurationCallback
    {
    
    // Establish a device from CoreAPI. List<IDevice> deviceList = CoreAPI.getDeviceList(
        context, 
        deviceListCallbac);
    IDevice device = deviceList[0];
    
    /* For a list of a single device type. DeviceType deviceType = DeviceType.MMS;
    List<IDevice> deviceList = CoreAPI.getDeviceList( 
        context,
        deviceType deviceListCallback);
    IDevice device = deviceList[0];
    */
    
    /* For a list of multiple device types. 
    List<DeviceType> deviceTypes = null; 
    deviceTypes.Add(DeviceType.MMS); 
    deviceTypes.Add(DeviceType.CMS);
    List<IDevice> deviceList = CoreAPI.getDeviceList( 
        context,
        deviceTypes, 
        deviceListCallback);
    IDevice device = deviceList[0];
    */
    
    /* Suscribe to events sent from the device.
    These would be but not limited to: card inserted, card removed, connection state...
    
    Set MainWindow to receive the events. */ 
    boolean return = device.unsubscribeAll(this);
    boolean return = device.subscribeAll(this);
    
    /* To handle events from some other class. 
    EventsVector eventsVector = new EventsVector() 
    boolean return = device.unsubscribeAll(eventsVector); 
    boolean return = device.subscribeAll(eventsVector);
    */
    
    // Assign parameters for the transaction.
    List<PaymentMethod> paymentMethod = new List<PaymentMethod>(); 
    paymentMethod.Add(PaymentMethod.MSR); 
    paymentMethod.Add(PaymentMethod.Contact); 
    paymentMethod.Add(PaymentMethod.Contactless);
    
    Transaction transaction = new Transaction(); 
    transaction.setAmount(“1.00”); 
    transaction.setCashBack(“0.00”); 
    transaction.setEMVOnly(true); 
    transaction.setPaymentMethods(paymentMethod); 
    transaction.setQuickChip(false);
    
    // Start transaction.
    boolean result = device.startTransaction(transaction);

    NFC_MIFARE_ULTRALIGHT

    String

    "nfc_mifare_ultralight"

    PersonalInfoEntry PersonalInfoEntryBuilder.GetPersonalInfoEntry( 
    DeviceType deviceType, 
    byte[] dataBytes);
    
    new PersonalInfoEntry( 
        byte[] data, 
        CaptureType dataType, 
        bool encrypted,
        ); 
    
    new PersonalInfoEntry( 
            byte[] data, 
            CaptureType dataType, 
            bool encrypted, 
            byte encryptionType, 
            byte[] ksn
            );

    deviceType

    Type of device.

    dataBytes

    Data to pass in after set from OnEvent().

    data()

    // A class to handle events.
    public class EventsVector implements IEventSubscriber
    {
        public void OnEvent(EventType eventType, IData data)
        {
            switch (eventType)
            {
    case ConnectionState:
    // Parse for the ConnectionState ConnectionState value =
    ConnectionStateBuilder.GetValue(data.StringValue());
    
    break;
    case DeviceResponse:
    
    break;
    case DeviceExtendedResponse:
    
    break;
    case DeviceNotification:
    
    break;
    case CardData:
    
    break;
    case TransactionStatus:
    // Parse for the transaction status code and detail. 
    TransactionStatus status = 
    TransactionStatusBuilder.GetStatusCode(data.StringValue());
    
    string statusDetail = TransactionStatusBuilder.GetStatusDetail(data.StringValue());
    
    break;
    case DisplayMessage:
    
    String message;
    // Get the message. if (data != null)
    {
    message = System.Text.Encoding.UTF8.GetString(data);
    }
    break;
    case InputRequest:
    
    break;
    case AuthorizationRequest:
    
    // Forward ARQC to processor.
    /* data[0..1] – ARQC length
    data[2..n] – remainder contains the ARQC TLV object
    */
    
    IData processorARPC = new 
    BaseData(sendForAuthorization(data.ByteArray()));
    
    // Send authorization to device when not in QuickChip mode. 
    if (transaction.QuickChip == false)
    {
    device.sendAuthorization(procesorARPC.ByteArray());
    }
    
    break;
    case TransactionResult
    
    /* data[0] – Signature Required
        data[1..2] – Batch Data length
        data[3..n] – remainder contains the Batch Data TLV object
    */
    
    // Parse the TLV from data[].
    .
    // Abstract Approval status from TLV tag “DFDF1A”.
    .
    // Abstract Signature Required status from TLV tag data[0].
    .
    
    break;
    case PINBlock:
    
    break;
    case Signature:
    
    break;
    // Establish a device from CoreAPI.
    List<IDevice> deviceList = CoreAPI.getDeviceList(); IDevice device = deviceList[0];
    
    // Establish a deviceControl from device.
    IDeviceControl deviceControl = device.getDeviceControl();
    
    // Open the device, then use the IDeviceControl functions. deviceControl.open();
    
    . . .
    
    // Close the device. deviceControl.close();
    // Establish a device from CoreAPI.
    List<IDevice> deviceList = CoreAPI.getDeviceList(); 
    IDevice device = deviceList[0];
    
    // Establish a ConnectionInfo from device.
    ConnectionInfo connectionInfo = device.getConnectionInfo();
    
    // Retrieve address, connectionType, and deviceType. 
    String address = connectionInfo.getAddress();
    ConnectionType connectionType = connectionInfo.getConnectionType(); 
    DeviceType deviceType = connectionInfo.getDeviceType();
     // Establish a device from CoreAPI.
    List<IDevice> deviceList = CoreAPI.getDeviceList(); 
    IDevice device = deviceList[0];
    
    // Establish a IDeviceCapabilities from device. 
    IDeviceCapabilities capabilities = device.getCapabilities();
    
    
    // Retrieve device capabilities.
    boolean batteryBackedClock = capabilities.BatteryBackedClock(); 
    if (batteryBackedClock)
    {
    // Call IDeviceControl.setDateTime().
    }
    
    // Retrieve supported card payment methods.
    List<PaymentMethod> paymentMethods = capabilities.PaymentMethods();
    
    . . .
    // Establish a device from CoreAPI.
    List<IDevice> deviceList = CoreAPI.getDeviceList(); 
    IDevice device = deviceList[0];
    
    IDeviceConfiguration deviceConfiguration = 
        device.getDeviceConfiguration();
    
    /* To handle events from some other class. ConfigCallBacks 
    configCallBacks = new ConfigCallBacks();
    */
    
    // Update firmware.
    byte[] data = getDataFromURI(uri);
    int return = deviceConfiguration.updateFirmware(1, data, this);
    
    /* Get configuration.
        Device-Driven Fallback OID = 1.2.1.1.1.1
                contructed OID = E2 08 E1 06 E1 04 E1 02 C1 00
        Note: first digit of OID is ommited in the construction and instead is passed in the configType.
    */
    byte configType = 0x01;
    data = new byte[] {0xE2,0x08,0xE1,0x06,0xE1,0x04,0xE1,0x02,0xC1,0x00
    };
    byte[] response = devConfig.getConfigInfo(configType, data);
    
    
    /* Set configuation.
        Device-Driven Fallback OID is 1.2.1.1.1.1
            Disabled contructed OID = E2 09 E1 07 E1 05 E1 03 C1 01 00
                Enabled contructed OID = E2 09 E1 07 E1 05 E1 03 C1 01 01
        Note: first digit of OID is ommited in the construction and instead 
    is passed in the configType.
    
    */
    data = new byte[]
    {0xE2,0x09,0xE1,0x07,0xE1,0x05,0xE1,0x03,0xC1,0x01,0x00 };
    result = devConfig.getConfigInfo(configType, data);
    // A class to handle configuration callback events.
    public class ConfigCallbacks implements IConfigurationCallback
    {
    
        public void OnProgress(int progress)
        {
            /* Handle progress.
                Progress is complete when progress = 100 */
        }
    public void OnResult(StatusCode status, byte[] data)
    {
        /* Handle result.
            A configuration process is complete when 
            status = StatusCode.Success */
    }
    public IResult OnCalculateMAC(byte macType, byte[] data)
    {
        IResult result = new Result(StatusCode.UNAVAILABLE); 
        byte[] macBytes = null;
        
        DeviceType deviceType =
            device.getConnection Info().getDeviceType();
    
        switch (deviceType)
        {
            case DeviceType.MMS:
                macBytes = getDynaFlexMAC(macType, data); 
                break;
        }
    
        if (macBytes != null)
        {
            result = new Result(StatusCode.SUCCESS); 
            result.Data = new BaseData(macBytes);
        }
    
        return result;
        }
    
    }

    IDevice Walk Through

    Handling Events

    Static members

    PersonalInfoEntry

    IDeviceControl Walk Through

    ConnectionInfo Walk Through

    IDeviceCapabilities Walk Through

    IDeviceConfiguration Walk Through

    Handling Events

    Reference Section

    Information Available

    The complete list of status and result codes returned by the SDK, with their meanings for handling success and error conditions.

    Appendices

    In This Section

    MIFARE_CLASSIC_1K

    String

    "mifare_classic_1k"

    MIFARE_CLASSIC_4K

    String

    "mifare_classic_4k"

    MIFARE_DESFIRE_LIGHT

    String

    "mifare_desfire_light"

    MIFARE_MINI

    String

    "mifare_mini"

    MIFARE_PLUS_EV1

    String

    "mifare_plus_ev1"

    MIFARE_PLUS_EV2

    String

    "mifare_plus_ev2"

    MIFARE_PLUS_SE

    String

    "mifare_plus_se"

    MIFARE_PLUS_X

    String

    "mifare_plus_x"

    MIFARE_DESFIRE_EV1

    String

    "mifare_desfire_ev1"

    MIFARE_DESFIRE_EV2

    String

    "mifare_desfire_ev2"

    MIFARE_DESFIRE_EV3

    String

    "mifare_desfire_ev3"

    MDL

    String

    "mdl"

    TAG_REMOVED

    String

    "tag_removed"

    FAILED

    String

    "failed"

    IO_FAILED

    String

    "io_failed"

    AUTHENTICATION_FAILED

    String

    "authentication_failed"

    Returns the data payload.

    dataType()

    Returns the capture type.

    encrypted()

    Returns the encryption status. false = data is not encrypted true = data is encrypted

    encryptionType()

    Returns the encryption type.

    ksn()

    Returns the Key Serial Number.

    B: API Walk Through

    A step-by-step walk-through of a typical integration, showing the API calls in sequence from connection through a completed transaction.

    C: EMV Transaction Flow

    The end-to-end EMV transaction sequence — the stages and SDK interactions involved in processing a chip-card payment.

    D: Apple VAS

    Guidance for using Apple Value Added Services to read Apple Wallet passes over contactless.

    E: Google Wallet Smart Tap VAS

    Guidance for using Google Wallet Smart Tap to read passes and value-added service data over contactless.

    Need More Help

    Need Help?

    For additional support, please contact MagTek Support:

    Technical Support:

    • 📧 Email: support@magtek.com

    • 📞 Phone: 1-562-546-6800 (US)

    • 🕐 Hours: Monday-Friday, 5:30 AM - 5:00 PM PST

    Online Resources:

    • 🌐 Support Portal: developer.magtek.com

    Documentation Feedback:

    Help us improve this documentation!

    A: Status Codes
    feedback@magtek.com

    Appendix C - EMV Transaction Flow

    This section demonstrates transaction flow.

    Flow Chart - QuickChip

    Sample Code - QuickChip

    The following breaks out the EMV flow chart into code. When enabling QuickChip mode, host does not send the ARPC to the device to complete the transaction. Events are shown separately and in the order received.

    // Assign parameters.
    List<PaymentMethod> paymentMethod = new List<PaymentMethod>(); 
    paymentMethod.Add(PaymentMethod.MSR); 
    paymentMethod.Add(PaymentMethod.Contact); 
    paymentMethod.Add(PaymentMethod.Contactless);
    
    Transaction transaction = new Transaction(); 
    transaction.setAmount(“1.00”); 
    transaction.setCashBack(“0.00”); 
    transaction.setEMVOnly(true); 
    transaction.setPaymentMethods(paymentMethod); 
    transaction.setQuickChip(true); // QuickChip mode enabled.
    
    // Start transaction.
    boolean result = device.startTransaction(transaction);
    public void OnEvent(EventType eventType, IData data)
    {
        String message 
        switch (eventType);
            {
                case EventType.DisplayMessage:
                    // Get the message.
                    message = data.StringValue();
        }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        String message; 
        switch (eventType);
            {
                case EventType.InputRequest:
                // Get the message.
                message = data.StringValue();
    
                // display/retrieve user selection.
    
                // set status and selection result.
                IData selectionData = new BaseData(new Byte[] {status, selection});
                device.sendSelection(selectionData);
        }
    }
    public void OnEvent(EventType eventType, IData data)
    {
    byte[] ARQC = null; 
    switch (eventType);
        {
            case EventType.AuthorizationRequest:
                // Forward ARQC to processor.
                /* data[0..1] – ARQC length
                    data[2..n] – remainder contains the ARQC TLV object */
        }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        String message; 
        switch (eventType);
            {
            
                case EventType.TransactionResult:
                    /* data[0]	– Signature Required 
                        data[1..2] – Batch Data length
                        data[3..n] – remainder contains the Batch Data TLV object
                    */
    
                    // Parse the TLV from data[].
                    // Abstract Approval status from TLV tag “DFDF1A”.
                    // Abstract Signature Required status from TLV tag data[0].
            }
    }

    Flow Chart – Signature Capture

    Sample Code – Signature Capture

    The following breaks out the EMV flow chart into code. Events are shown separately and in the order received.

    // Assign parameters.
    List<PaymentMethod> paymentMethod = new List<PaymentMethod>(); 
    paymentMethod.Add(PaymentMethod.MSR); 
    paymentMethod.Add(PaymentMethod.Contact); 
    paymentMethod.Add(PaymentMethod.Contactless);
    
    Transaction transaction = new Transaction(); 
    transaction.setAmount(“1.00”); 
    transaction.setCashBack(“0.00”); 
    transaction.setEMVOnly(true); 
    transaction.setPaymentMethods(paymentMethod); 
    transaction.setQuickChip(true);
    
    // Start transaction.
    boolean result = device.startTransaction(transaction);
    public void OnEvent(EventType eventType, IData data)
    {
        String message; 
        switch (eventType);
            {
                case EventType.DisplayMessage:
    
                    // Get the message.
                    message = data.StringValue();
        }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        byte[] ARQC = null; 
        switch (eventType);
            {
                case EventType.AuthorizationRequest:
                    // #4a
                    // Forward ARQC to processor.
                    /* data[0..1] – ARQC length
                        data[2..n] – remainder contains the ARQC TLV object */
            }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        String message; 
        switch (eventType);
            {
                case EventType.DisplayMessage:
                    // Display approval message. 
                    message = data.StringValue();
    
                    // A data size of 0 is an instruction to clear the display. 
                    if (data.StringValue().Length == 0)
                    {
                        // Clear the UI display.
                    }
            }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        String message; 
        switch (eventType);
            {
                case EventType.TransactionResult:
                    /* data[0]	– Signature Required 
                    data[1..2] – Batch Data length
                    data[3..n] – remainder contains the Batch Data TLV object
                    */
    
                    // Parse the TLV from data[].
                    // Abstract Approval status from TLV tag “DFDF1A”.
                    // Abstract Signature Required status from TLV tag data[0].
            }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        String signature; 
        switch (eventType);
            {
                case EventType.Signature: 
                    signature = data.StringValue();
            }
    }

    Flow Chart – With ARPC

    Sample Code – With ARPC

    The following breaks out the EMV flow chart into code. When disabling QuickChip mode, host must send the ARPC to the device to complete the transaction. Events are shown separately and in the order received.

    // Assign parameters.
    List<PaymentMethod> paymentMethod = new List<PaymentMethod>(); 
    paymentMethod.Add(PaymentMethod.MSR); 
    paymentMethod.Add(PaymentMethod.Contact); 
    paymentMethod.Add(PaymentMethod.Contactless);
    
    Transaction transaction = new Transaction(); 
    transaction.setAmount(“1.00”); 
    transaction.setCashBack(“0.00”); 
    transaction.setEMVOnly(true); 
    transaction.setPaymentMethods(paymentMethod); 
    transaction.setQuickChip(false); //QuickChip mode disabled.
    
    // Start transaction.
    boolean result = device.startTransaction(transaction);
    public void OnEvent(EventType eventType, IData data)
    {
        string message; 
        switch (eventType);
            {
                case EventType.DisplayMessage:
    
                    // Get the message.
                    message = data.StringValue;
        }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        string message; 
        switch (eventType);
            {
                case EventType.InputRequest:
                    // Get the message.
                    message = data.StringValue;
    
                    // display/retrieve user selection.
    
                    // set status and selection result.
                    IData selectionData = new BaseData(new Byte[] {status, selection});
    device.sendSelection(selectionData);
        }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        byte[] ARQC = null; 
        switch (eventType);
            {
                case EventType.AuthorizationRequest:
                    // Forward the ARQC to the processor.
                    /* data[0..1] – ARQC length
                    data[2..n] – remainder contains the ARQC TLV object */
    
                    ARQC.ByteArray = data.ByteArray;
                    // App function to send the request to the processor. 
                    ARPC = sendARQCToProcessorForApproval(ARQC.ByteArray());
    
            }
    }

    After the ARPC is returned from the processor, it is constructed into a TLV container and then sent to the device. The ARPC for approved (00) is set in ASCII 3030.

    The optional tags 91, 71, and 72 (Issuer Authentication Data, Issuer Script Template 1, and Issuer Script Template 2) are not included in this example.

    See the construction of the ARPCTLV in the table below.

    ARPC TLV object for sendAuthorization().

    Tag
    Len
    Value / Description
    Typ
    Req
    Default

    The use case for an MSR fallback is when communication with the chip results in a terminated transaction and the TransactionStatus is reported as MSRFallback.

    The host application will re-attempt the transaction. To invoke this use case, here are the following pre-requisites.

    Pre-requisites:

    • Device already configured for Device-Driven Fallback = Disabled.

    • A card to cause the fallback. Example but not limited to a card with no applications programmed or a card with an application not configured on the device.

    Scheme:

    • -->Host begins an initial transaction with PaymentMethod set to MSR+Chip+Contactless.

    • <--Device responds with fail and with status of MSRFallback.

    • -->Host displays a message to use magstripe.

    • -->Host starts a transaction with PaymentMethod set to MSR.

    Begin initial transaction:

    Continue with Fallback transaction:

    <--Device may respond with transaction cancelled card read error.

  • -->Host displays a message each time the transaction fails until successful or until Host decides to end the transaction.

  • <--Device sends the transaction result.

  • String ARPC = “8A3030”;
    IData ARPCTLV = new BaseData(“FF7413DFDF250742363243413546FA067004” + ARPC);
    
    device.sendAuthorization(ARPCTLV);

    FF74

    var

    Container for non-MAC ARPC

    public void OnEvent(EventType eventType, IData data)
    {
        String message; 
        switch (eventType);
            {
                case EventType.DisplayMessage:
                    // Display approval message. 
                    message = data.StringValue();
    
                    // A data size of 0 is an instruction to clear the display. 
                    if (data.StringValue().Length == 0)
                    {
                        // Clear the UI display.
                    }
            }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        String message; 
        switch (eventType);
            {
                case EventType.TransactionResult:
                    /* data[0]	– Signature Required 
                    data[1..2] – Batch Data length
                    data[3..n] – remainder contains the Batch Data TLV object
            */
    
            // Parse the TLV from data[].
            // Abstract Approval status from TLV tag “DFDF1A”.
            // Abstract Signature Required status from TLV tag data[0].
        }
    }
    public void OnEvent(EventType eventType, IData data)
    {
        String signature; 
        switch (eventType);
            {
                case EventType.Signature: 
                    signature = data.StringValue();
            }
    }

    MSR Fallback Flow

    T

    R

    /DFDF25

    var

    Device Serial Number (IFD Serial Number)

    B

    R

    /FA

    var

    Container for generic data

    T

    R

    //70

    var

    Container for ARPC

    T

    R

    ///8A

    02

    Authorization Response Code

    AN

    R

    · 0x3030 = Approved · 0x3031 = Issuer Referral · 0x3035 = Declined · 0x3132 = Switch Interface · 0x3133 = Request Online PIN

    ///91

    var

    Issuer Authentication Data

    B

    O

    As defined in EMV Integrated Circuit Card Specifications for Payment Systems 4.3

    ///71

    var

    Issuer Script Template 1

    B

    O

    As defined in EMV Integrated Circuit Card Specifications for Payment Systems 4.3. The host may include as many instances of this parameter as needed, up to a maximum length of 128 bytes including Tags and Lengths.

    ///72

    var

    Issuer Script Template 2

    B

    O

    As defined in EMV Integrated Circuit Card Specifications for Payment Systems 4.3. The host may include as many instances of this parameter as needed, up to a maximum length of 128 bytes including Tags and Lengths.