# Error Reference

Tokenization and 3D Secure failures are reported through [CompletePaymentSheet](/android/online/payment-sheet)'s `onFailure` callback. Each failure carries a `FinixErrorCode` describing the exact failure mode.

Deprecated signature
The deprecated signature had no failure callback — errors were surfaced via a toast inside the sheet. If you're still using the deprecated signature, tokenization errors won't reach your code. Migrate to the new [CompletePaymentSheet](/android/online/payment-sheet) signature.

## FinixErrorCode

A sealed interface — pattern-match on the specific type in `when` to branch per failure mode. Every variant carries a human-readable `message` suitable for surfacing to the buyer.


```kotlin
sealed interface FinixErrorCode {
    val message: String

    data object NetworkError : FinixErrorCode {
        override val message = "Network error. Please check your connection."
    }

    data object Timeout : FinixErrorCode {
        override val message = "Request timed out. Please try again."
    }

    data object PaymentFailed : FinixErrorCode {
        override val message = "Payment failed. Please try again."
    }

    data class MissingConfiguration(val field: String) : FinixErrorCode {
        override val message = "3DS is enabled but required field '$field' is missing."
    }

    data class ThreeDSFailed(val failureCode: ThreeDSFailureCode?) : FinixErrorCode {
        override val message =
            failureCode?.failureMessage ?: "3DS authentication failed. Please try again."
    }

    data class Unknown(val detail: String = "") : FinixErrorCode {
        override val message = detail.ifEmpty { "An unexpected error occurred." }
    }
}
```

| Variant | Meaning |
|  --- | --- |
| `NetworkError` | The device could not reach Finix (no connectivity, DNS failure, TLS error). |
| `Timeout` | A Finix API call did not return within the SDK's timeout window. |
| `PaymentFailed` | Tokenization reached Finix but did not succeed. Typically an invalid or declined card. |
| `MissingConfiguration(field)` | 3DS was enabled but a required field is missing from [PaymentSheetConfiguration](/android/online/configuration) — the `field` property names which one (e.g. `"merchantId"`, `"apiUsername"`). |
| `ThreeDSFailed(failureCode)` | 3D Secure authentication failed. The nested [ThreeDSFailureCode](#threedsfailurecode) describes the specific reason. No liability shift — do not charge. |
| `Unknown(detail)` | An unexpected error. `detail` carries any available context from the SDK. |


## ThreeDSFailureCode

Nested inside `FinixErrorCode.ThreeDSFailed` and populated on `ThreeDSResponse.failureCode`. Each case carries a `failureMessage` string explaining the failure.


```kotlin
enum class ThreeDSFailureCode(val failureMessage: String) {
    ACCESS_CONTROL_SERVER_UNAVAILABLE,
    AUTHENTICATION_FAILED,
    AUTHENTICATION_TIMED_OUT,
    CARD_NOT_ENROLLED,
    CHALLENGE_REQUIRED,
    DIRECTORY_SERVER_UNAVAILABLE,
    INVALID_ACQUIRER,
    INVALID_CARD,
    PROTOCOL_ERROR,
    REQUIRED_DATA_ELEMENT_MISSING,
    SUSPECTED_FRAUD,
    TRANSACTION_CANCELLED_BY_CARDHOLDER,
    TRANSACTION_NOT_PERMITTED,
    TRANSIENT_SYSTEM_FAILURE,
    UNSUPPORTED_3D_SECURE_VERSION,
}
```

| Case | Meaning |
|  --- | --- |
| `ACCESS_CONTROL_SERVER_UNAVAILABLE` | The card issuer's authentication server was unavailable. Retry later. |
| `AUTHENTICATION_FAILED` | The cardholder failed to provide the correct authentication details. Treat as potentially fraudulent. |
| `AUTHENTICATION_TIMED_OUT` | Authentication timed out, likely because the cardholder abandoned the transaction. |
| `CARD_NOT_ENROLLED` | The card is not enrolled in 3DS and cannot be authenticated. |
| `CHALLENGE_REQUIRED` | A challenge was required but the integration is configured to fail on challenge. |
| `DIRECTORY_SERVER_UNAVAILABLE` | The card network's directory server was unavailable. Retry later. |
| `INVALID_ACQUIRER` | The acquirer details provided are invalid. |
| `INVALID_CARD` | The card details are invalid. |
| `PROTOCOL_ERROR` | A protocol error occurred during authentication. |
| `REQUIRED_DATA_ELEMENT_MISSING` | A required data element is missing from the authentication request. |
| `SUSPECTED_FRAUD` | The transaction was flagged as suspected fraud by the issuer. |
| `TRANSACTION_CANCELLED_BY_CARDHOLDER` | The cardholder explicitly cancelled the authentication challenge. |
| `TRANSACTION_NOT_PERMITTED` | The transaction type is not permitted for this card. |
| `TRANSIENT_SYSTEM_FAILURE` | A transient system failure occurred. Retry later. |
| `UNSUPPORTED_3D_SECURE_VERSION` | The 3D Secure version required by the issuer is not supported. |


Pattern-match on the error code to branch per failure mode. `message` is safe to surface directly to the buyer.


```kotlin
onFailure = { code ->
    when (code) {
        FinixErrorCode.NetworkError,
        FinixErrorCode.Timeout -> showError(code.message)
        FinixErrorCode.PaymentFailed -> showError(code.message)
        is FinixErrorCode.MissingConfiguration ->
            // Bug in the integration — missing field named by code.field
            logConfigurationError(code.field)
        is FinixErrorCode.ThreeDSFailed ->
            // No liability shift — do not charge
            showError(code.message)
        is FinixErrorCode.Unknown -> showError(code.message)
    }
}
```