> For the complete documentation index, see [llms.txt](https://developer.magtek.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.magtek.com/sdks-and-tools/universal-sdk-documentation/ios/appendices/appendix-b-emv-transaction-flow.md).

# Appendix B - EMV Transaction Flow

This section demonstrates transaction flow.

### Flow Chart - QuickChip <a href="#b.1_flow_chart_-_quickchip" id="b.1_flow_chart_-_quickchip"></a>

<figure><img src="https://4093728396-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fwjbnqo0srzj14AwQMHQM%2Fuploads%2FS6yA8qxkQEROmpDyCY6Y%2Fquickchip%20flow%20chart.png?alt=media&amp;token=71c4a359-afa7-4e88-ba60-95c7180a6670" alt=""><figcaption></figcaption></figure>

### Sample Code - QuickChip <a href="#b.2_sample_code_-_quickchip" id="b.2_sample_code_-_quickchip"></a>

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.

{% code overflow="wrap" %}

```
// Assign parameters.
var transaction: ITransaction = ITransaction( 
Amount:“1.00”,
CashBack:“0.00”, 
TransactionType:0, 
Timeout:30,
For:MTU_PaymentMethod_MSR | MTU_PaymentMethod_Contact | 
MTU_PaymentMethod_Contactless,
QuickChip:true)

// Start transaction.
var result: BOOL = device.startTransaction(transaction)
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
        var message: NSString = “” 
        switch eventType
                {
                        case MTU_EventType_DisplayMessage:
                        // Get the message. 
                        message = data.StringValue
                }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
 func onEvent(_ eventType: MTU_EventType, data: IData!)
{
    var message: NSString = “” 
    switch eventType
        {
            case MTU_EventType_InputRequest:
                // Get the message. 
                message = data.StringValue
                
                // display/retrieve user selection.

                // set status and selection result.
                var statusSelection: NSString* = "0001"
                var selectionData: IData = IData.dataWithHex(statusSelection); 
                device.sendSelection(selectionData)
        }
}
```

{% endcode %}

<pre data-overflow="wrap"><code>func onEvent(_ eventType: MTU_EventType, data: IData!)
{
<strong>    var ARQC[]: Byte = nil; switch eventType
</strong>        {
            case MTU_EventType_AuthorizationRequest:
                // Forward ARQC to processor.
                /* data[0..1] – ARQC length
                data[2..n] – remainder contains the ARQC TLV object */
        }
}
</code></pre>

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
        var message: NSString = “” 
        switch eventType
                {
                        case MTU_EventType_DisplayMessage:
                                // Display approval message. 
                                message = data.StringValue
                        // A data size of 0 is an instruction to clear the display. 
                        if (data.StringValue.count == 0)
                        {
                                // Clear the UI display.
                        }
                }
}
```

{% endcode %}

<pre data-overflow="wrap"><code><strong>func onEvent(_ eventType: MTU_EventType, data: IData!)
</strong>{
    switch eventType
        (
            case MTU_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].
        }
}

</code></pre>

### Flow Chart – Signature Capture <a href="#b.3_flow_chart_-_signature_capture" id="b.3_flow_chart_-_signature_capture"></a>

<figure><img src="https://4093728396-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fwjbnqo0srzj14AwQMHQM%2Fuploads%2Fojo9HMraYa0NKzIl4WiG%2Fsignature%20capture.png?alt=media&amp;token=8168f1f1-5c9e-4484-aa22-b03eeed55fd2" alt=""><figcaption></figcaption></figure>

### Sample Code – Signature Capture <a href="#b.4_sample_code_-_signature_capture" id="b.4_sample_code_-_signature_capture"></a>

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

{% code overflow="wrap" %}

```
// Assign parameters.
var transaction: ITransaction = ITransaction( 
Amount: "1.00",
CashBack: "0.00", 
TransactionType:0, 
Timeout:30,
For:MTU_PaymentMethod_MSR | MTU_PaymentMethod_Contact | 
MTU_PaymentMethod_Contactless,
QuickChip:true
)

