# Android SDK

## Overview

Sola (Cardknox) Android SDK is a mobile SDK targeted towards Android developers, allowing developers to process transactions with the [Sola Transactions API](https://docs.solapayments.com/api/transaction).

{% hint style="info" %}
*Due to the necessity of the API key in this integration method, we strongly recommend reserving these features for integrations to be used solely on merchant-owned devices.*
{% endhint %}

## Getting started

To start, download the SDK framework file from the CDN:

* [Android SDK download](https://cdn.cardknox.com/sdk-android/versions.html)

Integrate the SDK file into your Android Studio project by referring to the [technical documentation](/sdk/android-sdk/android-sdk-technical-guide.md).

## Choose your integration path

The SDK offers developers a couple of ways to process transactions:

* In scope function
* Out of scope function
* Custom UI set of functions
* Payment Engine set of functions

### Out of scope

Use the out of scope function when the user needs to provide their credit card information. This function displays the SDK user interface, effectively giving the control over to the SDK to acquire the sensitive credit card data from the user. The user provides the sensitive information either via a form or via a credit card device, and then the SDK processes the transaction with the gateway.

### In scope

Use the in scope function when there is no need for the SDK to interact with the user through a user interface. The developer should either pass in a card number + an expiration date, or provide a tokenized card data via the xToken parameter to this function to quickly process the transaction and retrieve back the results.

### Custom UI

Custom-UI integration consists of a set of functions to control the card reader device via the SDK. Currently supported card reader device is a Bluetooth VP3300 card reader and USB connection. This integration path is useful when the developer has an existing UI and wishes to use a card reader device to obtain users' card sensitive information and then process the transaction with the gateway. The SDK offers a set of functions to control the card reader device. The SDK takes care of processing with the gateway and notifying the Developer’s application with the processing results.

### Payment Engine <a href="#payment-engine" id="payment-engine"></a>

The Payment Engine feature inside the SDK enables you to create transactions with a card reader over IP. The Payment Engine supports different card readers from Pax, Verifone, and Ingenico brands. See a full list of supported devices in the table below. The feature doesn't contain any UI. The developer provides device and transaction parameters to Payment Engine functions. The SDK takes care of communicating with the card reader and processing with the gateway. Finally, the SDK returns the device and transaction status and states.

| **Brand**                                  | **Model**            | **Suffix**                                | **Parameter value** |
| ------------------------------------------ | -------------------- | ----------------------------------------- | ------------------- |
| <p> </p><p> </p><p> </p><p> </p><p>Pax</p> | SP30                 | <p> </p><p> </p><p> </p><p> </p><p>.3</p> | Pax\_SP30.3         |
| S300                                       | Pax\_S300.3          |                                           |                     |
| S920                                       | Pax\_S920.3          |                                           |                     |
| A35                                        | Pax\_A35.3           |                                           |                     |
| A60                                        | Pax\_A60.3           |                                           |                     |
| A77                                        | Pax\_A773            |                                           |                     |
| A80                                        | Pax\_A80.3           |                                           |                     |
| A920                                       | Pax\_A920.3          |                                           |                     |
| PX5                                        | Pax\_PX5.3           |                                           |                     |
| PX7                                        | Pax\_PX7.3           |                                           |                     |
| D210                                       | Pax\_D210.3          |                                           |                     |
| D220                                       | Pax\_D22.3           |                                           |                     |
| Aries6                                     | Pax\_Aries6.3        |                                           |                     |
| Aries8                                     | Pax\_Aries8.3        |                                           |                     |
| <p> </p><p> </p><p> </p><p>Verifone</p>    | MX915                | <p> </p><p> </p><p> </p><p>.4</p>         | Verifone\_MX915.4   |
| MX925                                      | Verifone\_MX925.4    |                                           |                     |
| P200                                       | Verifone\_P200.4     |                                           |                     |
| P400                                       | Verifone\_P400.4     |                                           |                     |
| M400                                       | Verifone\_M400.4     |                                           |                     |
| E285                                       | Verifone\_E2854      |                                           |                     |
| <p> </p><p>Ingenico</p>                    | ICT250               | <p> </p><p>.2</p>                         | Ingenico\_ICT250.2  |
| Desk500                                    | Ingenico\_Desk5000.2 |                                           |                     |
| Move500                                    | Ingenico\_Move5000.2 |                                           |                     |

## Transaction workflows

Download our sample applications:

* [Java sample app](https://cdn.cardknox.com/sdk-android/versions.html)

### Basic parameters

| **Name**         | **Required** | **Description**                 | **Sample data** |
| ---------------- | ------------ | ------------------------------- | --------------- |
| xKey             | Yes          | Sola account key                | Sola            |
| xVersion         | Yes          | Gateway version                 | 4.5.9           |
| xSoftwareName    | Yes          | Name of your software           | My app          |
| xSoftwareVersion | Yes          | Version number of your software | 1.0.0           |

### Basic parameter functions

Prior to any processing, the Sola SDK needs to be configured with user’s metadata and the account key. These functions can be called anywhere in the application any number of times to change the metadata and/or current account key.

| **Function**              | **Description**                                                                                                                                                                                       | **Sample data**                                                             |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| setSoftwareConfigurations | Specifies the name of your software (xSoftwareName), version number of your software (xSoftwareVersion) and the gateway version (xVersion)                                                            | `CardknoxSDK.setSoftwareConfigurations("Your app name", "0.0.1", "4.5.9");` |
| setPrincipalKey           | <p>Accepts the xKey.</p><p>xKey is a Sola account key.</p><p>All transactions being processed after calling this function will be associated to the account that was passed in into the function.</p> | `CardknoxSDK.setPrincipalKey("ps_demo_cardknox");`                          |

### Transaction required parameters

Each integration path has a “process” function that accepts a “transaction parameters” object. Developers specify required values for transaction processing through that object. The same object can be used to specify optional; parameters to associate with a transaction, such as invoice numbers, billing address, etc.

| **Name** | **Description**       | **Sample data** |
| -------- | --------------------- | --------------- |
| xCommand | Sola transaction type | cc:sale         |

### Transaction optional parameters

Optional transaction parameters further complement the transaction processing. All the parameters are sent to the Gateway during processing.

| **Name**                     | **Description**                                                                                                                                                                                                                                                                                                                                                           | **Sample data**                                                                                                                                                          |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| VP3300TransactionTimeout     | <p>Start transaction timeout, in seconds.</p><p>Once the transaction with the VP3300 reader is started; the SDK times out if the card is not provided in the time frame specified by this timeout value.</p><p> </p><p>This parameter is only applicable for SDK integrations that use a VP3300 card reader; such as CustomUI or OutOfScope integrations.</p>             | Refer to the Custom UI flow or Out Of Scope flow for samples.                                                                                                            |
| xCardNum                     | Card number                                                                                                                                                                                                                                                                                                                                                               | 4444333322221111                                                                                                                                                         |
| xExpDate                     | <p>Card expiration date.</p><p><br>Expected format is MMYY where MM is a month, and YY are last 2 year digits</p>                                                                                                                                                                                                                                                         | <p>“1126” for (November 2026)</p><p>“0122” for “January 2022”</p>                                                                                                        |
| xToken                       | <p>From <a href="/pages/g1gMqjuhO4qESS2Yro3k">Transaction API:</a></p><p>The Cardknox token that references a previously used payment method. When using a token, <code>xCardNum</code>, <code>xExp</code> and <code>xMagstripe</code> should not be used.</p>                                                                                                            | 61h72mmh68phn9q233634ph3g54p1499m69qhp4816pn528h84                                                                                                                       |
| xRefNum                      | Used to reference a previous transaction when doing a follow-up transaction, typically a refund, void, or capture.                                                                                                                                                                                                                                                        | 12345678                                                                                                                                                                 |
| xInvoice                     | The merchant’s invoice number for the transaction. xInvoice is recommended when available for improved duplicate handling.                                                                                                                                                                                                                                                | The merchant’s invoice number for the transaction. xInvoice is recommended when available for improved duplicate handling.                                               |
| xPoNum                       | The merchant’s purchase order number for the transaction.                                                                                                                                                                                                                                                                                                                 | 123485                                                                                                                                                                   |
| xDescription                 | This is a description                                                                                                                                                                                                                                                                                                                                                     | This is a description                                                                                                                                                    |
| xName                        | The cardholder’s name.                                                                                                                                                                                                                                                                                                                                                    | John Doe                                                                                                                                                                 |
| xBillFirstName               | The customer’s first name for their billing profile.                                                                                                                                                                                                                                                                                                                      | John                                                                                                                                                                     |
| xBillLastName                | The customer’s last/family name for their billing profile.                                                                                                                                                                                                                                                                                                                | Doe                                                                                                                                                                      |
| xBillCompany                 | The customer’s company name for their billing profile.                                                                                                                                                                                                                                                                                                                    | Acme                                                                                                                                                                     |
| xBillStreet                  | The customer’s street address for their billing profile.                                                                                                                                                                                                                                                                                                                  | 123 Any Street                                                                                                                                                           |
| xBillStreet2                 | The customer’s second street address for their billing profile.                                                                                                                                                                                                                                                                                                           | 123 Any Street                                                                                                                                                           |
| xBillCity                    | The customer’s city for their billing profile.                                                                                                                                                                                                                                                                                                                            | Anytown                                                                                                                                                                  |
| xBillState                   | The customer’s state for their billing profile.                                                                                                                                                                                                                                                                                                                           | NY                                                                                                                                                                       |
| xBillZip                     | The customer’s zip code for their billing profile.                                                                                                                                                                                                                                                                                                                        | 12345                                                                                                                                                                    |
| xBillCountry                 | The customer’s phone number for their billing profile.                                                                                                                                                                                                                                                                                                                    | USA                                                                                                                                                                      |
| xBillPhone                   | The customer’s phone number for their billing profile.                                                                                                                                                                                                                                                                                                                    | 8005551212                                                                                                                                                               |
| xShipFirstName               | The customer’s last/family name for their shipping profile.                                                                                                                                                                                                                                                                                                               | John                                                                                                                                                                     |
| xShipLastName                | The customer’s last/family name for their shipping profile.                                                                                                                                                                                                                                                                                                               | Doe                                                                                                                                                                      |
| xShipCompany                 | The customer’s company name for their shipping profile.                                                                                                                                                                                                                                                                                                                   | Acme                                                                                                                                                                     |
| xShipStreet                  | The customer’s street address for their shipping profile.                                                                                                                                                                                                                                                                                                                 | 123 Any Street                                                                                                                                                           |
| xShipStreet2                 | The customer’s second street address for their shipping profile.                                                                                                                                                                                                                                                                                                          | 123 Any Street                                                                                                                                                           |
| xShipCity                    | The customer’s city for their shipping profile.                                                                                                                                                                                                                                                                                                                           | Anytown                                                                                                                                                                  |
| xShipState                   | The customer’s state for their shipping profile.                                                                                                                                                                                                                                                                                                                          | NY                                                                                                                                                                       |
| xShipZip                     | The customer’s zip code for their shipping profile.                                                                                                                                                                                                                                                                                                                       | 12345                                                                                                                                                                    |
| xShipCountry                 | The customer’s country for their shipping profile.                                                                                                                                                                                                                                                                                                                        | USA                                                                                                                                                                      |
| xShipPhone                   | The customer’s phone number for their shipping profile.                                                                                                                                                                                                                                                                                                                   | 1113333444                                                                                                                                                               |
| xCustom01                    | Custom field 1. Use this for any additional data                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                          |
| xCustom02                    | Custom field 2. Use this for any additional data                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                          |
| xCustom03                    | Custom field 3. Use this for any additional data                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                          |
| xAuthCode                    | xAuthCode is a verification number provided by the issuing bank to be used with the cc:postauth command.                                                                                                                                                                                                                                                                  |                                                                                                                                                                          |
| xAllowDuplicate              | By default, Cardknox rejects duplicate transactions within 10 minutes of the original transaction. This command overrides that safeguard. True/False allowed.                                                                                                                                                                                                             | False                                                                                                                                                                    |
| xCustReceipt                 | True/False value indicating if the email address specified in xEmail should receive a receipt containing the transaction details.                                                                                                                                                                                                                                         | False                                                                                                                                                                    |
| xEmail                       | The customer’s email address.                                                                                                                                                                                                                                                                                                                                             | <test@example.com>                                                                                                                                                       |
| Device\_name                 | PE device name                                                                                                                                                                                                                                                                                                                                                            | <p>Verifone\_P400.4</p><p>(The 4. column in Payment engine support device table)</p>                                                                                     |
| Device\_IP\_Address          | IP address of PE device                                                                                                                                                                                                                                                                                                                                                   | 172.21.2.7                                                                                                                                                               |
| Device\_Port                 | Port of PE device                                                                                                                                                                                                                                                                                                                                                         | 9006                                                                                                                                                                     |
| Device\_Timeout              | Timeout for PE device connecting                                                                                                                                                                                                                                                                                                                                          | 120                                                                                                                                                                      |
| VP3300StartTransactionMethod | <p>The card reader can scan a card in a few different ways: swipe, tap, or insert a card. This property defines how the card reader expects the card to be scanned.</p><p>See <a href="https://cardknox.atlassian.net/wiki/spaces/MOB/pages/2661711873/Android+SDK+User+Manual#Custom-UI-with-USB">SetVP3300StartTransactionMethod in Custom UI with USB section</a>.</p> | <p></p><p>Possible values:</p><ul><li>CTLS - tap a card (NFC)</li><li>EMV - insert card</li><li>MSR - swipe card</li><li>DEVICE - swipe, insert and tap a card</li></ul> |
| EnableTipPrompt              | Prompts the user on the device to add a tip to the transaction. This functionality is only available when the device is enabled. The response to the transaction will include two parameters: "xTip" (the tip amount) and "xAuthAmount" (the final authorized amount on the card, including the tip amount).                                                              | Available in the Payment Engine integration.                                                                                                                             |

### Retrieving results with callbacks <a href="#retrieving-results-with-callbacks" id="retrieving-results-with-callbacks"></a>

The SDK can notify the application about various events during processing, such as about different card reader events during out of scope processing, or perhaps about a completed bluetooth device scan during custom UI processing.

Developers opt in to receive callbacks by registering BroadcastReceivers with IntentFilters, using a predefined value from the SDK for the “action” parameter.

The SDK uses the same “action” value to report results & various information back to subscribers.

Available callback types and integrations where they are applicable in are as follows:

| **Callback type**             | **Description**                                                                                                                                                                                                                                                                                                                                                    | **Available in integration**                          |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- |
| Transaction result            | The SDK processes a payment with the Gateway and delivers an object containing all processed transaction details.                                                                                                                                                                                                                                                  | <p>Out of scope</p><p>Custom UI<br>Payment Engine</p> |
| Card reader event             | The SDK keeps informing the subscribers about various events taking place between the application and the card reader device; such as “connected”, “disconnected”, “transaction started”, “on bluetooth disabled error”, etc.                                                                                                                                      | <p>Out of scope</p><p>Custom UI</p>                   |
| Scanned bluetooth device      | <p>Trigger a bluetooth device scanning process with the “start scanning” function.</p><p><br>During the scanning process, the SDK keeps informing subscribers with objects that encapsulate all the information about each newly discovered Bluetooth device.<br></p><p>The SDK expects one of the objects as an argument in the “connect to device” function.</p> | Custom UI                                             |
| Scan completed                | <p>Trigger a bluetooth device scanning process with the “start scanning” function.<br></p><p>Stop the process with a “stop scanning” function.<br></p><p>Once the scanning process is stopped, the SDK reports back a list of all scanned bluetooth devices.<br></p><p>The SDK expects one of the objects as an argument in the “connect to device” function.</p>  | Custom UI                                             |
| Device status                 | <p>The SDK is sending information to subscribers about the device initialization process and the actions that the device expects from the user of the card scanner. </p><p>For example, waiting for the insert or swipe of a credit card.</p>                                                                                                                      | Payment Engine                                        |
| Transaction status            | The transaction status sends information about the card scanning process.                                                                                                                                                                                                                                                                                          | Payment Engine                                        |
| Result as JSON                | The result of created transaction return in JSON format.                                                                                                                                                                                                                                                                                                           | Payment Engine                                        |
| Payment engine LogCat logging | The payment engine supports two types of event logging. One prints logs directly to the LogCat console, while the other delivers logs via callbacks, allowing the app to handle them programmatically.                                                                                                                                                             | Payment Engine                                        |

### Callback subscriptions & result handling

Based on your integration path choice, choose an available callback type for that integration path and register a BroadcastReceiver to receive appropriate information back from the SDK.

#### Transaction result callback subscription

This callback delivers a “transaction processed response” object to the subscriber.

Subscription can be made in the appropriate Fragment lifecycle method:

{% code lineNumbers="true" %}

```javascript
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import cardknox.payments.sdk.CardknoxSDK;
import cardknox.payments.sdk.PaymentTransactionResponse;

public class TransactionResultExampleFragment extends Fragment {

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        RegisterIntentFilters();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        UnregisterIntentFilters();
    }

    private void RegisterIntentFilters()
    {
        Context c = getContext();

        if(c != null)
        {
            c.registerReceiver(Receiver_TransactionProcessing, new IntentFilter(CardknoxSDK.TRANSACTION_CALLBACK_INTENTFILTER_ACTION()));
        }
    }

    private void UnregisterIntentFilters()
    {
        Context c = this.getContext();

        if(c != null)
        {
            c.unregisterReceiver(Receiver_TransactionProcessing);
        }
    }

    private final BroadcastReceiver Receiver_TransactionProcessing = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();

            // Verify that the Cardknox SDK broadcasted the Intent
            if(action.equals(CardknoxSDK.TRANSACTION_CALLBACK_INTENTFILTER_ACTION()))
            {
                String extraKey = CardknoxSDK.TRANSACTION_CALLBACK_INTENTFILTER_EXTRA();
                java.lang.Object extra = intent.getParcelableExtra(extraKey);

                // Cast the 'extra' to the Cardknox SDK response type
                PaymentTransactionResponse response = (PaymentTransactionResponse)extra;

                if(response.GetIsSuccess())
                {
                    // Transaction successfully processed
                    String xRefNum = response.GetxRefNum();
                    // approved, declined, ...
                    String xStatus = response.GetxStatus();
                    String cvv = response.GetxCvvResult();
                    String avs = response.GetxAvsResult();
                    // ... other properties ...

                    Output("Transaction approved. Ref num: " + xRefNum);
                }
                else
                {
                    // Transaction processing resulted in an error; message can be extracted from this property:
                    String errorMessage = response.GetErrorMessage();
                    String errorCode = response.GetxErrorCode();
                    String error = response.GetxError();

                    Output("Transaction declined/errored. Ref num: " + response.GetxRefNum());
                }
            }
        }
    };

    private void Output(String text)
    {
        android.util.Log.d("ExampleTag", text);
    }
}
```

{% endcode %}

#### Card reader event callback subscription

This callback delivers information about various events happening between the application & the card reader.

For example, while out-of-scope processing the SDK can report back error events related to bluetooth device pairing, such as “bluetooth not turned on” to indicate that the mobile device wanted to use the bluetooth service to find a nearby card reader device but the service is unavailable, or an error such as “waiting for device bluetooth response” to indicate that the mobile device found an eligible bluetooth card reader device and is expecting the card reader to respond back with bluetooth data. This could mean that the bluetooth button on the card reader needs to be pressed.

After a bluetooth pairing is established, the SDK reports back events related to obtaining the card data via the card reader. For example, a “connected” event means that the mobile device & the card reader are connected and a card data transaction can start. A “transaction started” event means that the SDK initiated a card data transaction with the card reader and the physical card can be tapped onto the card reader.

Subscription can be made in the appropriate Fragment lifecycle method:

{% code lineNumbers="true" %}

```javascript
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import cardknox.payments.sdk.CardknoxCardReaderCallback;
import cardknox.payments.sdk.CardknoxCardReaderCallbackType;
import cardknox.payments.sdk.CardknoxSDK;

public class CardReaderEventsExampleFragment extends Fragment {
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        RegisterIntentFilters();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        UnregisterIntentFilters();
    }

    private void RegisterIntentFilters()
    {
        Context c = getContext();

        if(c != null)
        {
            c.registerReceiver(Receiver_CardReaderEvents, new IntentFilter(CardknoxSDK.CARDREADER_CALLBACK_INTENTFILTER_ACTION()));
        }
    }

    private void UnregisterIntentFilters()
    {
        Context c = this.getContext();

        if(c != null)
        {
            c.unregisterReceiver(Receiver_CardReaderEvents);
        }
    }

    private final BroadcastReceiver Receiver_CardReaderEvents = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();

            // Verify that the Cardknox SDK broadcasted the Intent
            if(action.equals(CardknoxSDK.CARDREADER_CALLBACK_INTENTFILTER_ACTION()))
            {
                String extraKey = CardknoxSDK.CARDREADER_CALLBACK_INTENTFILTER_EXTRA();
                CardknoxCardReaderCallback callback = intent.getParcelableExtra(extraKey);

                // Read the event code
                int code = callback.GetCode();

                // Read the event name
                String name = callback.GetName();

                Output("Card reader event: " + name);

                // Match the non-error code; for example "connected"
                if(code == CardknoxCardReaderCallbackType.CONNECTED){
                    Output("Connected!");
                }

                // Extract the message when there's an error
                if(code == CardknoxCardReaderCallbackType.ERROR){
                    String message = callback.GetMessage();
                    Output("Card reader event: " + message);
                }
            }
        }
    };

    private void Output(String text)
    {
        android.util.Log.d("ExampleTag", text);
    }
}
```

{% endcode %}

#### Card reader events

When a card reader event happens, the SDK delivers an object, of a type named similarly to “`CardknoxCardReaderCallback`”, back into the app.

The object encapsulates two things:

* an event integer code
* an event name; such as “connected”, “disconnected”, etc.

Event integer codes are enumerated in a type named similarly to "`CardknoxCardReaderCallbackType`".

Developers can match the received integer code value with the enumeration of interest to pinpoint a wanted event.

| **Event name**                          | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| connecting                              | <p>The Cardknox SDK calls into the card reader SDK to connect with the reader, in scenarios such as:</p><ul><li>“connect to device” method in the “custom ui” integration</li><li>when it presents its own UI in “process out of scope” integration</li></ul><p>The card reader SDK starts searching for nearby IDTech card readers & notifies the Cardknox SDK with a “connecting” event.<br></p><p>The Cardknox SDK raises a “connecting” callback which notifies the app.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| waitingForDeviceResponse                | <p>This event is raised whenever the Cardknox SDK scans for nearby card readers. Awake readers are usually auto connected straight away.<br></p><p>Asleep or not, this event is always raised from the SDK to indicate that some action is required on the device.<br></p><p>This event is raised in the “custom ui” integration when:</p><ul><li>a developer calls the “start scanning” method and the underlying bluetooth adapter starts scanning</li><li>or when a Developer calls the “connect to device” method. Sola SDK will call the card reader SDK to “connect” and raise this event</li></ul><p>This event is raised in the “process out of scope” integration when:</p><ul><li>the Cardknox SDK presents its user interface; automatically starting a bluetooth scan for a nearby card reader, expecting a response back</li></ul>                                                                                                                          |
| connected                               | <p>Raised when the app & the card reader establish a bluetooth connection.</p><p>Bluetooth connection is established when the Cardknox SDK scans for card readers, and card readers respond back with some bluetooth payload.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| disconnected                            | <p>Card reader SDK sends this event to the Cardknox SDK whenever a bluetooth card reader goes to sleep.<br></p><p>This event is never raised explicitly by the Cardknox SDK.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| transactionStarting                     | <p>Informational event.<br></p><p>Cardknox SDK raises this event before it places a call to the underlying card reader SDK in order to start a transaction with the card reader.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| transactionStarted                      | <p>Cardknox SDK attempts a “start transaction” call with the card reader SDK.<br></p><p>Card reader SDK successfully starts the transaction and notifies the Cardknox SDK with this event.<br></p><p>Cardknox SDK calls back with this event to the app.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| transactionStartErrorTimeout            | <p>Cardknox SDK attempts a “start transaction” call with the card reader SDK.</p><p><br>The card reader never receives a card in a specified timeout frame window (about 20 seconds) and the transaction times out.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| transactionStartDeviceDisconnected      | Cardknox SDK wants to start the transaction with a disconnected device.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| transactionCancelled                    | <p>Generally, this is raised whenever an error occurs at any point between starting a transaction with the reader and obtaining the card data.<br></p><p>See the “error” event for error examples.<br></p><p>The Cardknox SDK in cases of these errors preventively calls the “cancel any pending transactions” internally to clean up.</p><p>Specifically, this event is raised in the “custom ui” integration when:</p><ul><li>a “cancel transaction” method is called & the card reader SDK cancels all pending transactions between the app & the card reader</li></ul><p>Furthermore, this event is raised in the “process out of scope” integration when:</p><ul><li>the Cardknox SDK’s user interface is closed; either via a pull down gesture or via a “close” UI element; to clean things up</li><li>the charge amount gets modified via UI and becomes invalid, effectively invalidating any pending transactions between the app & the card reader</li></ul> |
| scanStop                                | <p>Indicates that the Cardknox SDK stopped its own bluetooth scanning.</p><p>Raised in the “custom ui” integration when:</p><ul><li>a Developer explicitly calls the “stop scanning” method</li><li>when the “start scanning” method was called with a timeout value and the timeout expired or was cancelled / interrupted</li><li>in the “disconnect from current device” call if the “connect to device” method was called beforehand but there is no connected device to disconnect from</li></ul><p>Raised in the “process out of scope” integration when:</p><ul><li>the SDK shows its' UI and automatically starts scanning for nearby readers. User can explicitly stop the scanning process</li></ul>                                                                                                                                                                                                                                                           |
| scanStart                               | <p>Indicates that the Cardknox SDK started a bluetooth scanning process.</p><p>Raised in the “custom ui” integration when:</p><ul><li>the “start scanning” method was called, with or without a timeout value</li></ul><p>Raised in the “process out of scope” integration when:</p><ul><li>the SDK shows its' UI and automatically starts scanning for nearby readers</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| error                                   | <p>This is raised whenever an error occurs at any point between starting a transaction with the reader and obtaining the card data.</p><p>Things that could go wrong (list is not exhaustive) are:</p><ul><li>transaction with the card reader failed to start</li><li>emv card readings are corrupted</li><li>transaction started but the card was not tapped / swiped / inserted in time</li></ul><p>A descriptive error message is always accompanying this event.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| swipe says use chip reader              | This card reader event is raised when the card with a chip is swiped, to indicate that a “fallback Swipe” was blocked. Reach out to Sola support to consult about “fallback Swipe”.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| card inserted when ctls swipe requested | in some scenarios, the VP3300 will expect a Swipe, but will receive a card Insert. In such cases this event is raised.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| contactless in msr card read event      | this event is raised when a Contactless MSD transaction is performed on a VP3300 device.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| USB detached                            | <p>This event occurs when the USB cable is unplugged, causing the connection between the mobile device and the card reader to be interrupted. As a result, any ongoing communication or data transfer between the two devices is immediately stopped.</p><p> </p><p>Note: Only available for <a href="https://cardknox.atlassian.net/wiki/spaces/MOB/pages/2661711873/Android+SDK+User+Manual#Custom-UI-with-USB">Custom UI with USB integration</a>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| USB device not found                    | <p>This is raised when you try to connect to the card reader that's not plugged in with a USB cable.</p><p> </p><p>Note: Only available for <a href="https://cardknox.atlassian.net/wiki/spaces/MOB/pages/2661711873/Android+SDK+User+Manual#Custom-UI-with-USB">Custom UI with USB integration</a>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| USB unsupported product                 | <p>This means that the connected USB device is not supported by the system or the driver.</p><p> </p><p>Note: Only available for <a href="https://cardknox.atlassian.net/wiki/spaces/MOB/pages/2661711873/Android+SDK+User+Manual#Custom-UI-with-USB">Custom UI with USB integration</a>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| USB permission not granted              | <p>This error occurs when the application does not have the necessary permission to access the connected USB device. The user must explicitly grant permission for the device to be recognized and used.</p><p> </p><p>Note: Only available for <a href="https://cardknox.atlassian.net/wiki/spaces/MOB/pages/2661711873/Android+SDK+User+Manual#Custom-UI-with-USB">Custom UI with USB integration</a>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |

#### Scanned bluetooth device callback subscription

One of the Custom UI integration functions is a “start scanning” function. The function keeps scanning for nearby bluetooth devices until it is manually stopped with the “stop scanning” function or if it times out.

During the scanning process, for every scanned device the SDK sends a “scanned device” object that contains all the necessary metadata about the scanned device, such as the devices' display name or its internal name.

Subscription can be made in the appropriate Fragment lifecycle method:

{% code lineNumbers="true" %}

```javascript
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import cardknox.payments.sdk.CardknoxSDKCustomUI;
import cardknox.payments.sdk.CardknoxSDKCustomUIScannedDevice;

public class ScannedDeviceExampleFragment extends Fragment {
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        RegisterIntentFilters();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        UnregisterIntentFilters();
    }

    private void RegisterIntentFilters()
    {
        Context c = getContext();

        if(c != null)
        {
            c.registerReceiver(Receiver_ScannedDevice, new IntentFilter(CardknoxSDKCustomUI.SCANNED_DEVICE_INTENTFILTER_ACTION()));
        }
    }

    private void UnregisterIntentFilters()
    {
        Context c = this.getContext();

        if(c != null)
        {
            c.unregisterReceiver(Receiver_ScannedDevice);
        }
    }

    private final BroadcastReceiver Receiver_ScannedDevice = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();

            // Verify that the Cardknox SDK broadcasted the Intent
            if(action.equals(CardknoxSDKCustomUI.SCANNED_DEVICE_INTENTFILTER_ACTION()))
            {
                String extraKey = CardknoxSDKCustomUI.SCANNED_DEVICE_INTENTFILTER_EXTRA();
                java.lang.Object extra = intent.getParcelableExtra(extraKey);

                CardknoxSDKCustomUIScannedDevice device = (CardknoxSDKCustomUIScannedDevice) extra;
                // Can be used with a 'connect' method, like so:
                String address = device.GetAddress();
                CardknoxSDKCustomUI example = null;
                example.connectWithAddress(address);
                
                // Output various data about the device
                Output("Scanned device name: " + device.GetName());
                Output("Scanned device display name: " + device.GetDisplayName());
                Output("Scanned device address: " + device.GetAddress());
            }
        }
    };

    private void Output(String text)
    {
        android.util.Log.d("ExampleTag", text);
    }
}
```

{% endcode %}

#### Scan completed callback subscription

One of the Custom UI integration functions is a “start scanning” function. The function keeps scanning for nearby bluetooth devices until it is manually stopped with the “stop scanning” function or if it times out.

Once the scanning process ends, the SDK sends a list of scanned device objects to all subscribers. Any object in the retrieved list can be used as an argument to the “connect to device” method.

Subscription can be made in the appropriate Fragment lifecycle method:

{% code lineNumbers="true" %}

```javascript
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import cardknox.payments.sdk.CardknoxSDKCustomUI;
import cardknox.payments.sdk.CardknoxSDKCustomUIScanCompleted;
import cardknox.payments.sdk.CardknoxSDKCustomUIScannedDevice;

public class ScanCompletedExampleFragment extends Fragment {
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        RegisterIntentFilters();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        UnregisterIntentFilters();
    }

    private void RegisterIntentFilters()
    {
        Context c = getContext();

        if(c != null)
        {
            c.registerReceiver(Receiver_ScanCompleted, new IntentFilter(CardknoxSDKCustomUI.SCAN_COMPLETED_INTENTFILTER_ACTION()));
        }
    }

    private void UnregisterIntentFilters()
    {
        Context c = this.getContext();

        if(c != null)
        {
            c.registerReceiver(Receiver_ScanCompleted, new IntentFilter(CardknoxSDKCustomUI.SCAN_COMPLETED_INTENTFILTER_ACTION()));
        }
    }

    private final BroadcastReceiver Receiver_ScanCompleted = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();

            // Verify that the Cardknox SDK broadcasted the Intent
            if(action.equals(CardknoxSDKCustomUI.SCAN_COMPLETED_INTENTFILTER_ACTION()))
            {
                String extraKey = CardknoxSDKCustomUI.SCAN_COMPLETED_INTENTFILTER_EXTRA();
                java.lang.Object extra = intent.getParcelableExtra(extraKey);
                CardknoxSDKCustomUIScanCompleted scanCompleted = (CardknoxSDKCustomUIScanCompleted) extra;

                if(scanCompleted != null && scanCompleted.scannedDevices() != null &&
                        scanCompleted.scannedDevices().size() > 0)
                {
                    for (Object device : scanCompleted.scannedDevices()) {
                        CardknoxSDKCustomUIScannedDevice device = (CardknoxSDKCustomUIScannedDevice)d;

                        // Can be used with a 'connect' method, like so:
                        String address = device.GetAddress();
                        CardknoxSDKCustomUI example = null;
                        example.connectWithAddress(address);

                        // Output various data about the device
                        Output("Scanned device name: " + device.GetName());
                        Output("Scanned device display name: " + device.GetDisplayName());
                        Output("Scanned device address: " + device.GetAddress());
                    }
                }
            }
        }
    };

    private void Output(String text)
    {
        android.util.Log.d("ExampleTag", text);
    }
}
```

{% endcode %}

#### Device status callback subscription

This callback provides information about the status of the card reader. It sends information about the initialization process of the device, the connection process of the card reader, and the mobile device. It also sends notifications about the actions expected by the user of the credit card.

```java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import cardknox.payments.sdk.CardknoxPaymentEngineSDK;

public class DeviceStatusExampleFragment extends Fragment {

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        RegisterIntentFilters();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        UnregisterIntentFilters();
    }

    private void RegisterIntentFilters()
    {
        Context c = getContext();

        if(c != null)
        {
            c.registerReceiver(Receiver_DeviceStatus, new IntentFilter(CardknoxPaymentEngineSDK.DEVICE_STATUS_INTENTFILTER_ACTION()));
        }
    }

    private void UnregisterIntentFilters()
    {
        Context c = this.getContext();

        if(c != null)
        {
            c.unregisterReceiver(Receiver_DeviceStatus);
        }
    }

    private final BroadcastReceiver Receiver_DeviceStatus = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            // Verify that the Cardknox SDK broadcasted the event
            if(action.equals(CardknoxPaymentEngineSDK.DEVICE_STATUS_INTENTFILTER_ACTION()))
            {
                String extraKey = CardknoxPaymentEngineSDK.DEVICE_STATUS_INTENTFILTER_EXTRA();
                String deviceStatus = intent.getStringExtra(extraKey);
                Output(deviceStatus);
            }
        }
    };

    private void Output(String text)
    {
        android.util.Log.d("ExampleTag", text);
    }
}
```

#### Transaction status callback subscription <a href="#transaction-status-callback-subscription" id="transaction-status-callback-subscription"></a>

The transaction status callback sends information about the card scanning process. This callback starts triggering when the user inserts or swipes the credit card and ends with the result of card scanning.

```java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import cardknox.payments.sdk.CardknoxPaymentEngineSDK;

public class TransactionStatusExampleFragment extends Fragment {

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        RegisterIntentFilters();
    }

    @Override
    public void onDetach() {
        super.onDetach();
        UnregisterIntentFilters();
    }

    private void RegisterIntentFilters()
    {
        Context c = getContext();

        if(c != null)
        {
            c.registerReceiver(Receiver_TransactionStatus, new IntentFilter(CardknoxPaymentEngineSDK.TRANSACTION_STATUS_INTENTFILTER_ACTION));
        }
    }

    private void UnregisterIntentFilters()
    {
        Context c = this.getContext();

        if(c != null)
        {
            c.unregisterReceiver(Receiver_TransactionStatus);
        }
    }

    private final BroadcastReceiver Receiver_TransactionStatus = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            // Verify that the Cardknox SDK broadcasted the event
            if(action.equals(CardknoxPaymentEngineSDK.TRANSACTION_STATUS_INTENTFILTER_ACTION()))
            {
                String extraKey = CardknoxPaymentEngineSDK.TRANSACTION_STATUS_INTENTFILTER_EXTRA();
                String deviceStatus = intent.getStringExtra(extraKey);
                Output(deviceStatus);
            }
        }
    };

    private void Output(String text)
    {
        android.util.Log.d("ExampleTag", text);
    }
}
```

#### Result as JSON callback subscription <a href="#result-as-json-callback-subscription" id="result-as-json-callback-subscription"></a>

The callback for a basic processed transaction response returns information about the transaction as an object with properties. Each property of the object corresponds to a specific piece of transaction data. However, the payment engine has an additional callback for the transaction result, which is returned as JSON. In this callback, instead of returning the transaction as an object, the processed transaction is provided as a text representation of a JSON object.

To receive the transaction response as JSON using this callback, you must call the `SetSendResponseAsJSON(true)` method on `CardknoxPaymentEngineSDK`object . Otherwise, the transaction result will return the response as an object. The transaction response can only be received through a single callback at any given time. This means that only one callback handler is allowed to process the response for a specific transaction, ensuring consistency and avoiding potential conflicts or duplicate processing.

```java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import androidx.fragment.app.Fragment;

import cardknox.payments.sdk.CardknoxPaymentEngineSDK;
import cardknox.payments.sdk.CardknoxPaymentEngineSDKRequest;
import cardknox.payments.sdk.CardknoxPaymentEngineSDKResponseJSON;
import cardknox.payments.sdk.CardknoxPaymentEngineSDKSettings;
import cardknox.payments.sdk.CardknoxSDK;

public class PaymentEngineExampleFragment extends Fragment {

    private void SetupReceivePaymentEngineResponseAsJSON(){
        Context applicationContext = null;
        CardknoxSDK.create().getPaymentEngine().SetSendResponseaAsJSON(true);
        try { applicationContext.unregisterReceiver(Result_PaymentEngineResponseAsJSON);} catch(Exception e) {}
        applicationContext.registerReceiver(Result_PaymentEngineResponseAsJSON, new IntentFilter(CardknoxPaymentEngineSDK.PAYMENTENGINE_JSON_INTENTFILTER_ACTION()));
    }

    private final BroadcastReceiver Result_PaymentEngineResponseAsJSON = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();
            // Verify that the Cardknox SDK broadcasted the Intent
            if (action != null && action.equals(CardknoxPaymentEngineSDK.PAYMENTENGINE_JSON_INTENTFILTER_ACTION())) {

                String extraKey = CardknoxPaymentEngineSDK.PAYMENTENGINE_JSON_INTENTFILTER_EXTRA();
                java.lang.Object extra = intent.getParcelableExtra(extraKey);
                // Cast
                CardknoxPaymentEngineSDKResponseJSON response = (CardknoxPaymentEngineSDKResponseJSON) extra;
                String json = response.GetJSON();
            }
        }
    };

    private void SetupPaymentEngineBroadcastsLogCatMessages(){
        Context context = null;
        CardknoxPaymentEngineSDK paymentEngine = CardknoxSDK.create().getPaymentEngine();
        // PaymentEngine logging, 2 options:
        // 1. SDK writes the PE log to LogCat directly
        // 2. SDK sends the PE log it wants to write to this app (via BroadcastReceiver)
        // Note: calling 1 method negates the other one
        boolean broadcast = false;
        boolean writeDirectly = true;
        if(broadcast && writeDirectly)
            throw new RuntimeException("PE logs can either be directly written to LogCat or broadcasted back to this app, not both");

        if(writeDirectly){
            paymentEngine.enableLogCatOutput("LogCatTag");
        }
        else if(broadcast){
            paymentEngine.enableLogCatBroadcasts(true);
            // subscribe to logcat broadcasts
            try { context.unregisterReceiver(Receiver_LogcatMessages);} catch(Exception e) {}
            context.registerReceiver(Receiver_LogcatMessages, new IntentFilter(CardknoxPaymentEngineSDK.LOGGER_INTENTFILTER_ACTION()));
        }
    }

    private final BroadcastReceiver Receiver_LogcatMessages = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent != null) {
                String action = intent.getAction();
                if (action != null && action.equals(CardknoxPaymentEngineSDK.LOGGER_INTENTFILTER_ACTION())) {
                    String logcatMessage = "unknown";

                    String extraKey= CardknoxPaymentEngineSDK.LOGGER_INTENTFILTER_EXTRA();
                    if(intent.hasExtra(extraKey))
                        logcatMessage = intent.getStringExtra(extraKey);

                    android.util.Log.d("SomeTag", logcatMessage);
                }
            }
        }
    };


    private void Device_ReprintReceipt_Example(){
        CardknoxPaymentEngineSDKSettings settings = new CardknoxPaymentEngineSDKSettings();
        settings.SetDevice_IP_Address("specify IP");
        settings.SetDevice_IP_Port("specify port");
        settings.SetDevice_Name("specify device name, such as PAX_A77.3");
        settings.SetDevice_Timeout(5 * 1000); /* milliseconds to seconds */

        CardknoxPaymentEngineSDKRequest request = new CardknoxPaymentEngineSDKRequest();
        request.SetxAuthCode("add auth code here");

        String response = CardknoxSDK.create().getPaymentEngine().Device_ReprintReceipt(settings, request);
        boolean success = response.equals("OK");
    }

} 
```

#### Payment engine LogCat logging callback subscription <a href="#payment-engine-logcat-logging-callback-subscription" id="payment-engine-logcat-logging-callback-subscription"></a>

LogCat callback logging is a feature that allows the payment engine to send log messages directly to the application through callbacks. When enabled—by setting the `EnableLogcatBroadcasts` property to true—the app receives log events programmatically instead of relying only on the standard LogCat console output.

This method gives developers more control over how logs are used. Logs can be captured, filtered, stored, or forwarded to external monitoring systems, making it especially useful in production environments where console access is limited. It also enables building custom logging tools within the app for advanced debugging and diagnostics.

```java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import androidx.fragment.app.Fragment;

import cardknox.payments.sdk.CardknoxPaymentEngineSDK;
import cardknox.payments.sdk.CardknoxPaymentEngineSDKRequest;
import cardknox.payments.sdk.CardknoxPaymentEngineSDKResponseJSON;
import cardknox.payments.sdk.CardknoxPaymentEngineSDKSettings;
import cardknox.payments.sdk.CardknoxSDK;

public class PaymentEngineExampleFragment extends Fragment {

    private void SetupPaymentEngineBroadcastsLogCatMessages(){
        Context context = null;
        CardknoxPaymentEngineSDK paymentEngine = CardknoxSDK.create().getPaymentEngine();
        // PaymentEngine logging, 2 options:
        // 1. SDK writes the PE log to LogCat directly
        // 2. SDK sends the PE log it wants to write to this app (via BroadcastReceiver)
        // Note: calling 1 method negates the other one
        boolean broadcast = false;
        boolean writeDirectly = true;
        if(broadcast && writeDirectly)
            throw new RuntimeException("PE logs can either be directly written to LogCat or broadcasted back to this app, not both");

        if(writeDirectly){
            paymentEngine.enableLogCatOutput("LogCatTag");
        }
        else if(broadcast){
            paymentEngine.enableLogCatBroadcasts(true);
            // subscribe to logcat broadcasts
            try { context.unregisterReceiver(Receiver_LogcatMessages);} catch(Exception e) {}
            context.registerReceiver(Receiver_LogcatMessages, new IntentFilter(CardknoxPaymentEngineSDK.LOGGER_INTENTFILTER_ACTION()));
        }
    }

    private final BroadcastReceiver Receiver_LogcatMessages = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent != null) {
                String action = intent.getAction();
                if (action != null && action.equals(CardknoxPaymentEngineSDK.LOGGER_INTENTFILTER_ACTION())) {
                    String logcatMessage = "unknown";

                    String extraKey= CardknoxPaymentEngineSDK.LOGGER_INTENTFILTER_EXTRA();
                    if(intent.hasExtra(extraKey))
                        logcatMessage = intent.getStringExtra(extraKey);

                    android.util.Log.d("SomeTag", logcatMessage);
                }
            }
        }
    };
}
```

### Out of scope integration

Out of scope processing feature allows the developer to show the Cardknox user interface for payment processing.

To show the user interface, create a request object that is capable of showing a user interface:

```javascript
// Create the parameters object
TransactionParameters parameters = new TransactionParameters()
{
    {
        // Required parameters
        // 1. command to use. One of the Cardknox Transaction API commands
        SetxCommand("cc:sale");
        // 2. amount
        SetxAmount(1.23);

        // Supplementary parameters
        // 1. card number - will be prefilled on the keyed form
        SetxCardNum("4444333322221111");

        // 2. expiration date - will be prefilled on the keyed form
        // Format "MMYY"
        // For example: December 2024
        SetxExp("1224");

        // Optional parameters to supplement the transaction
        // All of the available parameters will be sent to the gateway
        SetxInvoice("1234");
        SetxBillCity("New York");
        // ... other optional parameters.
    }
};

PaymentTransactionRequestUI request = cardknoxSDKUI.createRequestWithParameters(parameters);
```

Check if the request object is in a valid state. If it is, call the method to show the UI. Otherwise, inspect the validation errors to see what is incorrect in the request object:

```javascript
PaymentTransactionRequestUI request = cardknoxSDKUI.createRequestWithParameters(parameters);

if(request.GetIsValid()){
    // Supply the Activity reference here.
    // In fragments, that might be a 'getActivity()' call.
    android.app.Activity activity = null;
    
    // Show Cardknox SDK UI
    request.process(activity);
} else {
    // Extract all validation errors that block
    // the request object from showing the SDK UI
    String[] validationErrors = request.GetValidationErrors();
}
```

#### Available user interfaces

The SDK’s user interface consists of two fullscreen parts - a manual entry screen and a card reader screen. Manual entry screen is also abbreviated as a “keyed” screen. The card reader screen is also abbreviated as a “swipe” screen.

Showing the SDK user interface via a Request object will either show one of the screens, or both. Which screen will be visible depends on the global SDK configuration state prior to showing the SDK user interface via a Request object.

Note that if the SDK is configured to allow access to both processing screens, one of them will be shown by default and both of them will have some kind of a visual way to navigate to the other one.

The following table shows available functions to control which screen will be visible & accessible:

| **Function**               | **Description**                                                                            | **Sample data**                                      |
| -------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------- |
| EnableDeviceInsertSwipeTap | Globally configures the SDK to show the keyed screen that allows manual input interaction. | `CardknoxSDKUI.SetEnableDeviceInsertSwipeTap(true);` |
| EnableKeyedEntry           | Globally configures the SDK to show the swipe screen that allows card reader interaction.  | `CardknoxSDKUI.SetEnableKeyedEntry(true);`           |

The following mapping represents which screens will be available when the SDK shows its user interface:

| **EnableDeviceInsertSwipeTap** | **EnableKeyedEntry** | **Keyed screen available** | **Swipe screen available** |
| ------------------------------ | -------------------- | -------------------------- | -------------------------- |
| false                          | false                | Yes                        | No                         |
| true                           | false                | No                         | Yes                        |
| false                          | true                 | Yes                        | No                         |
| true                           | true                 | Yes                        | Yes                        |

<div align="left"><figure><img src="/files/FEvwxBIOfH35ATgx5Z5M" alt=""><figcaption><p>Example of a <strong>keyed</strong> user interface. Keyed screen has a top right corner icon to navigate to the <strong>swipe</strong> screen.</p></figcaption></figure></div>

<figure><img src="/files/KE1DnjaROdKT2kwWq6Ya" alt=""><figcaption><p>Example of a <strong>swipe</strong> user interface. The <strong>swipe</strong> screen contains a button on the bottom that navigates the user to the <strong>keyed</strong> user interface.</p></figcaption></figure>

The following mapping represents available Cardknox Transaction API commands on each user interface

| **Keyed**                            | **Swipe**                                                                                                                                                                                                                             |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Any Cardknox Transaction API command | <p>Any of the following credit card commands:</p><ul><li>cc:save</li><li>cc:credit</li><li>cc:authonly</li><li>cc:sale</li></ul><p>Reference: <a href="https://docs.cardknox.com/api/transaction#credit-card">Transaction API</a></p> |

#### Pre processing options

Developer using the Out Of Scope integration to process using the VP3300 card reader can specify a per-request transaction timeout value. The SDK will start a transaction with the VP3300 reader, and timeout in the specified time frame if the card is not tapped, swiped or inserted in that same time frame.

<table data-header-hidden><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td><strong>Function/property</strong></td><td><strong>Description</strong></td><td><strong>Sample data</strong></td></tr><tr><td>VP3300TransactionTimeout</td><td>Start transaction value, in seconds.</td><td><pre><code>CardknoxSDKUI ui = CardknoxSDKUI.create();
TransactionParameters parameters = new TransactionParameters();
parameters.SetVP3300TransactionTimeout(13);
PaymentTransactionRequestUI req = ui.createRequestWithParameters(parameters);
// Enable swipe screen in the Cardknox UI
CardknoxSDKUI.SetEnableDeviceInsertSwipeTap(true);
// Show Cardknox UI
Activity activity = null; // Obtain an Activity reference
req.process(activity);
</code></pre></td></tr></tbody></table>

#### Post processing options

After the out-of-scope function finishes with transaction processing, the SDK displays a popup containing a handful of information about the transaction.

The SDK can be configured to auto close the user interface immediately after the transaction processing has completed; regardless if the transaction was approved or not.

| **Function**                     | **Description**                                                                                                                   | **Sample data**                                           |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| CloseSDKUIOnProcessedTransaction | <p>Globally configures the SDK to auto close the user interface after processing a transaction.</p><p>Default value is false.</p> | CardknoxSDKUI.SetCloseSDKUIOnProcessedTransaction(false); |

<figure><img src="/files/2GtQAet3gMJUpjhvJYjl" alt=""><figcaption><p>Example of a <strong>success</strong> popup.</p></figcaption></figure>

<figure><img src="/files/Eea6WRwIoJPmOJZYmhue" alt=""><figcaption><p>Example of an <strong>error</strong> popup.</p></figcaption></figure>

#### In scope integration

In scope processing feature allows the developer to quickly process a payment and retrieve the response object.

To process directly, create a request object:

```javascript
// Create the parameters object
TransactionParameters parameters = new TransactionParameters()
{
    {
        // Required parameters
        SetxCommand("cc:sale");
        SetxAmount(1.23);
        SetxCardNum("4444333322221111");
        // Format "MMYY"
        // For example: December 2024
        SetxExp("1224");

        // Optional parameters to supplement the transaction
        SetxInvoice("1234");
    }
};

// Create the request object
PaymentTransactionRequestDirect request = cardknoxSDKDirect.createRequestWithParameters(parameters);
```

Check if the request object is in a valid state. If it is, call the method to process directly. Otherwise, inspect the validation errors to see what is incorrect in the request object:

```javascript
PaymentTransactionRequestDirect request = cardknoxSDKDirect.createRequestWithParameters(parameters);

if(request.GetIsValid()) {
    PaymentTransactionResponse response = request.process();

    boolean isSuccess = response.GetIsSuccess();
    String errorMessage = response.GetErrorMessage();
    String errorCode = response.GetxErrorCode();
    String refNum = response.GetxRefNum();
} 
else {
    String[] errors = request.GetValidationErrors();  
}
```

#### Available commands

* Check (ACH) commands
  * Reference: [Check (ACH)](/api/transaction/check-ach.md)
* Credit Card commands
  * Reference: [Credit Card](/api/transaction/credit-card.md)
* EBT Food Stamp commands
  * Reference: [EBT Food Stamp](/api/transaction/ebt.md#ebt-food-stamp)
* EBT Cash Benefits
  * Reference: [EBT Cash Benefits](/api/transaction/ebt.md#ebt-cash-benefits)
* EBT Wic
  * Reference: [EBT Wic](/api/transaction/ebt.md#ebt-wic-ewic)
* Gift Card commands
  * Reference: [Gift Card](/api/transaction/gift-card.md)

### Custom UI integration

Custom UI integration is similar to the “out of scope” integration in a way that the exact same methods that the “out of scope” is using under the hood for controlling the card reader, are exposed via the SDK for the Developer to use.

The Developer can choose and use two connection methods to create a transaction with the card reader device, the Bluetooth and USB. Bluetooth is a wireless method of communication between a card reader and a mobile device. To use Bluetooth, the mobile device must have Bluetooth capability and must have Bluetooth permissions enabled. The SDK takes care of the availability of Bluetooth and Bluetooth permissions. On the other hand, the USB connection method uses a wire for communication between the card reader and the mobile device. The USB method is the simplest and most direct method, as the connection between the card reader and the mobile phone is a strong connection. This means that the mobile device does not need to scan to find and communicate with the card reader. The USB method is also not affected by the card reader's sleep feature, while with Bluetooth, the connection is lost when the reader goes into sleep mode.

The SDK cannot automatically recognize what connection methods card reader supports and cannot automatically initiate communication between the reader and the mobile device. Therefore, the Developer must decide which connection method to use and for which card reader. The `CardknoxSDK` object has two different functions that return an instance of communication manager for card readers based on communication method. The `getCustomUIBluetooth()` for Custom UI with Bluetooth and `getCustomUIUSB()`for Custom UI with USB. Both Bluetooth and USB only support the VP3300 device.

The Developer provides the user interface and orchestrates the entire flow for obtaining the card data via the card reader by calling appropriate Custom UI functions at specific times.

#### Custom UI with Bluetooth <a href="#custom-ui-with-bluetooth" id="custom-ui-with-bluetooth"></a>

The `CardknoxSDK`type provides a function to obtain the Custom UI manager:

| `CardknoxSDK.create().getCustomUIBluetooth();` |
| ---------------------------------------------- |

<table data-header-hidden><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td><strong>Function</strong></td><td><strong>Description</strong></td><td><strong>Sample data</strong></td></tr><tr><td>StartScanningWithTimeout</td><td><p>Starts the “scan for nearby bluetooth devices” process.</p><p>If the timeout value is 0 or a negative number, the scanning never times out.</p><p><br>A card reader event similar to “waiting for device response” will be raised once the scanning starts. <br>This usually means that the user needs to press the physical button in order for the card reader device to be visible to nearby scanners.</p></td><td><pre><code>// Indefinite scan until stopped 
CardknoxSDK.create().getCustomUIBluetooth().startScanningWithTimeout(0);

// Scan with a timeout
CardknoxSDK.create().getCustomUIBluetooth().startScanningWithTimeout(20); </code></pre></td></tr><tr><td>StopScanning</td><td><p>Attempts to stop the bluetooth device scanning process.<br></p><p>Raises a “stop scan” card reader event.<br></p><p>Doesn’t do anything if scanning is not in progress.<br></p><p>If the method stops the scanning process, the SDK reports all scanned devices via a callback.</p></td><td><pre><code>CardknoxSDK.create().getCustomUIBluetooth().stopScanning(); </code></pre></td></tr><tr><td>ConnectWithName</td><td><p>Accepts a device name.</p><p>Configures the SDK to be ready to establish a Bluetooth connection with the nearby VP3300 device with a name equal to the provided name.</p><p>After the call:</p><ul><li>the card reader & the app are not connected immediately but rather the SDK notifies the developer about various card reader events taking place after this method is called; such as “connecting” and “waiting for device response”</li><li>if the VP3300 devices’ bluetooth is not asleep when this method is called, the card reader auto connects to the app</li></ul></td><td><pre><code>String deviceName = "IDTECH-VP3300-12345";
CardknoxSDK.create().getCustomUIBluetooth().connectWithName(deviceName); </code></pre></td></tr><tr><td>ConnectWithAddress</td><td><p>Accepts a MAC address.</p><p>Configures the SDK to be ready to establish a Bluetooth connection with the nearby VP3300 device with the internal MAC address equal to the provided value.</p></td><td><pre><code>String addr = "00:1C:97:1D:EA:50";
CardknoxSDK.create().getCustomUIBluetooth().connectWithAddress(addr); </code></pre></td></tr><tr><td>DisconnectFromCurrentDevice</td><td><p>Attempts to break the connection between the application & the card reader.<br><br>If the card reader is not connected to the app, a card reader event similar to “disconnected already” is raised.</p><p>Otherwise, the SDK attempts to disconnect the card reader. If successful, the “disconnected” card reader event is raised.</p></td><td><pre><code>CardknoxSDK.create().getCustomUIBluetooth().disconnectFromCurrentDevice(); </code></pre></td></tr><tr><td>StartTransaction</td><td><p>Starts a transaction between an already connected application & the card reader.</p><p>Once the transaction starts, the card reader is ready to accept cards, either via swipe, tap or insert.</p><p> </p><p>This method can timeout. Default value is 10 seconds. Developers can override this value via the “parameters” object.</p></td><td><pre><code>Activity activity = null; // Provide this
TransactionParameters prms = new TransactionParameters();
prms.SetxAmount(1.23);
prms.SetxInvoice("1234");
prms.SetxCommand("cc:sale");
prms.SetVP3300TransactionTimeout(13);
CardknoxSDK.create().getCustomUIBluetooth().startTransactionWithArgs(prms); </code></pre></td></tr><tr><td>CancelTransaction</td><td><p>Attempts to cancel an already started transaction between the application & the card reader.<br></p><p>If no transactions are started when this function is called, the function does not do anything.</p></td><td><pre><code>CardknoxSDKCustomUI customUI = null; /\* created object beforehand \*/

customUI.cancelTransaction(); </code></pre></td></tr></tbody></table>

#### Custom UI with USB <a href="#androidsdkusermanual-availablecommands.1" id="androidsdkusermanual-availablecommands.1"></a>

The `CardknoxSDK` object contains instance for connecting card reader with USB. Management of the card reader is done using the functions contained in the USB instance.

```
CardknoxSDK.create().getCustomUIUSB()
```

| **Function**                    | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | **Sample data**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ConnectVP3300                   | It tries to establish a communication channel between the application and the VP3300 card reader.                                                                                                                                                                                                                                                                                                                                                                                                                  | `CardknoxSDK.create().getCustomUIUSB().connectVP3300();`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| DisconnectFromCurrentDevice     | Termination of the communication channel between the currently connected card reader and the mobile device.                                                                                                                                                                                                                                                                                                                                                                                                        | `CardknoxSDK.create().getCustomUIUSB().disconnectFromCurrentDevice();`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| SetVP3300StartTransactionMethod | <p>The SetVP3300StartTransactionMethod function is a method of the <code>TransactionParameters</code> object used to configure how a card reader initiates a card transaction. It accepts a parameter of type <code>VP3300StartTransactionMethod</code>, which defines the scanning method the card reader should use.</p><p>By calling this method, developers can control the specific way in which the reader should prompt and process a card during a transaction, depending on the desired input method.</p> | <p>The <code>VP3300StartTransactionMethod</code> parameter is an enumerated type that supports the following constant values:</p><ul><li><code>CTLS</code> – Contactless card transaction</li><li><code>EMV</code> – Chip (contact) card transaction</li><li><code>MSR</code> – Magnetic stripe card transaction</li><li><code>DEVICE</code> – Default or device-specific scanning behaviour.</li></ul><p><code>TransactionParameters prms = new TransactionParameters(); prms.SetVP3300StartTransactionMethod(VP3300StartTransactionMethod.MSR); CardknoxSDK.create().getCustomUIUSB().startTransactionWithArgs(prms);</code></p> |
| StartTransactionWithArgs        | <p>Starts a transaction between an already connected application & the card reader.</p><p>Once the transaction starts, the card reader is ready to accept cards, either via swipe, tap or insert.</p><p>Developers can override this value via the “parameters” object.</p>                                                                                                                                                                                                                                        | `TransactionParameters prms = new TransactionParameters(); prms.SetxAmount(1.23); prms.SetxInvoice("1234"); prms.SetxCommand("cc:sale"); prms.SetVP3300TransactionTimeout(13); CardknoxSDK.create().getCustomUIUSB().startTransactionWithArgs(prms);`                                                                                                                                                                                                                                                                                                                                                                              |
| CancelTransaction               | <p>Attempts to cancel an already started transaction between the application & the card reader.</p><p>If no transactions are started when this function is called, the function does not do anything.</p>                                                                                                                                                                                                                                                                                                          | `CardknoxSDK.create().getCustomUIUSB().cancelTransaction();`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |

#### Available commands <a href="#androidsdkusermanual-availablecommands.1" id="androidsdkusermanual-availablecommands.1"></a>

Any of the following credit card commands are available for Custom UI:

* cc:save
* cc:credit
* cc:authonly
* cc:sale

Reference: [Credit Card](/api/transaction/credit-card.md)

#### Custom UI flow

First, create a “custom ui” object to get access to all the Custom UI functions. Afterwards, subscribe to all the relevant callbacks for this integration path:

* transaction result callback - to receive the “response” object after the SDK has processed a transaction
* card reader event callback - to be notified about various events that take place between the application & the card reader
* scanned bluetooth device callback - to be notified about every new scanned bluetooth device during the “scan for devices” process
* scan completed callback - to be notified about all the scanned devices once the “scan for devices” process ends

Next step is to establish a connection between the app and the card reader device. Use one of the “connect” methods on the “custom ui” to initiate a connection; such as “connect with name” or “connect with address”.

Device name or the MAC address can be obtained with the “scan for devices” flow. Initiate the “start scanning” function call, with or without a timeout.

<figure><img src="/files/41evHseOsy6uA6sNuate" alt=""><figcaption><p>Start scanning flow</p></figcaption></figure>

The scanning process stops with a call to the “stop scanning” function or when the “start scanning” function times out.

<figure><img src="/files/a40ISCpLNtp1asxqNZ8h" alt=""><figcaption><p>Stop scanning flow</p></figcaption></figure>

After establishing a connection with the card reader by calling one of the “connect” methods and receiving a “connected” card reader event via the BroadcastReceiver subscription, call the “start transaction” function to make the card reader ready for a card.

The SDK will report a “transaction started” event if the transaction with the card reader was successfully started, otherwise an “error” card reader event is reported back. At this point the card can be tapped, swiped or inserted into the card reader. The SDK will read the card information, process a transaction & deliver the results to the application via a callback.

If no card is tapped, swiped or inserted after the transaction started - a “timeout” card reader is reported back. The default timeout value is about 10 seconds. The developer can override this value via the “transaction parameters” object.

### Payment engine integration <a href="#payment-engine-integration" id="payment-engine-integration"></a>

The Payment Engine won't show any UI. The developer provides the user interface and uses three payment engine functions to create transactions with a card reader over IP. Data that is required to create a transaction is passed by developers as parameters to those SDK functions. The messages and results of creating a transaction with the Payments engine are obtained by the developer from transaction result callback, device status callback, and transaction status.

| **Function**                  | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | **Sample data**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Device\_Initialize            | <p>This function makes sure that the mobile device can communicate with the card reader and saves data that is needed for connecting to the card reader.</p><p>The initialization process can take about 2 minutes. But it is sufficient to execute it once per card reader and IP address.</p>                                                                                                                                                                                                                                                        | `CardknoxPaymentEngineSDKSettings settings = new CardknoxPaymentEngineSDKSettings(); settings.SetDevice_IP_Port("9001"); settings.SetDevice_IP_Address("127.21.2.7"); settings.SetDevice_Name("Verifone_P400.4"); settings.SetDevice_Timeout(120 * 1000); // 120 seconds; CardknoxSDK.create().getPaymentEngine().Device_Initialize(settings);`                                                                                                                                                                                                                                                 |
| ProcessOutOfScopeWithSettings | <p>Attempts to create a transaction with a card reader over IP. </p><p>This function will perform the initialization process if initialization has not been performed for the specific card reader.</p>                                                                                                                                                                                                                                                                                                                                                | `CardknoxPaymentEngineSDKSettings settings = new CardknoxPaymentEngineSDKSettings(); settings.SetDevice_IP_Port("9001"); settings.SetDevice_IP_Address("127.21.2.7"); settings.SetDevice_Name("Verifone_P400.4"); settings.SetDevice_Timeout(120 * 1000); // 120 seconds; CardknoxPaymentEngineSDKRequest request = new CardknoxPaymentEngineSDKRequest(); request.SetxCommand("cc:sale"); request.SetxAmount(1.23); CardknoxSDK.create().getPaymentEngine().ProcessOutOfScope(settings, request);`                                                                                             |
| Device\_CancelTransaction     | <p>Attempts to cancel an already started transaction between the application & the card reader.</p><p>If no transactions are started when this function is called, the function does not do anything.</p>                                                                                                                                                                                                                                                                                                                                              | `CardknoxSDK.create().getPaymentEngine().Device_CancelTransaction();`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| SetSendResponseaAsJSON        | This function configures the SDK for Payment Engine integration. When the value is set to `true`, the SDK returns a processed transaction response via the [Result as JSON callback](https://cardknox.atlassian.net/wiki/spaces/MOB/pages/2661711873/Android+SDK+User+Manual#Result-as-JSON-callback-subscription). Otherwise, the transaction response is provided through the basic [Transaction Result callback](https://cardknox.atlassian.net/wiki/spaces/MOB/pages/2661711873/Android+SDK+User+Manual#Transaction-result-callback-subscription). | `CardknoxSDK.create().getPaymentEngine().SetSendResponseaAsJSON(true);`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| EnableLogcatBroadcasts        | The EnableLogcatBroadcasts property enables log delivery via callbacks. When set to true, the payment engine sends logs to the app instead of just printing them to the LogCat console, allowing custom handling of log messages.                                                                                                                                                                                                                                                                                                                      | `CardknoxSDK.create().getPaymentEngine().enableLogCatBroadcasts(true);`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Device\_ReprintReceipt        | This method is used to reprint a transaction receipt from the card reader. This function allows users to reprint receipts for any previous transaction. It is useful in situations where a receipt was not printed correctly, was lost, or when a customer requests a duplicate or previous transaction receipt                                                                                                                                                                                                                                        | `CardknoxPaymentEngineSDKSettings settings = new CardknoxPaymentEngineSDKSettings(); settings.SetDevice_IP_Address("specify IP"); settings.SetDevice_IP_Port("specify port"); settings.SetDevice_Name("specify device name, such as PAX_A77.3"); settings.SetDevice_Timeout(5 * 1000); /* milliseconds to seconds */ CardknoxPaymentEngineSDKRequest request = new CardknoxPaymentEngineSDKRequest(); request.SetxAuthCode("add auth code here"); String response = CardknoxSDK.create().getPaymentEngine().Device_ReprintReceipt(settings, request); boolean success = response.equals("OK");` |

### Versioning

Developers can read from the `cardknox.payments.sdk.BuildConfig` class, properties are:

| `VERSION_NAME` | Major SDK version                       |
| -------------- | --------------------------------------- |
| `VERSION_CODE` | Release number in the major SDK version |
| `GIT_HASH`     | Git tag for troubleshooting             |

### Logging

SDK verbose logging can be enabled or disabled with a function call:

| **Function**  | **Description**                                                      | **Sample data**                   |
| ------------- | -------------------------------------------------------------------- | --------------------------------- |
| EnableLogging | <p>Accepts a boolean.</p><p>Enables or disables verbose logging.</p> | CardknoxSDK.enableLogging(false); |

### FAQ

1. As a Cardknox SDK user, I want to process without an internet connection. What will happen?
   * The SDK will return a `PaymentTransactionResponse` object with a special `xErrorCode` value `-1`
2. As a Cardknox SDK user, I’ve encountered errors during transaction processing. What response can I expect?
   * the `PaymentTransactionRequest` object will encapsulate all relevant information in respective fields; for example the `xErrorCode` property will return a code from the Cardknox Transaction API documentation, the `xErrorMessage` and `xError` properties can be used for a descriptive error message while the `xRefNum` gives back a unique ref num to follow up with the customer support


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.solapayments.com/sdk/android-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
