Save a card for future transactions
How to save a customer's card on file for use in future purchases or recurring payments.
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
- Generate a test merchant API token or OAuth access token.
- 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.
- Use the card token as the
source
to create a COF record for the customer's card.
Prerequisites
- For sandbox—Generate a test API token.
- For production—Generate OAuth expiring (access and refresh) token.
- Card token
- Customer record
Save a card-on-file for a new customer
- Send a POST request to
/v1/customers
. - 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:
- Revoke the existing card.
- Add the new card information.
- 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}'\
- 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: - Complete or review the information in the required fields:
source
token valuecustomerId
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.
- Set the
authorization: Bearer
as your OAuth-generatedaccess_token
. - 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 customerid
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:
Object | Type | Description |
---|---|---|
sequence | string | Indicates the sequence of the transaction for the same payment card. Values: - First - Subsequent |
is_scheduled | boolean | Indicates 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. |
initiator | string | Indicates whether the transaction is initiated by the merchant or with cardholder consent. Values: - Merchant - Cardholer |
installment_info | string | Installment information for the transaction. |
bill_pay_indicator | string | Indicates whether the transaction is a recurring or installment payment. Values: - Installment - Recurring - For Canadian merchants, the value must be "Recurring" |
invoice_number | string | Invoice number of the installment or recurring transaction. |
description | string | Description 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.
Message | Description | Variable | Description |
---|---|---|---|
200 | string | Successful response. Returns the charge object with any captured value set to true. | |
400 Bad Request | string | charge | Indicates a card-related error. Provides the unique identifier of the failed charge. |
400 Bad Request | string | code | Provides additional information about the error to help users identify the issue. |
400 Bad Request | string | decline_code | Indicates a card issuer declined the transaction, including the reason if specified by the issuer. |
400 Bad Request | string | doc_url | URL (link) for more information about the reported error code. |
400 Bad Request | string | message | Detailed information about the error code. For card-related errors, this can provide more information to users. |
400 Bad Request | string | param | Lists the specific parameter related to the error. Useful for informing users about specific issues with their card information entry. |
400 Bad Request | string | type | Returned error type: - api_connection_error - api_error - authentication_error - card_error - idempotency_error - invalid_request_error - rate_limit_error |
Updated 11 days ago