Version 44.0.0.20250319
of the Java SDK represents a full rewrite of the SDK with a number of breaking changes, outlined in the following sections. When upgrading to this version or later versions, take note of the changes in the SDK, including client construction and parameter names. If necessary, you can use the legacy version of the SDK along with the latest version.
SDK versions 43.1.0.20250220
and earlier continue to function as expected, but you should plan to update your integration as soon as possible to ensure continued support.
The new Client
class has some breaking changes and is constructed in a slightly different way than the legacy version of the SDK.
Legacy | New | Additional information |
---|---|---|
accessToken | token | The access token used for authentication. |
bearerAuthCredentials | Removed | Set using the token or SQUARE_TOKEN environment variable. |
customUrl | url | Sets the base URL for API requests and defaults to https://connect.squareup.com . |
squareVersion | version | The Square API version to use. |
additionalHeaders | Removed | Available through ClientOptions and RequestOptions objects. |
userAgentDetail | Removed | Configurable by setting the OkHttp client directly. |
timeout | timeout | Now takes an int rather than a long . |
httpCallback | Removed | Configurable by setting the OkHttp client directly. |
httpClientConfig | Removed | Configurable by setting the OkHttp client directly. |
new Builder | builder | See the following example. |
// LEGACY
import com.squareup.square.legacy.Environment;
import com.squareup.square.legacy.SquareClient;
SquareClient client = new SquareClient.Builder()
.environment(<YOUR_ENVIRONMENT>) // defaults to Environment.PRODUCTION
.accessToken("YOUR_TOKEN") // defaults to using "SQUARE_ACCESS_TOKEN" environment variable
.build();
// NEW
import com.squareup.square.Environment;
import com.squareup.square.SquareClient;
SquareClient client = SquareClient.builder()
.environment(<YOUR_ENVIRONMENT>) // defaults to Environment.PRODUCTION
.token("YOUR_TOKEN"); // defaults to using "SQUARE_TOKEN" environment variable
.build();
While the new SDK has many improvements, it takes time to upgrade when there are breaking changes. To make the migration easier, the new SDK exports the legacy SDK as com.squareup.square.legacy
. The following example shows how to use the new and legacy SDKs inside a single file:
package com.square.examples;
import com.squareup.square.SquareClient;
import com.squareup.square.core.Environment;
import com.squareup.square.legacy.exceptions.ApiException;
import com.squareup.square.legacy.models.CreateOrderRequest;
import com.squareup.square.legacy.models.CreateOrderResponse;
import com.squareup.square.legacy.models.Order;
import com.squareup.square.types.GetLocationResponse;
import com.squareup.square.types.GetLocationsRequest;
import com.squareup.square.types.Location;
import java.io.IOException;
import java.util.Optional;
import java.util.UUID;
public class SideBySide {
public static void main(String[] args) {
com.squareup.square.legacy.SquareClient legacyClient = new com.squareup.square.legacy.SquareClient.Builder()
.accessToken(System.getenv("SQUARE_TOKEN"))
.environment(com.squareup.square.legacy.Environment.SANDBOX)
.build();
SquareClient client = SquareClient.builder()
.token(System.getenv("SQUARE_TOKEN"))
.environment(Environment.SANDBOX)
.build();
Location location = getLocation(client).get();
CreateOrderResponse result = createOrder(legacyClient, location);
}
private static Optional<Location> getLocation(SquareClient client) {
GetLocationResponse response = client.locations()
.get(GetLocationsRequest.builder()
.locationId("YOUR_LOCATION_ID")
.build());
return response.getLocation();
}
private static CreateOrderResponse createOrder(
com.squareup.square.legacy.SquareClient legacyClient, Location location) {
try {
return legacyClient
.getOrdersApi()
.createOrder(new CreateOrderRequest.Builder()
.idempotencyKey(UUID.randomUUID().toString())
.order(new Order.Builder(location.getId().get()).build())
.build());
} catch (ApiException | IOException e) {
throw new RuntimeException(e);
}
}
}
You should migrate to the new SDK using the following steps:
Include the following dependencies in your project:
<dependency> <groupId>com.squareup</groupId> <artifactId>square</artifactId> <version>44.0.0.20250319</version> </dependency> <dependency> <groupId>com.squareup</groupId> <artifactId>square-legacy</artifactId> <version>44.0.0.20250319</version> </dependency>Search and replace all imports from
com.squareup.square
tocom.squareup.square.legacy
.Gradually introduce the new SDK by importing it from the
com.squareup.square
import.
There are two main differences between the request builders in the legacy SDK and the new SDK:
Instantiation - The legacy SDK builders are instantiated through their internal class constructors, whereas the new SDK builders are instantiated through static
builder()
methods.Required fields - In the legacy SDK, required fields are passed in as parameters to the builder constructor, while the new SDK has staged builders that won't expose the
.build()
method until all required fields are set.
// LEGACY
CreatePaymentRequest request = new CreatePaymentRequest.Builder("SOURCE_ID", "IDEMPOTENCY_KEY")
.amountMoney(new Money.Builder().amount(20L).currency("USD").build())
.tipMoney(new Money.Builder().amount(3L).currency("USD").build())
.build();
// NEW
CreatePaymentRequest request = CreatePaymentRequest.builder()
.sourceId("SOURCE_ID")
.idempotencyKey(UUID.randomUUID().toString())
.amountMoney(Money.builder().amount(20L).currency(Currency.USD).build())
.tipMoney(Money.builder().amount(3L).currency(Currency.USD).build())
.build();
Previously, API classes were named after the resource you're interacting with and suffixed with Api
. To interact with customer resources, you use the client.getCustomersApi()
method. The method was named based on the action you want to perform and the same resource name specified earlier. To list customers, you call client.getCustomersApi().listCustomers();
.
// LEGACY
client.getCustomersApi().listCustomers();
The new API classes are named by the resource without the Api
suffix, and the methods now name the action without mentioning the resource a second time.
// NEW
client.customers().list();
When interacting with a nested resource, you can chain the resources using dot-notation.
// NEW
client.customers().groups().list();
Some other class and method names might have changed. The differences are easiest to discover by exploring the new method signatures.
Square's paginated endpoints now support auto-pagination with an iterator. Callers don’t need to manually fetch the next page. You can now iterate over the entire list and the client automatically fetches the next page behind the scenes.
The following example shows the same code, with the legacy and new SDKs:
// LEGACY
import com.squareup.square.legacy.SquareClient;
import com.squareup.square.legacy.models.ListPaymentsResponse;
import com.squareup.square.legacy.models.Payment;
import java.util.List;
SquareClient legacyClient = new SquareClient.Builder()
.accessToken("YOUR_TOKEN")
.build();
ListPaymentsResponse response = legacyClient.getPaymentsApi().listPayments(...);
List<Payment> payments = response.getPayments();
String cursor = response.getCursor();
for (Payment payment : payments) {
System.out.printf("payment: ID: %s Created at: %s, Updated at: %s\n",
payment.getId(), payment.getCreatedAt(), payment.getUpdatedAt());
}
while (!response.getCursor().isEmpty()) {
response = legacyClient.getPaymentsApi().listPayments(..., cursor, ...);
payments = response.getPayments();
cursor = response.getCursor();
for (Payment payment : payments) {
System.out.printf("payment: ID: %s Created at: %s, Updated at: %s\n",
payment.getId(), payment.getCreatedAt(), payment.getUpdatedAt());
}
}
// NEW
import com.squareup.square.SquareClient;
import com.squareup.square.core.SyncPagingIterable;
import com.squareup.square.types.Payment;
import com.squareup.square.types.PaymentsListRequest;
SquareClient square = SquareClient.builder().token("YOUR_TOKEN").build();
SyncPagingIterable<Payment> payments =
square.payments().list(PaymentsListRequest.builder().total(100L).build());
for (Payment payment : payments) {
System.out.printf(
"payment: ID: %s Created at: %s, Updated at: %s\n",
payment.getId(), payment.getCreatedAt(), payment.getUpdatedAt());
}
If you need to paginate page by page, you can still do so.
// First page
List<Payment> pagePayments = payments.getItems();
for (Payment payment : pagePayments) {
// ...
}
// Remaining pages
while (payments.hasNext()) {
pagePayments = payments.nextPage().getItems();
for (Payment payment : pagePayments) {
// ...
}
}
In the legacy SDK, asynchronous calls can be made on the same client as synchronous calls by appending Async
to the method name. In the new SDK, async calls must be made to a class with the same name as the synchronous client with Async
prepended:
// LEGACY
SquareClient legacyClient = new SquareClient.Builder().accessToken("YOUR_TOKEN").build();
ListLocationsResponse syncResponse = legacyClient.getLocationsApi().listLocations();
CompletableFuture<ListLocationsResponse> asyncResponse = legacyClient.getLocationsApi().listLocationsAsync();
// NEW
SquareClient client = SquareClient.builder().token("YOUR_TOKEN").build();
AsyncSquareClient asyncClient = AsyncSquareClient.builder().token("YOUR_TOKEN").build();
ListLocationsResponse syncResponse = client.locations().list();
CompletableFuture<ListLocationsResponse> asyncResponse = asyncClient.locations().list();
In the legacy SDK, explicit null values can be sent using null values in the builder methods. In the new SDK, they can be set using Nullable.ofNull()
.
// LEGACY
new Transaction.Builder().clientId(null).build();
// NEW
Transaction.builder().clientId(Nullable.ofNull()).build();
Transaction.builder().clientId(Nullable.of(null)).build(); // also valid