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