// Start transaction.
var result: BOOL = device.startTransaction(transaction)
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
    var message: NSString = "" 
    switch eventType
        {
            case MTU_EventType_DisplayMessage:
            // Get the message. 
            message = data.StringValue
    }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
    var message: NSString = "" 
    switch eventType
        {
            case MTU_EventType_InputRequest:
        // Get the message. 
        message = data.StringValue

        // display/retrieve user selection.

        // set status and selection result.
        var statusSelection: NSString* = "0001"
        IData* selectionData = IData dataWithHex(statusSelection);             
        device.sendSelection(selectionData);
    }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
 func onEvent(_ eventType: MTU_EventType, data: IData!)
{
var ARQC[]: Byte = nil; switch eventType
  {
      case MTU_EventType_AuthorizationRequest:
          // Forward ARQC to processor.
          /* data[0..1] – ARQC length
          data[2..n] – remainder contains the ARQC TLV object */
    }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
    var message: NSString = "" 
    switch eventType
        {
            case MTU_EventType_DisplayMessage:
            // Display approval message. 
            message = data.StringValue;
            
            // A data size of 0 is an instruction to clear the display. 
            if (data.StringValue.count == 0)
        {
            // Clear the UI display.
        }
    }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
        switch eventType
        {
                case MTU_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].
        }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
    var signature: NSString = “”;
    switch eventType
        {
            case MTU_EventType_Signature:
           signature = data.StringValue;
        }
}
```

{% endcode %}

### Flow Chart – With ARPC <a href="#b.5_flow_chart_-_with_arpc" id="b.5_flow_chart_-_with_arpc"></a>

<figure><img src="https://4093728396-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fwjbnqo0srzj14AwQMHQM%2Fuploads%2FsJHKOQiGIgXcaJ4cQR3b%2Farpc.png?alt=media&amp;token=e23d5633-a7fb-4c2f-af70-8662749a6e30" alt=""><figcaption></figcaption></figure>

### Sample Code – With ARPC <a href="#b.6_sample_code_-_with_arpc" id="b.6_sample_code_-_with_arpc"></a>

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.

{% code overflow="wrap" %}

```
// Assign parameters.
var transaction: ITransaction = ITransaction( 
Amount:“1.00”,
CashBack:“0.00”, 
TransactionType:0, 
Timeout:30,
For:MTU_PaymentMethod_MSR | MTU_PaymentMethod_Contact | 
MTU_PaymentMethod_Contactless,
QuickChip:false
);

// Start transaction.
var result: BOOL = device.startTransaction(transaction)
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
    var message: NSString = "" 
    switch eventType
        {
            case MTU_EventType_DisplayMessage:
                // Get the message. 
                message = data.StringValue
    }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
        var message: NSString = ""; 
        switch eventType
                {
                        case MTU_EventType_InputRequest:
                                // Get the message. 
                                message = data.StringValue
                                
                                // display/retrieve user selection.

                                // set status and selection result. 
                                var statusSelection: NSString = "0001" 
                                var selectionData: IData* = IData
dataWithHex(statusSelection); 
                                device.sendSelection(selectionData)
        }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
    var ARQC: IData = data; 
    switch eventType        
        {
            case MTU_EventType_AuthorizationRequest:
                // Forward ARQC to processor.
                /* data[0..1] – ARQC length
                data[2..n] – remainder contains the ARQC TLV object */ 
                ARPC = sendARQCToProcessorForApproval(ARQC.ByteArray)
    }
}
```

{% endcode %}

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.&#x20;

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.

{% code overflow="wrap" %}

```
var ARPC: NSString = “8A3030”;
var ARPCTLV: IData = IData();
ARPCTLV.StringValue = "FF7413DFDF250742363243413546FA067004” + ARPC

