Save a card for future transactions

How to save a customer's card on file for use in future purchases or recurring payments.

North America—United States and Canada

What is card on file (COF)?

Card on file (COF) transactions are payments in which the cardholders have authorized merchants to store their credit or debit card information to use for future purchases or recurring payments. You can use sandbox test cards to build and test the COF feature. A COF payment requires that the Clover merchants have multi-pay tokens enabled in their gateway settings. After you generate a card token, use the source token to save COF.

🚧

IMPORTANT

  • Clover requires that the merchant gets the customer’s consent before you save card-on-file in the customer’s profile.
  • If the customer payment method changes, you must revoke the existing card-on-file (COF) and add a new one.

Before you begin

  1. Generate a test merchant API token or OAuth access token.
  2. Use the PAKMS key to create a card token. You must have all the required details, such as the card number, card verification value (CVV), and expiration date.
  3. Use the card token as the source to create a COF record for the customer's card.

Prerequisites

Save a card-on-file for a new customer

  1. Send a POST request to /v1/customers.
  2. Enter the required information
    • email—Customer's email address,
    • source—Payment source or token to charge, such as a card, gift card, or ACH.

Request and response example—Save card-on-file for a new customer

curl --request POST \
     --url https://scl-sandbox.dev.clover.com/v1/customers \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer ab86a5e8-48f3-b3bd-8c45-d415e9867833' \
     --header 'Content-Type: application/json' \
     --data '{"ecomind":"ecom"}'
{
  "id": "SSHHCDEXTF550",//customer Id
  "object": "customer",
  "created": 1659650347317,
  "currency": "USD",
  "email": "[email protected]",
  "phone": "4085551858",
  "name": "Joe Doe",
  "sources": {
    "object": "list",
    "data": [
      "ND2EFTHF8HM34"
    ]
  },
  "shipping": {
    "name": "Joe Doe",
    "phone": "4085551858"
  }
}

In response, a unique customerId is generated. You can use this customer id as the source value to submit payments with a saved customer card or card-on-file. See Use customer ID.


Save a new card for an existing customer

To save a new card for an existing customer, you need to complete two steps:

  1. Revoke the existing card.
  2. Add the new card information.
  3. Send a DELETE request to /v1/customers/{customerId}sources/{cardId}.
curl --request DELETE \
--url 'https://scl-sandbox.dev.clover.com/v1/customers/{customerId}/sources/{cardId}' \
--header 'accept: application/json' \
--header 'authorization: Bearer {accessToken}'\
  1. After the existing card is revoked, send a PUT request to the /v1/customers/{customerId} endpoint to add a new card to the existing customer record:
  2. Complete or review the information in the required fields:
  • source token value
  • customerId
  • email address—Used to notify the customers that their card data is saved to their profile. See the API reference for more information about other values you can set.
  1. Set the authorization: Bearer as your OAuth-generated access_token.
  2. Retokenize the card using your OAuth-generated access_token. See Generate a card token.
curl --request PUT \
  --url 'https://scl-sandbox.dev.clover.com/v1/customers/{customerId}' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access_token}' \
  --header 'content-type: application/json' \
  --data '{"source":"{token}"}'

Make subsequent payments with saved cards

To make a payment and then subsequent payments with a saved customer card, you can use either the customer id or the multi-pay card token as the source value in your payment request.

Use customer ID

To create a charge request, set the amount (in cents), currency, and source as the customer id.

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/charges' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access_token}' \
  --header 'idempotency-key {uuid4_key}' \
  --header 'content-type: application/json' \
  --header 'x-forwarded-for: {client_ip}' \
  --data '{"amount":2300,
  				"currency":"usd",
          "Source":"{customer_id}"}'

📘

NOTE

If your use case requires you to save one card per customer, set the source as the customer id in any subsequent payments for that customer. If you are saving multiple cards per customer, use the multi-pay token for that customer in subsequent payments.

Use a multi-pay card token

When you save a card on file using /v1/customers, Clover sets the card source token as a multi-pay token for the customer. If you set the source value as this multi-pay token for the customer, you must also include the required stored_credentials values in the payment request:

ObjectTypeDescription
sequencestringIndicates the sequence of the transaction for the same payment card.
Values:

- First
- Subsequent
is_scheduledbooleanIndicates whether the transaction is scheduled or part of an installment.
Values:

- True - Transaction is scheduled.
- False - Transaction is part of an installment.
Installments are only available in the US.
initiatorstringIndicates whether the transaction is initiated by the merchant or with cardholder consent.
Values:

- Merchant
- Cardholer
installment_infostringInstallment information for the transaction.
bill_pay_indicatorstringIndicates whether the transaction is a recurring or installment payment.
Values:

- Installment
- Recurring - For Canadian merchants, the value must be "Recurring"
invoice_numberstringInvoice number of the installment or recurring transaction.
descriptionstringDescription of the installment_info or recurring transaction.

Multi-pay card token example

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/charges' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access_token}' \
  --header 'idempotency-key {uuid4_key}' \
  --header 'content-type: application/json' \
  --header 'x-forwarded-for: {client_ip}' \
  --data '{"amount":1800,
  "currency":"usd",
  "source":"{multi_pay_token}",
  "stored_credentials":{
  "sequence": "SUBSEQUENT",
  "is_scheduled": false,
  "initiator": "CARDHOLDER"}}'

See the Create a charge for more information about otherPOST /v1/charges values you can set.

curl --request POST \
  --url 'https://scl-sandbox.dev.clover.com/v1/orders/{orderId}/pay' \
  --header 'accept: application/json'
  --header 'authorization: Bearer {access_token}'
  --header 'content-type: application/json'
  --header 'x-forwarded-for: {client_ip}' \
  --data '{"source":"{multi_pay_token}",
  "email":"[email protected]",
  "stored_credentials":{
  "sequence": "SUBSEQUENT",
  "is_scheduled": false,
  "initiator": "CARDHOLDER"}}'

See the Create an order for more information about otherPOST /v1/orders/{orderId}/pay values you can set.

Possible responses

The following table describes the possible responses when running an endpoint in the Clover Ecommerce services APIs. These responses include various status codes and error messages that can help you diagnose and handle issues effectively during API integration.

MessageDescriptionVariableDescription
200stringSuccessful response. Returns the charge object with any captured value set to true.
400 Bad RequeststringchargeIndicates a card-related error. Provides the unique identifier of the failed charge.
400 Bad RequeststringcodeProvides additional information about the error to help users identify the issue.
400 Bad Requeststringdecline_codeIndicates a card issuer declined the transaction, including the reason if specified by the issuer.
400 Bad Requeststringdoc_urlURL (link) for more information about the reported error code.
400 Bad RequeststringmessageDetailed information about the error code. For card-related errors, this can provide more information to users.
400 Bad RequeststringparamLists the specific parameter related to the error. Useful for informing users about specific issues with their card information entry.
400 Bad RequeststringtypeReturned error type:

- api_connection_error
- api_error
- authentication_error
- card_error
- idempotency_error
- invalid_request_error
- rate_limit_error