A comprehensive Point of Sale (POS) Android application that demonstrates payment processing capabilities using Dspread's POS SDK, offering secure and efficient transaction handling for retail environments.
- Payment Processing: Supports various card payment methods including swipe, tap, and insert transactions
- Receipt Generation And Printing: Generate and print transaction receipts
- Transaction History: View and manage completed transactions
- Device Configuration: Connect to and configure POS devices via Bluetooth, USB, or UART
- Gradle 7.5+
- Target Android SDK 34 (API Level 34)
- Minimum supported Android SDK 24 (Android 7.0 Nougat)
- Java 11 compatible development environment
- Clone the repository:
git clone https://github.com/DspreadOrg/pos_demo.git
cd pos_demo/pos_android_studio_demo- Open the project in Android Studio
- Sync the project with Gradle files
- Build and run the application on a compatible Android device
If you want to integrate SDK, please follow as below:
-
AAR
-
Download the SDK AAR Package: Obtain the SDK AAR package from the designated source(SDK aar link)
-
Place the AAR Package in the Project: Copy the downloaded AAR package (e.g., dspread_pos_sdk_8.0.0.aar) into the libs folder of your Android project.
-
-
MAVEN
Please access the below path to view the latest SDK version.
- Gradle Groovy DSL install command to module-level (
app/build.gradle) file:
implementation 'com.dspread.library:dspread_pos_sdk:8.0.0'
- Add Gradle Groovy DSL repository command to project-level (
build.gradle) file:
maven { url '<https://gitlab.com/api/v4/projects/4128550/packages/maven>' }
- Gradle Groovy DSL install command to module-level (
The POSManager class is the core component for interacting with POS devices. And we implement it in PaymentActivity. Here's a brief overview of its key features and functionality:
// Initialize POSManager
POSManager.init(context);
// Start payment transaction in background thread
// Handles device connection and transaction initialization
private void initConnectionCallback() {
connectionCallback = new ConnectionServiceCallback() {
@Override
public void onRequestNoQposDetected() {
ToastUtils.showLong("Device connected fail");
}
@Override
public void onRequestQposConnected() {
ToastUtils.showLong("Device connected");
}
@Override
public void onRequestQposDisconnected() {
ToastUtils.showLong("Device disconnected");
finish();
}
};
}
private void startTransaction() {
new Thread(() -> {
if (!POSManager.getInstance().isDeviceReady()) {
POSManager.getInstance().connect(deviceAddress, connectionCallback);
} else {
// if device has connected, just register connection callback
POSManager.getInstance().registerConnectionCallback(connectionCallback);
}
POSManager.getInstance().startTransaction(amount, paymentServiceCallback);
}).start();
}Here are the corresponding callbacks, where you can handle transaction results, PIN entry, and other related operations. These are also implemented in the PaymentActivity.
// Inner class to handle payment callbacks
// Implements all payment related events and UI updates
private class PaymentCallback implements PaymentServiceCallback {
@Override
public void onRequestTime() {
// Send current time.
POSManager.getInstance().sendTime(terminalTime);
}
@Override
public void onRequestSelectEmvApp(ArrayList<String> appList) {
// Select one application of the application list returned from EMV kernel, then set the application ID to EMV kernel
POSManager.getInstance().selectEmvApp(position);
// Cancel the process about setting the application
POSManager.getInstance().cancelSelectEmvApp();
}
@Override
public void onQposRequestPinResult(List<String> dataList, int offlineTime) {
// Send the pin keyboard datas to Smart Device for pin input.
POSManager.getInstance().pinMapSync(value, 20);
}
@Override
public void onRequestSetPin() {
//CR100 devices
// Set cancel input pin to CR100
POSManager.getInstance().cancelPin();
// Bypass pin input to CR100
POSManager.getInstance().bypassPin();
// Input the cipher pinblock on the client app side to CR100
POSManager.getInstance().sendCvmPin(pinBlock, true);
}
@Override
public void onRequestDisplay(QPOSService.Display displayMsg) {
// Return relevant prompt information.
..
}
@Override
public void onDoTradeResult(QPOSService.DoTradeResult result, Hashtable<String, String> decodeData) {
if(result == QPOSService.DoTradeResult.ICC){
// Send the command as executing the EMV transaction flow to POS
POSManager.getInstance().doEmvAPP();
}else{
// Return the transaction result of NFC and Swipe mode
..
}
}
@Override
public void onTransactionResult(boolean isCompleteTxns, PaymentResult result) {
// Return the transaction result
..
}
@Override
public void onRequestOnlineProcess(final String tlv) {
// Send online message tlv data to backend server
viewModel.requestOnlineAuth(true, paymentModel);
// If online request successful, call
POSManager.getInstance().sendOnlineProcessResult("8A02" + onlineRspCode);
}
@Override
public void onReturnGetPinInputResult(int num, QPOSService.PinError error, int minLen, int maxLen) {
// This is used for smart POS to return the number of pin inputs
..
}
}- QPOS doc :Please check the link to know more about the process, including connection, transaction, data decryption and more.
- API reference : Please check the link to know the specific API reference involved in SDK.
For issues and questions, please visit our community or contact Dspread support.
