Reusing Card Information

PaymentsOS allows you to save a customer’s card information, so that customers do not need to re-enter their payment details each time they want to initiate a transaction on your site.
Version Notice

This functionality requires API version 1.2.0 or higher.

If you want to enable users to save their card information, you will need to update your payment flow to include a step in which you ask users to save their cards for future use. Where you do this, depends entirely on your payment logic. For instance, if you are running an eCommerce store you would typically prompt users to save their card information while they are making a purchase on your site. Alternatively, you could also allow users to save theirs cards without requiring them to make a purchase (like when users sign-up for a free trial and only pay after the trial period ends).

Validating the Card

You may want to ensure that a card is valid before saving it. The only way to do this, is to invoke an authorization request and see that it goes through. If you prompt users to save their card while they are making a purchase, you can rest assured that the card is valid (since your payment flow will always include an authorization or charge request). If you want to validate the card without requiring users to make a purchase first, simply invoke an authorization request for a small amount and then void the authorization to cancel the payment.

Saving the Token

Once users gave their consent to store their card information and you validated their card, you can proceed to save it. A user’s card information is always represented as a token. PaymentsOS creates a token representation of that user’s card when you collect a user’s card information.

You can use a token only once in an authorization or charge request. If you want to reuse the token for subsequent transactions, you will need to save it in a customer object first.

Beware that the CVV code is not part of the token and is thus not saved. If you require a CVV code in your checkout form, you must pass it separately into the authorization or charge request.

If you imported our Postman Collection, you can follow-along with the examples in this topic by invoking the requests in the Reusing Card Information folder.

Step 1: Create the Customer Object

Invoke the Create Customer API to create a customer object. Notice that the request body requires a customer_reference. This is a string that you must provide to uniquely identify the customer.

   var request = new XMLHttpRequest();
   request.open('POST', 'https://api.paymentsos.com/customers');
   request.setRequestHeader('Content-Type', 'application/json');
   request.setRequestHeader('api-version', '1.3.0');
   request.setRequestHeader('x-payments-os-env', 'test');
   request.setRequestHeader('app-id', 'com.zooz.docapp');
   request.setRequestHeader('private-key', 'bede7ee5-eaad-4c8a-bc1f-617ba28257ae');
   request.setRequestHeader('idempotency-key', 'cust-34532-trans-001356-p');
   var body = {
   "customer_reference": "johntravolta18021954",
   "email": "john@travolta.com"}
   request.send(JSON.stringify(body));
  
   curl --compressed -X POST \
   https://api.paymentsos.com/customers \
      -H 'Content-Type: application/json' \
      -H 'api-version: 1.3.0' \
      -H 'x-payments-os-env: test' \
      -H 'app-id: com.zooz.docapp' \
      -H 'private-key: bede7ee5-eaad-4c8a-bc1f-617ba28257ae' \
      -H 'idempotency-key: cust-34532-trans-001356-p' \
      -d '{
         "customer_reference": "johntravolta18021954",
         "email": "john@travolta.com"
      }'    
  

Step 2: Store the Token in the Customer Object

From the response body of the Create Customer API, grab the customer id. Now invoke the Create Payment Method API request to store the token in the customer object. In the request URL, pass the customer id (the first parameter), together with the card’s token (the second parameter).

   var request = new XMLHttpRequest();
   request.open('POST', 'https://api.paymentsos.com/customers/{customer_id}/payment-methods/{token}');
   request.setRequestHeader('Content-Type', 'application/json');
   request.setRequestHeader('api-version', '1.3.0');
   request.setRequestHeader('x-payments-os-env', 'test');
   request.setRequestHeader('app-id', 'com.zooz.docapp');
   request.setRequestHeader('private-key', 'bede7ee5-eaad-4c8a-bc1f-617ba28257ae');
   request.setRequestHeader('idempotency-key', 'cust-34532-trans-001356-p');
   request.send();
  
   curl --compressed -X POST \
   https://api.paymentsos.com/customers/{customer_id}/payment-methods/{token} \
   -H 'Content-Type: application/json' \
   -H 'api-version: 1.3.0' \
   -H 'x-payments-os-env: test' \
   -H 'app-id: com.zooz.docapp' \
   -H 'private-key: bede7ee5-eaad-4c8a-bc1f-617ba28257ae' \
   -H 'idempotency-key: cust-34532-trans-001356-p' \    
  

