H2H: Manage Saved Cards
Use the payment instruments API to display a customer's saved cards, retrieve a card by its pi_ token or remove a saved card. Each card belongs to a settlement account and a customer identified by merchantPayerReference.
These endpoints manage cards saved through the API or Hosted Checkout. To create a saved card, see Card Tokenization via API. To charge it, see Payments with Saved Cards.
Access and customer identification
Ask the integration team to enable H2H tokenization for the settlement account. The feature must be enabled for listing, retrieving and deleting cards.
Paths below are relative to the processing base URL. See Access URLs and API Authentication.
Headers for all requests
| Header | Required | Value |
|---|---|---|
Authorization | Yes | Bearer <access_token> |
settlement-account-id | Yes | The settlement account in which the cards were saved |
For a list or deletion request, supply exactly one customer selector:
merchantPayerReference: the same nonblank customer reference you used when saving the card.payerId: the platform payer identifier, including itsPAYRprefix.
Do not send both selectors. payerId is an alternative for these management requests; payments by token still require payer.merchantPayerReference.
List saved cards
API reference: Get saved payment instruments by payer.
Endpoint: GET /api/v1/payment-instruments
Example: GET /api/v1/payment-instruments?merchantPayerReference=12345&status=ACTIVE
Use the shared request headers above. No request body is required. This example selects cards whose reported status is ACTIVE.
Query parameters
| Parameter | Requirement | Description |
|---|---|---|
merchantPayerReference | One customer selector required | Your nonblank customer reference; mutually exclusive with payerId |
payerId | One customer selector required | Platform payer ID, such as PAYR204264682781298689; mutually exclusive with merchantPayerReference |
paymentMethodName | Optional, repeatable | Match the method name, such as BankCardRU. An unknown name produces no matching cards |
type | Optional, repeatable | Instrument type. The supported value is CARD |
status | Optional, repeatable | ACTIVE, BLOCKED, TERMINATED, USABLE or UNUSABLE |
sort | Optional | desc by default, or asc, by lastUsedAt |
Omit status to include the available status categories. USABLE is a shorthand for ACTIVE; UNUSABLE selects BLOCKED or TERMINATED. These are status filters, not a guarantee of payment approval or MIT eligibility.
Repeat the parameter name to select multiple values. For example:
GET /api/v1/payment-instruments?merchantPayerReference=12345&paymentMethodName=BankCardRU&status=ACTIVE&status=TERMINATED&sort=descValues within one filter are combined with OR; different filters are combined with AND. Use status=ACTIVE&status=TERMINATED, without square brackets in parameter names. Empty optional filter values are ignored.
Sorting does not update lastUsedAt. Records with no lastUsedAt appear first for desc and last for asc. Deleted tokens are excluded from the list.
HTTP status: 200.
This excerpt shows one card in the paymentInstruments array. The complete card object is described in the response tab under Retrieve a saved card.
{
"paymentInstruments": [
{
"paymentInstrumentToken": "pi_01J8ZC4M7QK3T5V9XB2NDR6HAG",
"type": "CARD",
"status": "ACTIVE",
"paymentMethodName": "BankCardRU",
"merchantPayerReference": "12345",
"storedDetails": {
"brand": "VISA",
"maskedNumber": "446260******5620",
"expiryMonth": 12,
"expiryYear": 2028
}
}
]
}paymentInstruments[]
| Field | Type | Description |
|---|---|---|
paymentInstruments | Array of objects | Saved cards matching the selected customer and filters. Each item uses the card object returned by the single-card endpoint |
If no cards match, the response is HTTP 200 with an empty array:
{
"paymentInstruments": []
}Retrieve a saved card
API reference: Get saved payment instrument by token.
Endpoint: GET /api/v1/payment-instruments/{paymentInstrumentToken}
Example: GET /api/v1/payment-instruments/pi_01J8ZC4M7QK3T5V9XB2NDR6HAG
Use the shared request headers above. No request body or customer query parameter is required.
Path parameter
| Parameter | Type | Required | Description |
|---|---|---|---|
paymentInstrumentToken | String | Yes | The saved-card token beginning with pi_ |
The endpoint checks that the token belongs to the settlement account supplied in the header. Your application must still ensure that the returned card belongs to the user viewing it.
HTTP status: 200, with the card object directly in the response body.
{
"paymentInstrumentToken": "pi_01J8ZC4M7QK3T5V9XB2NDR6HAG",
"type": "CARD",
"status": "ACTIVE",
"statusReason": null,
"paymentMethodId": "PM204264682781298692",
"paymentMethodName": "BankCardRU",
"payerId": "PAYR204264682781298689",
"merchantPayerReference": "12345",
"createdAt": "2026-10-08T10:15:30Z",
"lastUsedAt": "2026-10-08T10:15:30Z",
"storedDetails": {
"brand": "VISA",
"maskedNumber": "446260******5620",
"expiryMonth": 12,
"expiryYear": 2028,
"holderName": "TEST CUSTOMER"
}
}Card object
| Field | Type | Nullable | Description |
|---|---|---|---|
paymentInstrumentToken | String | No | The reusable token for this saved card |
type | String | No | CARD |
status | String | No | The saved card's reported status; see the status values below |
statusReason | String | Yes | Additional reason when available; otherwise null |
paymentMethodId | String | No | Platform payment method identifier, beginning with PM |
paymentMethodName | String | No | Name of the associated payment method, such as BankCardRU |
payerId | String | No | Platform customer identifier, beginning with PAYR |
merchantPayerReference | String | No | Your customer reference, as supplied when the card was saved |
createdAt | String | No | Time the saved-card record was created, in ISO 8601 format |
lastUsedAt | String | Yes | Time it was last saved or successfully used, in ISO 8601 format |
storedDetails | Object | Yes | Non-sensitive card details; see the object below |
Nullable fields are returned as null when unavailable.
storedDetails
| Field | Type | Nullable | Description |
|---|---|---|---|
brand | String | Yes | Card brand, such as VISA |
maskedNumber | String | Yes | Masked card number |
expiryMonth | Integer | Yes | Expiry month from 1 to 12 |
expiryYear | Integer | Yes | Four-digit expiry year |
holderName | String | Yes | Cardholder name as stored with the saved card |
Each field can be null if unavailable, and the entire storedDetails object can be null. The full card number and CVV are not returned.
Card status values
| Status | Meaning |
|---|---|
ACTIVE | The saved card is available for payment attempts. Approval and MIT availability are determined when a payment is processed |
TERMINATED | The underlying card has been recognised as invalid; statusReason is INSTRUMENT_DEAD. The record can remain visible so the customer can remove it |
BLOCKED | A recognised API status and filter value; it is not currently produced by these endpoints |
A card's expiry date does not necessarily cause its displayed status to change immediately. Acceptance depends on the payment method and issuing bank. There is no separate MIT-readiness field in this response.
Deleting a token removes it from reads: deletion is not represented by returning a card with TERMINATED status.
Delete a saved card
API reference: Delete saved payment instrument by token.
Endpoint: DELETE /api/v1/payment-instruments/{paymentInstrumentToken}
Example: DELETE /api/v1/payment-instruments/pi_01J8ZC4M7QK3T5V9XB2NDR6HAG?merchantPayerReference=12345
Alternatively, identify the customer with payerId:
DELETE /api/v1/payment-instruments/pi_01J8ZC4M7QK3T5V9XB2NDR6HAG?payerId=PAYR204264682781298689Use the shared request headers above. No request body is required. The account, token and customer must match.
Path parameter
| Parameter | Type | Required | Description |
|---|---|---|---|
paymentInstrumentToken | String | Yes | The saved-card token beginning with pi_ |
Query parameters
| Parameter | Requirement | Description |
|---|---|---|
merchantPayerReference | One customer selector required | The same nonblank customer reference used when saving the card; mutually exclusive with payerId |
payerId | One customer selector required | Platform customer identifier, beginning with PAYR; mutually exclusive with merchantPayerReference |
HTTP status: 200 with an empty body. There is no JSON response object.
Repeating deletion of the same token for the same account and customer also returns HTTP 200, provided access to the feature remains enabled. Attempting to delete an unknown token or using a different customer returns 404.
After deletion:
- The token is excluded from card lists and cannot be used for new payments.
- Retrieving that token returns HTTP
404withINSTRUMENT_NOT_FOUND. - Saving the same card again creates a new token.
- Existing payment records remain available. A token echoed on a historical payment does not mean it is still usable.
flowchart LR saved["Saved card: pi_ token"] -->|"Eligible CIT or MIT payment"| saved saved -->|"Delete token"| deleted["Token unavailable"] deleted -->|"Save the card again"| replacement["New pi_ token"]
Deleting a card does not cancel or refund a payment already in progress. Check that payment's result and use the standard cancellation or refund operation when applicable.
Errors
| HTTP status | errorCode | Meaning |
|---|---|---|
400 | 400 | Invalid query parameters, such as missing or conflicting customer selectors, an invalid payer ID, status, type or sort value |
403 | CAPABILITY_DISABLED | H2H tokenization is disabled for the settlement account. This also applies to deletion |
404 | INSTRUMENT_NOT_FOUND | GET cannot find the token within the settlement account, including when it was deleted. DELETE cannot find it within the settlement account and customer scope |
Error response object
| Field | Type | Description |
|---|---|---|
errorCode | Number or string | Numeric 400 for an invalid request, or the named error code shown above |
failureMessage | String | Explanation of the error |
timestamp | Number | Time the error response was generated, as a Unix timestamp in seconds; it can include a fractional part |
Example HTTP 404 response excerpt:
{
"errorCode": "INSTRUMENT_NOT_FOUND",
"failureMessage": "Saved payment instrument not found"
}The full error response also includes timestamp.
Updated about 7 hours ago