device.sendAuthorization(ARPCTLV)
```

{% endcode %}

### ARPC TLV object for sendAuthorization().

<table data-header-hidden><thead><tr><th width="94.66668701171875" valign="top"></th><th width="65.33331298828125" valign="top"></th><th valign="top"></th><th width="64.3333740234375" valign="top"></th><th width="78" valign="top"></th><th width="96.33319091796875" valign="top"></th></tr></thead><tbody><tr><td valign="top">Tag</td><td valign="top">Len</td><td valign="top">Value / Description</td><td valign="top">Typ</td><td valign="top">Req</td><td valign="top">Default</td></tr><tr><td valign="top">FF74</td><td valign="top">var</td><td valign="top">Container for non-MAC ARPC</td><td valign="top">T</td><td valign="top">R</td><td valign="top"> </td></tr><tr><td valign="top">/DFDF25</td><td valign="top">var</td><td valign="top">Device Serial Number (IFD Serial Number)</td><td valign="top">B</td><td valign="top">R</td><td valign="top"> </td></tr><tr><td valign="top">/FA</td><td valign="top">var</td><td valign="top">Container for generic data</td><td valign="top">T</td><td valign="top">R</td><td valign="top"> </td></tr><tr><td valign="top">//70</td><td valign="top">var</td><td valign="top">Container for ARPC</td><td valign="top">T</td><td valign="top">R</td><td valign="top"> </td></tr><tr><td valign="top"><p> </p><p> </p><p>///8A</p></td><td valign="top"><p> </p><p> </p><p>02</p></td><td valign="top"><p>Authorization Response Code</p><p>·       0x3030 = Approved</p><p>·       0x3031 = Issuer Referral</p><p>·       0x3035 = Declined</p><p>·       0x3132 = Switch Interface</p><p>·       0x3133 = Request Online PIN</p></td><td valign="top"><p> </p><p> </p><p>AN</p></td><td valign="top"><p> </p><p> </p><p>R</p></td><td valign="top"> </td></tr><tr><td valign="top"><p> </p><p>///91</p></td><td valign="top"><p> </p><p>var</p></td><td valign="top"><p>Issuer Authentication Data</p><p>As defined in <em>EMV Integrated Circuit Card Specifications for Payment Systems 4.3</em></p></td><td valign="top"><p> </p><p>B</p></td><td valign="top"><p> </p><p>O</p></td><td valign="top"> </td></tr></tbody></table>

<table data-header-hidden><thead><tr><th width="66.66665649414062" valign="top"></th><th width="64.66665649414062" valign="top"></th><th valign="top"></th><th width="60.6666259765625" valign="top"></th><th width="74.6666259765625" valign="top"></th><th width="92.3333740234375" valign="top"></th></tr></thead><tbody><tr><td valign="top">Tag</td><td valign="top">Len</td><td valign="top">Value / Description</td><td valign="top">Typ</td><td valign="top">Req</td><td valign="top">Default</td></tr><tr><td valign="top"><p> </p><p> </p><p>///71</p></td><td valign="top"><p> </p><p> </p><p>var</p></td><td valign="top"><p>Issuer Script Template 1</p><p>As defined in <em>EMV Integrated Circuit Card Specifications for Payment Systems 4.3</em>. The host may include as many instances of this parameter as needed, up to a maximum length of 128 bytes including Tags and Lengths.</p></td><td valign="top"><p> </p><p> </p><p>B</p></td><td valign="top"><p> </p><p> </p><p>O</p></td><td valign="top"> </td></tr><tr><td valign="top"><p> </p><p> </p><p>///72</p></td><td valign="top"><p> </p><p> </p><p>var</p></td><td valign="top"><p>Issuer Script Template 2</p><p>As defined in <em>EMV Integrated Circuit Card Specifications for Payment Systems 4.3</em>. The host may include as many instances of this parameter as needed, up to a maximum length of 128 bytes including Tags and Lengths.</p></td><td valign="top"><p> </p><p> </p><p>B</p></td><td valign="top"><p> </p><p> </p><p>O</p></td><td valign="top"> </td></tr></tbody></table>

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
    var message: NSString = "" 
    switch eventType
        {
            case MTU_EventType_DisplayMessage:
            // Display approval message. 
            message = data.StringValue

            // A data size of 0 is an instruction to clear the display. 
            if (data.StringValue.count == 0)
            {
            // Clear the UI display.
            }
       }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
        switch eventType
                {
                        case MTU_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].
                }
}
```

{% endcode %}

{% code overflow="wrap" %}

```
func onEvent(_ eventType: MTU_EventType, data: IData!)
{
var signature: NSString* = "" 
switch eventType
    {
        case MTU_EventType_Signature: 
            signature = data.StringValue
    }
}
```

{% endcode %}

### MSR Fallback Flow <a href="#b.7_msr_fallback_flow" id="b.7_msr_fallback_flow"></a>

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 magnetic stripe.
* \-->Host starts a transaction with PaymentMethod set to MSR.
* <--Device may respond with transaction canceled 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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://developer.magtek.com/sdks-and-tools/universal-sdk-documentation/ios/appendices/appendix-b-emv-transaction-flow.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
