return is_array( $locations ) ? $locations : [ $locations ];
* Fetch Square seller account from Square.
* @param string $mode Square mode.
private function fetch_account( string $mode ) {
$connection = Connection::get( $mode );
$api = new Api( $connection );
$merchant = $api->get_merchant( $connection->get_merchant_id() );
return $merchant->jsonSerialize();
* Fetch new connection credentials.
* @param string $state Unique ID to safely fetch connection data.
private function fetch_new_connection( string $state ): array {
$response = wp_remote_post(
$this->get_server_url() . '/oauth/square-connect',
'action' => 'credentials',
if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 200 ) {
$body = json_decode( wp_remote_retrieve_body( $response ), true );
$connection = is_array( $body ) ? $body : [];
* Fetch refresh connection credentials.
* @param string $token The refresh token.
* @param string $mode Square mode.
private function fetch_refresh_connection( string $token, string $mode ) {
$response = wp_remote_post(
$this->get_server_url() . '/oauth/square-connect',
'live_mode' => absint( $mode === Environment::PRODUCTION ),
if ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
$body = json_decode( wp_remote_retrieve_body( $response ), true );
if ( ! is_array( $body ) ) {
if ( ! empty( $body['success'] ) ) {
$error_message = empty( $body['message'] ) ? '' : wp_kses_post( $body['message'] );
return new WP_Error( 'refresh_connection_fail', $error_message );
* Retrieve active business locations with processing capability.
* @param array $locations Locations.
private function active_locations_filter( array $locations ): array {
if ( empty( $locations ) ) {
return $active_locations;
foreach ( $locations as $location ) {
! $location instanceof Location ||
$location->getStatus() !== LocationStatus::ACTIVE ||
! is_array( $location->getCapabilities() ) ||
! in_array( LocationCapability::CREDIT_CARD_PROCESSING, $location->getCapabilities(), true )
$location_id = $location->getId();
$active_locations[ $location_id ] = [
'name' => $location->getName(),
'currency' => $location->getCurrency(),
return $active_locations;
* Set/update location things: ID and currency.
* @param array $locations Active locations.
* @param string $mode Square mode.
private function set_location( array $locations, string $mode ) {
$connection = Connection::get( $mode );
$stored_location_id = Helpers::get_location_id( $mode );
// Location ID was not set previously or saved ID is not available now.
if ( empty( $stored_location_id ) || ! isset( $locations[ $stored_location_id ] ) ) {
$stored_location_id = Helpers::array_key_first( $locations );
// Set a new location ID.
Helpers::set_locataion_id( $stored_location_id, $mode );
// Set location currency for connection.
// In this case, we can make sure that location currency is matched with WPForms currency.
if ( $connection !== null ) {
$connection->set_currency( $locations[ $stored_location_id ]['currency'] )->save();
* Reset location ID and currency if no locations are received.
* @param string $mode Square mode.
private function reset_location( string $mode ) {
Helpers::set_locataion_id( '', $mode );
$connection = Connection::get( $mode );
$connection->set_currency( '' )->save();
* Get cached business locations or fetch it from Square.
* @param string $mode Square mode.
public function get_connected_locations( string $mode ): array {
$mode = Helpers::validate_mode( $mode );
$locations = Transient::get( 'wpforms_square_active_locations_' . $mode );
if ( empty( $locations ) ) {
$locations = $this->prepare_locations( $mode );
* Get cached Square seller account or fetch it from Square.
* @param string $mode Square mode.
public function get_connected_account( string $mode ) {
$mode = Helpers::validate_mode( $mode );
$account = Transient::get( 'wpforms_square_account_' . $mode );
if ( empty( $account['id'] ) ) {
$account_id = $this->get_connected_account_id( $mode );
$account = $this->fetch_account( $mode );
if ( empty( $account['id'] ) || $account['id'] !== $account_id ) {
Transient::set( 'wpforms_square_account_' . $mode, $account );
* Retrieve saved Square seller account ID from DB.
* @param string $mode Square mode.
public function get_connected_account_id( string $mode ): string {
$connection = Connection::get( $mode );
$account_id = $connection ? $connection->get_merchant_id() : '';
* Filter the connected account ID.
* @param string $account_id Square account ID.
* @param string $mode Square mode.
return (string) apply_filters( 'wpforms_square_admin_connect_get_connected_account_id', $account_id, $mode ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
* Retrieve the connect URL.
* @param string $mode Square mode.
public function get_connect_url( string $mode ): string {
$mode = Helpers::validate_mode( $mode );
'live_mode' => absint( $mode === Environment::PRODUCTION ),
'state' => uniqid( '', true ),
'site_url' => rawurlencode( Helpers::get_settings_page_url() ),
'scopes' => implode( ' ', $this->get_scopes() ),
$this->get_server_url() . '/oauth/square-connect'
* Retrieve the disconnect URL.
* @param string $mode Square mode.
public function get_disconnect_url( string $mode ): string {
$mode = Helpers::validate_mode( $mode );
$action = 'wpforms_square_disconnect';
'live_mode' => absint( $mode === Environment::PRODUCTION ),
Helpers::get_settings_page_url()
return wp_nonce_url( $url, $action );
* Retrieve a connect server URL.
public function get_server_url(): string {
if ( defined( 'WPFORMS_SQUARE_LOCAL_CONNECT_SERVER' ) && WPFORMS_SQUARE_LOCAL_CONNECT_SERVER ) {
return self::WPFORMS_URL;
* Retrieve the connection scopes (permissions).
public function get_scopes(): array {
* Filter the connection scopes.
* @param array $scopes The connection scopes.
return (array) apply_filters( // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
'wpforms_square_admin_connect_get_scopes',
'PAYMENTS_WRITE_ADDITIONAL_RECIPIENTS',