Error Handling
Last updated: 2026-03-13
Result Codes
SoftPOS returns a standard Android result code to your Activity Result callback:
| Result Code | Value | Meaning |
|---|---|---|
RESULT_OK | -1 | The operation completed. Check isSuccess in the response extras to determine whether the transaction succeeded or failed. |
RESULT_CANCELED | 0 | The operation was cancelled or aborted before completion. Check the error / Error extra for the reason. |
Error Codes
The error extra (string) indicates the specific error condition. Always check both "error" and "Error" (capital E) key variants for compatibility:
kotlinval error = data?.getStringExtra("error") ?: data?.getStringExtra("Error")
| Value | Description |
|---|---|
None | No error. |
Aborted | The operation was aborted. |
Busy | The system is busy. Retry after a short delay. |
InProgress | An operation is already in progress. |
Failed | The operation failed. |
ResponseNotReceived | No response was received from the payment network. |
NotAllowed | The operation is not allowed in the current state. |
Refusal | The transaction was refused. |
WrongPIN | The cardholder entered an incorrect PIN. |
CardReadFailed | The card could not be read. Ask the cardholder to try again. |
Cancel | The operation was explicitly cancelled. |
Denial Reasons
The denialReason extra (string) provides additional context when a transaction is denied:
| Value | Description |
|---|---|
None | No denial reason. |
TechnicalError | A technical error occurred. |
CardReadError | The card could not be read correctly. |
ValidationError | Request validation failed. |
InputDataError | Invalid input data was provided. |
ConfigurationError | Terminal configuration error. |
CardDataError | Invalid card data. |
TransactionAuthorizationError | Authorization was denied by the card issuer. |
GatewayResponseError | An error was received from the payment gateway. |
MacGenerationFailed | MAC generation failed. |
CancelledByCardholder | The cardholder cancelled the transaction. |
MacValidationFailed | MAC validation failed. |
Transaction Status
The status extra (string) reflects the final state of the transaction:
| Value | Description |
|---|---|
None | No status (default). |
ValidCardDetails | Card details were successfully validated. |
Approved | The transaction was approved. |
Declined | The transaction was declined. |
VoiceReferral | A voice referral is required to complete the transaction. |
MustGoOnline | The terminal must go online to complete the transaction. |
MessageSequenceError | A message sequence error occurred. |
Error Handling Example
kotlinprivate fun handleTransactionError( denialReason: String?, error: String?, status: String? ) { when { error != null && error != "None" -> { when (error) { "Aborted" -> showError("Transaction was aborted") "Busy" -> showError("System is busy, please try again") "CardReadFailed" -> showError("Failed to read card, please try again") "WrongPIN" -> showError("Incorrect PIN entered") else -> showError("Transaction error: $error") } } denialReason != null && denialReason != "None" -> { when (denialReason) { "CancelledByCardholder" -> showError("Transaction cancelled by cardholder") "TechnicalError" -> showError("A technical error occurred") "GatewayResponseError" -> showError("Gateway communication error") else -> showError("Transaction denied: $denialReason") } } status == "Declined" -> showError("Transaction was declined") else -> showError("Transaction failed") } }
Common Issues
ActivityNotFoundException
Problem: The app crashes when launching a SoftPOS Intent.
Solution: Always verify SoftPOS is installed before launching:
kotlinif (intent.resolveActivity(packageManager) != null) { resultLauncher.launch(intent) } else { showError("WestPay SoftPOS is not installed") }
Error Extra Not Found
Problem: The error message is not retrieved from a cancelled result.
Solution: Check both key variants:
kotlinval error = data?.getStringExtra("error") ?: data?.getStringExtra("Error")
Amount Format Rejected
Problem: The transaction amount is not accepted by SoftPOS.
Solution: Use a comma as the decimal separator, not a period:
kotlinval amount = "100,50" // correct val amount = "100.50" // incorrect — will not be accepted
Date Format Issues
Problem: Transaction history query returns no results or fails.
Solution: Use the yyyy-MM-dd format for date extras:
kotlinval dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) val startDate = dateFormat.format(date)