## Save a card for future payments

Convert a single-use token into a reusable card that can be charged multiple times. This is useful for:

- Implementing "save card for later" functionality
- Setting up subscription billing
- Enabling one-click payments

The token must be created with multi-use capability (usage="multi"). Single-use tokens cannot be
saved as cards.

You can optionally provide your own external_id to help track the card in your system. This ID
can be used instead of the card ID in other API calls.

This card will be associated with that contact. If default is set to true,
the card will be set as the contact's default card.

The endpoint returns the unique card ID that you can use for future charges.

Note: A token can only be saved as a card once. Attempting to save the same token multiple times
will result in an error.

## Endpoint signature

```http
POST https://api.reservepay.com/merchants/save-card HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <token>

{
  external_id: string?,
  token: string,
  contact_id: string,
  contact_email: string?,
  contact_mobile: string?,
  contact_name: string?,
  default: boolean?,
}
```

Returns: string

## Request arguments

### `external_id` (string)

_Optional_. Your custom identifier for this card. This can be used instead of the card ID in other API calls to help match cards to your system's records. Must be unique across all your saved cards.

### `token` (string)

**Required**. The token ID to convert into a saved card. Must be a multi-use token that hasn't been saved before.

### `contact_id` (string)

**Required**. Either a Contact ID (starting with `ctc_`) or your own external
contact identifier. We'll link this card to an existing contact
if found, or create a new contact if not.

If you provide your own external ID and a contact with that ID
doesn't exist, we'll create a new contact using that ID as their
external identifier.

### `contact_email` (string)

_Optional_. The contact's email address. If provided, we'll either:

- Link this card to an existing contact with this email
- Create a new contact with this email if no match is found
- Update the email for the contact specified in contact_id (if provided)

### `contact_mobile` (string)

_Optional_. The contact's mobile number. If provided, we'll either:

- Link this card to an existing contact with this mobile
- Create a new contact with this mobile if no match is found
- Update the mobile for the contact specified in contact_id (if provided)

### `contact_name` (string)

_Optional_. The contact's name. If provided, we'll either:

- Update the name for an existing contact if found
- Set the name when creating a new contact
- Update the name for the contact specified in contact_id (if provided)

### `default` (boolean)

_Optional_. Make this card the primary card for the contact. Default: false.

## Errors specific to this endpoint

### `NOT_FOUND`

The token with the provided ID could not be found, or the contact with the provided contact_id could not be found. Verify that you're using the correct IDs.

### `NOT_REUSABLE`

The token is single-use and cannot be saved as a card. Create a new multi-use token instead.

### `ALREADY_SAVED`

This token has already been converted to a saved card. Use the existing card ID instead.

## Errors common to all endpoints

### `UNHANDLED_ERROR`

This error occurs when the server encounters an unexpected internal error that
it cannot handle gracefully. This typically happens due to bugs, infrastructure
issues, or edge cases that weren't anticipated during development.

### `INVALID_ARGUMENTS`

This error occurs when the request contains invalid or missing parameters.
Common cases include missing required fields, or values that don't match the
expected format or type.

### `BAD_VERSION`

This error occurs when making requests to an API version that does not exist.
This commonly happens when using an outdated SDK or when the API version
specified in the request URL is incorrect.
