Code Cookbook

Save Cards on File

Save cards on file with Reader SDK to create a seamless purchase experience for returning customers and enable recurring payments.

Reader SDK
Customers API
Transactions API
Java (Android)
Android
iOS
Save

Before you start

  • You will need an access token. If you are using OAuth, you will need CUSTOMERS_WRITE permission to save a card on file and PAYMENTS_WRITE permission to process payments with the saved card.
  • You need to have created a Customer object using the Customers API. You can follow The Customers API Setup Guide to create your first Customer object.
  • You need to have installed Reader SDK and configured your Android project.
  • You will need an access token. If you are using OAuth, you will need CUSTOMERS_WRITE permission to save a card on file and PAYMENTS_WRITE permission to process payments with the saved card.
  • You need to have created a Customer object using the Customers API. You can follow The Customers API Setup Guide to create your first Customer object.
  • You need to have installed Reader SDK and configured your iOS project.
  • You will need an access token. If you are using OAuth, you will need CUSTOMERS_WRITE permission to save a card on file and PAYMENTS_WRITE permission to process payments with the saved card.
  • You need to have created a Customer object using the Customers API. You can follow The Customers API Setup Guide to create your first Customer object.

Step 1: Collect the card information

Use the Reader SDK card on file workflow to create a customer card for an existing Customer object. The card on file workflow is a sequence of screens used by the customer to specify that they wish to save their card information for future purchases.

Use the Reader SDK card on file workflow to create a customer card for an existing Customer object. The card on file workflow is a sequence of screens used by the customer to specify that they wish to save their card information for future purchases.

Step 1.1: Create a customer card manager

The customer card manager lets you collect and store card information securely. Use the CustomerCardManager class to create a new information manager:

import com.squareup.sdk.reader.ReaderSdk;
import com.squareup.sdk.reader.crm.CustomerCardManager;

CustomerCardManager customerCardManager =
    ReaderSdk.customerCardManager();

Step 1.2: Write a callback to handle the result

Customer card information is stored on Square servers, not on the device running Reader SDK, so you need to implement a callback to handle the response from Square:

import com.squareup.sdk.reader.core.CallbackReference;

CallbackReference storeCardCallbackRef = customerCardManager.addStoreCardActivityCallback(result -> {
 hideLoadingIndicatorOnYourActivity();
 if (result.isSuccess()) {
   showStoreCardSuccessDialog(result.getSuccessValue());
 } else {
   showErrorDialog(result.getError());
 }
});

Implement the StoreCustomerCardControllerDelegate methods:

import SquareReaderSDK

extension <#YourViewController#>: SQRDStoreCustomerCardControllerDelegate {

    func storeCustomerCardController(_ storeCustomerCardController: SQRDStoreCustomerCardController, didFailWith error: Error) {
        hideLoadingView()

        // Show error message to user
    }

    func storeCustomerCardController(_ storeCustomerCardController: SQRDStoreCustomerCardController, didFinishWith card: SQRDCard) {
        hideLoadingView()

        // Indicate to user that card was linked
    }

    func storeCustomerCardControllerDidCancel(_ storeCustomerCardController: SQRDStoreCustomerCardController) {
        hideLoadingView()

        // Return to previous UI state
    }
}

Follow the steps in the Payment Form build guide or In-App Payments SDK to generate a valid card nonce.

Step 2: Save the customer card on file

Use the customer card manager to start the StoreCard activity and link the card to an existing customer ID:

showLoadingIndicatorOnYourActivity();
customerCardManager.startStoreCardActivity(activity, customerId));

Use the Customers API to send the card nonce and the customer ID to the CreateCustomerCard endpoint. It will return a customer card ID in the response field (customer_card_id).

$cardNonce = "{NONCE_FROM_STEP_1}";
$customerId = "{YOUR_CUSTOMER_ID}";  // Replace with an existing customer_id

// Create a CustomerCard request object
$body = new \SquareConnect\Model\CreateCustomerCardRequest();

// Set the card nonce value for your request object.
$body->setCardNonce($cardNonce);

// Send the request to the CreateCustomerCard endpoint

try {
  $result = $customersApi->createCustomerCard($customerId, $body);
  print_r($result);
} catch (Exception $e) {
  echo 'Error when calling createCustomerCard: ', $e->getMessage(), PHP_EOL;
}

Use the Customers API to send the card nonce and the customer ID to the CreateCustomerCard endpoint. It will return a customer card in the response field (customer_card).

access_token = '{A VALID SQUARE ACCESS TOKEN}'
card_nonce = '{NONCE_FROM_STEP_1}'
customer_id = '{YOUR_CUSTOMER_ID}'

# Create a CustomerCard request object
customer_card_api = SquareConnect::CustomerCardApi.new
customer_card_request = {
  card_nonce: card_nonce,
  billing_address: {
    address_line_1: '1455 Market St',
    address_line_2: 'Suite 600',
    locality: 'San Francisco',
    administrative_district_level_1: 'CA',
    postal_code: '94103',
    country: 'US'
  },
  cardholder_name: 'Amelia Earhart'
}

begin
  # Send the request to the CreateCustomerCard endpoint
  customer_card_response = customer_card_api.create_customer_card(
    access_token, customer_id, customer_card_request
  )
  puts 'CustomerCard ID to use with Charge:'
  puts customer_card_response.customer_card.id
rescue SquareConnect::ApiError => e
  raise "Error encountered while creating customer card: #{e.message}"
end

customer_card = customer_card_response.customer_card

Add code to start the store customer card flow:

import SquareReaderSDK

extension <#YourViewController#> {
    func storeCardOnFile() {
        showLoadingView()
        let cardOnFileController = SQRDStoreCustomerCardController(customerID: customerID, delegate: self)
        cardOnFileController.present(from: self)
    }
}

Contact Developer Support, join our Slack channel, or ask for help on Stack Overflow