Step 3: Use the Saved Token to Accept a Payment

The next time you want to create an authorization or charge, you’ll now need to fetch the token from the customer object. We’ll illustrate this using the Retrieve Customer API, which requires that you pass in the customer ID.

Let’s create the request:

    var request = new XMLHttpRequest();
    request.open('GET', 'https://api.paymentsos.com/customers/{customer_id}');
    request.setRequestHeader('Content-Type', 'application/json');
    request.setRequestHeader('api-version', '1.3.0');
    request.setRequestHeader('x-payments-os-env', 'test');
    request.setRequestHeader('app-id', 'com.zooz.docapp');
    request.setRequestHeader('private-key', 'bede7ee5-eaad-4c8a-bc1f-617ba28257ae');
    request.setRequestHeader('idempotency-key', 'cust-34532-trans-001356-p');
    request.send();
  
  curl --compressed -X GET \
    https://api.paymentsos.com/customers/{customer_id}/ \
    -H 'Content-Type: application/json' \
    -H 'api-version: 1.3.0' \
    -H 'x-payments-os-env: test' \
    -H 'app-id: com.zooz.docapp' \
    -H 'private-key: bede7ee5-eaad-4c8a-bc1f-617ba28257ae' \
    -H 'idempotency-key: cust-34532-trans-001356-p' \    
  

Now you can grab the token from the response body. Notice that the token is stored as an attribute in the payment_methods array of the response body. If you added multiple payment methods, they will be listed in the response as well (so customers can select their payment method of choice).

Here’s an example response (truncated for brevity):

{
 ...
 "payment_methods": [
   {
    "token": "f504fb05-474b-48c0-a2d0-ea080f2b2535",
     "type": "tokenized",
     "token_type": "credit_card",
     "fingerprint": "df0b5dda-1377-4dcd-87d4-b858c0eed43d",
     "holder_name": "John Mark",
     "expiration_date": "10/2029",
     "last_4_digits": "1111",
     ...
   }
 ]
}

Showing Card Information in a Checkout Page

You can use the response of the Retrieve Customer API request to list a customer’s payment options and show their card information in your checkout page. For security reasons, only part of a user’s card details can be shown.

Collecting the CVV Code

While you can reuse a customer’s saved card information, you may still be required to pass a customer’s CVV code in an authorization or charge request. Since the CVV code is not part of the saved token, you will thus need to collect the CVV code from your customers before you can proceed with the payment flow.

PaymentsOS allows you to securely collect a customer’s CVV code using either a Secure Code Form that you embed in your web page or the Javascript API. For help in creating the form and collecting the CVV code, see Collecting the CVV Code.

Passing a Card on File Indicator

When storing customers' card information for use in authorization, charge or credit requests, or when using this information in subsequent transactions, the major card brands now require that you indicate this in the transaction request. In PaymentsOS, you do this by explicitly informing PaymentsOS that you used a customer’s card on file (COF) to process the transaction.

In the first request, you must indicate that the customer gave consent for using her saved card information. You do this by passing a card_entry_mode indicator with a value of either consent_transaction or recurring_consent_transaction. Here’s an example request body for a Create Authorization request:

...
"cof_transaction_indicators": {
  "card_entry_mode": "consent_transaction",
},
"payment_method": {
    "credit_card_cvv": "123",
    "token": "f78cbf5b-0e23-44e0-be11-2081791d9501",
    "type": "tokenized"
  }

Depending on the provider processing the transaction, the provider_data object returned in the response of the consent transaction may include an ID that you must pass in all subsequent authorization, charge or credit requests. This ID identifies the initial consent transaction.

Here’s a sample provider_data object, in which the ID is returned in the network_transaction_id field. Bear in mind that depending on the provider, this ID may be returned in another field (to see which field returns the ID, refer to the notes in the field overview table of the sample request generated by the Bodybuilder).

{
  "provider_data": {
    ...
    "external_id": "string",
    "documents": [],
    "additional_information": {},
    "network_transaction_id": "1a2bcd3"
  },
}

