# Display card details Cards have non-sensitive details and sensitive details (credentials) that are subject to data protection regulations. You can: - View the details in the Dashboard. - Get the details using the API. - Display the details to cardholders in your app or on your website, and enable them to copy the card number to their clipboard. --- ## View card details in the Dashboard You must have the Admin [user role](https://www.checkout.com/docs/business-operations/use-the-dashboard/manage-users/user-permissions.md) or a custom role with one or both of the following permissions: - Non-sensitive details – `View all transactions, cards, cardholders, and card products` permission - Sensitive details – `View card number and CVC2` permission
For security reasons, no pre-defined roles include this permission by default. 1. Sign in to the [Dashboard](https://dashboard.checkout.com). 2. Go to _Issuing_ > _Cards_. 3. Use the search or filters to find the relevant card and then select it. 4. On the _Card details_ page, under _About this card_, you can see the non-sensitive details. 5. To see the sensitive details, select _View card credentials_. --- ## Get card details using the API ### Sensitive card details If your entity is regulated or you issue cards to your business, you can get sensitive card details using the API. Call the [Get card credentials](https://api-reference.checkout.com/tag/Cards/#operation/getCardCredentials) endpoint, and provide the following: - `{cardId}` path parameter – The unique identifier for the card – for example, `crd_fa6psq242dcd6fdn5gifcq1491` - `credentials` query parameter – The card credentials you want to retrieve, which can be one of or both of the following as a comma-separated list: - `number` – The full primary account number (PAN) - `cvc2` – The security code **Production** `GET` `https://{prefix}.api.checkout.com/issuing/cards/{cardId}/credentials?credentials=number,cvc2` **Sandbox** `GET` `https://{prefix}.api.sandbox.checkout.com/issuing/cards/{cardId}/credentials?credentials=number,cvc2` ### Response example ```json { "number": 4242424242424242, "cvc2": 604 } ``` ### Non-sensitive card details To retrieve non-sensitive card details, call the [Get card details](https://api-reference.checkout.com/tag/Cards/#operation/getCard) endpoint, and provide the `{cardId}` path parameter. **Production** `GET` `https://{prefix}.api.checkout.com/issuing/cards/{cardId}` **Sandbox** `GET` `https://{prefix}.api.sandbox.checkout.com/issuing/cards/{cardId}` ### Response example ```json { "id": "crd_fa6psq242dcd6fdn5gifcq1491", "client_id": "cli_vkuhvk4vjn2edkps7dfsq6emqm", "entity_id": "ent_fa6psq242dcd6fdn5gifcq1491", "cardholder_id": "crh_d3ozhf43pcq2xbldn2g45qnb44", "card_product_id": "pro_7syjig3jq3mezlc3vjrdpfitl4", "last_four": 1234, "expiry_month": 5, "expiry_year": 2025, "status": "active", "display_name": "JOHN KENNEDY", "type": "virtual", "billing_currency": "USD", "issuing_country": "US", "reference": "X-123456-N11", "metadata": { "udf1": "metadata1", "udf2": "metadata2", "udf3": "metadata3", "udf4": "metadata4", "udf5": "metadata5" }, "revocation_date": "2029-03-12", "root_card_id": "crd_fa6psq242dcd6fdn5gifcq1491", "created_date": "2025-09-09T19:41:39Z", "last_modified_date": "2025-09-09T19:41:39Z", "_links": { "self": { "href": "https://{prefix}.api.checkout.com/issuing/cards/crd_fa6psq242dcd6fdn5gifcq1491", "actions": [ "GET" ], "types": [ "application/json" ] }, "credentials": { "href": "https://{prefix}.api.checkout.com/issuing/cards/crd_fa6psq242dcd6fdn5gifcq1491/credentials", "actions": [ "GET" ], "types": [ "application/json" ] }, "revoke": { "href": "https://{prefix}.api.checkout.com/issuing/cards/crd_fa6psq242dcd6fdn5gifcq1491/revoke", "actions": [ "POST" ], "types": [ "application/json" ] }, "controls": { "href": "https://{prefix}.api.checkout.com/issuing/controls?target_id=crd_fa6psq242dcd6fdn5gifcq1491", "actions": [ "GET" ], "types": [ "application/json" ] } }, "is_single_use": false } ``` --- ## Display card details in your app After you've integrated the Card Management [Android SDK](https://www.checkout.com/docs/developer-resources/sdks/card-issuing-sdks/card-management-android-sdk.md) or [iOS SDK](https://www.checkout.com/docs/developer-resources/sdks/card-issuing-sdks/card-management-ios-sdk.md), you can enable your cardholders to view their card details in your app. > **Note** > > You must migrate to Android SDK version 3.0.0 or iOS SDK version 4.0.0. For guidance on how to update your integration, see Support – [Issuing Card Management SDKs migration guide](https://support.checkout.com/hc/en-us/articles/32194131879698). Follow these steps: 1. [Authenticate the cardholder](#Authenticate_the_cardholder). 2. [Retrieve the cardholder's cards and non-sensitive details](#Retrieve_the_cardholder's_cards). 3. [Retrieve the sensitive details](#Retrieve_the_sensitive_card_details). > **Information** > > In the iOS SDK stub environment, you can provide any `String` instead of an access token, because all responses return mock data. ### Authenticate the cardholder You are responsible for performing [Strong Customer Authentication (SCA)](https://www.checkout.com/docs/business-operations/ensure-regulatory-compliance/sca-compliance.md) on the cardholder for each session where they use functionality provided by the SDK. This applies to both the sandbox and production SDK environments. Pass an [access token](https://api-reference.checkout.com/tag/Access/#operation/requestAnAccessToken) that your app receives from your authentication back end. **Android SDK** ```kotlin val token = "{Access_token}" cardManager.logInSession(token) ``` **iOS SDK** ```swift let token = "{Access_token}" cardManager.logInSession(token: accessToken) ``` ### Retrieve the cardholder's cards Once you’ve authenticated the cardholder and your app, call the `getCards()` method to get all the cardholder's cards or `getCards(cardId)` to get a specific card and display a list of their cards and the following non-sensitive card details: - The last four digits of the primary account number (PAN) - The expiry month and year - The cardholder's name - The card's status – `active`, `inactive`, `revoked`, or `suspended` - The card ID – For example, `crd_fa6psq242dcd6fdn5gifcq1491` > **Note** > > The `getCards()` method throws a `CardManagementError` which you must catch. For example, using `catch` (as in the example) or `runCatching`. **Android SDK** ```kotlin // Call coroutineBased getCards in the context of a coroutineScope try { // Get all the cardholder's cards cardManager.getCards(statuses = setOf(CardState.ACTIVE, CardState.REVOKED)) // Get a specific card cardManager.getCard(cardId: "") } catch (e: CardManagementError) { when (error) { is CardManagementError.Unauthenticated -> // Prompt login is CardManagementError.ConnectionIssue -> // Show network error else -> // Handle other errors } } ``` **iOS SDK** ```swift do { // Get all the cardholder's cards let cards = try await cardManager.getCards(statuses: [.active, .suspended]) // Get a specific card let cards = try await cardManager.getCard(withID: cardId, statuses: [.active,.suspended]) } catch let error as CardManagementError { switch error { case .authenticationFailure: // Handle the authentication error default: // Handle other errors } } ``` ### Retrieve the sensitive card details Once you've retrieved a cardholder's cards, you can use the following methods to retrieve each card's sensitive details: - `Card.getPin()` – The personal identification number (PIN) for a physical card - `Card.getPan()` – The full PAN - `Card.getSecurityCode()` – The security code (CVC2) - `Card.getPANAndSecurityCode()` – The full PAN and CVC2 Every method is subject to a unique SCA flow. You can only [request a single-use token](https://api-reference.checkout.com/tag/Cardholder-access-tokens/#operation/requestCardholderAccessToken) after the SCA flow is completed. You must provide the token to the SDK to call the method. The UI component protects the sensitive details and securely displays them to the cardholder only. They are never displayed to you, or sent to your server. **Android SDK** ```kotlin val singleUseToken = "{Single_use_token_retrieved_after_SCA}" // Request sensitive data via the card object when (val result = card.getPin(singleUseToken)) { is CardSecureDataResult.Success -> { displaySecureView(result.data) } is CardSecureDataResult.Error -> { showError(result.message) handleError(result) } } ``` **iOS SDK** ```swift let singleUseToken = "{Single_use_token_retrieved_from_your_backend_after_SCA}" // Request sensitive details using the card object do { let pin = try await card.getPin(reason: reason) // Handle the PIN view here - This is a UI component that you can display to the user } catch let error as CardManagementError { // Request failed - Handle the error } ``` > **Note** > > Virtual cards do not have a PIN. If you call the `getPin()` method for a virtual card, you receive an `Unauthenticated` error. ### Copy the card number to clipboard You can enable cardholders to securely copy their card's primary account number (PAN) to the clipboard of their device. This feature includes: - Secure authorization – Every method is subject to a unique SCA flow. You can only request a single-use token after the SCA flow is completed. The PAN is retrieved and copied asynchronously. - Security validation – The cardholder must view the PAN before copying to prevent unauthorized access. - Automatic logging – Successful and failed copy attempts are tracked for analytics. - Granular error handling – Specific error cases are returned for different failure scenarios to enable troubleshooting. #### Prerequisites **Android SDK** The minimum supported SDK version for this feature is Android 7, API 24. **iOS SDK** The minimum supported version for this feature is iOS 14. To use this feature with other versions, see Apple Developer – [UIPasteboard](https://developer.apple.com/documentation/uikit/uipasteboard/#overview). #### Display PAN to cardholder Call one of the following methods to display the PAN to the cardholder: - `displayPan()` - `displayPANAndSecurityCode()` > **Information** > > We recommend explaining this security requirement to the cardholder for a smooth user experience. #### Initiate copy operation Call the `copyPan` method and provide the token: **Android SDK** ```kotlin public suspend fun copyPan(singleUseToken: String): Result ``` `completionHandler` is a closure executed on completion that returns a `Result` that indicates either success, or the reason for failure. **iOS SDK** ```swift func copyPan(singleUseToken: String) async throws ``` `completionHandler` is a closure executed on completion that returns a `CardDetailCopyResult` that indicates either success, or the reason for failure. ```swift public enum CardDetailCopyResult: Equatable { case success // PAN successfully copied to clipboard case failure(CardManagementError) // Operation failed with specific error case } ``` > **Note** > > To avoid errors, prevent the app from attempting multiple simultaneous copy operations. #### Error cases You can receive the following error cases: **Android SDK** | Error | Description | Recovery action | | --- | --- | --- | | `AuthenticationFailure` | The token was invalid or expired. | Authenticate the cardholder before calling the `copyPan` method. | | `PanNotViewedFailure` | The PAN was not viewed before copying. | Call one of the following methods before calling the `copyPan()` method:

- `displayPan()`
- `displayPANAndSecurityCode()` | | `SecureOperationsFailure` | The app could not copy the PAN returned by the API. | Check the clipboard permissions and network availability of the cardholder's device. | | `UnsupportedAPIVersion` | The Android version is not supported.

This applies to API versions 29, 30, 31, and 32. | The `copyPan` method is not supported for these API versions due to operating system security requirements. | **iOS SDK** | Error | Description | Recovery action | | --- | --- | --- | | `.unableToCopy(failure: .copyFailure)` | The operation failed to copy the PAN to clipboard. | Check:

- The clipboard permissions and network availability of the cardholder's device
- If the token was valid | | `.unableToCopy(failure: .dataNotViewed)` | The PAN was not viewed before copying. | Call one of the following methods before calling the `copyPan()` method:

- `displayPan()`
- `displayPANAndSecurityCode()` | | `.unableToCopy(failure: .missingManager)` | The card manager was deallocated. | Ensure the card manager stays in memory. | #### Examples **Android SDK** ```kotlin when (val result = card.copyPan(singleUseToken)) { is CardSecureDataResult.Success -> { showToast("Card number copied to clipboard") } is CardSecureDataResult.Error -> { // Handle the error } } // DEPRECATED using callbacks card.copyPan(singleUseToken = "{Single_use_token}") { result -> result.fold( onSuccess = { }, onFailure = { } ) } ``` **iOS SDK** ```swift do { try await card.copyPan(singleUseToken: token) } catch { // Handle the error } // DEPRECATED using completions card.copyPan(singleUseToken: "") { copyResult in switch copyResult { case .success: // handle success - indicates PAN is copied successfully. case .failure(let error): // handle error (either PAN is not viewed or another error) } } ``` #### See also **[Checkout.com Support](https://support.checkout.com/hc/en-us/articles/29101809788434-Android-version-limitations-for-copyPan)** Android version limitations for copyPan --- ## Display card details on your website After you've integrated the Card Management [Web SDK](https://www.checkout.com/docs/developer-resources/sdks/card-issuing-sdks/card-management-web-sdk.md), you can enable your cardholders to view their card details on your website or web application, and copy each value to their clipboard. Initialize the SDK with your public API key: ```javascript const sdk = new window.CheckoutCardManagement(); ``` ### Set up Strong Customer Authentication You are responsible for performing Strong Customer Authentication (SCA) on the cardholder for each session where they use functionality provided by the SDK. This applies to both the sandbox and production environments. Once the SCA flow is complete, request a single-use token from your authentication back end and pass it to the SDK. You can only generate one single-use token for each SCA flow you request. ### Retrieve the cardholder's cards Call the `getCards()` method with the cardholder ID prefixed with `crh_`, and a cardholder access token. The `options` object is optional, but if you provide it, `statuses` must be a non-empty array of `active`, `inactive`, `suspended`, or `revoked`. If the cardholder has no cards that match, the method returns an empty `cards` array. ```javascript try { const { cards } = await sdk.getCards('crh_d3ozhf43pcq2xbldn2g45qnb44', 'cardholderAccessToken', { statuses: ['active', 'suspended'], }); cards.forEach((card) => { console.log(card.id, card.last4, card.status); }); } catch (error) { console.error(error.code, error.message); } ``` If a request fails, the SDK rejects with an error object containing a `code` and a `message`. Branch on the `code`, because the `message` is intended for debugging and can change. For the full list of codes, see [Handle errors](https://www.checkout.com/docs/developer-resources/sdks/card-issuing-sdks/card-management-web-sdk.md#Handle_errors). ### Retrieve the card's details Call the `getCardDetails()` method with the card ID prefixed with `crd_`, and a cardholder access token. The method returns the card's non-sensitive details, including the last four digits of the card number, the card's status, and its expiry date. > **Note** > > `getCardDetails()` takes a cardholder access token, not the single-use token that `mountCardCredentials()` requires. ```javascript try { const { card } = await sdk.getCardDetails('crd_fa6psq242dcd6fdn5gifcq1491', 'cardholderAccessToken'); console.log(card.last4, card.status, card.expiryMonth, card.expiryYear); } catch (error) { console.error(error.code, error.message); } ``` The method returns `expiryMonth` and `expiryYear` as strings, so you can pass the card straight to `mountCardCredentials()`. ### Display the card credentials Call the `mountCardCredentials()` method to mount an iframe to the element you specify. The iframe displays the card number, expiry date, and card verification value (CVV) to the cardholder, along with a button to copy each value. ```javascript await sdk.mountCardCredentials( 'element_id', { cardId: 'crd_fa6psq242dcd6fdn5gifcq1491', expiryDate: { expiryMonth: '05', // For example, '01' for January expiryYear: '2029', }, }, 'singleUseToken', ) ``` The credentials are visible for 30 seconds. After this period of time, the SDK emits a `checkout:cardCredentialsUnmounted` event and removes the iframe from the DOM. To display the credentials again, complete a new SCA flow, request a new single-use token, and call the method again. The iframe protects the sensitive details and securely displays them to the cardholder only. They are never displayed to you, or sent to your server. ### Extend your integration To override the default styles for the credentials, or to add the SDK's TypeScript types to your project, see [Customize the user interface](https://www.checkout.com/docs/developer-resources/sdks/card-issuing-sdks/card-management-web-sdk.md#Customize_the_user_interface). To build your own experience around the credentials, such as a success message when a cardholder copies a value, see [SDK events](https://www.checkout.com/docs/developer-resources/sdks/card-issuing-sdks/card-management-web-sdk.md#SDK_events).