Localize API error messages
Localize API error messages so cardholders see errors in a language they understand.
Configure your Terminal integration to return API error messages in the cardholder’s or operator’s language.
Available in: Android SDK 5.6.0+ and iOS SDK 5.6.0+. Smart readers require reader software v2.43 or later.
Common mistake
Don’t parse error messages to drive application logic. Message content can change between SDK versions and varies by locale. Use error codes for programmatic error handling.
Understand which errors Stripe localizes
Only API errors returned by the Stripe API are localized. These errors originate from the Stripe backend in response to an API request, such as card declines during payment confirmation.
Errors that originate from the Terminal SDK or reader, such as connection failures, reader timeouts, or Bluetooth disconnects, are always in English and aren’t affected by LocaleConfig.
To determine whether an error message is localized, check for localizationResult on the API error. Not all API errors come from a network response. The Terminal SDK sometimes constructs API errors locally, for example for declined Interac refunds. Only API errors that come from the Stripe API have localizationResult, which confirms that Stripe localized the message.
Check for an ApiError in the error’s userInfo dictionary by using the SCPErrorKeyStripeAPIError key. Then check whether localizationResult is present.
Select a language
Swift
Objective-C
No results
guard let apiError = (error as NSError).userInfo[SCPErrorKeyStripeAPIError] as? ApiError else {
// SDK or reader error — always in English
return
}
if let localizationResult = apiError.localizationResult {
// Message was localized via a network response
let localizedMessage = apiError.message
print("Resolved locale: \(localizationResult.resolvedLocale)")
} else {
// API error constructed locally — message is not localized
}
Supported locales
The following locales are supported. Pass one of these locale codes to HardcodedLocale to localize API error messages to that language. If your configured locale isn’t supported, error messages fall back to English ( en-US).
| Language | Locale code |
|---|---|
| Bulgarian | bg-BG |
| Chinese Simplified | zh-Hans |
| Chinese Traditional (Hong Kong) | zh-HK |
| Chinese Traditional (Taiwan) | zh-TW |
| Croatian | hr-HR |
| Czech | cs-CZ |
| Danish | da-DK |
| Dutch | nl-NL |
| English (UK) | en-GB |
| English (US) | en-US |
| Estonian | et-EE |
| Filipino | fil-PH |
| Finnish | fi-FI |
| French (Canada) | fr-CA |
| French (France) | fr-FR |
| German | de-DE |
| Greek | el-GR |
| Hungarian | hu-HU |
| Indonesian | id-ID |
| Italian | it-IT |
| Japanese | ja-JP |
| Korean | ko-KR |
| Latvian | lv-LV |
| Lithuanian | lt-LT |
| Malay | ms-MY |
| Maltese | mt-MT |
| Norwegian | nb-NO |
| Polish | pl-PL |
| Portuguese (Brazil) | pt-BR |
| Portuguese (Portugal) | pt-PT |
| Romanian | ro-RO |
| Slovak | sk-SK |
| Slovenian | sl-SI |
| Spanish (Latin America) | es-419 |
| Spanish (Spain) | es-ES |
| Swedish | sv-SE |
| Thai | th-TH |
| Turkish | tr-TR |
| Vietnamese | vi-VN |
Choose a localization strategy
Terminal provides two strategies for localizing API error messages. Choose the one that best fits your use case.
| Strategy | Behavior |
|---|---|
| Hardcoded locale | All API error messages return in a fixed locale you specify |
| Card language preference | Uses the cardholder’s preferred language from the card during a transaction. Falls back to the device locale if unavailable |
Note
This configuration doesn’t change the reader’s display language. See Default reader language to configure that separately.
Configure localization
Pass an SCPLocaleConfig to Terminal.initWithTokenProvider. When omitted, all error messages remain in English ( en-US).
Select a language
Swift
Objective-C
No results
// Hardcoded locale — all API errors returned in Japanese
let localeConfig = try HardcodedLocaleConfigBuilder(locale: "ja-JP").build()
Terminal.initWithTokenProvider(
myTokenProvider,
delegate: myDelegate,
offlineDelegate: nil,
logLevel: .none,
localeConfig: localeConfig
)
// Card language preference — use card language if available,
// otherwise fall back to device locale
Terminal.initWithTokenProvider(
myTokenProvider,
delegate: myDelegate,
offlineDelegate: nil,
logLevel: .none,
localeConfig: .cardLanguagePreferenceIfAvailable
)
Display localized error messages to cardholders
When an API error occurs, check SCPApiError.type to determine who the message is for. Show only card_error messages to cardholders. Other types, such as invalid_request_error, indicate integration issues and are intended for developers or point-of-sale operators.
Inspect SCPApiError.localizationResult to see how the locale was resolved — SCPLocalizationResult.requestedLocale is what the SDK sent, and SCPLocalizationResult.resolvedLocale is what Stripe used to translate the message. If the requested locale isn’t supported, resolvedLocale returns en-US.
Select a language
Swift
Objective-C
No results
Terminal.shared.confirmPaymentIntent(paymentIntent) { _, error in
guard let nsError = error as NSError? else { return }
guard let apiError = nsError.userInfo[SCPErrorKeyStripeAPIError] as? ApiError else {
// SDK or reader error — always in English
self.log(nsError.localizedDescription)
return
}
// Check localizationResult to see the resolved locale
if let result = apiError.localizationResult {
self.log("requested=\(result.requestedLocale), resolved=\(result.resolvedLocale)")
}
if apiError.type == "card_error" {
// Card error — display message to the cardholder
self.showErrorToCardholder(apiError.message)
} else {
// Not intended for cardholders
self.log(apiError.message ?? "")
}
}
Reader support for card language preference
Not all reader types support extracting the card’s language preference. When the reader doesn’t support it, CardLanguagePreferenceIfAvailable falls back to the device locale.
| Reader type | Extracts card language preference |
|---|---|
| Tap to Pay on Android | Yes |
| Tap to Pay on iPhone | No, falls back to device locale |
| Smart readers | Contact transactions only. Contactless transactions fall back to device locale. |
| Mobile readers | No, falls back to device locale |
Limitations
Review these limitations before you rely on localized API error messages in production:
- SDK and smart reader can resolve different device locales : When using CardLanguagePreferenceIfAvailable with a smart reader, the SDK and reader resolve their device locale independently. Set both devices to the same locale to avoid inconsistent error languages. See Default reader language to configure the reader’s locale.
- Localized messages persist on the API resource. If confirmPaymentIntent returns an error message in Japanese, a subsequent retrievePaymentIntent call returns the same Japanese message in lastPaymentError. message , regardless of the locale configured at retrieval time.
Test your integration
Follow these steps to test localization:
- Initialize the SDK with a hardcoded locale (for example, "ja-JP" ).
- Use a Terminal test card with a test amount that triggers a decline.
- Verify that apiError. message is in the expected language.
- Inspect apiError. localizationResult to confirm these values:
- requestedLocale matches what you configured.
- resolvedLocale shows the locale that Stripe used to translate the message.
