Learn about the Square Java SDK features.
The import
statement allows you to use types defined in a namespace without specifying the fully qualified namespace of that type. You can add the following import
statements to import all the types from the Square namespace:
...
import com.squareup.square.*;
import com.squareup.square.api.*;
import com.squareup.square.exceptions.*;
import com.squareup.square.models.*;
import com.squareup.square.models.Error;
...
To use the Square API, instantiate a SquareClient
object and initialize it with the appropriate environment and corresponding access token, as shown:
For testing, Square provides a Sandbox environment.
... SquareClient client = new SquareClient.Builder() .bearerAuthCredentials(new BearerAuthModel.Builder(prop.getProperty("SQUARE_ACCESS_TOKEN")).build()) .environment(Environment.SANDBOX) .build(); ...To access production resources, set the environment to
PRODUCTION
.... SquareClient client = new SquareClient.Builder() .bearerAuthCredentials(new BearerAuthModel.Builder(prop.getProperty("SQUARE_ACCESS_TOKEN")).build()) .environment(Environment.PRODUCTION) .build(); ...To set a custom environment, provide a
CustomUrl
and set the environment toCUSTOM
.... SquareClient client = new SquareClient.Builder() .bearerAuthCredentials(new BearerAuthModel.Builder(prop.getProperty("SQUARE_ACCESS_TOKEN")).build()) .environment(Environment.CUSTOM) .customUrl("https://your.customdomain.com") .build(); ...
Each Square API request must be authenticated. Don't hardcode credentials (access tokens) in your code. The Quickstart exercise uses a configuration file in the project to store credentials. Your code can then read the credentials, as shown in the following code fragment:
...
InputStream inputStream =
App.class.getResourceAsStream("/config.properties");
Properties prop = new Properties();
try {
prop.load(inputStream);
} catch (IOException e) {
System.out.println("Error reading properties file");
e.printStackTrace();
}
SquareClient client = new SquareClient.Builder()
.bearerAuthCredentials(new BearerAuthModel.Builder(prop.getProperty("SQUARE_ACCESS_TOKEN")).build())
.environment(Environment.SANDBOX)
.build();
...
The configuration file (config.properties
) looks like the following:
SQUARE_ACCESS_TOKEN=EAAAEDPi8Zc2-Lb1vrUFb0S6Artq73vd27q9rWVIrS-pMWceYcY28hsCIEXAMPLE
Note
If you plan to upload your project to GitHub, don't upload this file with credentials. You might consider using a .gitignore file to prevent the configuration file from being uploaded to GitHub.
The Square Java SDK uses the CompletableFuture
framework for its asynchronous implementation. Each asynchronous API call returns a CompletableFuture
object, and you can orchestrate and combine them into a pipeline that returns a single result. For more information, see CompletableFuture.
The following example shows how to make an asynchronous call:
package com.square.examples;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import com.squareup.square.*;
import com.squareup.square.api.*;
import com.squareup.square.exceptions.*;
import com.squareup.square.models.*;
import com.squareup.square.models.Error;
public class App {
public static void main(String[] args) {
InputStream inputStream = App.class.getResourceAsStream("/config.properties");
Properties prop = new Properties();
try {
prop.load(inputStream);
} catch (IOException e) {
System.out.println("Error reading properties file");
e.printStackTrace();
}
SquareClient client = new SquareClient.Builder()
.bearerAuthCredentials(new BearerAuthModel.Builder(prop.getProperty("SQUARE_ACCESS_TOKEN")).build())
.environment(Environment.SANDBOX)
.build();
LocationsApi locationsApi = client.getLocationsApi();
locationsApi.listLocationsAsync()
.thenAccept(result -> {
for (Location l : result.getLocations()) {
System.out.printf(
"%s: %s, %s, %s\n",
l.getId(),
l.getName(),
l.getAddress().getAddressLine1(),
l.getAddress().getLocality());
}
})
.exceptionally(exception -> {
try {
throw exception.getCause();
} catch (ApiException ae) {
for (Error err : ae.getErrors()) {
System.out.println(err.getCategory());
System.out.println(err.getCode());
System.out.println(err.getDetail());
}
} catch (Throwable t) {
t.printStackTrace();
}
return null;
})
.join();
SquareClient.shutdown();
}
}
Note the following about this code:
- The
thenAccept
method defines actions to take if the operation is successful. - The
exceptionally
method defines actions to take if the operation returns an error. - The
join
method waits for the operation to complete and then returns control to the main program.
After you make the last async call in a program, use the Square client shutdown
method before the program exits.
SquareClient.shutdown();
Otherwise, the program stops responding for approximately 60 seconds until the async threads time out.
In the com.squareup.square.models
namespace, every object is a model. For example, complex types Address
, Customer
, and Order
are all models defined in the namespace. You pass these models, with values, as parameters as shown in the following example. The example passes the Address
model as a parameter to create a new customer.
...
import java.util.UUID;
...
CustomersApi customersApi = client.getCustomersApi();
Address address = new Address.Builder()
.addressLine1("1455 Market St")
.addressLine2("San Francisco, CA 94103")
.build();
CreateCustomerRequest body = new CreateCustomerRequest.Builder()
.givenName("John")
.familyName("Doe")
.address(address)
.idempotencyKey(UUID.randomUUID().toString())
.build();
customersApi.createCustomerAsync(body)
.thenAccept(result -> {
System.out.printf("customer created:\n Given name = %s Family name = %s",
result.getCustomer().getGivenName(),
result.getCustomer().getFamilyName());
})
.exceptionally(exception -> {
// Your error-handling code here
return null;
})
.join();
...
The Square API endpoints can have path parameters, query parameters, and a request body. When you make corresponding method calls using the Square Java SDK, you provide the values as follows:
Request body - For example,
createCustomer
andupdateCustomer
require aCustomer
object in the body. In the Square Java SDK, you use the builder pattern to specify the request body.... import java.util.UUID; ... CustomersApi customersApi = client.getCustomersApi(); Address address = new Address.Builder() .addressLine1("1455 Market St") .addressLine2("San Francisco, CA 94103") .build(); CreateCustomerRequest body = new CreateCustomerRequest.Builder() .givenName("Mary") .familyName("Smith") .address(address) .idempotencyKey(UUID.randomUUID().toString()) .build(); customersApi.createCustomerAsync(body) .thenAccept(result -> { System.out.println("customer created:"); System.out.printf("Given name = %s Family name = %s", result.getCustomer().getGivenName(), result.getCustomer().getFamilyName()); }) .exceptionally(exception -> { // Your error-handling code here return null; }) .join(); ...Path and query parameters - For example:
- The RetrieveCustomer endpoint has a
customer_id
path parameter (GET /v2/customers/{customer_id}
). - The ListCustomers endpoint has several query parameters such as
cursor
andlimit
.
You provide these as parameters to the method calls. The following example passes the
customer_id
path parameter as a parameter to theupdateCustomerAsync
method.... CustomersApi customersApi = client.getCustomersApi(); UpdateCustomerRequest body = new UpdateCustomerRequest.Builder() .givenName("Fred") .familyName("Jones") .version(0L) .build(); customersApi.updateCustomerAsync("GZ48C4P2CWVXV7F7K2ZH795RSG", body) .thenAccept(result -> { Customer customer = result.getCustomer(); System.out.printf( "customer updated:\n " + "Id: %s, Version:%s Given name:%s, Family name: %s", customer.getId(), customer.getVersion(), customer.getGivenName(), customer.getFamilyName()); }) .exceptionally(exception -> { // Your error-handling code here return null; }) .join(); ...For an example of query parameters, see Pagination.
- The RetrieveCustomer endpoint has a
You can configure the number of retries and the timeout values for HTTP requests when using the Square Java SDK:
Retries - By default, the Square SDK doesn't retry a failed request. When your application starts, the Square SDK sets the number of retries to 0. You have the option to configure a different value when you create a client. Retries can help improve application stability by allowing applications to handle momentary failures in connecting to a service by transparently retrying a failed request.
Timeout - Timeout is the time period that a client waits for a server response. The Square SDK sets the default timeout to 60 seconds. On timeout, the SDK throws an exception. You have the option to configure a timeout value at the client level.
The following code creates a client, setting the number of retries to 2 and the timeout to 60 seconds.
...
Consumer<HttpClientConfiguration.Builder> clientConfig = cfg -> {
cfg.numberOfRetries(2);
cfg.timeout(60);
cfg.build();
};
SquareClient client = new SquareClient.Builder()
.environment(Environment.SANDBOX)
.accessToken(prop.getProperty("SQUARE_ACCESS_TOKEN"))
.httpClientConfig(clientConfig)
.build();
...
Configuring a client with long timeout values and a high number of retries can cause some SDK operations to appear unresponsive. There are several considerations that apply when configuring the timeout and retries. These include:
- For network issues (decrease in network connectivity and response speed), how should the application respond? Do you want the call to fail fast, or do you want the application to retry the failed call?
- Buyer-facing applications might need to be responsive compared to a background job that can tolerate increased latency due increased timeout values and retries.
The response object contains the HttpContext
that describes both the request and the response:
- If an API call succeeds, a response object containing
HttpContext
is returned. ThisHttpContext
describes both the request and the response. - If an API call fails, you get an
ApiException
(see ApiException class).
...
locationsApi.listLocationsAsync()
.thenAccept(result -> {
System.out.println("Successfully called List Locations");
System.out.println("Request:\n" + result.getContext().getRequest();
System.out.println("Response:\n" + result.getContext().getResponse());
})
.exceptionally(exception -> {
System.out.println("Failed to make the request");
try {
throw exception.getCause();
} catch (ApiException ae) {
System.out.println("ApiException occurred");
for (Error err : ae.getErrors()) {
System.out.println(err.getCategory());
System.out.println(err.getCode());
System.out.println(err.getDetail());
}
} catch (Throwable t) {
System.out.println("Other exception occurred");
t.printStackTrace();
}
return null;
})
.join();
...
For more information, see Square API errors.