showing results ok
This commit is contained in:
parent
7ad09b2b5f
commit
2f8234e241
|
@ -2,20 +2,19 @@ package com.test.cardreadtest.payment;
|
||||||
|
|
||||||
import static android.content.Intent.getIntent;
|
import static android.content.Intent.getIntent;
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.databinding.DataBindingUtil;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import com.test.cardreadtest.R;
|
import com.test.cardreadtest.R;
|
||||||
import com.test.cardreadtest.databinding.ActivityPaymentBinding;
|
import com.test.cardreadtest.databinding.ActivityPaymentBinding;
|
||||||
import com.test.cardreadtest.posAPI.ConnectionServiceCallback;
|
import com.test.cardreadtest.posAPI.ConnectionServiceCallback;
|
||||||
import com.test.cardreadtest.posAPI.POSManager;
|
import com.test.cardreadtest.posAPI.POSManager;
|
||||||
|
import com.test.cardreadtest.posAPI.PaymentResult;
|
||||||
import com.test.cardreadtest.posAPI.PaymentServiceCallback;
|
import com.test.cardreadtest.posAPI.PaymentServiceCallback;
|
||||||
import com.test.cardreadtest.utils.TRACE;
|
import com.test.cardreadtest.utils.TRACE;
|
||||||
|
|
||||||
|
@ -24,9 +23,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
//import me.goldze.mvvmhabit.utils.ToastUtils;
|
|
||||||
|
|
||||||
public class PaymentActivity extends AppCompatActivity {
|
public class PaymentActivity extends AppCompatActivity {
|
||||||
private static final String TAG = "PaymentActivity";
|
private static final String TAG = "PaymentActivity";
|
||||||
private String amount;
|
private String amount;
|
||||||
|
@ -39,81 +35,101 @@ public class PaymentActivity extends AppCompatActivity {
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
// Simple DataBinding inflation - NO third-party dependencies
|
|
||||||
binding = ActivityPaymentBinding.inflate(getLayoutInflater());
|
binding = ActivityPaymentBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
// Use standard ViewModelProvider
|
|
||||||
viewModel = new ViewModelProvider(this).get(PaymentViewModel.class);
|
viewModel = new ViewModelProvider(this).get(PaymentViewModel.class);
|
||||||
binding.setViewModel(viewModel);
|
binding.setViewModel(viewModel);
|
||||||
|
binding.setLifecycleOwner(this);
|
||||||
|
|
||||||
initData();
|
initData();
|
||||||
|
setupClickListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupClickListeners() {
|
||||||
|
binding.btnCancel.setOnClickListener(v -> {
|
||||||
|
Log.d(TAG, "Cancel button clicked");
|
||||||
|
cancelTransactionAndFinish();
|
||||||
|
});
|
||||||
|
|
||||||
|
binding.btnBack.setOnClickListener(v -> {
|
||||||
|
Log.d(TAG, "Back button clicked");
|
||||||
|
cancelTransactionAndFinish();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelTransactionAndFinish() {
|
||||||
|
POSManager.getInstance().cancelTransaction();
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize payment activity data
|
* Initialize payment activity data
|
||||||
* Sets up initial UI state and starts transaction
|
|
||||||
*/
|
*/
|
||||||
public void initData() {
|
public void initData() {
|
||||||
paymentServiceCallback = new PaymentCallback();
|
paymentServiceCallback = new PaymentCallback();
|
||||||
|
|
||||||
// Get intent data
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
amount = intent.getStringExtra("amount");
|
amount = intent.getStringExtra("amount");
|
||||||
|
deviceAddress = intent.getStringExtra("deviceAddress");
|
||||||
|
|
||||||
// For testing, use default values if not provided
|
|
||||||
if (amount == null) amount = "1.00";
|
if (amount == null) amount = "1.00";
|
||||||
|
if (deviceAddress == null) deviceAddress = "UART";
|
||||||
|
|
||||||
viewModel.displayAmount(amount);//display to UI
|
viewModel.displayAmount(amount);
|
||||||
|
viewModel.setStatus("Initializing...");
|
||||||
startTransaction();
|
startTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start payment transaction in background thread
|
* Start payment transaction in background thread
|
||||||
* Handles device connection and transaction initialization
|
|
||||||
*/
|
*/
|
||||||
private void startTransaction() {
|
private void startTransaction() {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
// Initialize POSManager if not already done
|
|
||||||
POSManager.init(getApplicationContext());
|
POSManager.init(getApplicationContext());
|
||||||
|
|
||||||
|
viewModel.setWaitingStatus(true);
|
||||||
|
|
||||||
if(!POSManager.getInstance().isDeviceReady()){
|
if(!POSManager.getInstance().isDeviceReady()){
|
||||||
POSManager.getInstance().connect(deviceAddress, new ConnectionServiceCallback() {
|
POSManager.getInstance().connect(deviceAddress, new ConnectionServiceCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onRequestNoQposDetected() {
|
public void onRequestNoQposDetected() {
|
||||||
runOnUiThread(() -> Log.d(TAG, "No device detected"));
|
runOnUiThread(() -> {
|
||||||
|
viewModel.setStatus("No device detected");
|
||||||
|
viewModel.setWaitingStatus(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestQposConnected() {
|
public void onRequestQposConnected() {
|
||||||
runOnUiThread(() -> Log.d(TAG, "Device connected"));
|
runOnUiThread(() -> {
|
||||||
|
viewModel.setStatus("Device connected");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestQposDisconnected() {
|
public void onRequestQposDisconnected() {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
Log.d(TAG, "Device disconnected");
|
viewModel.setStatus("Device disconnected");
|
||||||
finish();
|
viewModel.setWaitingStatus(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start transaction with callback
|
|
||||||
POSManager.getInstance().startTransaction(amount, paymentServiceCallback);
|
POSManager.getInstance().startTransaction(amount, paymentServiceCallback);
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inner class to handle payment callbacks
|
* Inner class to handle payment callbacks
|
||||||
* Implements all payment related events and UI updates
|
|
||||||
*/
|
*/
|
||||||
private class PaymentCallback implements PaymentServiceCallback {
|
private class PaymentCallback implements PaymentServiceCallback {
|
||||||
@Override
|
@Override
|
||||||
public void onRequestWaitingUser() {
|
public void onRequestWaitingUser() {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
viewModel.setWaitingStatus(true);
|
viewModel.setWaitingStatus(true);
|
||||||
Log.d(TAG, "Please insert/swipe/tap card");
|
viewModel.setStatus("Please insert/swipe/tap card");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +143,6 @@ public class PaymentActivity extends AppCompatActivity {
|
||||||
@Override
|
@Override
|
||||||
public void onRequestSelectEmvApp(ArrayList<String> appList) {
|
public void onRequestSelectEmvApp(ArrayList<String> appList) {
|
||||||
TRACE.d("onRequestSelectEmvApp():" + appList.toString());
|
TRACE.d("onRequestSelectEmvApp():" + appList.toString());
|
||||||
// Auto-select first app for testing
|
|
||||||
if (!appList.isEmpty()) {
|
if (!appList.isEmpty()) {
|
||||||
POSManager.getInstance().selectEmvApp(0);
|
POSManager.getInstance().selectEmvApp(0);
|
||||||
}
|
}
|
||||||
|
@ -154,29 +169,53 @@ public class PaymentActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransactionCompleted(com.test.cardreadtest.posAPI.PaymentResult result) {
|
public void onTransactionCompleted(PaymentResult result) {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
Log.d(TAG, "Transaction completed: " + result.getTransactionType());
|
viewModel.setWaitingStatus(false);
|
||||||
// Display basic card info for testing
|
viewModel.showTransactionResults(true);
|
||||||
|
|
||||||
|
String transactionType = result.getTransactionType() != null ? result.getTransactionType() : "Unknown";
|
||||||
|
viewModel.setTransactionResult(transactionType);
|
||||||
|
viewModel.setStatus("Transaction Completed");
|
||||||
|
|
||||||
|
// Display card information if available
|
||||||
|
StringBuilder cardDetails = new StringBuilder();
|
||||||
if (result.getMaskedPAN() != null) {
|
if (result.getMaskedPAN() != null) {
|
||||||
Log.d(TAG, "Card: " + result.getMaskedPAN());
|
cardDetails.append("PAN: ").append(result.getMaskedPAN()).append(" ");
|
||||||
}
|
}
|
||||||
// finish();
|
if (result.getCardHolderName() != null) {
|
||||||
|
cardDetails.append("Name: ").append(result.getCardHolderName()).append(" ");
|
||||||
|
}
|
||||||
|
if (result.getExpiryDate() != null) {
|
||||||
|
cardDetails.append("Exp: ").append(result.getExpiryDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cardDetails.length() > 0) {
|
||||||
|
viewModel.setCardInfo(cardDetails.toString());
|
||||||
|
} else {
|
||||||
|
viewModel.setCardInfo("No card details available");
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "Transaction completed: " + transactionType);
|
||||||
|
Log.d(TAG, "Card info: " + cardDetails.toString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransactionFailed(String errorMessage, String data) {
|
public void onTransactionFailed(String errorMessage, String data) {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
|
viewModel.setWaitingStatus(false);
|
||||||
|
viewModel.setTransactionResult("Failed");
|
||||||
|
viewModel.setStatus("Error: " + errorMessage);
|
||||||
|
viewModel.setCardInfo("Transaction failed");
|
||||||
|
|
||||||
Log.d(TAG, "Transaction failed: " + errorMessage);
|
Log.d(TAG, "Transaction failed: " + errorMessage);
|
||||||
finish();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestOnlineProcess(final String tlv) {
|
public void onRequestOnlineProcess(final String tlv) {
|
||||||
TRACE.d("onRequestOnlineProcess" + tlv);
|
TRACE.d("onRequestOnlineProcess" + tlv);
|
||||||
// For testing, just send success response
|
|
||||||
POSManager.getInstance().sendOnlineProcessResult("8A023030");
|
POSManager.getInstance().sendOnlineProcessResult("8A023030");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +227,7 @@ public class PaymentActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
// Cancel transaction and go back
|
cancelTransactionAndFinish();
|
||||||
POSManager.getInstance().cancelTransaction();
|
|
||||||
super.onBackPressed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,19 +1,69 @@
|
||||||
package com.test.cardreadtest.payment;
|
package com.test.cardreadtest.payment;
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
public class PaymentViewModel extends ViewModel {
|
public class PaymentViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private MutableLiveData<String> amount = new MutableLiveData<>("Amount: --");
|
||||||
|
private MutableLiveData<String> status = new MutableLiveData<>("Status: Ready");
|
||||||
|
private MutableLiveData<String> transactionResult = new MutableLiveData<>("Transaction: Waiting...");
|
||||||
|
private MutableLiveData<String> cardInfo = new MutableLiveData<>("Card: --");
|
||||||
|
private MutableLiveData<Boolean> showProgress = new MutableLiveData<>(false);
|
||||||
|
private MutableLiveData<Boolean> showResults = new MutableLiveData<>(false);
|
||||||
|
|
||||||
public PaymentViewModel() {
|
public PaymentViewModel() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayAmount(String amount) {
|
public MutableLiveData<String> getAmount() {
|
||||||
// For testing
|
return amount;
|
||||||
System.out.println("Amount to display: " + amount);
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<String> getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<String> getTransactionResult() {
|
||||||
|
return transactionResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<String> getCardInfo() {
|
||||||
|
return cardInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<Boolean> getShowProgress() {
|
||||||
|
return showProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableLiveData<Boolean> getShowResults() {
|
||||||
|
return showResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayAmount(String amountValue) {
|
||||||
|
amount.postValue("Amount: $" + amountValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String statusText) {
|
||||||
|
status.postValue("Status: " + statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionResult(String result) {
|
||||||
|
transactionResult.postValue("Transaction: " + result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCardInfo(String cardDetails) {
|
||||||
|
cardInfo.postValue("Card: " + cardDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWaitingStatus(boolean waiting) {
|
public void setWaitingStatus(boolean waiting) {
|
||||||
System.out.println("Waiting status: " + waiting);
|
showProgress.postValue(waiting);
|
||||||
|
if (waiting) {
|
||||||
|
setStatus("Please insert/swipe/tap card"); // Already uses postValue internally
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showTransactionResults(boolean show) {
|
||||||
|
showResults.postValue(show);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,49 +1,121 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:view="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
<variable
|
<variable name="viewModel" type="com.test.cardreadtest.payment.PaymentViewModel"/>
|
||||||
name="viewModel"
|
|
||||||
type="com.test.cardreadtest.payment.PaymentViewModel" />
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:gravity="center"
|
|
||||||
android:padding="20dp">
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvAmount"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Amount: Testing..."
|
android:text="Payment Transaction"
|
||||||
android:textSize="24sp"
|
android:textSize="24sp"
|
||||||
android:layout_marginBottom="30dp"
|
android:textStyle="bold"
|
||||||
tools:text="Amount: $1.00" />
|
android:gravity="center"
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvStatus"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Status: Ready"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:layout_marginBottom="20dp" />
|
android:layout_marginBottom="20dp" />
|
||||||
|
|
||||||
|
<!-- Amount Section -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvAmount"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{viewModel.amount}"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
tools:text="Amount: $5.00" />
|
||||||
|
|
||||||
|
<!-- Status Section -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvStatus"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{viewModel.status}"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
tools:text="Status: Processing..." />
|
||||||
|
|
||||||
|
<!-- Progress Bar -->
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="gone" />
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginBottom="20dp" />
|
||||||
|
|
||||||
|
<!-- Transaction Results Section (Visible when transaction completes) -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@color/design_default_color_primary"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:layout_marginBottom="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Transaction Results"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvTransactionResult"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{viewModel.transactionResult}"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
tools:text="Transaction: Approved" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvCardInfo"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{viewModel.cardInfo}"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:text="Card: ****1234 Exp: 12/25" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Buttons Section -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btnCancel"
|
android:id="@+id/btnCancel"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Cancel Transaction"
|
android:layout_weight="1"
|
||||||
android:layout_marginTop="30dp" />
|
android:text="Cancel"
|
||||||
|
android:layout_marginEnd="10dp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnBack"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Back to Main"
|
||||||
|
android:layout_marginStart="10dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</layout>
|
</layout>
|
Loading…
Reference in New Issue