Menu Apps
Manage Apps

Processing Recurring Payments via Card on File

Version 2 of the Connect API provides the ability for a business to save information related to their e-commerce customers. This information falls into two primary categories: contact information and cards on file. In order to process recurring payments via the Connect API, you will need to use the CreateCustomer and CreateCustomerCard endpoints.

This document includes code samples inline with the text. At the end of the article, all of the code is placed together in one block so that it's more convenient to copy and paste. In this block, the only variables to replace values of are access_token and card_nonce.

Installing the square_connect gem

You install the square_connect gem the same way you install any other gem:

gem install square_connect

Retrieving your location IDs

Every Square merchant's business consists of one or more locations as described here. Every payment a merchant processes is associated with one of these locations (even online payments). In order to process a payment with Connect v2, you need to specify which location is taking the payment.

Each location has a set of capabilities. In order to process credit cards, you want a location with CREDIT_CARD_PROCESSING enabled.

The square_connect library has an easy method for obtaining a business' location IDs: the list_locations method.

require 'square_connect'

access_token = 'REPLACE_WITH_YOUR_ACCESS_TOKEN'

begin
  locations_response = location_api.list_locations(access_token)
  puts locations_response
rescue SquareConnect::ApiError => e
  puts 'Error encountered while listing locations:'
  puts e.message
end

location = locations_response.locations.detect do |l|
  l.capabilities.include?("CREDIT_CARD_PROCESSING")
end
if location.nil?
  puts "You need to activate your account for credit card processing"
else
  puts location
end

Creating a Customer

You can save a new customer for a business with the CreateCustomer endpoint. A valid Customer object must have at least one of the following:

  • Name (first and/or last)
  • Email address
  • Phone number
  • Company name

You can also save the following optional information:

  • Physical address
  • An informational note about the customer
  • A reference ID to associate the customer with an entity in your own system
require 'square_connect'
require 'securerandom'

access_token = 'REPLACE_WITH_YOUR_ACCESS_TOKEN'
customer_api = SquareConnect::CustomerApi.new
reference_id = SecureRandom.uuid

customer_request = {
  given_name: 'Amelia',
  family_name: 'Earhart',
  email_address: 'Amelia.Earhart@example.com',
  address: {
    address_line_1: '500 Electric Ave',
    address_line_2: 'Suite 600',
    locality: 'New York',
    administrative_district_level_1: 'NY',
    postal_code: '10003',
    country: 'US'
  },
  phone_number: '1-555-555-0122',
  reference_id: reference_id,
  note: 'a customer'
}

begin
  customer_response = customer_api.create_customer(access_token, customer_request)
  puts 'Customer ID to use with CreateCustomerCard:'
  puts customer_response
rescue SquareConnect::ApiError => e
  puts 'Error encountered while creating customer:'
  puts e.message
end

customer = customer_response.customer

Creating a CustomerCard

Once you have created a customer, you need a card nonce to create the customer card and add it as a card on file. Use the SqPaymentForm to generate a card nonce and provide that card nonce to the CreateCustomerCard endpoint.

require 'square_connect'

access_token = 'REPLACE_WITH_YOUR_ACCESS_TOKEN'

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
  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
  puts 'Error encountered while creating customer card:'
  puts e.message
end

customer_card = customer_card_response.customer_card

Charging the CustomerCard

Now that you've generated a card nonce with the SqPaymentForm and you have a way to retrieve a business' location IDs, you can charge a customer's card on file. You charge a card on file like so:

require 'square_connect'
require 'securerandom'

# Assume you have correct values assigned to the following variables:
#   location
#   customer
#   customer_card
# See the above code samples for how to obtain them.

access_token = 'REPLACE_WITH_YOUR_ACCESS_TOKEN'

transaction_api = SquareConnect::TransactionApi.new

# Every payment you process for a given business hae a unique idempotency key.
# If you're unsure whether a particular payment succeeded, you can reattempt
# it with the same idempotency key without worrying about double charging
# the buyer.

idempotency_key = SecureRandom.uuid


# Monetary amounts are specified in the smallest unit of the applicable currency.
# This amount is in cents. It's also hard-coded for $1, which is not very useful.

amount_money = { :amount => 100, :currency => 'USD' }

transaction_request = {
  :customer_id => customer.id,
  :customer_card_id => customer_card.id,
  :amount_money => amount_money,
  :idempotency_key => idempotency_key
}

# The SDK throws an exception if a Connect endpoint responds with anything besides 200 (success).
# This block catches any exceptions that occur from the request.
begin
  transaction_response = transaction_api.charge(access_token, location.id, transaction_request)
rescue SquareConnect::ApiError => e
  puts 'Error encountered while charging card:'
  puts e.message
end
puts transaction_response

The value of transaction_response is a hash that contains all of the details of the processed transaction.

Trying it out

A full sample that uses the SqPaymentForm and the Unirest Python library is available on Github. See the sample's README for information on running the sample. There are also code samples for interacting with the API available in other languages.

If you want to test out charging cards without actually moving any money, you can configure the sample to communicate with Connect v2 sandbox endpoints. For more information, see Using the API sandbox.

Full code

Below you can find all the code samples above in one copy and paste snippet, so that the only variables you need to replace are the access_token and the card_nonce.

require 'square_connect'
require 'securerandom'

access_token = 'REPLACE_WITH_YOUR_ACCESS_TOKEN'
card_nonce = 'CARD_NONCE_FROM_PAYMENT_FORM'

location_api = SquareConnect::LocationApi.new
begin
  locations_response = location_api.list_locations(access_token)
  puts locations_response
rescue SquareConnect::ApiError => e
  puts 'Error encountered while listing locations:'
  puts e.message
end

location = locations_response.locations.detect do |l|
  l.capabilities.include?("CREDIT_CARD_PROCESSING")
end

customer_api = SquareConnect::CustomerApi.new
reference_id = SecureRandom.uuid

customer_request = {
  given_name: 'Amelia',
  family_name: 'Earhart',
  email_address: 'Amelia.Earhart@example.com',
  address: {
    address_line_1: '500 Electric Ave',
    address_line_2: 'Suite 600',
    locality: 'New York',
    administrative_district_level_1: 'NY',
    postal_code: '10003',
    country: 'US'
  },
  phone_number: '1-555-555-0122',
  reference_id: reference_id,
  note: 'a customer'
}

begin
  customer_response = customer_api.create_customer(access_token, customer_request)
  puts 'Customer ID to use with CreateCustomerCard:'
  puts customer_response.customer.id
rescue SquareConnect::ApiError => e
  puts 'Error encountered while creating customer:'
  puts e.message
end

customer = customer_response.customer

customer_card_api = SquareConnect::CustomerCardApi.new
customer_card_request = {
  card_nonce: card_nonce,
  billing_address: customer.address.to_hash,
  cardholder_name: 'Amelia Earhart'
}

begin
  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
  puts 'Error encountered while creating customer card:'
  puts e.message
end

customer_card = customer_card_response.customer_card

transaction_api = SquareConnect::TransactionApi.new
idempotency_key = SecureRandom.uuid
amount_money = { :amount => 100, :currency => 'USD' }

transaction_request = {
  :customer_id => customer.id,
  :customer_card_id => customer_card.id,
  :amount_money => amount_money,
  :idempotency_key => idempotency_key
}

begin
  transaction_response = transaction_api.charge(access_token, location.id, transaciton_request)
rescue SquareConnect::ApiError => e
  puts 'Error encountered while charging card:'
  puts e.message
end

puts transaction_response

Was this page helpful?