Step 2: Create all Subsequent Transactions

In all subsequent authorization, charge or credit requests, pass one of the following card_entry_mode values:

  • cof_cardholder_initiated_transaction: The card holder initiated the transaction.
  • cof_merchant_initiated_transaction: You, as the merchant, initiated the transaction.
  • recurring_subsequent_transaction: The transaction is a recurring one.

If the initial consent transaction request returned an ID that identifies the request, then pass this identifier in the cof_consent_transaction_id field.

In the example body below, we pass a card_entry_mode with a value of cof_cardholder_initiated_transaction, to indicate that the transaction was initiated by the card holder:

{
  "cof_transaction_indicators": {
    "card_entry_mode": "cof_cardholder_initiated_transaction", // The card holder initiated the transaction
    "cof_consent_transaction_id": "1a2bcd3" // Pass if returned by the consent transaction request
  },
  "payment_method": {
    "credit_card_cvv": "123",
    "token": "f78cbf5b-0e23-44e0-be11-2081791d9501",
    "type": "tokenized"
  }
}

Updating a Customer’s Card Information

To update a customer’s card information, you need to delete the existing token from the customer object and then add the new token again. To delete the token, invoke the Delete Payment Method API. In the request URL, pass the customer id (the first parameter) and the card’s token (the second parameter).

    var request = new XMLHttpRequest();
    request.open('DELETE', 'https://api.paymentsos.com/customers/{customer_id}/payment-methods/{token}');
    request.setRequestHeader('Content-Type', 'application/json');
    request.setRequestHeader('api-version', '1.3.0');
    request.setRequestHeader('x-payments-os-env', 'test');
    request.setRequestHeader('app-id', 'com.zooz.docapp');
    request.setRequestHeader('private-key', 'bede7ee5-eaad-4c8a-bc1f-617ba28257ae');
    request.setRequestHeader('idempotency-key', 'cust-34532-trans-001356-p');
request.send();
  
  curl -X DELETE \
    https://api.paymentsos.com/customers/{customer_id}/payment-methods/{token} \
    -H 'Content-Type: application/json' \
    -H 'x-payments-os-env: test'
    -H 'api-version: 1.3.0' \
    -H 'app-id: com.zooz.docapp' \
    -H 'idempotency-key: cust-34532-trans-001356-p' \
    -H 'private-key: e1a5dacb-1484-4ee2-adcb-98c96c8c5fdb' \   
  

Deleting a Customer’s Card Information

To delete a customer’s card information, simply delete the token from the customer object by invoking the Delete Payment Method API. In the request URL, pass in the token to delete as the second parameter:

DELETE https://api.paymentsos.com/customers/{customer_id}/payment-methods/{token}

Checking for Identical Card Numbers

There are scenarios in which you may want to check whether a customer’s card number already exists when storing the card’s token. For instance, a customer may need to update her account with new card information if her old card expired, in which case you can prompt your customer to remove the expired card details from her account rather than keeping both cards on file. You can also check for potentially fraudulent behavior when a customer adds her card details, by identifying whether another customer account already has an identical card number registered.

To check whether two cards are identical, you can use that card’s fingerprint. The fingerprint is a value that uniquely identifies a particular card number. Here’s an example of a fingerprint returned in the response data of the Create Payment Method API:

{
    "type": "tokenized",
    "token": "b7094f8f-03cf-4bb7-86e6-08b6aa5030e7",
    "token_type": "credit_card",
    "fingerprint": "df0b5dda-1377-4dcd-87d4-b858c0eed43d",
    ...
}

After storing a customer’s card information, you can always fetch a card’s fingerprint by retrieving a customer’s information using either the Retrieve Customer API or the Retrieve Customer by Reference API. Retrieving a customer’s payment methods using the Retrieve all Payment Methods API or the Retrieve a Payment Method API, will return the fingerprint as well.


Topics in this Section

Collecting the CVV Code

While you can reuse a customer’s saved card information, you may still be required to pass a customer’s CVV code in an authorization or charge request. Since the CVV code is not part of the saved token, you will thus need to collect the CVV code from your customers before you can proceed with the payment flow.servers.

Last modified May 30, 2022