Take Payments

Transactions API Setup

Integrate with the Transactions API to process online payments and link payments with itemized orders and customer profiles.

This document provides guidance for taking online payments with Square's Transactions API.

Server Side
Languages Supported
Additional Resources

Prerequisites

To use the Transactions API, the following must be true:

  • You have a Square account. create a Square account in minutes if you don't already have one.
  • Your eCommerce site sells products/services in line with Square's Terms of Service.
  • Your eCommerce pages are hosted on systems that support dynamic pages with server-side processing (e.g., PHP, Ruby, ASP, Java pages). Hosting solutions that only support HTML pages cannot use the Transactions API.
  • You have embedded Square's secure payment form and configured it to POST the nonce to your payment processing page OR you have previously stored customer card information using the Customers API and will use it to process a card on file.

If you plan to use the Transactions API to accept online payments on your own eCommerce site and have not enabled payment processing on your account (or you're not sure), activate your account before continuing.

Assumptions

This guide makes the following assumptions:

  • You have read the Transactions API Overview. This is a how-to guide and does not cover general functionality of the API.
  • You can create and run websites on localhost or a development server.
  • You are familiar with HTTP and JSON. If you are new to JSON , we recommend reading the JSON Getting Started Guide on Codular before continuing.

Process overview

Processing online payments with the Transactions API generally includes the following steps:

  1. Get your authorization ID
  2. Get your location ID
  3. Build a transaction request and call Charge
  4. Optional: Split transactions with additional recipients
  5. Optional: Link a Square Order object ID
  6. Optional: Link a Customer ID

Working example

In order to provide concrete instruction, this guide is based on a hypothetical site with the following characteristics:

  • The Transactions API is being used as a single merchant solution. In other words, the merchant site and the Square account used to process payments are associated with the same person and the site will use a Personal Access Token for authorization.
  • The merchant site uses PHP version 5.4 or later. PHP was selected for the example code because it is a common web language and relatively approachable for new developers, but the Transactions API is language agnostic and the setup steps are comparable across languages.
  • The merchant site has installed the Square Connect v2 PHP SDK. Installing the SDK is optional. As long as you can package and receive JSON messages you can use Square's APIs, but installing the SDK makes things easier.
  • The merchant site supports HTTPS. You can get a HTTPS certificate from your hosting provider or for free from the nonprofit Let's Encrypt. If this is your first time working with HTTPS you may want to read the How it Works page of the Let's Encrypt site before continuing.

If your situation is different from the working example outlined here, you should still be able to follow along with the steps in this guide. The example code has been written to avoid PHP-specific functionality as much as possible, but you may need to make slight changes in how you handle authorization (e.g., OAuth) or create your JSON messages.

Step 1: Get your authorization ID

You cannot use the Transactions API endpoints without authorizing access to your Square account.

We recommend using sandbox ID and locations for testing and development. To get your sandbox ID:

  1. Open your Application Dashboard.
  2. If you DO have an application you want to use for accepting online payments, click on the application.
  3. If you DO NOT have an application you want to use for accepting online payments, click New Application, enter a name for your application (e.g., "My Online Store") and click Create Application.
  4. Copy the Sandbox Access Token on the Credentials tab of the application control panel.

Instead of a sandbox or personal access token, you can also use OAuth and the PAYMENTS_WRITE permission. OAuth is the preferred method because it provides better security for the targeted merchant account, but sandbox tokens and personal access tokens are appropriate for testing and development.

Step 2: Get your location ID

All transactions processed with the Transactions API must be credited to a valid location ID for the associated Square account. Use the Locations API find your location ID:

1. Initialize the API object.

// Include the Square Connect API resources
require_once '/local/path/to/sdk/SquareConnect/autoload.php';

$authzToken = "MY_SANDBOX_TOKEN"; // put your sandbox token here
$locationId = "";                 // we'll set this programmatically

// Create and configure a new API client object
$defaultApiConfig = new \SquareConnect\Configuration();
$defaultApiConfig->setAccessToken($authzToken);
$defaultApiClient = new \SquareConnect\ApiClient($defaultApiConfig) ;

// Create a LocationsApi client to load the location ID
$locationsApi = new SquareConnect\Api\LocationsApi($defaultApiClient);

2. Call ListLocations and save the first viable location ID. Only locations configured for credit card processing can accept online payments.

try {

 $apiResponse = $locationsApi->listLocations();

  foreach ($apiResponse->getLocations() as $location) {
    if (in_array('CREDIT_CARD_PROCESSING', $location->getCapabilities())) {
      $locationId = $location->getId();
    }
  }
  if ($locationId == null) {
    print("[ERROR] LOCATION ID NOT SET");
    throw new RuntimeException('No location ID found');
  }
} catch (\SquareConnect\ApiException $e) {
  // Display the exception details and forward the exception
  echo "The SquareConnect\Api\LocationApi object threw an exception.<br>" .
       "API call: LocationApi->listLocations" .
       "<pre>" . var_dump($e) . "</pre>";
  throw $e;
}

Note: If you only have one location, you can simply grab the first object in the list returned by ListLocations. If you have more than one location, you can modify the for loop to check the location names for your account in the Square Dashboard and select the correct location by name. For example:

$locationName = "MY_LOCATION_NAME";

$apiResponse = $locationsApi->listLocations();

foreach ($apiResponse->getLocations() as $location) {
  if ($locationName == $location->getName()) {
    $locationId = $location->getId();
    if (!in_array('CREDIT_CARD_PROCESSING', $location->getCapabilities())) {
      print(
        "[ERROR] LOCATION $locationName INVALID: ".
        "Location cannot process online payments."
      );
      throw new RuntimeException('Location cannot process online payments')
    }
  }
}

Step 3: Build a transaction request and call Charge

The Transactions API accepts two types of encrypted payment tokens: unique nonces generated with Square's SqPaymentForm object and customer card IDs created with the Customers API for card on file payments.

1. Build the buyer information.

$buyerInfo = array();
$buyerInfo['buyer_email_address'] = "thebuyer@example.com";
$buyerInfo['shipping_address'] = array(
  'address_line_1' => "123 Main St",
  'locality' => "San Francisco",
  'administrative_district_level_1' => "CA",
  'postal_code' => "94114",
  'country' => "US"
);
$buyerInfo['billing_address'] = array(
  'address_line_1' => "500 Electric Ave",
  'address_line_2' => "Suite 600",
  'administrative_district_level_1' => "NY",
  'locality' => "New York",
  'postal_code' => "20003",
  'country' => "US"
);

2. Configure payment information using one of Square's test nonces.

// This is a sandbox nonce; replace this with a nonce generated by SqPaymentForm
$cardNonce = "fake-card-nonce-ok";

$idempotencyKey = uniqid();

$paymentInfo = array();
$paymentInfo['idempotency_key'] = $idempotencyKey;
$paymentInfo['amount_money'] = array('amount' => 1000, 'currency' => "USD");
$paymentInfo['card_nonce'] = $cardNonce;

OR

If you have already called the Customers API to load customer information and want to process a card on file:

$idempotencyKey = uniqid();

$paymentInfo = array();
$paymentInfo['idempotency_key'] = $idempotencyKey;
$paymentInfo['amount_money'] = array('amount' => 1000, 'currency' => "USD");
$paymentInfo['customer_id'] = $customerIdFromCustomersAPI;
$paymentInfo['customer_card_id'] = $customerCardIdFromCustomersAPI;

Note: when processing payments with a card on file, both customer_id and customer_card_id are required fields.

3. Configure any external reference information.

$referenceInfo = array();
$referenceInfo['reference_id'] = 'Confirmation #12345';
$referenceInfo['note'] = 'A useful note about this transaction';

4. Build the transaction request object and call the Charge endpoint.

$txRequest = array_merge(
  $buyerInfo,
  $paymentInfo,
  $referenceInfo
);

$transactionsApi = new \SquareConnect\Api\TransactionsApi($defaultApiClient);

try {

  $apiResponse = $transactionsApi->charge($locationId, $txRequest);

  // For now, just print the result to the screen
  echo "<pre>" . print_r($apiResponse, true) . "</pre>";

} catch (\SquareConnect\ApiException $e) {
  echo "<hr>" .
       "The SquareConnect\Api\TransactionsApi object threw an exception.<br>" .
       "API call: <code>TransactionsApi->charge</code>" .
       "<pre>" . var_dump($e) . "</pre>";
  throw $e;
}

 

Optional: Split transactions with additional recipients

The Charge endpoint supports multi-party transactions through the additional_recipients field. Additional recipients are defined with a Money object, a location ID, and a description to explain the purpose of the distribution. While the additional_recipients block is considered an optional parameter for transaction, if it is included, ALL of the additional_recipients child elements are required.

To configure a multi-party transaction, add the additional_recipients field to your transaction request before calling the Charge endpoint. For example:

// Configure the additional recipients
$recipientInfo = array();
$recipientInfo['additional_recipients'] = array() ;
$recipientInfo['additional_recipients'][] = array(
  'location_id' => $recipientLocation,
  'description' => "Charity donation: CA wildfire recovery",
  'amount_money' => array('amount' => 200, 'currency' => "USD")
);

...

$txRequest = array_merge(
  $buyerInfo,
  $paymentInfo,
  $referenceInfo,
  $recipientInfo
);

You will need to use OAuth and have PAYMENTS_WRITE_ADDITIONAL_RECIPIENTS permission for the accounts associated with the location IDs to split the payment. If you are using a personal access token or lack the necessary OAuth permissions on any of the additional recipient accounts, the transaction is declined and Charge returns an error.

To reference an Customer object in a transaction, set the customer_id field on your transaction request to a valid customer ID returned by the Customers API RetrieveCustomer endpoint. For example:

// Link an order ID
$txRequest['customer_id'] = "CUSTOMER_ID_RETURNED_BY_RETRIEVECUSTOMER";

Linking a Customer ID and transaction provides reporting and analytic benefits in the Square Dashboard.

For more information on working with Customers, see the Customers API Overview.

Handling delayed capture transactions

By default, the Charge endpoint charges a card as soon as it is successfully processed. If you prefer, you can delay capture of transactions so that the buyer's credit card is authorized but not charged. You have up to six days after the authorization to either capture the funds or void (i.e., cancel) the transaction. After six days, any transaction that has not been captured is voided automatically.

To initiate a delayed capture transaction, set the delay_capture field to true. For example:

$txRequest['delay_capture'] = true;

The Tender object returned with the Transaction will have a status of AUTHORIZED instead of CAPTURED. You will need to save the transaction ID to capture or void it later!

To capture the transaction, call the CaptureTransaction endpoint with the saved transaction ID:

$transactionsApi = new \SquareConnect\Api\TransactionsApi($defaultApiClient);

try {
  $apiResponse = $transactionsApi->captureTransaction($locationId, $transactionId);
} catch (\SquareConnect\ApiException $e) {
  ...
}

To void the transaction, call the VoidTransaction endpoint with the saved transaction ID:

$transactionsApi = new \SquareConnect\Api\TransactionsApi($defaultApiClient);

try {
  $apiResponse = $transactionsApi->voidTransaction($locationId, $transactionId);
} catch (\SquareConnect\ApiException $e) {
  ...
}

In both cases, the endpoint responds with an empty JavaScript object, {}, on success. To view the finalized transaction, use the RetrieveTransaction endpoint with the saved transaction ID. For example:

$transactionsApi = new \SquareConnect\Api\TransactionsApi($defaultApiClient);

try {
  $apiResponse = $transactionsApi->retreieveTransaction($locationId, $transactionId);
} catch (\SquareConnect\ApiException $e) {
  ...
}

Handling Refunds

Refunds are processed based on the Tender IDs for the Transaction object returned by Charge. Refunds can be issued for a portion, or all, of the original Tender amount. Transactions may have multiple refunds associated with them if they were for partial amounts or different tenders.

To process a refund, load the existing transaction by calling ListTransactions and searching the list for the right Transaction objects based on the external reference ID set during the call to Charge. For example:

$transactionsApi = new \SquareConnect\Api\TransactionsApi($defaultApiClient);

try {

  $apiResponse = $transactionsApi->listTransactions($locationId);
  foreach ($apiResponse->getTransactions() as $transaction) {

    // We will call createRefund for each element of this array.
    $tenders = [];

    if ($transaction->getReferenceId() == $refIdIWant) {
      for ($transaction->getTenders() as $tender) {
        $tenders[] = array(
          'id' => $tender->getId(),
          'amount_money' => $tender->getAmountMoney()
        );
      }
      $transactionId = $transaction->getId();
    }
  }
} catch (\SquareConnect\ApiException $e) {
  ...
}

Or, if you already know the transaction ID, you can call the RetreiveTransactions endpoint and load the details specifically for that transaction. For example:

$transactionsApi = new \SquareConnect\Api\TransactionsApi($defaultApiClient);

try {

  $apiResponse = $transactionsApi->retreieveTransaction($locationId, $transactionId);

  // We will call createRefund for each element of this array.
  $tenders = [];

  for ($apiResponse->getTransaction()->getTenders() as $tender) {
    $tenders[] = array(
      'id' => $tender->getId(),
      'amount_money' => $tender->getAmountMoney()
    );
  }
} catch (\SquareConnect\ApiException $e) {
  ...
}

Once you have the transaction ID and the list of associated Tender IDs, call CreateRefund to process the refund. As with the original Charge, issuing refunds requires an idempotency key. For example:

$transactionsApi = new \SquareConnect\Api\TransactionsApi($defaultApiClient);

try {

  foreach($tenders as $tender) {

    $refund = array(
      'idempotency_key' => uniqid(),
      'tender_id' => $tender['id'],
      'amount_money' => $tender['amount_money'],
      'reason' => "Cosmetic damage found on delivery, item not returned"
    );

    $apiResponse = $transactionsApi->createRefund($locationId, $transactionId, $refund);
  }

} catch (\SquareConnect\ApiException $e) {
  ...
}

Note: Transactions processed through Square's APIs will only ever have a single Tender object, but transactions processed with a Square reader may have multiple Tender objects.

Prev
< Transactions API Overview

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