# 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                                                     | 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

The following local failures can appear as the `underlyingError` of a `StripeCryptoOnrampError` with code `unexpected_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` 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

Missing-customer and missing-payment-method failures can appear in `StripeCryptoOnrampError.underlyingError` with code `unexpected_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`.                                                                                         |

### Platform Pay account change 

`createCryptoPaymentToken` returns `OnrampCreateCryptoPaymentTokenResult.Failed` with `PlatformPayAccountChangedException` if a Google Pay or Samsung Pay method was collected under a different onramp merchant of record from the one required by the customer’s KYC region. This can happen when you collect the payment method before authentication or KYC submission.

Keep the authenticated coordinator, present the wallet again, and retry token creation only after collection succeeds. If the customer cancels, stop instead of retrying with the previous selection. `createCryptoPaymentToken` doesn’t present UI automatically. An accurate `countryHint` reduces the likelihood of this error but doesn’t override an established KYC region.

### Checkout error

`PaymentFailedException` can appear in `StripeCryptoOnrampError.underlyingError` with code `unexpected_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. Make sure 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 sandbox publishable key, which starts with `pk_test_`, the SDK operates against your sandbox. 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. Otherwise-unmapped structured Stripe API errors become `UncategorizedException`. Local failures can instead use `unexpected_error`, with the original cause in `underlyingError`.

