> For the complete documentation index, see [llms.txt](https://docs.verifone.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.verifone.com/psdk-latest/reference-material/code-labs/device-functions.md).

# Device Functions

{% columns %}
{% column width="41.66666666666667%" %} <i class="fa-clock">:clock:</i> 9 minutes reading time\ <i class="fa-calendar">:calendar:</i> Last updated: 23rd November, 2023
{% endcolumn %}

{% column width="24.999999999999986%" %}

{% endcolumn %}

{% column %}
✅ Overview

✅ User Prompts

✅ Receipt Print

✅ Display

✅ Barcode Scanning
{% endcolumn %}
{% endcolumns %}

{% stepper %}
{% step %}

### Overview

This code lab describes steps for using API's in ECR/POS for displaying user prompts, recipt printing, displaying content on the terminal and Barcode scanning using PSDK.

#### What you should already know

* The device you will be using for integration.
* Setting up the device and development environment for developing PSDK application
* Connecting to a terminal

#### What you'll need

* Any Verifone device with necessary software loaded.
* Internet connectivity
  {% endstep %}

{% step %}

### User Prompts

User Prompts

User prompts basically will be used to collect data from the customer. This section covers the details to create user prompts on the terminal using various options as below:

1. Menu Options
2. Number
3. Password
4. Email
5. Signature
6. Decimal
7. Text
8. Manager Approval
9. Any Key (Text, HTML)

Creating User prompts requires using API requestUserInput2(RequestParameters params) which presents the user with a screen to collect information,

#### Create User prompts

By this time you would have already created a [**PaymentPSDK**](https://docs.verifone.com/psdk-api-latest/android-java/index/paymentsdk) and [**CommerceListenerAdapter**](https://app.gitbook.com/s/yzyMJNwlQJZoQOIC8vZ8/api/moduleindex-4/_commerce_listener_adapter_8java) object. So you can now call the API [requestUserInput2(RequestParameters params) ](https://docs.verifone.com/psdk-api-latest/android-java/index/transactionmanager#requestuserinput2-requestparameters)to create the prompts as required.

#### Menu options

Input type to present multiple options in a menu. While creating the menu options using [RequestParameters](https://docs.verifone.com/psdk-api-latest/android-java/index/requestparameters), Input type should be set as [InputType.MENU\_OPTIONS](https://docs.verifone.com/psdk-api-latest/android-java/index/inputtype). Please refer below code snippet

```java
RequestParameters params = RequestParameters.
                           createRequest(InputType.MENU_OPTIONS);
ArrayList<MenuEntry> menu = new ArrayList<>();
params.setContent("Menu");
for(int i = 0 ; i < 4 ; i++) {
    MenuEntry menuEntry = MenuEntry.create();
    menu.add(menuEntry);
    String option = "Option".concat(String.valueOf(i));
    menu.get(i).setContent(option);
    params.addMenuEntry(menu.get(i));

    //Optional values which can be applied to params as below
    params.setShouldWaitForUserValidation(boolean b);
    params.setShouldRespondImmediately(boolean b);
}
Status result = PaymentSdk.getTransactionManager().requestUserInput2(params);

//The response from the terminal will be provided as part of the
//handleUserInputEvent with type RECEIVED_TYPE
@Override
public void handleUserInputEvent(UserInputEvent event) {
    if (event.RECEIVED_TYPE.equals(event.getType()) &&
        event.getStatus() == StatusCode.SUCCESS) {
        Values valueFromTerminal = event.getValues();
        if (event.getInputType() == InputType.MENU_OPTIONS) {
            int selectedIndex = valueFromTerminal.getSelectedIndices().get(0);
            //"Menu option selected index ="  -  selectedIndex + 1;
        }
    }
}
```

#### Number

Presents a terminal screen to allow the user to enter a numerical value which is returned to POS both as a text value (phone number) and as a decimal value (payment related amount) to be selected based on the context. While creating the prompt using RequestParameters, Input type should be set as [InputType.MENU\_NUMBER](https://docs.verifone.com/psdk-api-latest/android-java/index/inputtype). Please refer below code snippet

<pre class="language-java"><code class="lang-java">RequestParameters params = RequestParameters.createRequest(InputType.NUMBER);
<strong>params.setDefaultValue("1234");
</strong>params.setContent("Enter phone number");
//Optional values which can be applied to params as below
params.setMaximumInputTime(int value);
params.setShouldMaskCharacters(boolean b);
params.setMaximumLength(int value);
params.setMinimumLength(int value);
params.setFromRightToLeft(boolean b);

Status result = PaymentSdk.getTransactionManager().requestUserInput2(params);
</code></pre>

You can handle user input events from a terminal with the following code snippet.

```java
@Override
public void handleUserInputEvent(UserInputEvent event) {
    if (UserInputEvent.RECEIVED_TYPE.equals(event.getType()) && event.getStatus() == StatusCode.SUCCESS) {
        Values valueFromTerminal = event.getValues();
        if (event.getInputType() == InputType.NUMBER) {
            Decimal value = valueFromTerminal.getNumericValue();
            System.out.println("Number response: " + value.toString());
        }
    }
}
```

#### Password

Presents a terminal screen to allow the user to enter a password. While creating the prompt using RequestParameters, Input type should be set as [InputType.PASSWORDS](https://docs.verifone.com/psdk-api-latest/android-java/index/inputtype). Please refer below code snippet

```java
RequestParameters params = RequestParameters.createRequest(InputType.PASSWORD);
params.setShouldMaskCharacters(true);
params.setMaximumInputTime(5);
params.setContent("Enter Password");
Status result = PaymentSdk.getTransactionManager().requestUserInput2(params);
```

```java
@Override
public void handleUserInputEvent(UserInputEvent event) {
    if (UserInputEvent.RECEIVED_TYPE.equals(event.getType()) 
        && event.getStatus() == StatusCode.SUCCESS) {
        
        Values valueFromTerminal = event.getValues();
        
        if (event.getInputType() == InputType.PASSWORD) {
            String value = valueFromTerminal.getValue();
            System.out.println("Password response: " + value);
        }
    }
}
```

#### Email

Presents a terminal screen to allow the user to enter their email address which is returned as a string to the POS. While creating the prompt using RequestParameters, Input type should be set as [InputType.EMAIL ](https://docs.verifone.com/psdk-api-latest/android-java/index/inputtype)Please refer below code snippet

```java
RequestParameters params = RequestParameters.createRequest(InputType.EMAIL);
params.setContent("Enter Your mail ID");
params.setMaximumInputTime(5);
Status result = PaymentSdk.getTransactionManager().requestUserInput2(params);
//The response from the terminal will be provided as part of the 
//handleUserInputEvent with type RECEIVED_TYPE

@Override
public void handleUserInputEvent(UserInputEvent event) {
if (event.RECEIVED_TYPE.equals(event.getType()) 
    && event.getStatus() == StatusCode.SUCCESS) {
    Values valueFromTerminal = event.getValues();
        if (event.getInputType() == InputType.EMAIL) { 
        String value = valueFromTerminal.getValue();
            //"EMAIL response: " - value.toString();
        }
    }
}
```

#### Signature

Presents a terminal screen to allow the user to enter their signature which is returned as an image to the POS. Input type should be set as [InputType.SIGNATURE](https://docs.verifone.com/psdk-api-latest/android-java/index/inputtype). Please refer below code snippet

```java
RequestParameters params = RequestParameters.createRequest(InputType.SIGNATURE);
params.setContent("Please provide your signature");
Status result = PaymentSdk.getTransactionManager().requestUserInput2(params);
//The response from the terminal will be provided as part of the 
//handleUserInputEvent with type RECEIVED_TYPE
@Override
public void handleUserInputEvent(UserInputEvent event) {
    Values valueFromTerminal = event.getValues();
    if (event.RECEIVED_TYPE.equals(event.getType())
        && event.getStatus() == StatusCode.SUCCESS) {
        if (event.getInputType() == InputType.SIGNATURE) { 
            Image image = valueFromTerminal.getImage();  
        }
    }
}
```

#### Decimal

Presents a terminal screen to allow the user to enter a decimal value which is returned to POS. while creating the prompt using RequestParameters, Input type should be set as [InputType.DECIMAL](https://docs.verifone.com/psdk-api-latest/android-java/index/inputtype). Please refer below code snippet

```java
RequestParameters params = RequestParameters.createRequest(InputType.DECIMAL);
params.setContent("Enter Price");
params.setMaximumDecimalLength(int value);
params.setMaximumInputTime(int value);
Status result = PaymentSdk.getTransactionManager().requestUserInput2(params);
//The response from the terminal will be provided as part of the 
//handleUserInputEvent with type RECEIVED_TYPE
@Override
public void handleUserInputEvent(UserInputEvent event) {
if (event.RECEIVED_TYPE.equals(event.getType()) 
    && event.getStatus() == StatusCode.SUCCESS) {
    Values valueFromTerminal = event.getValues();
        if (event.getInputType() == InputType.DECIMAL) {
            Decimal value = valueFromTerminal.getNumericValue();
            BigDecimal bd = value.toBigDecimal();
            //Decimal response: "  - bd;
        }
    }
}
```

#### Text

Presents a terminal screen to allow the user to enter text. while creating the prompt using RequestParameters, Input type should be set as [InputType.TEXT](https://docs.verifone.com/psdk-api-latest/android-java/index/inputtype) Please refer below code snippet

```java
RequestParameters params = RequestParameters.createRequest(InputType.TEXT);
Status result = PaymentSdk.getTransactionManager().requestUserInput2(params);
//The response from the terminal will be provided as part of the
//handleUserInputEvent with type RECEIVED_TYPE
@Override
public void handleUserInputEvent(UserInputEvent event) {
if (event.RECEIVED_TYPE.equals(event.getType()) 
    && event.getStatus() == StatusCode.SUCCESS) {

    Values valueFromTerminal = event.getValues();
    if (event.getInputType() == InputType.TEXT) {
        String value = valueFromTerminal.getValue();
        //"Text response = " - value;
        }
    }
}
```

#### Managers Approval

Presents a terminal screen to request manager approval. Input type should be set as [InputType.MANAGER\_APPROVAL](https://docs.verifone.com/psdk-api-latest/android-java/index/inputtype). It is supported only with AGPA solutions Please refer below code snippet

```java
RequestParameters params = RequestParameters.
                           createRequest(InputType.MANAGER_APPROVAL);
params.setMaximumInputTime(5);
params.setContent("Managers Approval");
Status result = PaymentSdk.getTransactionManager().requestUserInput2(params);
//The response from the terminal will be provided as part of the
//handleUserInputEvent with type RECEIVED_TYPE
@Override
public void handleUserInputEvent(UserInputEvent event) {
if (event.RECEIVED_TYPE.equals(event.getType())
    && event.getStatus() == StatusCode.SUCCESS) {
    Values valueFromTerminal = event.getValues();
    if (event.getInputType() == InputType.MANAGER_APPROVAL) { 
        //"Managerapprovalprompt " - event.getInputType();
        }
    }
}
```

#### Any Key (Text, HTML)

Input type requiring any key to proceed. Provides an OK button at the bottom of the terminal screen which must be pressed in order to proceed.while creating the prompt using RequestParameters, Input type should be set as [InputType.ANY\_KEY](https://docs.verifone.com/psdk-api-latest/android-java/index/inputtype). Please refer below code snippet

```java
RequestParameters params = RequestParameters.createRequest(InputType.ANY_KEY);

params.setContentType(ContentType.TEXT); 
//Or params.setContentType(ContentType.HTML);

params.setContent("Transaction completed Select OK");
Status result = PaymentSdk.getTransactionManager().requestUserInput2(params);
//The response from the terminal will be provided as part of the 
//handleUserInputEvent with type RECEIVED_TYPE
@Override
public void handleUserInputEvent(UserInputEvent event) {
if (event.RECEIVED_TYPE.equals(event.getType()) 
   && event.getStatus() == StatusCode.SUCCESS) {
    Values valueFromTerminal = event.getValues();
    if (event.getInputType() == InputType.ANY_KEY) {
        //"AnyKey handleUserInputEvent - event.getInputType();
     }
  }
}
```

{% endstep %}

{% step %}

### Receipt Print

* PSDK supports printing receipt using print API part of [TransactionManager. **print(String document, ContentType contentType, ReceiptType receiptType, DeliveryMethod receiptDeliveryMethod, String deliveryAddress)**](https://docs.verifone.com/psdk-api-latest/android-java/index/transactionmanager#print-string-contenttype-receipttype-deliverymethod-string)
* Customer can customize the receipt content using PSDK receipt printing API.
* Receipts can be printed using the following API:

  ```java
  // Print merchant receipt in HTML format
  Status status = PaymentSdk.TransactionManager.print(
      sampleHtmlString,
      ContentType.HTML,
      ReceiptType.MERCHANT,
      DeliveryMethod.PRINT,
      optionalEmailString
  );
  ```

This call consists of five parameters.

1. `sampleHtmlString`: The content to be printed. This can be simple text or HTML.
2. [`ContentType.HTML`](https://docs.verifone.com/psdk-api-latest/android-java/index/contenttype): The format of the content. Different types are defined in the ContentType enum. They include:
   * `HTML`: HTML format of the display/message content.
   * `TEXT`: Simple text format of the display/message content.
3. [`ReceiptType.MERCHANT`](https://docs.verifone.com/psdk-api-latest/android-java/index/payment_sdk_receipttype): This indicates the type of receipt. The type of receipts can be for the customer, the merchant, or a specific document.
4. [`DeliveryMethod.PRINT`](https://docs.verifone.com/psdk-api-latest/android-java/index/deliverymethod): Specifies the delivery method for the receipt. The different delivery methods are Print, Email, SMS, or None.
5. `optionalEmailString`: An optional parameter to provide the recipient's email address when choosing the EMAIL delivery method.

#### Handling the Response

Responses for the print API are handled using the [`handleCommerceEvent`](https://docs.verifone.com/psdk-api-latest/android-java/index/commercelistener2#handlecommerceevent-commerceevent) method in CommerceListenerAdapter Please refer below code snippet

```java
@Override
public void handleCommerceEvent(CommerceEvent event) {
    switch (event.getType()) {
        case RECEIPT_PRINTED:
            if (event.getStatus() == StatusCode.SUCCESS) {
                // Printing was successful
            } else {
              // printing failed, use event.message for reason for failure
            }
            break;
            default:
            break;
        }
    }
```

{% endstep %}

{% step %}

### Display

PSDK supports displaying either HTML or text content on a customer-facing display. This functionality is commonly used in off-device integrations. The displayed content remains visible until:

* A new request is received to show different content.
* The managing device determines that an update is necessary based on the minimum display time.

Both HTML and text formats can be used for the displayed content.

#### Displaying Text

```java
String plainString = "This is for demo";
Status result = PaymentSdk.getTransactionManager().
               presentCustomerContent(plainString, ContentType.TEXT,0);
```

**Displaying HTML**

```
String htmlString =  "<!DOCTYPE html>\n" 
"<html>\n" +
"<head>\n" +
"<title>Page Title</title>\n" +
"</head>\n" +
"<body>\n" +
"\n" +
"<h1>This is a Heading</h1>\n" +
"<p>This is a paragraph.</p>\n" +
"\n" +
"</body>\n" +
"</html>" ;
Status result = PaymentSdk.getTransactionManager().
                presentCustomerContent( htmlString, ContentType.HTML,0);
```

{% endstep %}

{% step %}

### Barcode scanning

This section describes the implementation of barcode scanning performed on the terminal using PSDK. This will be applicable only for **ondevice android** solutions.

#### Barcode Scanning

Barcode scanning APIs are available for scanning if the BYOD device has a Camera. To setup the scanner first add a listener [PaymentSdk.initScanListener(scannerListener)](https://docs.verifone.com/psdk-api-latest/android-java/index/paymentsdkbase#initscanlistener-scannerlistener) to receive the scan results. Then the scanning can be started using [PaymentSdk.startBarcodeScanner(attributes)](https://docs.verifone.com/psdk-api-latest/android-java/index/paymentsdkbase#startbarcodescanner-hashmapstringobject). There are a few attributes like scan formats, display feed, scan area, front/rear camera etc that you can pass to the API. The scan formats are listed under the [ScannerBarcodeFormatEnum](https://docs.verifone.com/psdk-api-latest/android-java/index/scannerbarcodeformatenum) enumeration. For Android the attributes must contain an Activity or Fragment under the [ScannerConfiguration.ATTRIBUTE\_DISPLAY\_FEED\_PARENT](https://docs.verifone.com/psdk-api-latest/android-java/index/scannerconfiguration) key to work. The listener that was setup will receive the results as they are scanned.

* Below is the list of scan formats available as part of [ScannerBarcodeFormatEnum](https://docs.verifone.com/psdk-api-latest/android-java/index/scannerbarcodeformatenum) in PSDK

  ```plaintext
  - NONE
  - PARTIAL
  - EAN8
  - UPCE
  - ISBN10
  - UPCA
  - EAN13
  - ISBN13
  - I25
  - DATABAR
  - DATABAR_EXP
  - CODABAR
  - CODE39
  - PDF417
  - QRCODE
  - CODE93
  - CODE128
  - AZTEC
  - DATA_MATRIX
  - MAXICODE
  - GS1_128
  - CODE11
  - CODE32
  - MSI
  - CHINESE_POST
  - KOREAN_POST
  - UQRCODE
  ```

#### Dependencies

* Following dependencies need to be added to the application’s build.gradle.

```java
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.google.zxing:core:3.4.0'
    implementation 'androidx.preference:preference-ktx:1.1.1'
```

The following code demonstrates the call of the barcode scannnig APIs to scan barcodes during the process of a transaction.

* Set up the listener for scan status.

```java
 private final ScannerListener mScannerListener = new ScannerListener() {
    @Override
    public void onBarcodeResult(String status, @Nullable HashMap<String, Object> attributes) {
        String barcode = "";
        String barcodeType = "";

        if (status == STATUS_BARCODE_DETECTED) {
            if (attributes.containsKey(ATTRIBUTE_BARCODE)) {
                barcode = (String) attributes.get(ATTRIBUTE_BARCODE);
            }
            if (attributes.containsKey(ATTRIBUTE_BARCODE_FORMAT)) {
                barcodeType = (String) attributes.get(ATTRIBUTE_BARCODE_FORMAT);
            }
            Log.d(TAG, "Scanner status:" + status + barcode + "-" + barcodeType);
        } else {
            Log.d(TAG, "Scanner status:" + status);
        }
    }
};
```

* Initialize the scanner listener, configure barcode scanning attributes, and activate scanning using the specified settings.

```java
void initScanner() {
    mPsdk.initScanListener(mScannerListener);
    HashMap<String, Object> attributes = new HashMap<>();
    // Display the scanner at 90% of display view
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    Rect rect = new Rect((int)((float)metrics.widthPixels * .1f),
            (int)((float)metrics.heightPixels * .1f),
            (int)((float)metrics.widthPixels * .9f),
            (int)((float)metrics.heightPixels * .9f));
    attributes.put(ScannerConfiguration.ATTRIBUTE_SCAN_AREA_LIMIT, rect);
    attributes.put(ScannerConfiguration.ATTRIBUTE_SET_DIRECTION, 2);
    attributes.put(ScannerConfiguration.ATTRIBUTE_ACTIVATE_LIGHT, false);
    attributes.put(ScannerConfiguration.ATTRIBUTE_PLAY_SOUND, true);
    attributes.put(ScannerConfiguration.ATTRIBUTE_DISPLAY_FEED_PARENT, this);
    // Optionally limit the barcode formats. Leaving this empty
    // will search for the default list of barcodes.
    ScannerBarcodeFormatEnum[] scanFormats = new ScannerBarcodeFormatEnum[] {
            ScannerBarcodeFormatEnum.UPCA,
            ScannerBarcodeFormatEnum.UPCE,
            ScannerBarcodeFormatEnum.QRCODE
    };
    attributes.put(ScannerConfiguration.ATTRIBUTE_SCANNING_FORMATS, scanFormats);
    mPsdk.startBarcodeScanner(attributes);
}

Following dependencies need to be added to the application’s build.gradle.

```

To stop the scanner in Android there are few options

1. On the scanner UI, close button can be pressed.
2. If the POS wants to exit the scanner after a single scan, it could set the attribute [ScannerConfiguration.ATTRIBUTE\_CONTINUOUS\_SCAN](https://docs.verifone.com/psdk-api-latest/android-java/index/scannerconfiguration) to false when initiating the scanner.
3. [PaymentSdk.stopBarcodeScanner()](https://docs.verifone.com/psdk-api-latest/android-java/index/paymentsdkbase#stopbarcodescanner) could be called based on an inactivity timeout that the POS can decide on.

```java
mPsdk.startBarcodeScanner(attributes);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        mViewModel.mPaymentSdk.stopBarcodeScanner();
    }
}, 10000); // 10 seconds delay
```

{% endstep %}
{% endstepper %}


---

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

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

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

```
GET https://docs.verifone.com/psdk-latest/reference-material/code-labs/device-functions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
