# Stored Cards

https://dev.wisecp.com/es/stored-cards

The three endpoints that read a client's stored cards, pick the default and delete one.

## Overview

A stored card is a card held at the client's payment provider. WISECP does **not** keep the card number; it holds a token from the provider and enough to recognise the card — the last four digits, the brand, the expiry.

That is why there is no endpoint here that *adds* a card. A card is stored on the provider's own screen while the client pays; the API only reads what exists, moves the default and deletes.

## Reference

### Listing Cards

get/api/v1/admin/clients/{id}/cards

`Clients/GetClientCards` admin

Returns the client's stored cards. The card number never comes back; only the last four digits show.

Response fields data[] — 6

idintId of the stored card.

last4stringThe last four digits of the card number.

brandstringCard brand, for example `visa` or `mastercard`.

modulestringThe payment module holding the card, for example `Stripe`.

is_defaultboolWhether this is the default card.

expirystringExpiry date, in `12/27` form.

Errors 2

not_found404No such client or card.

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl 'https://panel.example.com/api/v1/admin/clients/42/cards' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch('https://panel.example.com/api/v1/admin/clients/42/cards', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();

const primary = body.data.find((card) => card.is_default);
```

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/cards');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Clients()->GetClientCards(['id' => 42]);

foreach ($response['data'] as $card) {
    if ($card['is_default']) {
        $primary = $card;
    }
}
```

Response 200

```json
{
  "data": [
    {
      "id": 88,
      "last4": "4242",
      "brand": "visa",
      "module": "Stripe",
      "is_default": true,
      "expiry": "12/27"
    }
  ]
}
```

### Setting the Default Card

put/api/v1/admin/clients/{id}/cards/{card_id}/default

`Clients/SetClientCardDefault` admin

Makes a card the default. The flag on the previous one clears by itself.

Body —

——No body is needed; send an empty one. Both the client and the card come from the path.

——There is no way to clear the default without another card taking its place.

Response fields data — 2

card_idintId of the card that became the default.

defaultboolAlways `true`.

Errors 2

not_found404No such client or card.

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X PUT 'https://panel.example.com/api/v1/admin/clients/42/cards/88/default' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/cards/88/default', {
  method: 'PUT',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/cards/88/default');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Clients()->SetClientCardDefault([
    'id'      => 42,
    'card_id' => 88,
]);
```

### Deleting a Card

delete/api/v1/admin/clients/{id}/cards/{card_id}

`Clients/DeleteClientCard` admin may move the default

Deletes the stored card. If it was the default, another one takes its place and the id comes back in the response.

Response fields data — 3

deletedboolWhether the delete succeeded.

card_idintId of the deleted card.

new_default_idintId of the new default card. `0` when the deleted card was not the default.

Errors 2

not_found404No such client or card.

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X DELETE 'https://panel.example.com/api/v1/admin/clients/42/cards/88' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/cards/88', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();

if (body.data.new_default_id) {
  // The default moved to another card.
}
```

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/cards/88');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
$response = Api::Clients()->DeleteClientCard([
    'id'      => 42,
    'card_id' => 88,
]);

$newDefault = $response['data']['new_default_id'] ?? 0;
```

## Pitfalls

> **There is no endpoint that adds a card**
> 
> A card can only be stored during the client's payment flow, because the number is entered at the provider. An integration trying to add one through the API is looking for an endpoint that does not exist.

> **Deleting can move the default**
> 
> Delete the default card and another takes its place; its id comes back in `new_default_id`. If you keep the default on your side, read that value and update it.

> **What you see is not the card number**
> 
> `last4` is only there to recognise the card. The API never returns the card number, the full expiry or the security code on any endpoint.

## Related Articles

- [Client Endpoints](https://dev.wisecp.com/en/client-endpoints)
- [Request and Response Format](https://dev.wisecp.com/en/request-and-response-format)
