From 0dfe1d8afafc59c4a5559c498342668d5a58d6ef Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Thu, 23 Jul 2026 22:41:41 +0000
Subject: [PATCH] =Still working away at the Integrations overhaul
---
inc/integrations/services/Square.php | 359 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 352 insertions(+), 7 deletions(-)
diff --git a/inc/integrations/services/Square.php b/inc/integrations/services/Square.php
index e3dbfff..a2b6c9a 100644
--- a/inc/integrations/services/Square.php
+++ b/inc/integrations/services/Square.php
@@ -3,6 +3,7 @@
namespace JVBase\integrations\services;
use Exception;
use JVBase\integrations\Admin;
+use JVBase\integrations\APIEndpoint;
use JVBase\integrations\Instance;
use JVBase\integrations\Integrations;
use JVBase\integrations\OAuth;
@@ -35,7 +36,13 @@
Webhooks;
protected string $orderPostType = '_square_order';
- protected string $apiVersion = '2025-09-24';
+ protected string $apiVersion = '2026-07-15';
+ public bool $hasBatchCreate = true;
+ public bool $hasBatchUpdate = true;
+ public bool $hasBatchDelete = true;
+ public array $apiEndpoints = [
+
+ ];
protected function __construct()
{
@@ -157,8 +164,58 @@
protected function initialize(): void
{
- // TODO: Implement initialize() method.
+ $this->defineEndpoints();
}
+ protected function defineEndpoints():void
+ {
+ $this->defineCustomerEndpoints();
+ $this->defineProductEndpoints();
+ $this->defineOrderEndpoints();
+ $this->definePaymentEndpoints();
+ }
+ protected function defineCustomerEndpoints():void
+ {
+ $customer = new APIEndpoint();
+ $customer->setCreate('/v2/customers');
+ $customer->setBatchCreate('/v2/customers/bulk-create');
+ $customer->setDelete('/v2/customers/');//add the item_id to the end
+ $customer->setBatchDelete('/v2/customers/bulk-delete');
+ $customer->setUpdate('/v2/customers/');//add the item_id to the end
+ $customer->setBatchUpdate('/v2/customers/bulk-update');
+ $customer->setSearch('/v2/customers/search');
+ $customer->setImport('/v2/customers');
+ $this->apiEndpoints['customer'] = $customer;
+ }
+ protected function defineProductEndpoints():void
+ {
+ $product = new APIEndpoint();
+ $product->setSearch('/v2/catalog/search-catalog-items');
+ $product->setImport('/v2/catalog/list');
+ $product->setImage('/v2/catalog/images');
+ $product->setCreate('/v2/catalog/object');
+ $product->setBatchCreate('/v2/catalog/batch-upsert');
+ $product->setUpdate('/v2/catalog/object');
+ $product->setBatchUpdate('/v2/catalog/batch-upsert');
+ $product->setDelete('/v2/catalog/object/');//add the item_id to the end
+ $product->setBatchDelete('/v2/catalog/batch-delete');
+ $this->apiEndpoints['product'] = $product;
+ }
+
+ protected function defineOrderEndpoints():void
+ {
+ $order = new APIEndpoint();
+ $order->setCreate('/v2/orders');
+ $order->setSearch('/v2/orders/search');
+ $order->setUpdate('/v2/orders/'); //add order_id
+ $this->apiEndpoints['order'] = $order;
+ }
+ protected function definePaymentEndpoints():void
+ {
+ $payment = new APIEndpoint();
+ $payment->setCreate('/v2/payments');
+
+ $this->apiEndpoints['payment'] = $payment;
+ }
protected function refreshAccessToken(OAuthCredentials $credentials): array
{
@@ -227,8 +284,275 @@
protected function setContentTypes(): void
{
- // TODO: Implement setContentTypes() method.
+ $base = $this->getBaseFields();
+ $this->contentTypes = [
+ 'customer' => $this->getCustomerFields(),
+ 'REGULAR' => $base,
+ 'FOOD_AND_BEV' => array_merge($base, $this->setFoodAndBevFields()),
+ 'APPOINTMENTS_SERVICE' => array_merge($base, $this->setAppointmentServiceFields()),
+ 'EVENT' => array_merge($base, $this->setEventFields()),
+ 'GIFT_CARD' => array_merge($base, $this->setGiftCardFields()),
+ ];
}
+ protected function getCustomerFields():array
+ {
+ return [
+ 'address' => [
+ 'type' => 'group',
+ 'fields' => [
+ 'address_line_1' => [
+ 'type' => 'text',
+ 'label' => 'Address Line 1',
+ 'hint' => 'ex: 6551 111 St NW',
+ 'required' => true,
+ 'section' => 'address'
+ ],
+ 'address_line_2' => [
+ 'type' => 'text',
+ 'label' => 'Address Line 2',
+ 'hint' => 'ex: Unit 2',
+ 'section' => 'address'
+ ],
+ 'locality' => [
+ 'type' => 'text',
+ 'label'=> 'City',
+ 'section' => 'address',
+ 'required' => true,
+ ],
+ 'administrative_district_level_1' => [
+ 'type' => 'text',
+ 'label' => 'Province',
+ 'hint' => 'The two-character code, example: AB',
+ 'default'=> 'AB',
+ 'section' => 'address',
+ 'required' => true,
+ ],
+ 'postal_code' => [
+ 'type' => 'text',
+ 'label' => 'Postal Code',
+ 'section'=> 'address'
+ ],
+ 'country' => [
+ 'type' => 'text',
+ 'label' => 'Country Code',
+ 'hint' => 'The tw-character country code, example: CA',
+ 'default' => 'CA',
+ 'section' => 'address',
+ 'required' => true,
+ ],
+ 'first_name' => [
+ 'type' => 'text',
+ 'label' => 'First Name (if different)',
+ 'hint' => 'Optional field to save the address to someone that isn\'t you'
+ ],
+ 'last_name' => [
+ 'type' => 'text',
+ 'label' => 'Last Name (if different)',
+ 'hint' => 'Optional field to save the address to someone that isn\'t you'
+ ]
+ ]
+ ]
+ ];
+ }
+ protected function getBaseFields():array
+ {
+ return [
+ 'price' => [
+ 'type' => 'number',
+ 'label' => 'Price',
+ 'step' => 0.01,
+ 'max' => 99999,
+ 'description' => 'Price for this variation'
+ ],
+ 'sku' => [
+ 'type' => 'text',
+ 'label' => 'SKU',
+ 'description' => 'Stock keeping unit'
+ ],
+ 'cart_quantity' => [
+ 'type' => 'number',
+ 'label' => 'Quantity',
+ 'hidden' => true,
+ ],
+ 'available_for_pickup' => [
+ 'type' => 'true_false',
+ 'label' => 'Available for Pick Up',
+ 'section'=> 'square-advanced'
+ ],
+ 'available_online' => [
+ 'type' => 'true_false',
+ 'label' => 'Available online',
+ 'section'=> 'square-advanced'
+ ],
+ 'product_variations' => [
+ 'type' => 'repeater',
+ 'label' => 'Product Variations',
+ 'description' => 'Different versions of this product (sizes, colors, etc.)',
+ 'add_label' => 'Add Variation',
+ 'section' => 'variations',
+ 'fields' => $this->setVariationFields()
+ ],
+ ];
+ }
+ protected function setVariationFields(?string $type = null):array
+ {
+ $fields = [
+ 'name' => [
+ 'type' => 'text',
+ 'label' => 'Variation Name',
+ 'description' => 'e.g., "Small", "Large", "Red", etc.'
+ ],
+ 'sku' => [
+ 'type' => 'text',
+ 'label' => 'SKU',
+ 'description' => 'Stock keeping unit'
+ ],
+ 'price' => [
+ 'type' => 'number',
+ 'label' => 'Price',
+ 'step' => 0.01,
+ 'max' => 99999,
+ 'description' => 'Price for this variation'
+ ],
+ 'track_inventory' => [
+ 'type' => 'true_false',
+ 'label' => 'Track Inventory',
+ ],
+ 'item_id' => [
+ 'type' => 'text',
+ 'label' => 'Square Variation ID',
+ 'description' => 'Square catalog ID for this variation',
+ 'hidden' => true
+ ],
+ 'last_sync' => [
+ 'type' => 'datetime',
+ 'label' => 'Last Sync',
+ 'hidden' => true
+ ]
+ ];
+
+ switch ($type) {
+ case 'FOOD_AND_BEV':
+ $fields['ingredients'] = [
+ 'type' => 'textarea',
+ 'label' => 'Ingredients List',
+ 'description' => 'Separate ingredients with commas',
+ ];
+ $fields['preparation_time_duration'] = [
+ 'type' => 'number',
+ 'label' => 'Preparation time (in minutes)',
+ ];
+ break;
+ case 'GIFT_CARD':
+ $fields['gift_card_type'] = [
+ 'type' => 'select',
+ 'label' => 'Gift Card Type',
+ 'options' => [
+ 'PHYSICAL' => 'Physical',
+ 'DIGITAL' => 'Digital',
+ ],
+ 'default' => 'DIGITAL',
+ ];
+ break;
+ case 'APPOINTMENTS_SERVICE':
+ $fields['service_duration'] = [
+ 'type' => 'number',
+ 'label' => 'Duration of Service in Minutes'
+ ];
+ $fields['available_for_booking'] = [
+ 'type' => 'true_false',
+ 'label' => 'Available for Booking'
+ ];
+ break;
+ }
+ return array_combine(
+ array_map(fn($k) => '_square_' . $k, array_keys($fields)),
+ $fields
+ );
+ }
+ protected function setFoodAndBevFields():array
+ {
+ return [
+ 'ingredients' => [
+ 'type' => 'textarea',
+ 'label' => 'Ingredients',
+ 'hint' => 'A comma separated list of ingredients'
+ ],
+ 'preparation_time_duration' => [
+ 'label' => 'Preparation Time',
+ 'type' => 'number',
+ 'hint' => 'Preparation time in minutes'
+ ],
+ 'product_variations' => [
+ 'type' => 'repeater',
+ 'label' => 'Product Variations',
+ 'description' => 'Different versions of this product (sizes, colors, etc.)',
+ 'add_label' => 'Add Variation',
+ 'section' => 'variations',
+ 'fields' => $this->setVariationFields('FOOD_AND_BEV')
+ ],
+ ];
+ /* TODO: Set definitions for:
+ 'dietary_preferences' => [
+
+ ],
+ 'calories_text' => [
+
+ ],
+ */
+ }
+ protected function setAppointmentServiceFields():array
+ {
+ return [
+
+ 'product_variations' => [
+ 'type' => 'repeater',
+ 'label' => 'Product Variations',
+ 'description' => 'Different versions of this product (sizes, colors, etc.)',
+ 'add_label' => 'Add Variation',
+ 'section' => 'variations',
+ 'fields' => $this->setVariationFields('APPOINTMENTS_SERVICE')
+ ],
+ ];
+ }
+
+ protected function setEventFields():array
+ {
+ return [
+ 'venue_details' => [
+ 'type' => 'textarea',
+ 'label' => 'Venue Details',
+ ],
+ 'capacity' => [
+ 'type' => 'number',
+ 'label' => 'Capacity'
+ ],
+ 'product_variations' => [
+ 'type' => 'repeater',
+ 'label' => 'Product Variations',
+ 'description' => 'Different versions of this product (sizes, colors, etc.)',
+ 'add_label' => 'Add Variation',
+ 'section' => 'variations',
+ 'fields' => $this->setVariationFields('EVENT')
+ ],
+ ];
+ }
+ protected function setGiftCardFields():array
+ {
+ return [
+ // 'allowed_locations' => [
+ //
+ // ],
+ 'product_variations' => [
+ 'type' => 'repeater',
+ 'label' => 'Product Variations',
+ 'description' => 'Different versions of this product (sizes, colors, etc.)',
+ 'add_label' => 'Add Variation',
+ 'section' => 'variations',
+ 'fields' => $this->setVariationFields('GIFT_CARD')
+ ],
+ ];
+ }
protected function formatForService(int $itemID, string $type = 'post'): array
{
@@ -255,21 +579,28 @@
]
]
);
- return $response['id'];
+ return $response['data'];
} catch (Exception $e) {
return false;
}
}
protected function handleEmailSearchResponse(WP_Error|array $response, string $method):array
{
-
+ $data = empty($response['customers'])
+ ? false
+ : $response['customers'][0]??false;
+ return $this->response(true, 'Successfully got results.', $data);
}
protected function handleCreateUser(array $data): array
{
try {
return $this->postRequest(
- sprintf('%s/v2/customers',$this->getBaseURL()),
+ sprintf(
+ '%s%s',
+ $this->getBaseURL(),
+ $this->apiEndpoints['customer']['create']->getEndpoint()
+ ),
$data
);
} catch (Exception $e) {
@@ -278,7 +609,10 @@
}
protected function handleCreateUserResponse(WP_Error|array $response, string $method):array
{
-
+ $data = empty($response['customer'])
+ ? false
+ : $response['customer'];
+ return $this->response(true, 'Successfully got results.', $data);
}
protected function validateUserFields(int $userID, array $fields):array|false
{
@@ -616,5 +950,16 @@
}
}
+ public function getAdditionalFields(?string $content_type = null):array
+ {
+ $this->setContentTypes();
+ if (is_null($content_type) || !array_key_exists($content_type, $this->contentTypes)) {
+ return [];
+ }
+ return $this->contentTypes[$content_type];
+ }
+
+
+
}
--
Gitblit v1.10.0