# Error handling

Handle errors that occur during onramp sessions.

For general error handling, see the [Stripe error handling guide](https://docs.stripe.com/error-handling.md).

For error codes specific to the crypto onramp, see [Crypto onramp error codes](https://docs.stripe.com/crypto/onramp/embedded-components-error-codes.md).

# Android


## SDK errors

### Configuration error

| Error                                                                                                     | Cause and fix                                                                                                                                                                                                                                                                              |
| --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `IllegalArgumentException`: `merchantDisplayName` must not be null and `publishableKey` must not be null. | Both `merchantDisplayName` and `publishableKey` are required on `OnrampConfiguration`. Set both before you call `onrampCoordinator.configure(configuration)`.                                                                                                                              |
| `IllegalArgumentException`: Callback must not be null                                                     | All callbacks on `OnrampCallbacks` are required except `googlePayIsReadyCallback`. Set `verifyIdentityCallback`, `verifyKycCallback`, `collectPaymentCallback`, `authorizeCallback`, `checkoutCallback`, and `onrampSessionClientSecretProvider` before you build the `OnrampCoordinator`. |
| `OnrampConfigurationResult.Failed`                                                                        | The `configure` call can fail if the underlying Link SDK fails to initialize. Inspect the `error` property. A common cause is an invalid publishable key.                                                                                                                                  |

### Authentication error

| Error                                                     | Cause and fix                                                                                                                                                                                                                                                                                                   |
| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MissingConsumerSecretException`: Missing consumer secret | The user’s session wasn’t established or expired. Make sure that the user completed authentication through `authorize` or `authenticateUserWithToken` before you call other APIs. This error can come from `registerLinkUser`, `registerWalletAddress`, `attachKycInfo`, `verifyKycInfo`, and `verifyIdentity`. |
| Link authorization error or forced re-authentication      | If an API call returns an authorization error, the SDK automatically clears the cached Link account state. Subsequent calls fail with `MissingConsumerSecretException`. Re-authenticate the user by calling `authorize` again.                                                                                  |

### Payment error

| Error                                                        | Cause and fix                                                                                                                                                                                                                |
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MissingCryptoCustomerException`: Missing crypto customer ID | No crypto customer is associated with the current session. A crypto customer ID is created during `authorize` or `registerLinkUser`. Make sure that one of these calls completed before you call `createCryptoPaymentToken`. |
| `MissingPaymentMethodException`: Missing payment method      | Payment method collection appeared to succeed, but we couldn’t resolve the selected method internally. Retry `collectPaymentMethod`.                                                                                         |

### Checkout error

| Error                                        | Cause and fix                                                                                                                                                                                                                                                                                                                                                                                                         |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PaymentFailedException`: Payment failed     | The underlying `PaymentIntent` reached a terminal failure state, such as a declined card, processing error, or unresolvable session after process failure. Inspect the error and offer the user an option to retry or select a different payment method.                                                                                                                                                              |
| `onrampSessionClientSecretProvider` failures | This callback must call your back end, which calls the onramp session checkout endpoint with the session ID and returns the `client_secret`. It might be called more than once during a single checkout, initially and again after handling a required next action such as 3DS. Make sure that your back end can handle repeated calls for the same session ID. If this callback results in an error, checkout fails. |

### Identity and KYC error

| Error                                                             | Cause and fix                                                                                                                                                                      |
| ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OnrampVerifyIdentityResult.Failed` with “No ephemeral key found” | The server responded without an ephemeral key. This usually indicates a back-end configuration issue. Ensure that the user’s account is properly set up for identity verification. |
| `OnrampVerifyKycInfoResult.UpdateAddress`                         | This isn’t an error. The user indicated that their address needs updating. Show your address form, then call `onrampPresenter.verifyKycInfo(updatedAddress)` again.                |

### General guidance

- All `Failed` result types include an `error: Throwable` property. Log or inspect it for detailed diagnostics.
- Only one `OnrampCoordinator` instance can be active at a time. Creating multiple instances can lead to undefined behavior.
- Always call `logOut()` when the user logs out of your app to clean up SDK state and avoid stale session issues.
- When you use a test mode publishable key that contains `test`, the SDK operates against the Stripe test environment. No real transactions are processed, and no actual identity verification occurs.

## API errors

### Transaction blocked errors

Transactions can be blocked to meet compliance or risk requirements. For compliance reasons, Stripe can’t provide additional details about why a specific transaction was blocked. If you believe a transaction was blocked incorrectly, contact Stripe.

| Error code                          | Description                                                          | How to handle                                                                                         |
| ----------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `crypto_onramp_transaction_blocked` | The transaction was blocked to meet compliance or risk requirements. | Show a generic error message. If you believe the transaction was blocked incorrectly, contact Stripe. |

> When testing, use the [test values](https://docs.stripe.com/crypto/onramp/embedded-components-integration-guide.md?platform=android#test-values) to avoid triggering compliance or risk checks.

### Wallet ownership verification errors

The [EU Travel Rule](https://docs.stripe.com/crypto/onramp/eu-kyc-integration-guide.md?platform=android#travel-rule-wallet-ownership) wallet ownership methods—`getWalletOwnershipChallenge` and `submitWalletOwnershipSignature`—return a `Failed` result whose `error` is one of the following typed exceptions:

| Error                                      | Description                                                                                                       | How to handle                                                                   |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| `WalletNotFoundException`                  | The wallet isn’t registered on the authenticated user.                                                            | Register the wallet with `registerWalletAddress`, then request a new challenge. |
| `UnsupportedNetworkException`              | The network doesn’t support wallet ownership verification. Only EVM-compatible networks and Solana are supported. | Don’t retry with this network.                                                  |
| `WalletOwnershipChallengeExpiredException` | The challenge expired.                                                                                            | Request a new challenge, collect a new signature, then submit again.            |
| `InvalidWalletOwnershipChallengeException` | The challenge is invalid or was already used.                                                                     | Request a new challenge, then submit again.                                     |
| `InvalidWalletOwnershipSignatureException` | The signature doesn’t prove control of the wallet.                                                                | Restart the full challenge and signing flow. Don’t resubmit the same signature. |

These exceptions map to the same underlying API error codes used by the web, React Native, and iOS SDKs. Other failures (such as an unauthenticated user or a rate-limited request) aren’t specific to wallet ownership verification and we label them as `UncategorizedException`.

