diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index dc3c91c5be..2d6b6eb2c0 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -1958,6 +1958,17 @@ export function WhatsAppIcon(props: SVGProps) { ) } +export function SquareIcon(props: SVGProps) { + return ( + + + + ) +} + export function StripeIcon(props: SVGProps) { return ( = { slack: SlackIcon, smtp: SmtpIcon, sqs: SQSIcon, + square: SquareIcon, ssh: SshIcon, stagehand: StagehandIcon, stripe: StripeIcon, diff --git a/apps/docs/content/docs/en/integrations/meta.json b/apps/docs/content/docs/en/integrations/meta.json index 0ee2e26089..ab898490da 100644 --- a/apps/docs/content/docs/en/integrations/meta.json +++ b/apps/docs/content/docs/en/integrations/meta.json @@ -192,6 +192,7 @@ "slack", "smtp", "sqs", + "square", "ssh", "stagehand", "stripe", diff --git a/apps/docs/content/docs/en/integrations/square.mdx b/apps/docs/content/docs/en/integrations/square.mdx new file mode 100644 index 0000000000..d741dbdb24 --- /dev/null +++ b/apps/docs/content/docs/en/integrations/square.mdx @@ -0,0 +1,1479 @@ +--- +title: Square +description: Process payments and manage Square commerce data +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +## Usage Instructions + +Integrate Square into the workflow. Take and refund payments, manage customers, build catalog items and images, create and search orders, and issue invoices. Authenticate with a Square access token (personal access token). + + + +## Actions + +### `square_create_payment` + +Take a payment using a payment source such as a card nonce or a card on file + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `sourceId` | string | Yes | ID of the payment source \(card nonce, card-on-file ID, or wallet token\) | +| `amount` | number | Yes | Amount in the smallest currency denomination \(e.g. 1000 = $10.00\) | +| `currency` | string | Yes | Three-letter ISO 4217 currency code \(e.g. USD\) | +| `idempotencyKey` | string | No | Unique key to make the request idempotent \(auto-generated if omitted\) | +| `customerId` | string | No | ID of the customer associated with the payment | +| `locationId` | string | No | ID of the location where the payment is taken \(defaults to the main location\) | +| `orderId` | string | No | ID of the order associated with the payment | +| `referenceId` | string | No | Optional external reference for the payment | +| `note` | string | No | Optional note attached to the payment | +| `autocomplete` | boolean | No | Whether to immediately capture the payment \(defaults to true\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `payment` | object | The created payment object | +| ↳ `id` | string | Unique ID for the payment | +| ↳ `status` | string | Payment status \(APPROVED, PENDING, COMPLETED, CANCELED, or FAILED\) | +| ↳ `amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `approved_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `app_fee_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `refunded_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `tip_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `source_type` | string | Source of the payment \(CARD, BANK_ACCOUNT, WALLET, etc.\) | +| ↳ `card_details` | json | Details about a card payment | +| ↳ `location_id` | string | ID of the location where the payment was taken | +| ↳ `order_id` | string | ID of the associated order | +| ↳ `customer_id` | string | ID of the associated customer | +| ↳ `reference_id` | string | Optional external reference for the payment | +| ↳ `receipt_number` | string | Receipt number for the payment | +| ↳ `receipt_url` | string | URL of the payment receipt | +| ↳ `note` | string | Optional note attached to the payment | +| ↳ `refund_ids` | array | IDs of refunds associated with the payment | +| ↳ `processing_fee` | array | Processing fees applied to the payment | +| ↳ `created_at` | string | Timestamp when the payment was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the payment was last updated \(RFC 3339\) | +| ↳ `version_token` | string | Optimistic concurrency token for the payment | +| `metadata` | json | Payment summary metadata | +| ↳ `id` | string | Square payment ID | +| ↳ `status` | string | Current payment status | +| ↳ `order_id` | string | Associated order ID | + +### `square_get_payment` + +Retrieve details for a single payment by its ID + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `paymentId` | string | Yes | ID of the payment to retrieve | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `payment` | object | The retrieved payment object | +| ↳ `id` | string | Unique ID for the payment | +| ↳ `status` | string | Payment status \(APPROVED, PENDING, COMPLETED, CANCELED, or FAILED\) | +| ↳ `amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `approved_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `app_fee_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `refunded_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `tip_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `source_type` | string | Source of the payment \(CARD, BANK_ACCOUNT, WALLET, etc.\) | +| ↳ `card_details` | json | Details about a card payment | +| ↳ `location_id` | string | ID of the location where the payment was taken | +| ↳ `order_id` | string | ID of the associated order | +| ↳ `customer_id` | string | ID of the associated customer | +| ↳ `reference_id` | string | Optional external reference for the payment | +| ↳ `receipt_number` | string | Receipt number for the payment | +| ↳ `receipt_url` | string | URL of the payment receipt | +| ↳ `note` | string | Optional note attached to the payment | +| ↳ `refund_ids` | array | IDs of refunds associated with the payment | +| ↳ `processing_fee` | array | Processing fees applied to the payment | +| ↳ `created_at` | string | Timestamp when the payment was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the payment was last updated \(RFC 3339\) | +| ↳ `version_token` | string | Optimistic concurrency token for the payment | +| `metadata` | json | Payment summary metadata | +| ↳ `id` | string | Square payment ID | +| ↳ `status` | string | Current payment status | +| ↳ `order_id` | string | Associated order ID | + +### `square_list_payments` + +List payments taken by the account, optionally filtered by location and time range + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `locationId` | string | No | Filter payments by location ID | +| `beginTime` | string | No | RFC 3339 timestamp for the beginning of the reporting period | +| `endTime` | string | No | RFC 3339 timestamp for the end of the reporting period | +| `limit` | number | No | Maximum number of results to return per page | +| `cursor` | string | No | Pagination cursor from a previous response | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `payments` | array | Array of payment objects | +| ↳ `id` | string | Unique ID for the payment | +| ↳ `status` | string | Payment status \(APPROVED, PENDING, COMPLETED, CANCELED, or FAILED\) | +| ↳ `amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `approved_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `app_fee_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `refunded_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `tip_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `source_type` | string | Source of the payment \(CARD, BANK_ACCOUNT, WALLET, etc.\) | +| ↳ `card_details` | json | Details about a card payment | +| ↳ `location_id` | string | ID of the location where the payment was taken | +| ↳ `order_id` | string | ID of the associated order | +| ↳ `customer_id` | string | ID of the associated customer | +| ↳ `reference_id` | string | Optional external reference for the payment | +| ↳ `receipt_number` | string | Receipt number for the payment | +| ↳ `receipt_url` | string | URL of the payment receipt | +| ↳ `note` | string | Optional note attached to the payment | +| ↳ `refund_ids` | array | IDs of refunds associated with the payment | +| ↳ `processing_fee` | array | Processing fees applied to the payment | +| ↳ `created_at` | string | Timestamp when the payment was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the payment was last updated \(RFC 3339\) | +| ↳ `version_token` | string | Optimistic concurrency token for the payment | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + +### `square_cancel_payment` + +Cancel (void) an authorized payment that has not been captured + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `paymentId` | string | Yes | ID of the payment to cancel | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `payment` | object | The canceled payment object | +| ↳ `id` | string | Unique ID for the payment | +| ↳ `status` | string | Payment status \(APPROVED, PENDING, COMPLETED, CANCELED, or FAILED\) | +| ↳ `amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `approved_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `app_fee_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `refunded_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `tip_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `source_type` | string | Source of the payment \(CARD, BANK_ACCOUNT, WALLET, etc.\) | +| ↳ `card_details` | json | Details about a card payment | +| ↳ `location_id` | string | ID of the location where the payment was taken | +| ↳ `order_id` | string | ID of the associated order | +| ↳ `customer_id` | string | ID of the associated customer | +| ↳ `reference_id` | string | Optional external reference for the payment | +| ↳ `receipt_number` | string | Receipt number for the payment | +| ↳ `receipt_url` | string | URL of the payment receipt | +| ↳ `note` | string | Optional note attached to the payment | +| ↳ `refund_ids` | array | IDs of refunds associated with the payment | +| ↳ `processing_fee` | array | Processing fees applied to the payment | +| ↳ `created_at` | string | Timestamp when the payment was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the payment was last updated \(RFC 3339\) | +| ↳ `version_token` | string | Optimistic concurrency token for the payment | +| `metadata` | json | Payment summary metadata | +| ↳ `id` | string | Square payment ID | +| ↳ `status` | string | Current payment status | +| ↳ `order_id` | string | Associated order ID | + +### `square_complete_payment` + +Capture (complete) a payment that was authorized with delayed capture + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `paymentId` | string | Yes | ID of the payment to complete | +| `versionToken` | string | No | Optional version token for optimistic concurrency control | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `payment` | object | The completed payment object | +| ↳ `id` | string | Unique ID for the payment | +| ↳ `status` | string | Payment status \(APPROVED, PENDING, COMPLETED, CANCELED, or FAILED\) | +| ↳ `amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `approved_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `app_fee_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `refunded_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `tip_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `source_type` | string | Source of the payment \(CARD, BANK_ACCOUNT, WALLET, etc.\) | +| ↳ `card_details` | json | Details about a card payment | +| ↳ `location_id` | string | ID of the location where the payment was taken | +| ↳ `order_id` | string | ID of the associated order | +| ↳ `customer_id` | string | ID of the associated customer | +| ↳ `reference_id` | string | Optional external reference for the payment | +| ↳ `receipt_number` | string | Receipt number for the payment | +| ↳ `receipt_url` | string | URL of the payment receipt | +| ↳ `note` | string | Optional note attached to the payment | +| ↳ `refund_ids` | array | IDs of refunds associated with the payment | +| ↳ `processing_fee` | array | Processing fees applied to the payment | +| ↳ `created_at` | string | Timestamp when the payment was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the payment was last updated \(RFC 3339\) | +| ↳ `version_token` | string | Optimistic concurrency token for the payment | +| `metadata` | json | Payment summary metadata | +| ↳ `id` | string | Square payment ID | +| ↳ `status` | string | Current payment status | +| ↳ `order_id` | string | Associated order ID | + +### `square_refund_payment` + +Refund all or part of a completed payment + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `paymentId` | string | Yes | ID of the payment to refund | +| `amount` | number | Yes | Amount to refund in the smallest currency denomination \(e.g. 100 = $1.00\) | +| `currency` | string | Yes | Three-letter ISO 4217 currency code \(e.g. USD\) | +| `idempotencyKey` | string | No | Unique key to make the request idempotent \(auto-generated if omitted\) | +| `reason` | string | No | Reason for the refund | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `refund` | object | The created refund object | +| ↳ `id` | string | Unique ID for the refund | +| ↳ `status` | string | Refund status \(PENDING, COMPLETED, REJECTED, or FAILED\) | +| ↳ `amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `processing_fee` | array | Processing fees refunded | +| ↳ `payment_id` | string | ID of the payment being refunded | +| ↳ `order_id` | string | ID of the associated order | +| ↳ `location_id` | string | ID of the associated location | +| ↳ `reason` | string | Reason for the refund | +| ↳ `created_at` | string | Timestamp when the refund was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the refund was last updated \(RFC 3339\) | +| `metadata` | json | Refund summary metadata | +| ↳ `id` | string | Square refund ID | +| ↳ `status` | string | Current refund status | +| ↳ `payment_id` | string | Refunded payment ID | + +### `square_get_refund` + +Retrieve a single payment refund by its ID + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `refundId` | string | Yes | ID of the refund to retrieve | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `refund` | object | The retrieved refund object | +| ↳ `id` | string | Unique ID for the refund | +| ↳ `status` | string | Refund status \(PENDING, COMPLETED, REJECTED, or FAILED\) | +| ↳ `amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `processing_fee` | array | Processing fees refunded | +| ↳ `payment_id` | string | ID of the payment being refunded | +| ↳ `order_id` | string | ID of the associated order | +| ↳ `location_id` | string | ID of the associated location | +| ↳ `reason` | string | Reason for the refund | +| ↳ `created_at` | string | Timestamp when the refund was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the refund was last updated \(RFC 3339\) | +| `metadata` | json | Refund summary metadata | +| ↳ `id` | string | Square refund ID | +| ↳ `status` | string | Current refund status | +| ↳ `payment_id` | string | Refunded payment ID | + +### `square_list_refunds` + +List payment refunds, optionally filtered by location, status, and time range + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `locationId` | string | No | Filter refunds by location ID | +| `status` | string | No | Filter by refund status \(PENDING, COMPLETED, REJECTED, or FAILED\) | +| `beginTime` | string | No | RFC 3339 timestamp for the beginning of the reporting period | +| `endTime` | string | No | RFC 3339 timestamp for the end of the reporting period | +| `limit` | number | No | Maximum number of results to return per page | +| `cursor` | string | No | Pagination cursor from a previous response | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `refunds` | array | Array of refund objects | +| ↳ `id` | string | Unique ID for the refund | +| ↳ `status` | string | Refund status \(PENDING, COMPLETED, REJECTED, or FAILED\) | +| ↳ `amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `processing_fee` | array | Processing fees refunded | +| ↳ `payment_id` | string | ID of the payment being refunded | +| ↳ `order_id` | string | ID of the associated order | +| ↳ `location_id` | string | ID of the associated location | +| ↳ `reason` | string | Reason for the refund | +| ↳ `created_at` | string | Timestamp when the refund was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the refund was last updated \(RFC 3339\) | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + +### `square_create_customer` + +Create a new customer profile in the Square customer directory + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `givenName` | string | No | First name of the customer | +| `familyName` | string | No | Last name of the customer | +| `companyName` | string | No | Business name of the customer | +| `nickname` | string | No | Nickname of the customer | +| `emailAddress` | string | No | Email address of the customer | +| `phoneNumber` | string | No | Phone number of the customer | +| `birthday` | string | No | Birthday in YYYY-MM-DD or MM-DD format | +| `note` | string | No | Note about the customer | +| `referenceId` | string | No | Optional external reference for the customer | +| `address` | json | No | Square address object for the customer | +| `idempotencyKey` | string | No | Unique key to make the request idempotent \(auto-generated if omitted\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `customer` | object | The created customer object | +| ↳ `id` | string | Unique ID for the customer | +| ↳ `given_name` | string | First name of the customer | +| ↳ `family_name` | string | Last name of the customer | +| ↳ `nickname` | string | Nickname of the customer | +| ↳ `company_name` | string | Business name of the customer | +| ↳ `email_address` | string | Email address of the customer | +| ↳ `phone_number` | string | Phone number of the customer | +| ↳ `address` | object | Physical address | +| ↳ `address_line_1` | string | First line of the address | +| ↳ `address_line_2` | string | Second line of the address | +| ↳ `address_line_3` | string | Third line of the address | +| ↳ `locality` | string | City or town | +| ↳ `sublocality` | string | Neighborhood or district | +| ↳ `administrative_district_level_1` | string | State, province, or region | +| ↳ `postal_code` | string | Postal or ZIP code | +| ↳ `country` | string | Two-letter ISO 3166-1 alpha-2 country code | +| ↳ `first_name` | string | First name of the addressee | +| ↳ `last_name` | string | Last name of the addressee | +| ↳ `birthday` | string | Birthday in YYYY-MM-DD or MM-DD format | +| ↳ `reference_id` | string | Optional external reference for the customer | +| ↳ `note` | string | Note about the customer | +| ↳ `creation_source` | string | How the customer profile was created | +| ↳ `preferences` | json | Customer communication preferences | +| ↳ `group_ids` | array | IDs of customer groups the customer belongs to | +| ↳ `segment_ids` | array | IDs of customer segments the customer belongs to | +| ↳ `version` | number | Optimistic concurrency version of the customer | +| ↳ `created_at` | string | Timestamp when the customer was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the customer was last updated \(RFC 3339\) | +| `metadata` | json | Customer summary metadata | +| ↳ `id` | string | Square customer ID | +| ↳ `email_address` | string | Customer email address | +| ↳ `given_name` | string | Customer first name | +| ↳ `family_name` | string | Customer last name | + +### `square_get_customer` + +Retrieve a single customer profile by its ID + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `customerId` | string | Yes | ID of the customer to retrieve | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `customer` | object | The retrieved customer object | +| ↳ `id` | string | Unique ID for the customer | +| ↳ `given_name` | string | First name of the customer | +| ↳ `family_name` | string | Last name of the customer | +| ↳ `nickname` | string | Nickname of the customer | +| ↳ `company_name` | string | Business name of the customer | +| ↳ `email_address` | string | Email address of the customer | +| ↳ `phone_number` | string | Phone number of the customer | +| ↳ `address` | object | Physical address | +| ↳ `address_line_1` | string | First line of the address | +| ↳ `address_line_2` | string | Second line of the address | +| ↳ `address_line_3` | string | Third line of the address | +| ↳ `locality` | string | City or town | +| ↳ `sublocality` | string | Neighborhood or district | +| ↳ `administrative_district_level_1` | string | State, province, or region | +| ↳ `postal_code` | string | Postal or ZIP code | +| ↳ `country` | string | Two-letter ISO 3166-1 alpha-2 country code | +| ↳ `first_name` | string | First name of the addressee | +| ↳ `last_name` | string | Last name of the addressee | +| ↳ `birthday` | string | Birthday in YYYY-MM-DD or MM-DD format | +| ↳ `reference_id` | string | Optional external reference for the customer | +| ↳ `note` | string | Note about the customer | +| ↳ `creation_source` | string | How the customer profile was created | +| ↳ `preferences` | json | Customer communication preferences | +| ↳ `group_ids` | array | IDs of customer groups the customer belongs to | +| ↳ `segment_ids` | array | IDs of customer segments the customer belongs to | +| ↳ `version` | number | Optimistic concurrency version of the customer | +| ↳ `created_at` | string | Timestamp when the customer was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the customer was last updated \(RFC 3339\) | +| `metadata` | json | Customer summary metadata | +| ↳ `id` | string | Square customer ID | +| ↳ `email_address` | string | Customer email address | +| ↳ `given_name` | string | Customer first name | +| ↳ `family_name` | string | Customer last name | + +### `square_list_customers` + +List customer profiles in the Square customer directory + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `limit` | number | No | Maximum number of results to return per page \(max 100\) | +| `cursor` | string | No | Pagination cursor from a previous response | +| `sortField` | string | No | Field to sort by \(DEFAULT or CREATED_AT\) | +| `sortOrder` | string | No | Sort order \(ASC or DESC\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `customers` | array | Array of customer objects | +| ↳ `id` | string | Unique ID for the customer | +| ↳ `given_name` | string | First name of the customer | +| ↳ `family_name` | string | Last name of the customer | +| ↳ `nickname` | string | Nickname of the customer | +| ↳ `company_name` | string | Business name of the customer | +| ↳ `email_address` | string | Email address of the customer | +| ↳ `phone_number` | string | Phone number of the customer | +| ↳ `address` | object | Physical address | +| ↳ `address_line_1` | string | First line of the address | +| ↳ `address_line_2` | string | Second line of the address | +| ↳ `address_line_3` | string | Third line of the address | +| ↳ `locality` | string | City or town | +| ↳ `sublocality` | string | Neighborhood or district | +| ↳ `administrative_district_level_1` | string | State, province, or region | +| ↳ `postal_code` | string | Postal or ZIP code | +| ↳ `country` | string | Two-letter ISO 3166-1 alpha-2 country code | +| ↳ `first_name` | string | First name of the addressee | +| ↳ `last_name` | string | Last name of the addressee | +| ↳ `birthday` | string | Birthday in YYYY-MM-DD or MM-DD format | +| ↳ `reference_id` | string | Optional external reference for the customer | +| ↳ `note` | string | Note about the customer | +| ↳ `creation_source` | string | How the customer profile was created | +| ↳ `preferences` | json | Customer communication preferences | +| ↳ `group_ids` | array | IDs of customer groups the customer belongs to | +| ↳ `segment_ids` | array | IDs of customer segments the customer belongs to | +| ↳ `version` | number | Optimistic concurrency version of the customer | +| ↳ `created_at` | string | Timestamp when the customer was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the customer was last updated \(RFC 3339\) | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + +### `square_search_customers` + +Search customer profiles using filters such as email, phone, or creation date + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `query` | json | No | Square customer query object with optional filter and sort \(e.g. \{"filter":\{"email_address":\{"exact":"a@b.com"\}\}\}\) | +| `limit` | number | No | Maximum number of results to return per page | +| `cursor` | string | No | Pagination cursor from a previous response | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `customers` | array | Array of matching customer objects | +| ↳ `id` | string | Unique ID for the customer | +| ↳ `given_name` | string | First name of the customer | +| ↳ `family_name` | string | Last name of the customer | +| ↳ `nickname` | string | Nickname of the customer | +| ↳ `company_name` | string | Business name of the customer | +| ↳ `email_address` | string | Email address of the customer | +| ↳ `phone_number` | string | Phone number of the customer | +| ↳ `address` | object | Physical address | +| ↳ `address_line_1` | string | First line of the address | +| ↳ `address_line_2` | string | Second line of the address | +| ↳ `address_line_3` | string | Third line of the address | +| ↳ `locality` | string | City or town | +| ↳ `sublocality` | string | Neighborhood or district | +| ↳ `administrative_district_level_1` | string | State, province, or region | +| ↳ `postal_code` | string | Postal or ZIP code | +| ↳ `country` | string | Two-letter ISO 3166-1 alpha-2 country code | +| ↳ `first_name` | string | First name of the addressee | +| ↳ `last_name` | string | Last name of the addressee | +| ↳ `birthday` | string | Birthday in YYYY-MM-DD or MM-DD format | +| ↳ `reference_id` | string | Optional external reference for the customer | +| ↳ `note` | string | Note about the customer | +| ↳ `creation_source` | string | How the customer profile was created | +| ↳ `preferences` | json | Customer communication preferences | +| ↳ `group_ids` | array | IDs of customer groups the customer belongs to | +| ↳ `segment_ids` | array | IDs of customer segments the customer belongs to | +| ↳ `version` | number | Optimistic concurrency version of the customer | +| ↳ `created_at` | string | Timestamp when the customer was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the customer was last updated \(RFC 3339\) | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + +### `square_update_customer` + +Update fields on an existing customer profile + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `customerId` | string | Yes | ID of the customer to update | +| `givenName` | string | No | First name of the customer | +| `familyName` | string | No | Last name of the customer | +| `companyName` | string | No | Business name of the customer | +| `nickname` | string | No | Nickname of the customer | +| `emailAddress` | string | No | Email address of the customer | +| `phoneNumber` | string | No | Phone number of the customer | +| `birthday` | string | No | Birthday in YYYY-MM-DD or MM-DD format | +| `note` | string | No | Note about the customer | +| `referenceId` | string | No | Optional external reference for the customer | +| `address` | json | No | Square address object for the customer | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `customer` | object | The updated customer object | +| ↳ `id` | string | Unique ID for the customer | +| ↳ `given_name` | string | First name of the customer | +| ↳ `family_name` | string | Last name of the customer | +| ↳ `nickname` | string | Nickname of the customer | +| ↳ `company_name` | string | Business name of the customer | +| ↳ `email_address` | string | Email address of the customer | +| ↳ `phone_number` | string | Phone number of the customer | +| ↳ `address` | object | Physical address | +| ↳ `address_line_1` | string | First line of the address | +| ↳ `address_line_2` | string | Second line of the address | +| ↳ `address_line_3` | string | Third line of the address | +| ↳ `locality` | string | City or town | +| ↳ `sublocality` | string | Neighborhood or district | +| ↳ `administrative_district_level_1` | string | State, province, or region | +| ↳ `postal_code` | string | Postal or ZIP code | +| ↳ `country` | string | Two-letter ISO 3166-1 alpha-2 country code | +| ↳ `first_name` | string | First name of the addressee | +| ↳ `last_name` | string | Last name of the addressee | +| ↳ `birthday` | string | Birthday in YYYY-MM-DD or MM-DD format | +| ↳ `reference_id` | string | Optional external reference for the customer | +| ↳ `note` | string | Note about the customer | +| ↳ `creation_source` | string | How the customer profile was created | +| ↳ `preferences` | json | Customer communication preferences | +| ↳ `group_ids` | array | IDs of customer groups the customer belongs to | +| ↳ `segment_ids` | array | IDs of customer segments the customer belongs to | +| ↳ `version` | number | Optimistic concurrency version of the customer | +| ↳ `created_at` | string | Timestamp when the customer was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the customer was last updated \(RFC 3339\) | +| `metadata` | json | Customer summary metadata | +| ↳ `id` | string | Square customer ID | +| ↳ `email_address` | string | Customer email address | +| ↳ `given_name` | string | Customer first name | +| ↳ `family_name` | string | Customer last name | + +### `square_delete_customer` + +Delete a customer profile from the Square customer directory + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `customerId` | string | Yes | ID of the customer to delete | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `deleted` | boolean | Whether the customer was deleted | +| `id` | string | ID of the deleted customer | + +### `square_list_locations` + +List all locations associated with the Square account + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `locations` | array | Array of location objects | +| ↳ `id` | string | Unique ID for the location | +| ↳ `name` | string | Name of the location | +| ↳ `address` | object | Physical address | +| ↳ `address_line_1` | string | First line of the address | +| ↳ `address_line_2` | string | Second line of the address | +| ↳ `address_line_3` | string | Third line of the address | +| ↳ `locality` | string | City or town | +| ↳ `sublocality` | string | Neighborhood or district | +| ↳ `administrative_district_level_1` | string | State, province, or region | +| ↳ `postal_code` | string | Postal or ZIP code | +| ↳ `country` | string | Two-letter ISO 3166-1 alpha-2 country code | +| ↳ `first_name` | string | First name of the addressee | +| ↳ `last_name` | string | Last name of the addressee | +| ↳ `timezone` | string | IANA timezone of the location | +| ↳ `status` | string | Location status \(ACTIVE or INACTIVE\) | +| ↳ `type` | string | Location type \(PHYSICAL or MOBILE\) | +| ↳ `merchant_id` | string | ID of the merchant that owns the location | +| ↳ `country` | string | Country code of the location | +| ↳ `language_code` | string | Language code of the location | +| ↳ `currency` | string | Currency used by the location | +| ↳ `phone_number` | string | Phone number of the location | +| ↳ `business_name` | string | Business name shown to customers | +| ↳ `business_email` | string | Email of the business | +| ↳ `description` | string | Description of the location | +| ↳ `capabilities` | array | Capabilities of the location \(e.g. CREDIT_CARD_PROCESSING\) | +| ↳ `created_at` | string | Timestamp when the location was created \(RFC 3339\) | +| `metadata` | json | List metadata | +| ↳ `count` | number | Number of locations returned | + +### `square_get_location` + +Retrieve a single location by its ID + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `locationId` | string | Yes | ID of the location to retrieve \(use "main" for the main location\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `location` | object | The retrieved location object | +| ↳ `id` | string | Unique ID for the location | +| ↳ `name` | string | Name of the location | +| ↳ `address` | object | Physical address | +| ↳ `address_line_1` | string | First line of the address | +| ↳ `address_line_2` | string | Second line of the address | +| ↳ `address_line_3` | string | Third line of the address | +| ↳ `locality` | string | City or town | +| ↳ `sublocality` | string | Neighborhood or district | +| ↳ `administrative_district_level_1` | string | State, province, or region | +| ↳ `postal_code` | string | Postal or ZIP code | +| ↳ `country` | string | Two-letter ISO 3166-1 alpha-2 country code | +| ↳ `first_name` | string | First name of the addressee | +| ↳ `last_name` | string | Last name of the addressee | +| ↳ `timezone` | string | IANA timezone of the location | +| ↳ `status` | string | Location status \(ACTIVE or INACTIVE\) | +| ↳ `type` | string | Location type \(PHYSICAL or MOBILE\) | +| ↳ `merchant_id` | string | ID of the merchant that owns the location | +| ↳ `country` | string | Country code of the location | +| ↳ `language_code` | string | Language code of the location | +| ↳ `currency` | string | Currency used by the location | +| ↳ `phone_number` | string | Phone number of the location | +| ↳ `business_name` | string | Business name shown to customers | +| ↳ `business_email` | string | Email of the business | +| ↳ `description` | string | Description of the location | +| ↳ `capabilities` | array | Capabilities of the location \(e.g. CREDIT_CARD_PROCESSING\) | +| ↳ `created_at` | string | Timestamp when the location was created \(RFC 3339\) | +| `metadata` | json | Location summary metadata | +| ↳ `id` | string | Square location ID | +| ↳ `name` | string | Location name | + +### `square_create_order` + +Create an order with line items, taxes, discounts, and fulfillments + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `order` | json | Yes | Square order object including location_id and line_items \(e.g. \{"location_id":"L1","line_items":\[\{"name":"Coffee","quantity":"1","base_price_money":\{"amount":250,"currency":"USD"\}\}\]\}\) | +| `idempotencyKey` | string | No | Unique key to make the request idempotent \(auto-generated if omitted\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `order` | object | The created order object | +| ↳ `id` | string | Unique ID for the order | +| ↳ `location_id` | string | ID of the location for the order | +| ↳ `reference_id` | string | Optional external reference for the order | +| ↳ `customer_id` | string | ID of the associated customer | +| ↳ `state` | string | Order state \(OPEN, COMPLETED, or CANCELED\) | +| ↳ `version` | number | Optimistic concurrency version of the order | +| ↳ `line_items` | array | Line items in the order | +| ↳ `taxes` | array | Taxes applied to the order | +| ↳ `discounts` | array | Discounts applied to the order | +| ↳ `fulfillments` | array | Fulfillments for the order | +| ↳ `net_amounts` | json | Net money amounts for the order | +| ↳ `total_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_tax_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_discount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_service_charge_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_tip_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `created_at` | string | Timestamp when the order was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the order was last updated \(RFC 3339\) | +| ↳ `closed_at` | string | Timestamp when the order was closed \(RFC 3339\) | +| `metadata` | json | Order summary metadata | +| ↳ `id` | string | Square order ID | +| ↳ `state` | string | Current order state | +| ↳ `location_id` | string | Order location ID | + +### `square_get_order` + +Retrieve a single order by its ID + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `orderId` | string | Yes | ID of the order to retrieve | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `order` | object | The retrieved order object | +| ↳ `id` | string | Unique ID for the order | +| ↳ `location_id` | string | ID of the location for the order | +| ↳ `reference_id` | string | Optional external reference for the order | +| ↳ `customer_id` | string | ID of the associated customer | +| ↳ `state` | string | Order state \(OPEN, COMPLETED, or CANCELED\) | +| ↳ `version` | number | Optimistic concurrency version of the order | +| ↳ `line_items` | array | Line items in the order | +| ↳ `taxes` | array | Taxes applied to the order | +| ↳ `discounts` | array | Discounts applied to the order | +| ↳ `fulfillments` | array | Fulfillments for the order | +| ↳ `net_amounts` | json | Net money amounts for the order | +| ↳ `total_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_tax_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_discount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_service_charge_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_tip_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `created_at` | string | Timestamp when the order was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the order was last updated \(RFC 3339\) | +| ↳ `closed_at` | string | Timestamp when the order was closed \(RFC 3339\) | +| `metadata` | json | Order summary metadata | +| ↳ `id` | string | Square order ID | +| ↳ `state` | string | Current order state | +| ↳ `location_id` | string | Order location ID | + +### `square_search_orders` + +Search orders across one or more locations using filters and sorting + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `locationIds` | array | Yes | Array of location IDs to search within | +| `query` | json | No | Square order query object with optional filter and sort \(e.g. \{"filter":\{"state_filter":\{"states":\["OPEN"\]\}\}\}\) | +| `limit` | number | No | Maximum number of results to return per page | +| `cursor` | string | No | Pagination cursor from a previous response | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `orders` | array | Array of matching order objects | +| ↳ `id` | string | Unique ID for the order | +| ↳ `location_id` | string | ID of the location for the order | +| ↳ `reference_id` | string | Optional external reference for the order | +| ↳ `customer_id` | string | ID of the associated customer | +| ↳ `state` | string | Order state \(OPEN, COMPLETED, or CANCELED\) | +| ↳ `version` | number | Optimistic concurrency version of the order | +| ↳ `line_items` | array | Line items in the order | +| ↳ `taxes` | array | Taxes applied to the order | +| ↳ `discounts` | array | Discounts applied to the order | +| ↳ `fulfillments` | array | Fulfillments for the order | +| ↳ `net_amounts` | json | Net money amounts for the order | +| ↳ `total_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_tax_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_discount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_service_charge_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_tip_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `created_at` | string | Timestamp when the order was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the order was last updated \(RFC 3339\) | +| ↳ `closed_at` | string | Timestamp when the order was closed \(RFC 3339\) | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + +### `square_pay_order` + +Pay for an order using one or more already-approved payments + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `orderId` | string | Yes | ID of the order to pay for | +| `paymentIds` | array | No | IDs of approved payments to apply to the order | +| `orderVersion` | number | No | Version of the order being paid \(for optimistic concurrency\) | +| `idempotencyKey` | string | No | Unique key to make the request idempotent \(auto-generated if omitted\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `order` | object | The paid order object | +| ↳ `id` | string | Unique ID for the order | +| ↳ `location_id` | string | ID of the location for the order | +| ↳ `reference_id` | string | Optional external reference for the order | +| ↳ `customer_id` | string | ID of the associated customer | +| ↳ `state` | string | Order state \(OPEN, COMPLETED, or CANCELED\) | +| ↳ `version` | number | Optimistic concurrency version of the order | +| ↳ `line_items` | array | Line items in the order | +| ↳ `taxes` | array | Taxes applied to the order | +| ↳ `discounts` | array | Discounts applied to the order | +| ↳ `fulfillments` | array | Fulfillments for the order | +| ↳ `net_amounts` | json | Net money amounts for the order | +| ↳ `total_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_tax_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_discount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_service_charge_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `total_tip_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `created_at` | string | Timestamp when the order was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the order was last updated \(RFC 3339\) | +| ↳ `closed_at` | string | Timestamp when the order was closed \(RFC 3339\) | +| `metadata` | json | Order summary metadata | +| ↳ `id` | string | Square order ID | +| ↳ `state` | string | Current order state | +| ↳ `location_id` | string | Order location ID | + +### `square_create_invoice` + +Create a draft invoice for an existing order and customer + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `invoice` | json | Yes | Square invoice object including location_id, order_id, primary_recipient, and payment_requests \(e.g. \{"location_id":"L1","order_id":"O1","primary_recipient":\{"customer_id":"C1"\},"payment_requests":\[\{"request_type":"BALANCE","due_date":"2026-07-01"\}\]\}\) | +| `idempotencyKey` | string | No | Unique key to make the request idempotent \(auto-generated if omitted\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `invoice` | object | The created invoice object | +| ↳ `id` | string | Unique ID for the invoice | +| ↳ `version` | number | Optimistic concurrency version of the invoice | +| ↳ `location_id` | string | ID of the location for the invoice | +| ↳ `order_id` | string | ID of the order the invoice bills for | +| ↳ `status` | string | Invoice status \(DRAFT, UNPAID, SCHEDULED, PARTIALLY_PAID, PAID, etc.\) | +| ↳ `invoice_number` | string | Human-readable invoice number | +| ↳ `title` | string | Title of the invoice | +| ↳ `description` | string | Description of the invoice | +| ↳ `public_url` | string | URL where the customer can view and pay the invoice | +| ↳ `primary_recipient` | json | Primary recipient of the invoice | +| ↳ `payment_requests` | array | Payment requests for the invoice | +| ↳ `next_payment_amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `scheduled_at` | string | Timestamp when the invoice is scheduled to be sent \(RFC 3339\) | +| ↳ `timezone` | string | Timezone used for invoice dates | +| ↳ `delivery_method` | string | How the invoice is delivered \(EMAIL, SHARE_MANUALLY, SMS\) | +| ↳ `created_at` | string | Timestamp when the invoice was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the invoice was last updated \(RFC 3339\) | +| `metadata` | json | Invoice summary metadata | +| ↳ `id` | string | Square invoice ID | +| ↳ `status` | string | Current invoice status | +| ↳ `version` | number | Invoice version | + +### `square_get_invoice` + +Retrieve a single invoice by its ID + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `invoiceId` | string | Yes | ID of the invoice to retrieve | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `invoice` | object | The retrieved invoice object | +| ↳ `id` | string | Unique ID for the invoice | +| ↳ `version` | number | Optimistic concurrency version of the invoice | +| ↳ `location_id` | string | ID of the location for the invoice | +| ↳ `order_id` | string | ID of the order the invoice bills for | +| ↳ `status` | string | Invoice status \(DRAFT, UNPAID, SCHEDULED, PARTIALLY_PAID, PAID, etc.\) | +| ↳ `invoice_number` | string | Human-readable invoice number | +| ↳ `title` | string | Title of the invoice | +| ↳ `description` | string | Description of the invoice | +| ↳ `public_url` | string | URL where the customer can view and pay the invoice | +| ↳ `primary_recipient` | json | Primary recipient of the invoice | +| ↳ `payment_requests` | array | Payment requests for the invoice | +| ↳ `next_payment_amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `scheduled_at` | string | Timestamp when the invoice is scheduled to be sent \(RFC 3339\) | +| ↳ `timezone` | string | Timezone used for invoice dates | +| ↳ `delivery_method` | string | How the invoice is delivered \(EMAIL, SHARE_MANUALLY, SMS\) | +| ↳ `created_at` | string | Timestamp when the invoice was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the invoice was last updated \(RFC 3339\) | +| `metadata` | json | Invoice summary metadata | +| ↳ `id` | string | Square invoice ID | +| ↳ `status` | string | Current invoice status | +| ↳ `version` | number | Invoice version | + +### `square_list_invoices` + +List invoices for a specific location + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `locationId` | string | Yes | ID of the location to list invoices for | +| `limit` | number | No | Maximum number of results to return per page | +| `cursor` | string | No | Pagination cursor from a previous response | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `invoices` | array | Array of invoice objects | +| ↳ `id` | string | Unique ID for the invoice | +| ↳ `version` | number | Optimistic concurrency version of the invoice | +| ↳ `location_id` | string | ID of the location for the invoice | +| ↳ `order_id` | string | ID of the order the invoice bills for | +| ↳ `status` | string | Invoice status \(DRAFT, UNPAID, SCHEDULED, PARTIALLY_PAID, PAID, etc.\) | +| ↳ `invoice_number` | string | Human-readable invoice number | +| ↳ `title` | string | Title of the invoice | +| ↳ `description` | string | Description of the invoice | +| ↳ `public_url` | string | URL where the customer can view and pay the invoice | +| ↳ `primary_recipient` | json | Primary recipient of the invoice | +| ↳ `payment_requests` | array | Payment requests for the invoice | +| ↳ `next_payment_amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `scheduled_at` | string | Timestamp when the invoice is scheduled to be sent \(RFC 3339\) | +| ↳ `timezone` | string | Timezone used for invoice dates | +| ↳ `delivery_method` | string | How the invoice is delivered \(EMAIL, SHARE_MANUALLY, SMS\) | +| ↳ `created_at` | string | Timestamp when the invoice was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the invoice was last updated \(RFC 3339\) | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + +### `square_search_invoices` + +Search invoices across one or more locations + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `locationId` | string | Yes | ID of the location to search within \(Square allows one location per search\) | +| `limit` | number | No | Maximum number of results to return per page | +| `cursor` | string | No | Pagination cursor from a previous response | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `invoices` | array | Array of matching invoice objects | +| ↳ `id` | string | Unique ID for the invoice | +| ↳ `version` | number | Optimistic concurrency version of the invoice | +| ↳ `location_id` | string | ID of the location for the invoice | +| ↳ `order_id` | string | ID of the order the invoice bills for | +| ↳ `status` | string | Invoice status \(DRAFT, UNPAID, SCHEDULED, PARTIALLY_PAID, PAID, etc.\) | +| ↳ `invoice_number` | string | Human-readable invoice number | +| ↳ `title` | string | Title of the invoice | +| ↳ `description` | string | Description of the invoice | +| ↳ `public_url` | string | URL where the customer can view and pay the invoice | +| ↳ `primary_recipient` | json | Primary recipient of the invoice | +| ↳ `payment_requests` | array | Payment requests for the invoice | +| ↳ `next_payment_amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `scheduled_at` | string | Timestamp when the invoice is scheduled to be sent \(RFC 3339\) | +| ↳ `timezone` | string | Timezone used for invoice dates | +| ↳ `delivery_method` | string | How the invoice is delivered \(EMAIL, SHARE_MANUALLY, SMS\) | +| ↳ `created_at` | string | Timestamp when the invoice was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the invoice was last updated \(RFC 3339\) | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + +### `square_publish_invoice` + +Publish a draft invoice so it is sent to the customer and becomes payable + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `invoiceId` | string | Yes | ID of the invoice to publish | +| `version` | number | Yes | Current version of the invoice \(use the version returned by Create Invoice\) | +| `idempotencyKey` | string | No | Unique key to make the request idempotent \(auto-generated if omitted\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `invoice` | object | The published invoice object | +| ↳ `id` | string | Unique ID for the invoice | +| ↳ `version` | number | Optimistic concurrency version of the invoice | +| ↳ `location_id` | string | ID of the location for the invoice | +| ↳ `order_id` | string | ID of the order the invoice bills for | +| ↳ `status` | string | Invoice status \(DRAFT, UNPAID, SCHEDULED, PARTIALLY_PAID, PAID, etc.\) | +| ↳ `invoice_number` | string | Human-readable invoice number | +| ↳ `title` | string | Title of the invoice | +| ↳ `description` | string | Description of the invoice | +| ↳ `public_url` | string | URL where the customer can view and pay the invoice | +| ↳ `primary_recipient` | json | Primary recipient of the invoice | +| ↳ `payment_requests` | array | Payment requests for the invoice | +| ↳ `next_payment_amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `scheduled_at` | string | Timestamp when the invoice is scheduled to be sent \(RFC 3339\) | +| ↳ `timezone` | string | Timezone used for invoice dates | +| ↳ `delivery_method` | string | How the invoice is delivered \(EMAIL, SHARE_MANUALLY, SMS\) | +| ↳ `created_at` | string | Timestamp when the invoice was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the invoice was last updated \(RFC 3339\) | +| `metadata` | json | Invoice summary metadata | +| ↳ `id` | string | Square invoice ID | +| ↳ `status` | string | Current invoice status | +| ↳ `version` | number | Invoice version | + +### `square_cancel_invoice` + +Cancel a published invoice that is unpaid or partially paid + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `invoiceId` | string | Yes | ID of the invoice to cancel | +| `version` | number | Yes | Current version of the invoice | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `invoice` | object | The canceled invoice object | +| ↳ `id` | string | Unique ID for the invoice | +| ↳ `version` | number | Optimistic concurrency version of the invoice | +| ↳ `location_id` | string | ID of the location for the invoice | +| ↳ `order_id` | string | ID of the order the invoice bills for | +| ↳ `status` | string | Invoice status \(DRAFT, UNPAID, SCHEDULED, PARTIALLY_PAID, PAID, etc.\) | +| ↳ `invoice_number` | string | Human-readable invoice number | +| ↳ `title` | string | Title of the invoice | +| ↳ `description` | string | Description of the invoice | +| ↳ `public_url` | string | URL where the customer can view and pay the invoice | +| ↳ `primary_recipient` | json | Primary recipient of the invoice | +| ↳ `payment_requests` | array | Payment requests for the invoice | +| ↳ `next_payment_amount_money` | object | Monetary amount with a currency | +| ↳ `amount` | number | Amount in the smallest denomination of the currency \(e.g. cents for USD\) | +| ↳ `currency` | string | Three-letter ISO 4217 currency code \(e.g. USD\) | +| ↳ `scheduled_at` | string | Timestamp when the invoice is scheduled to be sent \(RFC 3339\) | +| ↳ `timezone` | string | Timezone used for invoice dates | +| ↳ `delivery_method` | string | How the invoice is delivered \(EMAIL, SHARE_MANUALLY, SMS\) | +| ↳ `created_at` | string | Timestamp when the invoice was created \(RFC 3339\) | +| ↳ `updated_at` | string | Timestamp when the invoice was last updated \(RFC 3339\) | +| `metadata` | json | Invoice summary metadata | +| ↳ `id` | string | Square invoice ID | +| ↳ `status` | string | Current invoice status | +| ↳ `version` | number | Invoice version | + +### `square_delete_invoice` + +Delete a draft invoice + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `invoiceId` | string | Yes | ID of the draft invoice to delete | +| `version` | number | No | Current version of the invoice \(required if the invoice has been updated\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `deleted` | boolean | Whether the invoice was deleted | +| `id` | string | ID of the deleted invoice | + +### `square_upsert_catalog_object` + +Create or update a catalog object such as an item, variation, or category + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `object` | json | Yes | Square catalog object to create or update. Use ID "#name" for new objects \(e.g. \{"type":"ITEM","id":"#Coffee","item_data":\{"name":"Coffee"\}\}\) | +| `idempotencyKey` | string | No | Unique key to make the request idempotent \(auto-generated if omitted\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `object` | object | The created or updated catalog object | +| ↳ `type` | string | Type of catalog object \(ITEM, ITEM_VARIATION, CATEGORY, IMAGE, etc.\) | +| ↳ `id` | string | Unique ID for the catalog object | +| ↳ `version` | number | Optimistic concurrency version of the object | +| ↳ `updated_at` | string | Timestamp when the object was last updated \(RFC 3339\) | +| ↳ `is_deleted` | boolean | Whether the object is deleted | +| ↳ `present_at_all_locations` | boolean | Whether the object is present at all locations | +| ↳ `item_data` | json | Item-specific data \(when type is ITEM\) | +| ↳ `item_variation_data` | json | Variation-specific data \(when type is ITEM_VARIATION\) | +| ↳ `category_data` | json | Category-specific data \(when type is CATEGORY\) | +| ↳ `image_data` | json | Image-specific data \(when type is IMAGE\) | +| `metadata` | json | Catalog object summary metadata | +| ↳ `id` | string | Square catalog object ID | +| ↳ `type` | string | Catalog object type | +| ↳ `version` | number | Catalog object version | + +### `square_get_catalog_object` + +Retrieve a single catalog object by its ID + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `objectId` | string | Yes | ID of the catalog object to retrieve | +| `includeRelatedObjects` | boolean | No | Whether to include related objects such as an item variations | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `object` | object | The retrieved catalog object | +| ↳ `type` | string | Type of catalog object \(ITEM, ITEM_VARIATION, CATEGORY, IMAGE, etc.\) | +| ↳ `id` | string | Unique ID for the catalog object | +| ↳ `version` | number | Optimistic concurrency version of the object | +| ↳ `updated_at` | string | Timestamp when the object was last updated \(RFC 3339\) | +| ↳ `is_deleted` | boolean | Whether the object is deleted | +| ↳ `present_at_all_locations` | boolean | Whether the object is present at all locations | +| ↳ `item_data` | json | Item-specific data \(when type is ITEM\) | +| ↳ `item_variation_data` | json | Variation-specific data \(when type is ITEM_VARIATION\) | +| ↳ `category_data` | json | Category-specific data \(when type is CATEGORY\) | +| ↳ `image_data` | json | Image-specific data \(when type is IMAGE\) | +| `metadata` | json | Catalog object summary metadata | +| ↳ `id` | string | Square catalog object ID | +| ↳ `type` | string | Catalog object type | +| ↳ `version` | number | Catalog object version | + +### `square_list_catalog` + +List catalog objects, optionally filtered by type + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `types` | string | No | Comma-separated catalog object types to return \(e.g. ITEM,CATEGORY\). Defaults to all top-level types | +| `cursor` | string | No | Pagination cursor from a previous response | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `objects` | array | Array of catalog objects | +| ↳ `type` | string | Type of catalog object \(ITEM, ITEM_VARIATION, CATEGORY, IMAGE, etc.\) | +| ↳ `id` | string | Unique ID for the catalog object | +| ↳ `version` | number | Optimistic concurrency version of the object | +| ↳ `updated_at` | string | Timestamp when the object was last updated \(RFC 3339\) | +| ↳ `is_deleted` | boolean | Whether the object is deleted | +| ↳ `present_at_all_locations` | boolean | Whether the object is present at all locations | +| ↳ `item_data` | json | Item-specific data \(when type is ITEM\) | +| ↳ `item_variation_data` | json | Variation-specific data \(when type is ITEM_VARIATION\) | +| ↳ `category_data` | json | Category-specific data \(when type is CATEGORY\) | +| ↳ `image_data` | json | Image-specific data \(when type is IMAGE\) | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + +### `square_search_catalog_objects` + +Search catalog objects by type and query filters + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `objectTypes` | array | No | Array of catalog object types to search \(e.g. \["ITEM","CATEGORY"\]\) | +| `query` | json | No | Square catalog query object \(e.g. \{"text_query":\{"keywords":\["coffee"\]\}\} or \{"prefix_query":\{...\}\}\) | +| `limit` | number | No | Maximum number of results to return per page | +| `cursor` | string | No | Pagination cursor from a previous response | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `objects` | array | Array of matching catalog objects | +| ↳ `type` | string | Type of catalog object \(ITEM, ITEM_VARIATION, CATEGORY, IMAGE, etc.\) | +| ↳ `id` | string | Unique ID for the catalog object | +| ↳ `version` | number | Optimistic concurrency version of the object | +| ↳ `updated_at` | string | Timestamp when the object was last updated \(RFC 3339\) | +| ↳ `is_deleted` | boolean | Whether the object is deleted | +| ↳ `present_at_all_locations` | boolean | Whether the object is present at all locations | +| ↳ `item_data` | json | Item-specific data \(when type is ITEM\) | +| ↳ `item_variation_data` | json | Variation-specific data \(when type is ITEM_VARIATION\) | +| ↳ `category_data` | json | Category-specific data \(when type is CATEGORY\) | +| ↳ `image_data` | json | Image-specific data \(when type is IMAGE\) | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + +### `square_create_catalog_image` + +Upload an image and attach it to the catalog, optionally to a specific item + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `file` | file | Yes | The image file to upload \(UserFile object\) | +| `fileName` | string | No | Optional filename override for the image | +| `objectId` | string | No | ID of the catalog object \(e.g. an item\) to attach the image to | +| `caption` | string | No | Caption \(alt text\) for the image | +| `idempotencyKey` | string | No | Unique key to make the request idempotent \(auto-generated if omitted\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `object` | object | The created catalog image object | +| ↳ `type` | string | Type of catalog object \(ITEM, ITEM_VARIATION, CATEGORY, IMAGE, etc.\) | +| ↳ `id` | string | Unique ID for the catalog object | +| ↳ `version` | number | Optimistic concurrency version of the object | +| ↳ `updated_at` | string | Timestamp when the object was last updated \(RFC 3339\) | +| ↳ `is_deleted` | boolean | Whether the object is deleted | +| ↳ `present_at_all_locations` | boolean | Whether the object is present at all locations | +| ↳ `item_data` | json | Item-specific data \(when type is ITEM\) | +| ↳ `item_variation_data` | json | Variation-specific data \(when type is ITEM_VARIATION\) | +| ↳ `category_data` | json | Category-specific data \(when type is CATEGORY\) | +| ↳ `image_data` | json | Image-specific data \(when type is IMAGE\) | +| `metadata` | json | Catalog object summary metadata | +| ↳ `id` | string | Square catalog object ID | +| ↳ `type` | string | Catalog object type | +| ↳ `version` | number | Catalog object version | + +### `square_delete_catalog_object` + +Delete a catalog object and its children (e.g. an item and its variations) + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `objectId` | string | Yes | ID of the catalog object to delete | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `deleted` | boolean | Whether the catalog object was deleted | +| `deleted_object_ids` | array | IDs of all catalog objects deleted \(including children\) | +| `deleted_at` | string | Timestamp when the deletion occurred \(RFC 3339\) | + +### `square_batch_retrieve_inventory_counts` + +Retrieve current inventory counts for catalog items across locations + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Square access token \(personal access token\) | +| `catalogObjectIds` | array | No | IDs of the catalog item variations to retrieve counts for | +| `locationIds` | array | No | IDs of the locations to retrieve counts for \(defaults to all locations\) | +| `states` | array | No | Inventory states to filter by \(e.g. IN_STOCK, SOLD, IN_TRANSIT\) | +| `updatedAfter` | string | No | Only return counts updated after this RFC 3339 timestamp | +| `limit` | number | No | Maximum number of results to return per page \(1-1000\) | +| `cursor` | string | No | Pagination cursor from a previous response | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `counts` | array | Array of inventory count objects | +| ↳ `catalog_object_id` | string | ID of the catalog object \(item variation\) being counted | +| ↳ `catalog_object_type` | string | Type of the counted catalog object \(usually ITEM_VARIATION\) | +| ↳ `state` | string | Inventory state \(e.g. IN_STOCK, SOLD, WASTE\) | +| ↳ `location_id` | string | ID of the location for this count | +| ↳ `quantity` | string | Number of units in the given state at the location | +| ↳ `calculated_at` | string | Timestamp when the count was calculated \(RFC 3339\) | +| `metadata` | json | List pagination metadata | +| ↳ `count` | number | Number of items returned in this page | +| ↳ `cursor` | string | Pagination cursor to fetch the next page, if more results exist | + + diff --git a/apps/sim/app/api/tools/square/catalog-image/route.ts b/apps/sim/app/api/tools/square/catalog-image/route.ts new file mode 100644 index 0000000000..622c5c1c7a --- /dev/null +++ b/apps/sim/app/api/tools/square/catalog-image/route.ts @@ -0,0 +1,121 @@ +import { createLogger } from '@sim/logger' +import { getErrorMessage } from '@sim/utils/errors' +import { generateId } from '@sim/utils/id' +import { type NextRequest, NextResponse } from 'next/server' +import { squareCatalogImageContract } from '@/lib/api/contracts/tools/square' +import { parseRequest } from '@/lib/api/server' +import { checkInternalAuth } from '@/lib/auth/hybrid' +import { generateRequestId } from '@/lib/core/utils/request' +import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { processFilesToUserFiles, type RawFileInput } from '@/lib/uploads/utils/file-utils' +import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server' +import { assertToolFileAccess } from '@/app/api/files/authorization' +import { SQUARE_API_VERSION, SQUARE_BASE_URL } from '@/tools/square/types' + +export const dynamic = 'force-dynamic' + +const logger = createLogger('SquareCatalogImageAPI') + +export const POST = withRouteHandler(async (request: NextRequest) => { + const requestId = generateRequestId() + + try { + const authResult = await checkInternalAuth(request, { requireWorkflowId: false }) + + if (!authResult.success || !authResult.userId) { + logger.warn(`[${requestId}] Unauthorized Square catalog image upload: ${authResult.error}`) + return NextResponse.json( + { success: false, error: authResult.error || 'Authentication required' }, + { status: 401 } + ) + } + + const parsed = await parseRequest(squareCatalogImageContract, request, {}) + if (!parsed.success) return parsed.response + const validatedData = parsed.data.body + + if (!validatedData.file) { + return NextResponse.json({ success: false, error: 'File is required' }, { status: 400 }) + } + + const userFiles = processFilesToUserFiles( + [validatedData.file as RawFileInput], + requestId, + logger + ) + + if (userFiles.length === 0) { + return NextResponse.json({ success: false, error: 'Invalid file input' }, { status: 400 }) + } + + const userFile = userFiles[0] + const denied = await assertToolFileAccess(userFile.key, authResult.userId, requestId, logger) + if (denied) return denied + + const fileBuffer = await downloadFileFromStorage(userFile, requestId, logger) + const fileName = validatedData.fileName || userFile.name + const mimeType = userFile.type || 'application/octet-stream' + + const imageRequest: Record = { + idempotency_key: validatedData.idempotencyKey || generateId(), + image: { + type: 'IMAGE', + id: '#square_catalog_image', + image_data: validatedData.caption ? { caption: validatedData.caption } : {}, + }, + } + if (validatedData.objectId) imageRequest.object_id = validatedData.objectId + + const formData = new FormData() + formData.append('request', JSON.stringify(imageRequest)) + formData.append('file', new Blob([new Uint8Array(fileBuffer)], { type: mimeType }), fileName) + + const response = await fetch(`${SQUARE_BASE_URL}/v2/catalog/images`, { + method: 'POST', + headers: { + Authorization: `Bearer ${validatedData.accessToken}`, + 'Square-Version': SQUARE_API_VERSION, + }, + body: formData, + }) + + if (!response.ok) { + const errorText = await response.text() + let detail: string | undefined + try { + detail = JSON.parse(errorText)?.errors?.[0]?.detail + } catch { + detail = undefined + } + logger.error(`[${requestId}] Square API error:`, { status: response.status, body: errorText }) + return NextResponse.json( + { + success: false, + error: detail || `Failed to upload catalog image (HTTP ${response.status})`, + }, + { status: response.status } + ) + } + + const data = await response.json() + const object = data.image ?? {} + + return NextResponse.json({ + success: true, + output: { + object, + metadata: { + id: object.id ?? '', + type: object.type ?? null, + version: object.version ?? null, + }, + }, + }) + } catch (error) { + logger.error(`[${requestId}] Unexpected error:`, error) + return NextResponse.json( + { success: false, error: getErrorMessage(error, 'Unknown error') }, + { status: 500 } + ) + } +}) diff --git a/apps/sim/blocks/blocks/square.ts b/apps/sim/blocks/blocks/square.ts new file mode 100644 index 0000000000..17d4f7c295 --- /dev/null +++ b/apps/sim/blocks/blocks/square.ts @@ -0,0 +1,978 @@ +import { SquareIcon } from '@/components/icons' +import type { BlockConfig, BlockMeta } from '@/blocks/types' +import { AuthMode, IntegrationType } from '@/blocks/types' +import { normalizeFileInput } from '@/blocks/utils' +import type { SquareResponse } from '@/tools/square/types' + +export const SquareBlock: BlockConfig = { + type: 'square', + name: 'Square', + description: 'Process payments and manage Square commerce data', + authMode: AuthMode.ApiKey, + longDescription: + 'Integrate Square into the workflow. Take and refund payments, manage customers, build catalog items and images, create and search orders, and issue invoices. Authenticate with a Square access token (personal access token).', + docsLink: 'https://docs.sim.ai/integrations/square', + category: 'tools', + integrationType: IntegrationType.Commerce, + bgColor: '#000000', + icon: SquareIcon, + + subBlocks: [ + { + id: 'operation', + title: 'Operation', + type: 'dropdown', + options: [ + // Payments + { label: 'Create Payment', id: 'create_payment' }, + { label: 'Get Payment', id: 'get_payment' }, + { label: 'List Payments', id: 'list_payments' }, + { label: 'Cancel Payment', id: 'cancel_payment' }, + { label: 'Complete Payment', id: 'complete_payment' }, + // Refunds + { label: 'Refund Payment', id: 'refund_payment' }, + { label: 'Get Refund', id: 'get_refund' }, + { label: 'List Refunds', id: 'list_refunds' }, + // Customers + { label: 'Create Customer', id: 'create_customer' }, + { label: 'Get Customer', id: 'get_customer' }, + { label: 'List Customers', id: 'list_customers' }, + { label: 'Search Customers', id: 'search_customers' }, + { label: 'Update Customer', id: 'update_customer' }, + { label: 'Delete Customer', id: 'delete_customer' }, + // Locations + { label: 'List Locations', id: 'list_locations' }, + { label: 'Get Location', id: 'get_location' }, + // Orders + { label: 'Create Order', id: 'create_order' }, + { label: 'Get Order', id: 'get_order' }, + { label: 'Search Orders', id: 'search_orders' }, + { label: 'Pay Order', id: 'pay_order' }, + // Invoices + { label: 'Create Invoice', id: 'create_invoice' }, + { label: 'Get Invoice', id: 'get_invoice' }, + { label: 'List Invoices', id: 'list_invoices' }, + { label: 'Search Invoices', id: 'search_invoices' }, + { label: 'Publish Invoice', id: 'publish_invoice' }, + { label: 'Cancel Invoice', id: 'cancel_invoice' }, + { label: 'Delete Invoice', id: 'delete_invoice' }, + // Catalog + { label: 'Upsert Catalog Object', id: 'upsert_catalog_object' }, + { label: 'Get Catalog Object', id: 'get_catalog_object' }, + { label: 'List Catalog', id: 'list_catalog' }, + { label: 'Search Catalog Objects', id: 'search_catalog_objects' }, + { label: 'Create Catalog Image', id: 'create_catalog_image' }, + { label: 'Delete Catalog Object', id: 'delete_catalog_object' }, + // Inventory + { label: 'Batch Retrieve Inventory Counts', id: 'batch_retrieve_inventory_counts' }, + ], + value: () => 'create_payment', + }, + { + id: 'apiKey', + title: 'Square Access Token', + type: 'short-input', + password: true, + placeholder: 'Enter your Square access token', + required: true, + }, + + // Payments + { + id: 'sourceId', + title: 'Source ID', + type: 'short-input', + placeholder: 'Card nonce, card-on-file ID, or wallet token', + condition: { field: 'operation', value: 'create_payment' }, + required: { field: 'operation', value: 'create_payment' }, + }, + { + id: 'paymentId', + title: 'Payment ID', + type: 'short-input', + placeholder: 'Square payment ID', + condition: { + field: 'operation', + value: ['get_payment', 'refund_payment', 'cancel_payment', 'complete_payment'], + }, + required: { + field: 'operation', + value: ['get_payment', 'refund_payment', 'cancel_payment', 'complete_payment'], + }, + }, + { + id: 'refundId', + title: 'Refund ID', + type: 'short-input', + placeholder: 'Square refund ID', + condition: { field: 'operation', value: 'get_refund' }, + required: { field: 'operation', value: 'get_refund' }, + }, + { + id: 'status', + title: 'Status', + type: 'short-input', + placeholder: 'Filter by status (e.g. COMPLETED)', + condition: { field: 'operation', value: 'list_refunds' }, + mode: 'advanced', + }, + { + id: 'amount', + title: 'Amount', + type: 'short-input', + placeholder: 'Smallest denomination (e.g. 1000 for $10.00)', + condition: { field: 'operation', value: ['create_payment', 'refund_payment'] }, + required: { field: 'operation', value: ['create_payment', 'refund_payment'] }, + }, + { + id: 'currency', + title: 'Currency', + type: 'short-input', + placeholder: 'ISO 4217 code (e.g. USD)', + condition: { field: 'operation', value: ['create_payment', 'refund_payment'] }, + required: { field: 'operation', value: ['create_payment', 'refund_payment'] }, + }, + { + id: 'reason', + title: 'Refund Reason', + type: 'short-input', + placeholder: 'Reason for the refund', + condition: { field: 'operation', value: 'refund_payment' }, + }, + { + id: 'versionToken', + title: 'Version Token', + type: 'short-input', + placeholder: 'Optional version token for concurrency control', + condition: { field: 'operation', value: 'complete_payment' }, + mode: 'advanced', + }, + { + id: 'autocomplete', + title: 'Capture Immediately', + type: 'dropdown', + options: [ + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + condition: { field: 'operation', value: 'create_payment' }, + mode: 'advanced', + }, + { + id: 'beginTime', + title: 'Begin Time', + type: 'short-input', + placeholder: 'RFC 3339 timestamp', + condition: { field: 'operation', value: ['list_payments', 'list_refunds'] }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate an RFC 3339 timestamp. Return ONLY the timestamp string.', + generationType: 'timestamp', + }, + }, + { + id: 'endTime', + title: 'End Time', + type: 'short-input', + placeholder: 'RFC 3339 timestamp', + condition: { field: 'operation', value: ['list_payments', 'list_refunds'] }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate an RFC 3339 timestamp. Return ONLY the timestamp string.', + generationType: 'timestamp', + }, + }, + + // Customers + { + id: 'customerId', + title: 'Customer ID', + type: 'short-input', + placeholder: 'Square customer ID', + condition: { + field: 'operation', + value: ['create_payment', 'get_customer', 'update_customer', 'delete_customer'], + }, + required: { + field: 'operation', + value: ['get_customer', 'update_customer', 'delete_customer'], + }, + }, + { + id: 'givenName', + title: 'First Name', + type: 'short-input', + placeholder: 'Customer first name', + condition: { field: 'operation', value: ['create_customer', 'update_customer'] }, + }, + { + id: 'familyName', + title: 'Last Name', + type: 'short-input', + placeholder: 'Customer last name', + condition: { field: 'operation', value: ['create_customer', 'update_customer'] }, + }, + { + id: 'companyName', + title: 'Company Name', + type: 'short-input', + placeholder: 'Customer business name', + condition: { field: 'operation', value: ['create_customer', 'update_customer'] }, + mode: 'advanced', + }, + { + id: 'nickname', + title: 'Nickname', + type: 'short-input', + placeholder: 'Customer nickname', + condition: { field: 'operation', value: ['create_customer', 'update_customer'] }, + mode: 'advanced', + }, + { + id: 'emailAddress', + title: 'Email Address', + type: 'short-input', + placeholder: 'customer@example.com', + condition: { field: 'operation', value: ['create_customer', 'update_customer'] }, + }, + { + id: 'phoneNumber', + title: 'Phone Number', + type: 'short-input', + placeholder: '+15551234567', + condition: { field: 'operation', value: ['create_customer', 'update_customer'] }, + mode: 'advanced', + }, + { + id: 'birthday', + title: 'Birthday', + type: 'short-input', + placeholder: 'YYYY-MM-DD or MM-DD', + condition: { field: 'operation', value: ['create_customer', 'update_customer'] }, + mode: 'advanced', + }, + { + id: 'address', + title: 'Address (JSON)', + type: 'code', + language: 'json', + placeholder: '{"address_line_1": "123 Main St", "locality": "New York", "country": "US"}', + condition: { field: 'operation', value: ['create_customer', 'update_customer'] }, + mode: 'advanced', + }, + { + id: 'sortField', + title: 'Sort Field', + type: 'dropdown', + options: [ + { label: 'Default', id: 'DEFAULT' }, + { label: 'Created At', id: 'CREATED_AT' }, + ], + condition: { field: 'operation', value: 'list_customers' }, + mode: 'advanced', + }, + { + id: 'sortOrder', + title: 'Sort Order', + type: 'dropdown', + options: [ + { label: 'Ascending', id: 'ASC' }, + { label: 'Descending', id: 'DESC' }, + ], + condition: { field: 'operation', value: 'list_customers' }, + mode: 'advanced', + }, + + // Shared note / reference (payments + customers) + { + id: 'note', + title: 'Note', + type: 'long-input', + placeholder: 'Optional note', + condition: { + field: 'operation', + value: ['create_payment', 'create_customer', 'update_customer'], + }, + mode: 'advanced', + }, + { + id: 'referenceId', + title: 'Reference ID', + type: 'short-input', + placeholder: 'Optional external reference', + condition: { + field: 'operation', + value: ['create_payment', 'create_customer', 'update_customer'], + }, + mode: 'advanced', + }, + + // Search query — shared across the three search operations. The placeholder + // stays schema-neutral (each endpoint expects a different query shape) and + // the examples for each are spelled out in the wand prompt. + { + id: 'query', + title: 'Query (JSON)', + type: 'code', + language: 'json', + placeholder: 'Square search query JSON for the selected operation', + condition: { + field: 'operation', + value: ['search_customers', 'search_orders', 'search_catalog_objects'], + }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate a Square search query JSON object for the selected operation. For Search Customers use a filter like {"filter":{"email_address":{"exact":"a@b.com"}}}; for Search Orders use {"filter":{"state_filter":{"states":["OPEN"]}}}; for Search Catalog Objects use {"text_query":{"keywords":["coffee"]}}. Return ONLY the JSON object.', + generationType: 'json-object', + }, + }, + + // Orders + { + id: 'order', + title: 'Order (JSON)', + type: 'code', + language: 'json', + placeholder: + '{"location_id": "L123", "line_items": [{"name": "Coffee", "quantity": "1", "base_price_money": {"amount": 250, "currency": "USD"}}]}', + condition: { field: 'operation', value: 'create_order' }, + required: { field: 'operation', value: 'create_order' }, + wandConfig: { + enabled: true, + prompt: + 'Generate a Square order JSON object with a location_id and line_items. Return ONLY the JSON object.', + generationType: 'json-object', + }, + }, + { + id: 'orderId', + title: 'Order ID', + type: 'short-input', + placeholder: 'Square order ID', + condition: { field: 'operation', value: ['create_payment', 'get_order', 'pay_order'] }, + required: { field: 'operation', value: ['get_order', 'pay_order'] }, + }, + { + id: 'paymentIds', + title: 'Payment IDs (JSON Array)', + type: 'code', + language: 'json', + placeholder: '["paymentId1", "paymentId2"]', + condition: { field: 'operation', value: 'pay_order' }, + mode: 'advanced', + }, + { + id: 'orderVersion', + title: 'Order Version', + type: 'short-input', + placeholder: 'Current order version', + condition: { field: 'operation', value: 'pay_order' }, + mode: 'advanced', + }, + { + id: 'locationIds', + title: 'Location IDs (JSON Array)', + type: 'code', + language: 'json', + placeholder: '["L123", "L456"]', + condition: { + field: 'operation', + value: ['search_orders', 'batch_retrieve_inventory_counts'], + }, + required: { field: 'operation', value: 'search_orders' }, + }, + + // Invoices + { + id: 'invoice', + title: 'Invoice (JSON)', + type: 'code', + language: 'json', + placeholder: + '{"location_id": "L123", "order_id": "O123", "primary_recipient": {"customer_id": "C123"}, "payment_requests": [{"request_type": "BALANCE"}]}', + condition: { field: 'operation', value: 'create_invoice' }, + required: { field: 'operation', value: 'create_invoice' }, + wandConfig: { + enabled: true, + prompt: + 'Generate a Square invoice JSON object with location_id, order_id, primary_recipient, and payment_requests. Return ONLY the JSON object.', + generationType: 'json-object', + }, + }, + { + id: 'invoiceId', + title: 'Invoice ID', + type: 'short-input', + placeholder: 'Square invoice ID', + condition: { + field: 'operation', + value: ['get_invoice', 'publish_invoice', 'cancel_invoice', 'delete_invoice'], + }, + required: { + field: 'operation', + value: ['get_invoice', 'publish_invoice', 'cancel_invoice', 'delete_invoice'], + }, + }, + { + id: 'version', + title: 'Invoice Version', + type: 'short-input', + placeholder: 'Current invoice version (e.g. 0)', + condition: { + field: 'operation', + value: ['publish_invoice', 'cancel_invoice', 'delete_invoice'], + }, + required: { field: 'operation', value: ['publish_invoice', 'cancel_invoice'] }, + }, + + // Catalog + { + id: 'object', + title: 'Catalog Object (JSON)', + type: 'code', + language: 'json', + placeholder: '{"type": "ITEM", "id": "#Coffee", "item_data": {"name": "Coffee"}}', + condition: { field: 'operation', value: 'upsert_catalog_object' }, + required: { field: 'operation', value: 'upsert_catalog_object' }, + wandConfig: { + enabled: true, + prompt: + 'Generate a Square catalog object JSON for upsert. Use a temporary id like "#Name" for new objects. Return ONLY the JSON object.', + generationType: 'json-object', + }, + }, + { + id: 'objectId', + title: 'Catalog Object ID', + type: 'short-input', + placeholder: 'Square catalog object ID', + condition: { + field: 'operation', + value: ['get_catalog_object', 'create_catalog_image', 'delete_catalog_object'], + }, + required: { field: 'operation', value: ['get_catalog_object', 'delete_catalog_object'] }, + }, + { + id: 'catalogObjectIds', + title: 'Catalog Object IDs (JSON Array)', + type: 'code', + language: 'json', + placeholder: '["variationId1", "variationId2"]', + condition: { field: 'operation', value: 'batch_retrieve_inventory_counts' }, + mode: 'advanced', + }, + { + id: 'states', + title: 'Inventory States (JSON Array)', + type: 'code', + language: 'json', + placeholder: '["IN_STOCK", "SOLD"]', + condition: { field: 'operation', value: 'batch_retrieve_inventory_counts' }, + mode: 'advanced', + }, + { + id: 'updatedAfter', + title: 'Updated After', + type: 'short-input', + placeholder: 'RFC 3339 timestamp', + condition: { field: 'operation', value: 'batch_retrieve_inventory_counts' }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate an RFC 3339 timestamp. Return ONLY the timestamp string.', + generationType: 'timestamp', + }, + }, + { + id: 'includeRelatedObjects', + title: 'Include Related Objects', + type: 'dropdown', + options: [ + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + condition: { field: 'operation', value: 'get_catalog_object' }, + mode: 'advanced', + }, + { + id: 'types', + title: 'Types', + type: 'short-input', + placeholder: 'Comma-separated (e.g. ITEM,CATEGORY)', + condition: { field: 'operation', value: 'list_catalog' }, + mode: 'advanced', + }, + { + id: 'objectTypes', + title: 'Object Types (JSON Array)', + type: 'code', + language: 'json', + placeholder: '["ITEM", "CATEGORY"]', + condition: { field: 'operation', value: 'search_catalog_objects' }, + mode: 'advanced', + }, + + // Catalog image upload (file) + { + id: 'uploadFile', + title: 'Image File', + type: 'file-upload', + canonicalParamId: 'file', + placeholder: 'Upload an image', + acceptedTypes: 'image/*', + mode: 'basic', + multiple: false, + condition: { field: 'operation', value: 'create_catalog_image' }, + required: { field: 'operation', value: 'create_catalog_image' }, + }, + { + id: 'fileRef', + title: 'Image File', + type: 'short-input', + canonicalParamId: 'file', + placeholder: 'Reference an image from previous blocks', + mode: 'advanced', + condition: { field: 'operation', value: 'create_catalog_image' }, + required: { field: 'operation', value: 'create_catalog_image' }, + }, + { + id: 'fileName', + title: 'File Name', + type: 'short-input', + placeholder: 'Optional filename override', + condition: { field: 'operation', value: 'create_catalog_image' }, + mode: 'advanced', + }, + { + id: 'caption', + title: 'Caption', + type: 'short-input', + placeholder: 'Image caption (alt text)', + condition: { field: 'operation', value: 'create_catalog_image' }, + }, + + // Shared pagination (list / search) + { + id: 'locationId', + title: 'Location ID', + type: 'short-input', + placeholder: 'Square location ID', + condition: { + field: 'operation', + value: [ + 'create_payment', + 'list_payments', + 'list_invoices', + 'search_invoices', + 'list_refunds', + 'get_location', + ], + }, + required: { field: 'operation', value: ['list_invoices', 'search_invoices', 'get_location'] }, + }, + { + id: 'limit', + title: 'Limit', + type: 'short-input', + placeholder: 'Max results per page', + condition: { + field: 'operation', + value: [ + 'list_payments', + 'list_refunds', + 'list_customers', + 'search_customers', + 'search_orders', + 'list_invoices', + 'search_invoices', + 'search_catalog_objects', + 'batch_retrieve_inventory_counts', + ], + }, + mode: 'advanced', + }, + { + id: 'cursor', + title: 'Cursor', + type: 'short-input', + placeholder: 'Pagination cursor from a previous response', + condition: { + field: 'operation', + value: [ + 'list_payments', + 'list_refunds', + 'list_customers', + 'search_customers', + 'search_orders', + 'list_invoices', + 'search_invoices', + 'search_catalog_objects', + 'list_catalog', + 'batch_retrieve_inventory_counts', + ], + }, + mode: 'advanced', + }, + + // Idempotency (create-style operations) + { + id: 'idempotencyKey', + title: 'Idempotency Key', + type: 'short-input', + placeholder: 'Optional unique key (auto-generated if omitted)', + condition: { + field: 'operation', + value: [ + 'create_payment', + 'refund_payment', + 'create_customer', + 'create_order', + 'pay_order', + 'create_invoice', + 'publish_invoice', + 'upsert_catalog_object', + 'create_catalog_image', + ], + }, + mode: 'advanced', + }, + ], + + tools: { + access: [ + 'square_create_payment', + 'square_get_payment', + 'square_list_payments', + 'square_cancel_payment', + 'square_complete_payment', + 'square_refund_payment', + 'square_get_refund', + 'square_list_refunds', + 'square_create_customer', + 'square_get_customer', + 'square_list_customers', + 'square_search_customers', + 'square_update_customer', + 'square_delete_customer', + 'square_list_locations', + 'square_get_location', + 'square_create_order', + 'square_get_order', + 'square_search_orders', + 'square_pay_order', + 'square_create_invoice', + 'square_get_invoice', + 'square_list_invoices', + 'square_search_invoices', + 'square_publish_invoice', + 'square_cancel_invoice', + 'square_delete_invoice', + 'square_upsert_catalog_object', + 'square_get_catalog_object', + 'square_list_catalog', + 'square_search_catalog_objects', + 'square_create_catalog_image', + 'square_delete_catalog_object', + 'square_batch_retrieve_inventory_counts', + ], + config: { + tool: (params) => `square_${params.operation}`, + params: (params) => { + const { + operation, + address, + query, + order, + invoice, + object, + locationIds, + objectTypes, + paymentIds, + catalogObjectIds, + states, + amount, + limit, + version, + orderVersion, + autocomplete, + includeRelatedObjects, + ...rest + } = params + + // The basic/advanced image inputs are collapsed into the canonical `file` + // param before this runs, so normalize from params.file. + const normalizedFile = normalizeFileInput(params.file, { single: true }) + + // Parse a JSON-typed input, naming the field in any error so the user + // knows exactly which input to fix, and validating the parsed shape so a + // valid-but-wrong-type value (e.g. a string where an array is expected) + // fails locally instead of as a confusing Square API error. + const parseJsonField = ( + value: unknown, + field: string, + expected: 'object' | 'array' + ): unknown => { + if (value === undefined || value === null || value === '') return undefined + let parsed: unknown = value + if (typeof value === 'string') { + try { + parsed = JSON.parse(value) + } catch (error) { + throw new Error( + `Invalid JSON in "${field}": ${error instanceof Error ? error.message : 'unknown error'}` + ) + } + } + if (expected === 'array' && !Array.isArray(parsed)) { + throw new Error(`"${field}" must be a JSON array`) + } + if ( + expected === 'object' && + (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) + ) { + throw new Error(`"${field}" must be a JSON object`) + } + return parsed + } + + const parsedAddress = parseJsonField(address, 'address', 'object') + const parsedQuery = parseJsonField(query, 'query', 'object') + const parsedOrder = parseJsonField(order, 'order', 'object') + const parsedInvoice = parseJsonField(invoice, 'invoice', 'object') + const parsedObject = parseJsonField(object, 'object', 'object') + const parsedLocationIds = parseJsonField(locationIds, 'locationIds', 'array') + const parsedObjectTypes = parseJsonField(objectTypes, 'objectTypes', 'array') + const parsedPaymentIds = parseJsonField(paymentIds, 'paymentIds', 'array') + const parsedCatalogObjectIds = parseJsonField(catalogObjectIds, 'catalogObjectIds', 'array') + const parsedStates = parseJsonField(states, 'states', 'array') + + // Coerce a numeric input, failing locally with a clear message rather than + // forwarding NaN to Square when the value is non-numeric. + const coerceNumber = (value: unknown, field: string): number | undefined => { + if (value === undefined || value === null || value === '') return undefined + const num = Number(value) + if (!Number.isFinite(num)) { + throw new Error(`"${field}" must be a valid number`) + } + return num + } + + // Accept both the dropdown's string values and real booleans (which can + // arrive via connected blocks or templated inputs). + const coerceBoolean = (value: unknown): boolean => value === true || value === 'true' + + const coercedAmount = coerceNumber(amount, 'amount') + const coercedLimit = coerceNumber(limit, 'limit') + const coercedVersion = coerceNumber(version, 'version') + const coercedOrderVersion = coerceNumber(orderVersion, 'orderVersion') + + return { + ...rest, + ...(normalizedFile && { file: normalizedFile }), + ...(parsedAddress !== undefined && { address: parsedAddress }), + ...(parsedQuery !== undefined && { query: parsedQuery }), + ...(parsedOrder !== undefined && { order: parsedOrder }), + ...(parsedInvoice !== undefined && { invoice: parsedInvoice }), + ...(parsedObject !== undefined && { object: parsedObject }), + ...(parsedLocationIds !== undefined && { locationIds: parsedLocationIds }), + ...(parsedObjectTypes !== undefined && { objectTypes: parsedObjectTypes }), + ...(parsedPaymentIds !== undefined && { paymentIds: parsedPaymentIds }), + ...(parsedCatalogObjectIds !== undefined && { catalogObjectIds: parsedCatalogObjectIds }), + ...(parsedStates !== undefined && { states: parsedStates }), + ...(coercedAmount !== undefined && { amount: coercedAmount }), + ...(coercedLimit !== undefined && { limit: coercedLimit }), + ...(coercedVersion !== undefined && { version: coercedVersion }), + ...(coercedOrderVersion !== undefined && { orderVersion: coercedOrderVersion }), + ...(autocomplete !== undefined && { autocomplete: coerceBoolean(autocomplete) }), + ...(includeRelatedObjects !== undefined && { + includeRelatedObjects: coerceBoolean(includeRelatedObjects), + }), + } + }, + }, + }, + + inputs: { + operation: { type: 'string', description: 'Operation to perform' }, + apiKey: { type: 'string', description: 'Square access token' }, + sourceId: { type: 'string', description: 'Payment source ID' }, + paymentId: { type: 'string', description: 'Payment ID' }, + refundId: { type: 'string', description: 'Refund ID' }, + status: { type: 'string', description: 'Status filter' }, + amount: { type: 'number', description: 'Amount in smallest currency denomination' }, + currency: { type: 'string', description: 'ISO 4217 currency code' }, + reason: { type: 'string', description: 'Refund reason' }, + versionToken: { type: 'string', description: 'Version token for payment concurrency control' }, + autocomplete: { type: 'boolean', description: 'Capture payment immediately' }, + beginTime: { type: 'string', description: 'Start of the reporting period (RFC 3339)' }, + endTime: { type: 'string', description: 'End of the reporting period (RFC 3339)' }, + customerId: { type: 'string', description: 'Customer ID' }, + givenName: { type: 'string', description: 'Customer first name' }, + familyName: { type: 'string', description: 'Customer last name' }, + companyName: { type: 'string', description: 'Customer company name' }, + nickname: { type: 'string', description: 'Customer nickname' }, + emailAddress: { type: 'string', description: 'Customer email address' }, + phoneNumber: { type: 'string', description: 'Customer phone number' }, + birthday: { type: 'string', description: 'Customer birthday (YYYY-MM-DD or MM-DD)' }, + address: { type: 'json', description: 'Customer address object' }, + note: { type: 'string', description: 'Note' }, + referenceId: { type: 'string', description: 'External reference ID' }, + sortField: { type: 'string', description: 'Field to sort by' }, + sortOrder: { type: 'string', description: 'Sort order (ASC or DESC)' }, + query: { type: 'json', description: 'Search query object' }, + order: { type: 'json', description: 'Order object' }, + orderId: { type: 'string', description: 'Order ID' }, + orderVersion: { type: 'number', description: 'Order version for payment' }, + paymentIds: { type: 'json', description: 'Array of payment IDs to apply to an order' }, + locationIds: { type: 'json', description: 'Array of location IDs' }, + invoice: { type: 'json', description: 'Invoice object' }, + invoiceId: { type: 'string', description: 'Invoice ID' }, + version: { type: 'number', description: 'Invoice version' }, + object: { type: 'json', description: 'Catalog object' }, + objectId: { type: 'string', description: 'Catalog object ID' }, + includeRelatedObjects: { type: 'boolean', description: 'Include related catalog objects' }, + types: { type: 'string', description: 'Comma-separated catalog object types' }, + objectTypes: { type: 'json', description: 'Array of catalog object types to search' }, + catalogObjectIds: { type: 'json', description: 'Array of catalog object IDs for inventory' }, + states: { type: 'json', description: 'Array of inventory states to filter by' }, + updatedAfter: { + type: 'string', + description: 'Only return inventory counts updated after this time', + }, + file: { type: 'json', description: 'Image file to upload (canonical param)' }, + fileName: { type: 'string', description: 'Filename override for the image' }, + caption: { type: 'string', description: 'Image caption' }, + locationId: { type: 'string', description: 'Location ID' }, + limit: { type: 'number', description: 'Maximum results to return' }, + cursor: { type: 'string', description: 'Pagination cursor' }, + idempotencyKey: { type: 'string', description: 'Idempotency key' }, + }, + + outputs: { + payment: { type: 'json', description: 'Payment object' }, + payments: { type: 'json', description: 'Array of payment objects' }, + refund: { type: 'json', description: 'Refund object' }, + refunds: { type: 'json', description: 'Array of refund objects' }, + customer: { type: 'json', description: 'Customer object' }, + customers: { type: 'json', description: 'Array of customer objects' }, + location: { type: 'json', description: 'Location object' }, + locations: { type: 'json', description: 'Array of location objects' }, + order: { type: 'json', description: 'Order object' }, + orders: { type: 'json', description: 'Array of order objects' }, + invoice: { type: 'json', description: 'Invoice object' }, + invoices: { type: 'json', description: 'Array of invoice objects' }, + object: { type: 'json', description: 'Catalog object' }, + objects: { type: 'json', description: 'Array of catalog objects' }, + counts: { type: 'json', description: 'Array of inventory count objects' }, + deleted: { type: 'boolean', description: 'Whether the resource was deleted' }, + deleted_object_ids: { type: 'json', description: 'IDs of deleted catalog objects' }, + deleted_at: { type: 'string', description: 'Timestamp when deletion occurred' }, + id: { type: 'string', description: 'ID of the affected resource' }, + metadata: { type: 'json', description: 'Operation summary metadata' }, + }, +} + +export const SquareBlockMeta = { + tags: ['payments', 'subscriptions', 'automation'], + url: 'https://squareup.com', + templates: [ + { + icon: SquareIcon, + title: 'Daily sales summary', + prompt: + 'Build a scheduled daily workflow that lists Square payments from the previous day across all locations, totals gross sales, refunds, and net revenue, writes the figures to a table for historical tracking, and posts a Slack summary with day-over-day trends.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'reporting', 'founder'], + alsoIntegrations: ['slack'], + }, + { + icon: SquareIcon, + title: 'Refund pattern monitor', + prompt: + 'Create a scheduled weekly workflow that lists Square payments and their refunds, classifies each refund by reason and location, flags any location with an unusually high refund rate, and emails finance a narrative report with recommended actions.', + modules: ['scheduled', 'agent', 'files', 'workflows'], + category: 'operations', + tags: ['finance', 'analysis', 'monitoring'], + alsoIntegrations: ['gmail'], + }, + { + icon: SquareIcon, + title: 'New customer welcome', + prompt: + 'Build a workflow that takes a new Square customer, creates a welcome email tailored to their purchase, adds them to an onboarding tracking table, and posts a notification to the customer success Slack channel.', + modules: ['tables', 'agent', 'workflows'], + category: 'operations', + tags: ['sales', 'automation'], + alsoIntegrations: ['gmail', 'slack'], + }, + { + icon: SquareIcon, + title: 'Invoice chase automation', + prompt: + 'Create a scheduled workflow that lists Square invoices for a location, finds those that are unpaid past their due date, sends a polite reminder email per customer, and logs every chase action to a collections table.', + modules: ['scheduled', 'tables', 'agent', 'workflows'], + category: 'operations', + tags: ['finance', 'automation', 'reporting'], + alsoIntegrations: ['gmail'], + }, + { + icon: SquareIcon, + title: 'Catalog image enrichment', + prompt: + 'Build a workflow that lists Square catalog items missing images, generates a product image for each one, uploads it as a catalog image attached to the item, and writes a report of which items were updated.', + modules: ['agent', 'files', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'automation'], + }, + { + icon: SquareIcon, + title: 'Low-stock reorder alerts', + prompt: + 'Create a scheduled workflow that lists the Square catalog, identifies items flagged as low or out of stock, drafts a reorder summary grouped by supplier, and posts it to a Slack purchasing channel with the items and quantities to reorder.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'operations', + tags: ['ecommerce', 'operations'], + alsoIntegrations: ['slack'], + }, + { + icon: SquareIcon, + title: 'Customer purchase history lookup', + prompt: + 'Build a workflow that searches Square customers by email, pulls their orders and payments, summarizes lifetime spend and most-purchased items, and returns a concise profile the support team can use during a conversation.', + modules: ['agent', 'workflows'], + category: 'support', + tags: ['support', 'analysis'], + }, + ], + skills: [ + { + name: 'take-payment', + description: 'Take a Square payment from a payment source and confirm the result.', + content: + '# Take Payment\n\nCharge a customer using Square.\n\n## Steps\n1. Run Create Payment with the source ID (card nonce or card on file), the amount in the smallest denomination, and the currency.\n2. Optionally attach a customer ID, location ID, or order ID.\n3. Confirm the result with Get Payment if you need the latest status.\n\n## Output\nReturn the payment ID, status (APPROVED, COMPLETED, or FAILED), and the amount charged. If a refund is needed, run Refund Payment with the payment ID.', + }, + { + name: 'issue-and-publish-invoice', + description: 'Create a Square invoice for an order and publish it to the customer.', + content: + '# Issue And Publish Invoice\n\nBill a customer with a Square invoice.\n\n## Steps\n1. Make sure an order exists (use Create Order if needed) and you have the customer ID.\n2. Run Create Invoice with an invoice object referencing the location, order, primary recipient (customer), and payment requests. Note the returned invoice ID and version.\n3. Run Publish Invoice with that invoice ID and version to send it to the customer.\n4. Track payment with Get Invoice.\n\n## Output\nReturn the invoice ID, status, and the public URL where the customer can pay.', + }, + { + name: 'manage-catalog-item', + description: 'Create or update a Square catalog item and attach an image to it.', + content: + '# Manage Catalog Item\n\nBuild out the Square catalog.\n\n## Steps\n1. Run Upsert Catalog Object with an ITEM object (use a temporary id like "#Name" for new items). Capture the returned object ID.\n2. To add a picture, run Create Catalog Image with the image file and the object ID to attach it to the item.\n3. Verify with Get Catalog Object or Search Catalog Objects.\n\n## Output\nReturn the catalog object ID, type, and version, plus the image object ID when an image was attached.', + }, + { + name: 'find-customer-activity', + description: 'Look up a Square customer and summarize their orders and payments.', + content: + '# Find Customer Activity\n\nBuild a purchase history view for one customer.\n\n## Steps\n1. Run Search Customers (by email or phone) or Get Customer to identify the customer and their ID.\n2. Run Search Orders across the relevant locations filtered to that customer.\n3. Run List Payments and match payments to the customer for a full financial picture.\n\n## Output\nReturn the customer ID and email plus a summary of their orders and payments: total spend, number of orders, and any refunds.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index 88f0325047..1d2066d265 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -268,6 +268,7 @@ import { SlackBlock, SlackBlockMeta } from '@/blocks/blocks/slack' import { SmtpBlock } from '@/blocks/blocks/smtp' import { SpotifyBlock, SpotifyBlockMeta } from '@/blocks/blocks/spotify' import { SQSBlock, SQSBlockMeta } from '@/blocks/blocks/sqs' +import { SquareBlock, SquareBlockMeta } from '@/blocks/blocks/square' import { SSHBlock } from '@/blocks/blocks/ssh' import { StagehandBlock, StagehandBlockMeta } from '@/blocks/blocks/stagehand' import { StartTriggerBlock } from '@/blocks/blocks/start_trigger' @@ -569,6 +570,7 @@ const BLOCK_REGISTRY: Record = { smtp: SmtpBlock, spotify: SpotifyBlock, sqs: SQSBlock, + square: SquareBlock, ssh: SSHBlock, stagehand: StagehandBlock, start_trigger: StartTriggerBlock, @@ -827,6 +829,7 @@ const BLOCK_META_REGISTRY: Record = { slack: SlackBlockMeta, spotify: SpotifyBlockMeta, sqs: SQSBlockMeta, + square: SquareBlockMeta, stagehand: StagehandBlockMeta, stripe: StripeBlockMeta, sts: STSBlockMeta, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index dc3c91c5be..2d6b6eb2c0 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -1958,6 +1958,17 @@ export function WhatsAppIcon(props: SVGProps) { ) } +export function SquareIcon(props: SVGProps) { + return ( + + + + ) +} + export function StripeIcon(props: SVGProps) { return ( + +export const squareCatalogImageContract = defineRouteContract({ + method: 'POST', + path: '/api/tools/square/catalog-image', + body: squareCatalogImageBodySchema, + response: { mode: 'json', schema: squareCatalogImageResponseSchema }, +}) diff --git a/apps/sim/lib/integrations/icon-mapping.ts b/apps/sim/lib/integrations/icon-mapping.ts index 9dc7ae5b4c..04b349d7c4 100644 --- a/apps/sim/lib/integrations/icon-mapping.ts +++ b/apps/sim/lib/integrations/icon-mapping.ts @@ -190,6 +190,7 @@ import { SlackIcon, SmtpIcon, SQSIcon, + SquareIcon, SshIcon, STSIcon, STTIcon, @@ -415,6 +416,7 @@ export const blockTypeToIconMap: Record = { slack: SlackIcon, smtp: SmtpIcon, sqs: SQSIcon, + square: SquareIcon, ssh: SshIcon, stagehand: StagehandIcon, stripe: StripeIcon, diff --git a/apps/sim/lib/integrations/integrations.json b/apps/sim/lib/integrations/integrations.json index 219fed3b77..64e1d3ebc1 100644 --- a/apps/sim/lib/integrations/integrations.json +++ b/apps/sim/lib/integrations/integrations.json @@ -14660,6 +14660,161 @@ "category": "tools", "integrationType": "email" }, + { + "type": "square", + "slug": "square", + "name": "Square", + "description": "Process payments and manage Square commerce data", + "longDescription": "Integrate Square into the workflow. Take and refund payments, manage customers, build catalog items and images, create and search orders, and issue invoices. Authenticate with a Square access token (personal access token).", + "bgColor": "#000000", + "iconName": "SquareIcon", + "docsUrl": "https://docs.sim.ai/integrations/square", + "operations": [ + { + "name": "Create Payment", + "description": "Take a payment using a payment source such as a card nonce or a card on file" + }, + { + "name": "Get Payment", + "description": "Retrieve details for a single payment by its ID" + }, + { + "name": "List Payments", + "description": "List payments taken by the account, optionally filtered by location and time range" + }, + { + "name": "Cancel Payment", + "description": "Cancel (void) an authorized payment that has not been captured" + }, + { + "name": "Complete Payment", + "description": "Capture (complete) a payment that was authorized with delayed capture" + }, + { + "name": "Refund Payment", + "description": "Refund all or part of a completed payment" + }, + { + "name": "Get Refund", + "description": "Retrieve a single payment refund by its ID" + }, + { + "name": "List Refunds", + "description": "List payment refunds, optionally filtered by location, status, and time range" + }, + { + "name": "Create Customer", + "description": "Create a new customer profile in the Square customer directory" + }, + { + "name": "Get Customer", + "description": "Retrieve a single customer profile by its ID" + }, + { + "name": "List Customers", + "description": "List customer profiles in the Square customer directory" + }, + { + "name": "Search Customers", + "description": "Search customer profiles using filters such as email, phone, or creation date" + }, + { + "name": "Update Customer", + "description": "Update fields on an existing customer profile" + }, + { + "name": "Delete Customer", + "description": "Delete a customer profile from the Square customer directory" + }, + { + "name": "List Locations", + "description": "List all locations associated with the Square account" + }, + { + "name": "Get Location", + "description": "Retrieve a single location by its ID" + }, + { + "name": "Create Order", + "description": "Create an order with line items, taxes, discounts, and fulfillments" + }, + { + "name": "Get Order", + "description": "Retrieve a single order by its ID" + }, + { + "name": "Search Orders", + "description": "Search orders across one or more locations using filters and sorting" + }, + { + "name": "Pay Order", + "description": "Pay for an order using one or more already-approved payments" + }, + { + "name": "Create Invoice", + "description": "Create a draft invoice for an existing order and customer" + }, + { + "name": "Get Invoice", + "description": "Retrieve a single invoice by its ID" + }, + { + "name": "List Invoices", + "description": "List invoices for a specific location" + }, + { + "name": "Search Invoices", + "description": "Search invoices across one or more locations" + }, + { + "name": "Publish Invoice", + "description": "Publish a draft invoice so it is sent to the customer and becomes payable" + }, + { + "name": "Cancel Invoice", + "description": "Cancel a published invoice that is unpaid or partially paid" + }, + { + "name": "Delete Invoice", + "description": "Delete a draft invoice" + }, + { + "name": "Upsert Catalog Object", + "description": "Create or update a catalog object such as an item, variation, or category" + }, + { + "name": "Get Catalog Object", + "description": "Retrieve a single catalog object by its ID" + }, + { + "name": "List Catalog", + "description": "List catalog objects, optionally filtered by type" + }, + { + "name": "Search Catalog Objects", + "description": "Search catalog objects by type and query filters" + }, + { + "name": "Create Catalog Image", + "description": "Upload an image and attach it to the catalog, optionally to a specific item" + }, + { + "name": "Delete Catalog Object", + "description": "Delete a catalog object and its children (e.g. an item and its variations)" + }, + { + "name": "Batch Retrieve Inventory Counts", + "description": "Retrieve current inventory counts for catalog items across locations" + } + ], + "operationCount": 34, + "triggers": [], + "triggerCount": 0, + "authType": "api-key", + "category": "tools", + "integrationType": "commerce", + "tags": ["payments", "subscriptions", "automation"] + }, { "type": "ssh", "slug": "ssh", diff --git a/apps/sim/tools/error-extractors.ts b/apps/sim/tools/error-extractors.ts index ff4c442e64..0bfc70c7c5 100644 --- a/apps/sim/tools/error-extractors.ts +++ b/apps/sim/tools/error-extractors.ts @@ -176,6 +176,17 @@ const ERROR_EXTRACTORS: ErrorExtractorConfig[] = [ examples: ['Hunter.io API'], extract: (errorInfo) => errorInfo?.data?.errors?.[0]?.details, }, + { + id: 'square-errors', + description: 'Square API error format with errors[].detail and errors[].code', + examples: ['Square API'], + extract: (errorInfo) => { + const err = errorInfo?.data?.errors?.[0] + if (!err) return undefined + if (err.detail) return err.code ? `${err.detail} (${err.code})` : err.detail + return err.code + }, + }, { id: 'errors-array-string', description: 'Errors array containing strings or objects with messages', @@ -302,6 +313,7 @@ export const ErrorExtractorId = { BATCH_VALIDATION_ERRORS: 'batch-validation-errors', NESTJS_VALIDATION_ERRORS: 'nestjs-validation-errors', HUNTER_ERRORS: 'hunter-errors', + SQUARE_ERRORS: 'square-errors', ERRORS_ARRAY_STRING: 'errors-array-string', TELEGRAM_DESCRIPTION: 'telegram-description', STANDARD_MESSAGE: 'standard-message', diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index a5ffd6ba05..45fef1980a 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -3135,6 +3135,42 @@ import { spotifyUpdatePlaylistTool, } from '@/tools/spotify' import { sqsSendTool } from '@/tools/sqs' +import { + squareBatchRetrieveInventoryCountsTool, + squareCancelInvoiceTool, + squareCancelPaymentTool, + squareCompletePaymentTool, + squareCreateCatalogImageTool, + squareCreateCustomerTool, + squareCreateInvoiceTool, + squareCreateOrderTool, + squareCreatePaymentTool, + squareDeleteCatalogObjectTool, + squareDeleteCustomerTool, + squareDeleteInvoiceTool, + squareGetCatalogObjectTool, + squareGetCustomerTool, + squareGetInvoiceTool, + squareGetLocationTool, + squareGetOrderTool, + squareGetPaymentTool, + squareGetRefundTool, + squareListCatalogTool, + squareListCustomersTool, + squareListInvoicesTool, + squareListLocationsTool, + squareListPaymentsTool, + squareListRefundsTool, + squarePayOrderTool, + squarePublishInvoiceTool, + squareRefundPaymentTool, + squareSearchCatalogObjectsTool, + squareSearchCustomersTool, + squareSearchInvoicesTool, + squareSearchOrdersTool, + squareUpdateCustomerTool, + squareUpsertCatalogObjectTool, +} from '@/tools/square' import { sshCheckCommandExistsTool, sshCheckFileExistsTool, @@ -7045,6 +7081,40 @@ export const tools: Record = { spotify_set_repeat: spotifySetRepeatTool, spotify_set_shuffle: spotifySetShuffleTool, spotify_transfer_playback: spotifyTransferPlaybackTool, + square_create_payment: squareCreatePaymentTool, + square_get_payment: squareGetPaymentTool, + square_list_payments: squareListPaymentsTool, + square_cancel_payment: squareCancelPaymentTool, + square_complete_payment: squareCompletePaymentTool, + square_refund_payment: squareRefundPaymentTool, + square_get_refund: squareGetRefundTool, + square_list_refunds: squareListRefundsTool, + square_create_customer: squareCreateCustomerTool, + square_get_customer: squareGetCustomerTool, + square_list_customers: squareListCustomersTool, + square_search_customers: squareSearchCustomersTool, + square_update_customer: squareUpdateCustomerTool, + square_delete_customer: squareDeleteCustomerTool, + square_list_locations: squareListLocationsTool, + square_get_location: squareGetLocationTool, + square_create_order: squareCreateOrderTool, + square_get_order: squareGetOrderTool, + square_search_orders: squareSearchOrdersTool, + square_pay_order: squarePayOrderTool, + square_create_invoice: squareCreateInvoiceTool, + square_get_invoice: squareGetInvoiceTool, + square_list_invoices: squareListInvoicesTool, + square_search_invoices: squareSearchInvoicesTool, + square_publish_invoice: squarePublishInvoiceTool, + square_cancel_invoice: squareCancelInvoiceTool, + square_delete_invoice: squareDeleteInvoiceTool, + square_upsert_catalog_object: squareUpsertCatalogObjectTool, + square_get_catalog_object: squareGetCatalogObjectTool, + square_list_catalog: squareListCatalogTool, + square_search_catalog_objects: squareSearchCatalogObjectsTool, + square_create_catalog_image: squareCreateCatalogImageTool, + square_delete_catalog_object: squareDeleteCatalogObjectTool, + square_batch_retrieve_inventory_counts: squareBatchRetrieveInventoryCountsTool, upstash_redis_get: upstashRedisGetTool, upstash_redis_set: upstashRedisSetTool, upstash_redis_delete: upstashRedisDeleteTool, diff --git a/apps/sim/tools/square/batch_retrieve_inventory_counts.ts b/apps/sim/tools/square/batch_retrieve_inventory_counts.ts new file mode 100644 index 0000000000..686db62746 --- /dev/null +++ b/apps/sim/tools/square/batch_retrieve_inventory_counts.ts @@ -0,0 +1,112 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { + BatchRetrieveInventoryCountsParams, + InventoryCountListResponse, +} from '@/tools/square/types' +import { + INVENTORY_COUNT_OUTPUT, + LIST_METADATA_OUTPUT_PROPERTIES, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareBatchRetrieveInventoryCountsTool: ToolConfig< + BatchRetrieveInventoryCountsParams, + InventoryCountListResponse +> = { + id: 'square_batch_retrieve_inventory_counts', + name: 'Square Batch Retrieve Inventory Counts', + description: 'Retrieve current inventory counts for catalog items across locations', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + catalogObjectIds: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'IDs of the catalog item variations to retrieve counts for', + }, + locationIds: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'IDs of the locations to retrieve counts for (defaults to all locations)', + }, + states: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Inventory states to filter by (e.g. IN_STOCK, SOLD, IN_TRANSIT)', + }, + updatedAfter: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Only return counts updated after this RFC 3339 timestamp', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of results to return per page (1-1000)', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/inventory/counts/batch-retrieve`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = {} + if (params.catalogObjectIds) body.catalog_object_ids = params.catalogObjectIds + if (params.locationIds) body.location_ids = params.locationIds + if (params.states) body.states = params.states + if (params.updatedAfter) body.updated_after = params.updatedAfter + if (params.limit !== undefined) body.limit = params.limit + if (params.cursor) body.cursor = params.cursor + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const counts = data.counts ?? [] + return { + success: true, + output: { + counts, + metadata: { + count: counts.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + counts: { + type: 'array', + description: 'Array of inventory count objects', + items: INVENTORY_COUNT_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/cancel_invoice.ts b/apps/sim/tools/square/cancel_invoice.ts new file mode 100644 index 0000000000..8e864146db --- /dev/null +++ b/apps/sim/tools/square/cancel_invoice.ts @@ -0,0 +1,71 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CancelInvoiceParams, InvoiceResponse } from '@/tools/square/types' +import { + INVOICE_METADATA_OUTPUT_PROPERTIES, + INVOICE_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareCancelInvoiceTool: ToolConfig = { + id: 'square_cancel_invoice', + name: 'Square Cancel Invoice', + description: 'Cancel a published invoice that is unpaid or partially paid', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + invoiceId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the invoice to cancel', + }, + version: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Current version of the invoice', + }, + }, + + request: { + url: (params) => + `${SQUARE_BASE_URL}/v2/invoices/${encodeURIComponent(params.invoiceId)}/cancel`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => ({ version: params.version }), + }, + + transformResponse: async (response) => { + const data = await response.json() + const invoice = data.invoice ?? {} + return { + success: true, + output: { + invoice, + metadata: { + id: invoice.id, + status: invoice.status ?? null, + version: invoice.version ?? null, + }, + }, + } + }, + + outputs: { + invoice: { ...INVOICE_OUTPUT, description: 'The canceled invoice object' }, + metadata: { + type: 'json', + description: 'Invoice summary metadata', + properties: INVOICE_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/cancel_payment.ts b/apps/sim/tools/square/cancel_payment.ts new file mode 100644 index 0000000000..8e4b4a7b81 --- /dev/null +++ b/apps/sim/tools/square/cancel_payment.ts @@ -0,0 +1,65 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CancelPaymentParams, PaymentResponse } from '@/tools/square/types' +import { + PAYMENT_METADATA_OUTPUT_PROPERTIES, + PAYMENT_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareCancelPaymentTool: ToolConfig = { + id: 'square_cancel_payment', + name: 'Square Cancel Payment', + description: 'Cancel (void) an authorized payment that has not been captured', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + paymentId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the payment to cancel', + }, + }, + + request: { + url: (params) => + `${SQUARE_BASE_URL}/v2/payments/${encodeURIComponent(params.paymentId)}/cancel`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: () => ({}), + }, + + transformResponse: async (response) => { + const data = await response.json() + const payment = data.payment ?? {} + return { + success: true, + output: { + payment, + metadata: { + id: payment.id, + status: payment.status ?? null, + order_id: payment.order_id ?? null, + }, + }, + } + }, + + outputs: { + payment: { ...PAYMENT_OUTPUT, description: 'The canceled payment object' }, + metadata: { + type: 'json', + description: 'Payment summary metadata', + properties: PAYMENT_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/complete_payment.ts b/apps/sim/tools/square/complete_payment.ts new file mode 100644 index 0000000000..6d70634ba4 --- /dev/null +++ b/apps/sim/tools/square/complete_payment.ts @@ -0,0 +1,71 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CompletePaymentParams, PaymentResponse } from '@/tools/square/types' +import { + PAYMENT_METADATA_OUTPUT_PROPERTIES, + PAYMENT_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareCompletePaymentTool: ToolConfig = { + id: 'square_complete_payment', + name: 'Square Complete Payment', + description: 'Capture (complete) a payment that was authorized with delayed capture', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + paymentId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the payment to complete', + }, + versionToken: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional version token for optimistic concurrency control', + }, + }, + + request: { + url: (params) => + `${SQUARE_BASE_URL}/v2/payments/${encodeURIComponent(params.paymentId)}/complete`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => (params.versionToken ? { version_token: params.versionToken } : {}), + }, + + transformResponse: async (response) => { + const data = await response.json() + const payment = data.payment ?? {} + return { + success: true, + output: { + payment, + metadata: { + id: payment.id, + status: payment.status ?? null, + order_id: payment.order_id ?? null, + }, + }, + } + }, + + outputs: { + payment: { ...PAYMENT_OUTPUT, description: 'The completed payment object' }, + metadata: { + type: 'json', + description: 'Payment summary metadata', + properties: PAYMENT_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/create_catalog_image.ts b/apps/sim/tools/square/create_catalog_image.ts new file mode 100644 index 0000000000..10be9b47fd --- /dev/null +++ b/apps/sim/tools/square/create_catalog_image.ts @@ -0,0 +1,91 @@ +import type { CatalogObjectResponse, CreateCatalogImageParams } from '@/tools/square/types' +import { + CATALOG_OBJECT_METADATA_OUTPUT_PROPERTIES, + CATALOG_OBJECT_OUTPUT, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareCreateCatalogImageTool: ToolConfig< + CreateCatalogImageParams, + CatalogObjectResponse +> = { + id: 'square_create_catalog_image', + name: 'Square Create Catalog Image', + description: 'Upload an image and attach it to the catalog, optionally to a specific item', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + file: { + type: 'file', + required: true, + visibility: 'user-or-llm', + description: 'The image file to upload (UserFile object)', + }, + fileName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional filename override for the image', + }, + objectId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'ID of the catalog object (e.g. an item) to attach the image to', + }, + caption: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Caption (alt text) for the image', + }, + idempotencyKey: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Unique key to make the request idempotent (auto-generated if omitted)', + }, + }, + + request: { + url: '/api/tools/square/catalog-image', + method: 'POST', + headers: () => ({ + 'Content-Type': 'application/json', + }), + body: (params) => ({ + accessToken: params.apiKey, + file: params.file, + fileName: params.fileName, + objectId: params.objectId, + caption: params.caption, + idempotencyKey: params.idempotencyKey, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + if (!data.success) { + throw new Error(data.error || 'Failed to upload catalog image') + } + return { + success: true, + output: data.output, + } + }, + + outputs: { + object: { ...CATALOG_OBJECT_OUTPUT, description: 'The created catalog image object' }, + metadata: { + type: 'json', + description: 'Catalog object summary metadata', + properties: CATALOG_OBJECT_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/create_customer.ts b/apps/sim/tools/square/create_customer.ts new file mode 100644 index 0000000000..787ab46ddb --- /dev/null +++ b/apps/sim/tools/square/create_customer.ts @@ -0,0 +1,141 @@ +import { generateId } from '@sim/utils/id' +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CreateCustomerParams, CustomerResponse } from '@/tools/square/types' +import { + CUSTOMER_METADATA_OUTPUT_PROPERTIES, + CUSTOMER_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareCreateCustomerTool: ToolConfig = { + id: 'square_create_customer', + name: 'Square Create Customer', + description: 'Create a new customer profile in the Square customer directory', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + givenName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'First name of the customer', + }, + familyName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Last name of the customer', + }, + companyName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Business name of the customer', + }, + nickname: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Nickname of the customer', + }, + emailAddress: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Email address of the customer', + }, + phoneNumber: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Phone number of the customer', + }, + birthday: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Birthday in YYYY-MM-DD or MM-DD format', + }, + note: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Note about the customer', + }, + referenceId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional external reference for the customer', + }, + address: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: 'Square address object for the customer', + }, + idempotencyKey: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Unique key to make the request idempotent (auto-generated if omitted)', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/customers`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = { + idempotency_key: params.idempotencyKey || generateId(), + } + if (params.givenName) body.given_name = params.givenName + if (params.familyName) body.family_name = params.familyName + if (params.companyName) body.company_name = params.companyName + if (params.nickname) body.nickname = params.nickname + if (params.emailAddress) body.email_address = params.emailAddress + if (params.phoneNumber) body.phone_number = params.phoneNumber + if (params.birthday) body.birthday = params.birthday + if (params.note) body.note = params.note + if (params.referenceId) body.reference_id = params.referenceId + if (params.address) body.address = params.address + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const customer = data.customer ?? {} + return { + success: true, + output: { + customer, + metadata: { + id: customer.id, + email_address: customer.email_address ?? null, + given_name: customer.given_name ?? null, + family_name: customer.family_name ?? null, + }, + }, + } + }, + + outputs: { + customer: { ...CUSTOMER_OUTPUT, description: 'The created customer object' }, + metadata: { + type: 'json', + description: 'Customer summary metadata', + properties: CUSTOMER_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/create_invoice.ts b/apps/sim/tools/square/create_invoice.ts new file mode 100644 index 0000000000..bd5e82a8dd --- /dev/null +++ b/apps/sim/tools/square/create_invoice.ts @@ -0,0 +1,75 @@ +import { generateId } from '@sim/utils/id' +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CreateInvoiceParams, InvoiceResponse } from '@/tools/square/types' +import { + INVOICE_METADATA_OUTPUT_PROPERTIES, + INVOICE_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareCreateInvoiceTool: ToolConfig = { + id: 'square_create_invoice', + name: 'Square Create Invoice', + description: 'Create a draft invoice for an existing order and customer', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + invoice: { + type: 'json', + required: true, + visibility: 'user-or-llm', + description: + 'Square invoice object including location_id, order_id, primary_recipient, and payment_requests (e.g. {"location_id":"L1","order_id":"O1","primary_recipient":{"customer_id":"C1"},"payment_requests":[{"request_type":"BALANCE","due_date":"2026-07-01"}]})', + }, + idempotencyKey: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Unique key to make the request idempotent (auto-generated if omitted)', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/invoices`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => ({ + idempotency_key: params.idempotencyKey || generateId(), + invoice: params.invoice, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + const invoice = data.invoice ?? {} + return { + success: true, + output: { + invoice, + metadata: { + id: invoice.id, + status: invoice.status ?? null, + version: invoice.version ?? null, + }, + }, + } + }, + + outputs: { + invoice: { ...INVOICE_OUTPUT, description: 'The created invoice object' }, + metadata: { + type: 'json', + description: 'Invoice summary metadata', + properties: INVOICE_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/create_order.ts b/apps/sim/tools/square/create_order.ts new file mode 100644 index 0000000000..5cd023b3ab --- /dev/null +++ b/apps/sim/tools/square/create_order.ts @@ -0,0 +1,75 @@ +import { generateId } from '@sim/utils/id' +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CreateOrderParams, OrderResponse } from '@/tools/square/types' +import { + ORDER_METADATA_OUTPUT_PROPERTIES, + ORDER_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareCreateOrderTool: ToolConfig = { + id: 'square_create_order', + name: 'Square Create Order', + description: 'Create an order with line items, taxes, discounts, and fulfillments', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + order: { + type: 'json', + required: true, + visibility: 'user-or-llm', + description: + 'Square order object including location_id and line_items (e.g. {"location_id":"L1","line_items":[{"name":"Coffee","quantity":"1","base_price_money":{"amount":250,"currency":"USD"}}]})', + }, + idempotencyKey: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Unique key to make the request idempotent (auto-generated if omitted)', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/orders`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => ({ + idempotency_key: params.idempotencyKey || generateId(), + order: params.order, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + const order = data.order ?? {} + return { + success: true, + output: { + order, + metadata: { + id: order.id, + state: order.state ?? null, + location_id: order.location_id ?? null, + }, + }, + } + }, + + outputs: { + order: { ...ORDER_OUTPUT, description: 'The created order object' }, + metadata: { + type: 'json', + description: 'Order summary metadata', + properties: ORDER_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/create_payment.ts b/apps/sim/tools/square/create_payment.ts new file mode 100644 index 0000000000..02380bf860 --- /dev/null +++ b/apps/sim/tools/square/create_payment.ts @@ -0,0 +1,132 @@ +import { generateId } from '@sim/utils/id' +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CreatePaymentParams, PaymentResponse } from '@/tools/square/types' +import { + PAYMENT_METADATA_OUTPUT_PROPERTIES, + PAYMENT_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareCreatePaymentTool: ToolConfig = { + id: 'square_create_payment', + name: 'Square Create Payment', + description: 'Take a payment using a payment source such as a card nonce or a card on file', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + sourceId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the payment source (card nonce, card-on-file ID, or wallet token)', + }, + amount: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Amount in the smallest currency denomination (e.g. 1000 = $10.00)', + }, + currency: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Three-letter ISO 4217 currency code (e.g. USD)', + }, + idempotencyKey: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Unique key to make the request idempotent (auto-generated if omitted)', + }, + customerId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'ID of the customer associated with the payment', + }, + locationId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'ID of the location where the payment is taken (defaults to the main location)', + }, + orderId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'ID of the order associated with the payment', + }, + referenceId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional external reference for the payment', + }, + note: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional note attached to the payment', + }, + autocomplete: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to immediately capture the payment (defaults to true)', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/payments`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = { + idempotency_key: params.idempotencyKey || generateId(), + source_id: params.sourceId, + amount_money: { amount: params.amount, currency: params.currency }, + } + if (params.customerId) body.customer_id = params.customerId + if (params.locationId) body.location_id = params.locationId + if (params.orderId) body.order_id = params.orderId + if (params.referenceId) body.reference_id = params.referenceId + if (params.note) body.note = params.note + if (params.autocomplete !== undefined) body.autocomplete = params.autocomplete + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const payment = data.payment ?? {} + return { + success: true, + output: { + payment, + metadata: { + id: payment.id, + status: payment.status ?? null, + order_id: payment.order_id ?? null, + }, + }, + } + }, + + outputs: { + payment: { ...PAYMENT_OUTPUT, description: 'The created payment object' }, + metadata: { + type: 'json', + description: 'Payment summary metadata', + properties: PAYMENT_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/delete_catalog_object.ts b/apps/sim/tools/square/delete_catalog_object.ts new file mode 100644 index 0000000000..9cf1e37a09 --- /dev/null +++ b/apps/sim/tools/square/delete_catalog_object.ts @@ -0,0 +1,62 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CatalogDeleteResponse, DeleteCatalogObjectParams } from '@/tools/square/types' +import { SQUARE_BASE_URL, squareHeaders } from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareDeleteCatalogObjectTool: ToolConfig< + DeleteCatalogObjectParams, + CatalogDeleteResponse +> = { + id: 'square_delete_catalog_object', + name: 'Square Delete Catalog Object', + description: 'Delete a catalog object and its children (e.g. an item and its variations)', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + objectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the catalog object to delete', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/catalog/object/${encodeURIComponent(params.objectId)}`, + method: 'DELETE', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + return { + success: true, + output: { + deleted: true, + deleted_object_ids: data.deleted_object_ids ?? [], + deleted_at: data.deleted_at ?? null, + }, + } + }, + + outputs: { + deleted: { type: 'boolean', description: 'Whether the catalog object was deleted' }, + deleted_object_ids: { + type: 'array', + description: 'IDs of all catalog objects deleted (including children)', + items: { type: 'string' }, + }, + deleted_at: { + type: 'string', + description: 'Timestamp when the deletion occurred (RFC 3339)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/square/delete_customer.ts b/apps/sim/tools/square/delete_customer.ts new file mode 100644 index 0000000000..14d255d31c --- /dev/null +++ b/apps/sim/tools/square/delete_customer.ts @@ -0,0 +1,49 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CustomerDeleteResponse, DeleteCustomerParams } from '@/tools/square/types' +import { SQUARE_BASE_URL, squareHeaders } from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareDeleteCustomerTool: ToolConfig = { + id: 'square_delete_customer', + name: 'Square Delete Customer', + description: 'Delete a customer profile from the Square customer directory', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + customerId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the customer to delete', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/customers/${encodeURIComponent(params.customerId)}`, + method: 'DELETE', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response, params) => { + await response.json().catch(() => ({})) + return { + success: true, + output: { + deleted: true, + id: params?.customerId ?? '', + }, + } + }, + + outputs: { + deleted: { type: 'boolean', description: 'Whether the customer was deleted' }, + id: { type: 'string', description: 'ID of the deleted customer' }, + }, +} diff --git a/apps/sim/tools/square/delete_invoice.ts b/apps/sim/tools/square/delete_invoice.ts new file mode 100644 index 0000000000..4b8e806482 --- /dev/null +++ b/apps/sim/tools/square/delete_invoice.ts @@ -0,0 +1,60 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { DeleteInvoiceParams, InvoiceDeleteResponse } from '@/tools/square/types' +import { SQUARE_BASE_URL, squareHeaders } from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareDeleteInvoiceTool: ToolConfig = { + id: 'square_delete_invoice', + name: 'Square Delete Invoice', + description: 'Delete a draft invoice', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + invoiceId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the draft invoice to delete', + }, + version: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Current version of the invoice (required if the invoice has been updated)', + }, + }, + + request: { + url: (params) => { + const url = new URL(`${SQUARE_BASE_URL}/v2/invoices/${encodeURIComponent(params.invoiceId)}`) + if (params.version !== undefined) + url.searchParams.append('version', params.version.toString()) + return url.toString() + }, + method: 'DELETE', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response, params) => { + await response.json().catch(() => ({})) + return { + success: true, + output: { + deleted: true, + id: params?.invoiceId ?? '', + }, + } + }, + + outputs: { + deleted: { type: 'boolean', description: 'Whether the invoice was deleted' }, + id: { type: 'string', description: 'ID of the deleted invoice' }, + }, +} diff --git a/apps/sim/tools/square/get_catalog_object.ts b/apps/sim/tools/square/get_catalog_object.ts new file mode 100644 index 0000000000..d6651041f3 --- /dev/null +++ b/apps/sim/tools/square/get_catalog_object.ts @@ -0,0 +1,78 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CatalogObjectResponse, GetCatalogObjectParams } from '@/tools/square/types' +import { + CATALOG_OBJECT_METADATA_OUTPUT_PROPERTIES, + CATALOG_OBJECT_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareGetCatalogObjectTool: ToolConfig = + { + id: 'square_get_catalog_object', + name: 'Square Get Catalog Object', + description: 'Retrieve a single catalog object by its ID', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + objectId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the catalog object to retrieve', + }, + includeRelatedObjects: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to include related objects such as an item variations', + }, + }, + + request: { + url: (params) => { + const url = new URL( + `${SQUARE_BASE_URL}/v2/catalog/object/${encodeURIComponent(params.objectId)}` + ) + if (params.includeRelatedObjects !== undefined) { + url.searchParams.append('include_related_objects', String(params.includeRelatedObjects)) + } + return url.toString() + }, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const object = data.object ?? {} + return { + success: true, + output: { + object, + metadata: { + id: object.id, + type: object.type ?? null, + version: object.version ?? null, + }, + }, + } + }, + + outputs: { + object: { ...CATALOG_OBJECT_OUTPUT, description: 'The retrieved catalog object' }, + metadata: { + type: 'json', + description: 'Catalog object summary metadata', + properties: CATALOG_OBJECT_METADATA_OUTPUT_PROPERTIES, + }, + }, + } diff --git a/apps/sim/tools/square/get_customer.ts b/apps/sim/tools/square/get_customer.ts new file mode 100644 index 0000000000..950aca1457 --- /dev/null +++ b/apps/sim/tools/square/get_customer.ts @@ -0,0 +1,64 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CustomerResponse, GetCustomerParams } from '@/tools/square/types' +import { + CUSTOMER_METADATA_OUTPUT_PROPERTIES, + CUSTOMER_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareGetCustomerTool: ToolConfig = { + id: 'square_get_customer', + name: 'Square Get Customer', + description: 'Retrieve a single customer profile by its ID', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + customerId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the customer to retrieve', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/customers/${encodeURIComponent(params.customerId)}`, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const customer = data.customer ?? {} + return { + success: true, + output: { + customer, + metadata: { + id: customer.id, + email_address: customer.email_address ?? null, + given_name: customer.given_name ?? null, + family_name: customer.family_name ?? null, + }, + }, + } + }, + + outputs: { + customer: { ...CUSTOMER_OUTPUT, description: 'The retrieved customer object' }, + metadata: { + type: 'json', + description: 'Customer summary metadata', + properties: CUSTOMER_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/get_invoice.ts b/apps/sim/tools/square/get_invoice.ts new file mode 100644 index 0000000000..bc89c9b6c6 --- /dev/null +++ b/apps/sim/tools/square/get_invoice.ts @@ -0,0 +1,63 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { GetInvoiceParams, InvoiceResponse } from '@/tools/square/types' +import { + INVOICE_METADATA_OUTPUT_PROPERTIES, + INVOICE_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareGetInvoiceTool: ToolConfig = { + id: 'square_get_invoice', + name: 'Square Get Invoice', + description: 'Retrieve a single invoice by its ID', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + invoiceId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the invoice to retrieve', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/invoices/${encodeURIComponent(params.invoiceId)}`, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const invoice = data.invoice ?? {} + return { + success: true, + output: { + invoice, + metadata: { + id: invoice.id, + status: invoice.status ?? null, + version: invoice.version ?? null, + }, + }, + } + }, + + outputs: { + invoice: { ...INVOICE_OUTPUT, description: 'The retrieved invoice object' }, + metadata: { + type: 'json', + description: 'Invoice summary metadata', + properties: INVOICE_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/get_location.ts b/apps/sim/tools/square/get_location.ts new file mode 100644 index 0000000000..17ae2755e8 --- /dev/null +++ b/apps/sim/tools/square/get_location.ts @@ -0,0 +1,60 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { GetLocationParams, LocationResponse } from '@/tools/square/types' +import { LOCATION_OUTPUT, SQUARE_BASE_URL, squareHeaders } from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareGetLocationTool: ToolConfig = { + id: 'square_get_location', + name: 'Square Get Location', + description: 'Retrieve a single location by its ID', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + locationId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the location to retrieve (use "main" for the main location)', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/locations/${encodeURIComponent(params.locationId)}`, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const location = data.location ?? {} + return { + success: true, + output: { + location, + metadata: { + id: location.id, + name: location.name ?? null, + }, + }, + } + }, + + outputs: { + location: { ...LOCATION_OUTPUT, description: 'The retrieved location object' }, + metadata: { + type: 'json', + description: 'Location summary metadata', + properties: { + id: { type: 'string', description: 'Square location ID' }, + name: { type: 'string', description: 'Location name', optional: true }, + }, + }, + }, +} diff --git a/apps/sim/tools/square/get_order.ts b/apps/sim/tools/square/get_order.ts new file mode 100644 index 0000000000..b2277a32d6 --- /dev/null +++ b/apps/sim/tools/square/get_order.ts @@ -0,0 +1,63 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { GetOrderParams, OrderResponse } from '@/tools/square/types' +import { + ORDER_METADATA_OUTPUT_PROPERTIES, + ORDER_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareGetOrderTool: ToolConfig = { + id: 'square_get_order', + name: 'Square Get Order', + description: 'Retrieve a single order by its ID', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + orderId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the order to retrieve', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/orders/${encodeURIComponent(params.orderId)}`, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const order = data.order ?? {} + return { + success: true, + output: { + order, + metadata: { + id: order.id, + state: order.state ?? null, + location_id: order.location_id ?? null, + }, + }, + } + }, + + outputs: { + order: { ...ORDER_OUTPUT, description: 'The retrieved order object' }, + metadata: { + type: 'json', + description: 'Order summary metadata', + properties: ORDER_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/get_payment.ts b/apps/sim/tools/square/get_payment.ts new file mode 100644 index 0000000000..9114aa80a7 --- /dev/null +++ b/apps/sim/tools/square/get_payment.ts @@ -0,0 +1,63 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { GetPaymentParams, PaymentResponse } from '@/tools/square/types' +import { + PAYMENT_METADATA_OUTPUT_PROPERTIES, + PAYMENT_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareGetPaymentTool: ToolConfig = { + id: 'square_get_payment', + name: 'Square Get Payment', + description: 'Retrieve details for a single payment by its ID', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + paymentId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the payment to retrieve', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/payments/${encodeURIComponent(params.paymentId)}`, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const payment = data.payment ?? {} + return { + success: true, + output: { + payment, + metadata: { + id: payment.id, + status: payment.status ?? null, + order_id: payment.order_id ?? null, + }, + }, + } + }, + + outputs: { + payment: { ...PAYMENT_OUTPUT, description: 'The retrieved payment object' }, + metadata: { + type: 'json', + description: 'Payment summary metadata', + properties: PAYMENT_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/get_refund.ts b/apps/sim/tools/square/get_refund.ts new file mode 100644 index 0000000000..3ca9bc7803 --- /dev/null +++ b/apps/sim/tools/square/get_refund.ts @@ -0,0 +1,63 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { GetRefundParams, RefundResponse } from '@/tools/square/types' +import { + REFUND_METADATA_OUTPUT_PROPERTIES, + REFUND_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareGetRefundTool: ToolConfig = { + id: 'square_get_refund', + name: 'Square Get Refund', + description: 'Retrieve a single payment refund by its ID', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + refundId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the refund to retrieve', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/refunds/${encodeURIComponent(params.refundId)}`, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const refund = data.refund ?? {} + return { + success: true, + output: { + refund, + metadata: { + id: refund.id, + status: refund.status ?? null, + payment_id: refund.payment_id ?? null, + }, + }, + } + }, + + outputs: { + refund: { ...REFUND_OUTPUT, description: 'The retrieved refund object' }, + metadata: { + type: 'json', + description: 'Refund summary metadata', + properties: REFUND_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/index.ts b/apps/sim/tools/square/index.ts new file mode 100644 index 0000000000..9daac26ec5 --- /dev/null +++ b/apps/sim/tools/square/index.ts @@ -0,0 +1,34 @@ +export { squareBatchRetrieveInventoryCountsTool } from '@/tools/square/batch_retrieve_inventory_counts' +export { squareCancelInvoiceTool } from '@/tools/square/cancel_invoice' +export { squareCancelPaymentTool } from '@/tools/square/cancel_payment' +export { squareCompletePaymentTool } from '@/tools/square/complete_payment' +export { squareCreateCatalogImageTool } from '@/tools/square/create_catalog_image' +export { squareCreateCustomerTool } from '@/tools/square/create_customer' +export { squareCreateInvoiceTool } from '@/tools/square/create_invoice' +export { squareCreateOrderTool } from '@/tools/square/create_order' +export { squareCreatePaymentTool } from '@/tools/square/create_payment' +export { squareDeleteCatalogObjectTool } from '@/tools/square/delete_catalog_object' +export { squareDeleteCustomerTool } from '@/tools/square/delete_customer' +export { squareDeleteInvoiceTool } from '@/tools/square/delete_invoice' +export { squareGetCatalogObjectTool } from '@/tools/square/get_catalog_object' +export { squareGetCustomerTool } from '@/tools/square/get_customer' +export { squareGetInvoiceTool } from '@/tools/square/get_invoice' +export { squareGetLocationTool } from '@/tools/square/get_location' +export { squareGetOrderTool } from '@/tools/square/get_order' +export { squareGetPaymentTool } from '@/tools/square/get_payment' +export { squareGetRefundTool } from '@/tools/square/get_refund' +export { squareListCatalogTool } from '@/tools/square/list_catalog' +export { squareListCustomersTool } from '@/tools/square/list_customers' +export { squareListInvoicesTool } from '@/tools/square/list_invoices' +export { squareListLocationsTool } from '@/tools/square/list_locations' +export { squareListPaymentsTool } from '@/tools/square/list_payments' +export { squareListRefundsTool } from '@/tools/square/list_refunds' +export { squarePayOrderTool } from '@/tools/square/pay_order' +export { squarePublishInvoiceTool } from '@/tools/square/publish_invoice' +export { squareRefundPaymentTool } from '@/tools/square/refund_payment' +export { squareSearchCatalogObjectsTool } from '@/tools/square/search_catalog_objects' +export { squareSearchCustomersTool } from '@/tools/square/search_customers' +export { squareSearchInvoicesTool } from '@/tools/square/search_invoices' +export { squareSearchOrdersTool } from '@/tools/square/search_orders' +export { squareUpdateCustomerTool } from '@/tools/square/update_customer' +export { squareUpsertCatalogObjectTool } from '@/tools/square/upsert_catalog_object' diff --git a/apps/sim/tools/square/list_catalog.ts b/apps/sim/tools/square/list_catalog.ts new file mode 100644 index 0000000000..04ad484a93 --- /dev/null +++ b/apps/sim/tools/square/list_catalog.ts @@ -0,0 +1,78 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CatalogListResponse, ListCatalogParams } from '@/tools/square/types' +import { + CATALOG_OBJECT_OUTPUT, + LIST_METADATA_OUTPUT_PROPERTIES, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareListCatalogTool: ToolConfig = { + id: 'square_list_catalog', + name: 'Square List Catalog', + description: 'List catalog objects, optionally filtered by type', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + types: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated catalog object types to return (e.g. ITEM,CATEGORY). Defaults to all top-level types', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + }, + + request: { + url: (params) => { + const url = new URL(`${SQUARE_BASE_URL}/v2/catalog/list`) + if (params.types) url.searchParams.append('types', params.types) + if (params.cursor) url.searchParams.append('cursor', params.cursor) + return url.toString() + }, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const objects = data.objects ?? [] + return { + success: true, + output: { + objects, + metadata: { + count: objects.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + objects: { + type: 'array', + description: 'Array of catalog objects', + items: CATALOG_OBJECT_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/list_customers.ts b/apps/sim/tools/square/list_customers.ts new file mode 100644 index 0000000000..7ffe04cec4 --- /dev/null +++ b/apps/sim/tools/square/list_customers.ts @@ -0,0 +1,91 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CustomerListResponse, ListCustomersParams } from '@/tools/square/types' +import { + CUSTOMER_OUTPUT, + LIST_METADATA_OUTPUT_PROPERTIES, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareListCustomersTool: ToolConfig = { + id: 'square_list_customers', + name: 'Square List Customers', + description: 'List customer profiles in the Square customer directory', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of results to return per page (max 100)', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + sortField: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Field to sort by (DEFAULT or CREATED_AT)', + }, + sortOrder: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Sort order (ASC or DESC)', + }, + }, + + request: { + url: (params) => { + const url = new URL(`${SQUARE_BASE_URL}/v2/customers`) + if (params.limit !== undefined) url.searchParams.append('limit', params.limit.toString()) + if (params.cursor) url.searchParams.append('cursor', params.cursor) + if (params.sortField) url.searchParams.append('sort_field', params.sortField) + if (params.sortOrder) url.searchParams.append('sort_order', params.sortOrder) + return url.toString() + }, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const customers = data.customers ?? [] + return { + success: true, + output: { + customers, + metadata: { + count: customers.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + customers: { + type: 'array', + description: 'Array of customer objects', + items: CUSTOMER_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/list_invoices.ts b/apps/sim/tools/square/list_invoices.ts new file mode 100644 index 0000000000..752dc018d1 --- /dev/null +++ b/apps/sim/tools/square/list_invoices.ts @@ -0,0 +1,84 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { InvoiceListResponse, ListInvoicesParams } from '@/tools/square/types' +import { + INVOICE_OUTPUT, + LIST_METADATA_OUTPUT_PROPERTIES, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareListInvoicesTool: ToolConfig = { + id: 'square_list_invoices', + name: 'Square List Invoices', + description: 'List invoices for a specific location', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + locationId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the location to list invoices for', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of results to return per page', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + }, + + request: { + url: (params) => { + const url = new URL(`${SQUARE_BASE_URL}/v2/invoices`) + url.searchParams.append('location_id', params.locationId) + if (params.limit !== undefined) url.searchParams.append('limit', params.limit.toString()) + if (params.cursor) url.searchParams.append('cursor', params.cursor) + return url.toString() + }, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const invoices = data.invoices ?? [] + return { + success: true, + output: { + invoices, + metadata: { + count: invoices.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + invoices: { + type: 'array', + description: 'Array of invoice objects', + items: INVOICE_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/list_locations.ts b/apps/sim/tools/square/list_locations.ts new file mode 100644 index 0000000000..e52bbaf6ac --- /dev/null +++ b/apps/sim/tools/square/list_locations.ts @@ -0,0 +1,56 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { ListLocationsParams, LocationListResponse } from '@/tools/square/types' +import { LOCATION_OUTPUT, SQUARE_BASE_URL, squareHeaders } from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareListLocationsTool: ToolConfig = { + id: 'square_list_locations', + name: 'Square List Locations', + description: 'List all locations associated with the Square account', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/locations`, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const locations = data.locations ?? [] + return { + success: true, + output: { + locations, + metadata: { + count: locations.length, + }, + }, + } + }, + + outputs: { + locations: { + type: 'array', + description: 'Array of location objects', + items: LOCATION_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List metadata', + properties: { + count: { type: 'number', description: 'Number of locations returned' }, + }, + }, + }, +} diff --git a/apps/sim/tools/square/list_payments.ts b/apps/sim/tools/square/list_payments.ts new file mode 100644 index 0000000000..8ae3495390 --- /dev/null +++ b/apps/sim/tools/square/list_payments.ts @@ -0,0 +1,98 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { ListPaymentsParams, PaymentListResponse } from '@/tools/square/types' +import { + LIST_METADATA_OUTPUT_PROPERTIES, + PAYMENT_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareListPaymentsTool: ToolConfig = { + id: 'square_list_payments', + name: 'Square List Payments', + description: 'List payments taken by the account, optionally filtered by location and time range', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + locationId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Filter payments by location ID', + }, + beginTime: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'RFC 3339 timestamp for the beginning of the reporting period', + }, + endTime: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'RFC 3339 timestamp for the end of the reporting period', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of results to return per page', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + }, + + request: { + url: (params) => { + const url = new URL(`${SQUARE_BASE_URL}/v2/payments`) + if (params.locationId) url.searchParams.append('location_id', params.locationId) + if (params.beginTime) url.searchParams.append('begin_time', params.beginTime) + if (params.endTime) url.searchParams.append('end_time', params.endTime) + if (params.limit !== undefined) url.searchParams.append('limit', params.limit.toString()) + if (params.cursor) url.searchParams.append('cursor', params.cursor) + return url.toString() + }, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const payments = data.payments ?? [] + return { + success: true, + output: { + payments, + metadata: { + count: payments.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + payments: { + type: 'array', + description: 'Array of payment objects', + items: PAYMENT_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/list_refunds.ts b/apps/sim/tools/square/list_refunds.ts new file mode 100644 index 0000000000..c63cac762e --- /dev/null +++ b/apps/sim/tools/square/list_refunds.ts @@ -0,0 +1,105 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { ListRefundsParams, RefundListResponse } from '@/tools/square/types' +import { + LIST_METADATA_OUTPUT_PROPERTIES, + REFUND_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareListRefundsTool: ToolConfig = { + id: 'square_list_refunds', + name: 'Square List Refunds', + description: 'List payment refunds, optionally filtered by location, status, and time range', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + locationId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Filter refunds by location ID', + }, + status: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Filter by refund status (PENDING, COMPLETED, REJECTED, or FAILED)', + }, + beginTime: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'RFC 3339 timestamp for the beginning of the reporting period', + }, + endTime: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'RFC 3339 timestamp for the end of the reporting period', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of results to return per page', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + }, + + request: { + url: (params) => { + const url = new URL(`${SQUARE_BASE_URL}/v2/refunds`) + if (params.locationId) url.searchParams.append('location_id', params.locationId) + if (params.status) url.searchParams.append('status', params.status) + if (params.beginTime) url.searchParams.append('begin_time', params.beginTime) + if (params.endTime) url.searchParams.append('end_time', params.endTime) + if (params.limit !== undefined) url.searchParams.append('limit', params.limit.toString()) + if (params.cursor) url.searchParams.append('cursor', params.cursor) + return url.toString() + }, + method: 'GET', + headers: (params) => squareHeaders(params.apiKey), + }, + + transformResponse: async (response) => { + const data = await response.json() + const refunds = data.refunds ?? [] + return { + success: true, + output: { + refunds, + metadata: { + count: refunds.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + refunds: { + type: 'array', + description: 'Array of refund objects', + items: REFUND_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/pay_order.ts b/apps/sim/tools/square/pay_order.ts new file mode 100644 index 0000000000..d2b60122ff --- /dev/null +++ b/apps/sim/tools/square/pay_order.ts @@ -0,0 +1,90 @@ +import { generateId } from '@sim/utils/id' +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { OrderResponse, PayOrderParams } from '@/tools/square/types' +import { + ORDER_METADATA_OUTPUT_PROPERTIES, + ORDER_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squarePayOrderTool: ToolConfig = { + id: 'square_pay_order', + name: 'Square Pay Order', + description: 'Pay for an order using one or more already-approved payments', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + orderId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the order to pay for', + }, + paymentIds: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'IDs of approved payments to apply to the order', + }, + orderVersion: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Version of the order being paid (for optimistic concurrency)', + }, + idempotencyKey: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Unique key to make the request idempotent (auto-generated if omitted)', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/orders/${encodeURIComponent(params.orderId)}/pay`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = { + idempotency_key: params.idempotencyKey || generateId(), + } + if (params.paymentIds) body.payment_ids = params.paymentIds + if (params.orderVersion !== undefined) body.order_version = params.orderVersion + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const order = data.order ?? {} + return { + success: true, + output: { + order, + metadata: { + id: order.id, + state: order.state ?? null, + location_id: order.location_id ?? null, + }, + }, + } + }, + + outputs: { + order: { ...ORDER_OUTPUT, description: 'The paid order object' }, + metadata: { + type: 'json', + description: 'Order summary metadata', + properties: ORDER_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/publish_invoice.ts b/apps/sim/tools/square/publish_invoice.ts new file mode 100644 index 0000000000..418d1468c7 --- /dev/null +++ b/apps/sim/tools/square/publish_invoice.ts @@ -0,0 +1,81 @@ +import { generateId } from '@sim/utils/id' +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { InvoiceResponse, PublishInvoiceParams } from '@/tools/square/types' +import { + INVOICE_METADATA_OUTPUT_PROPERTIES, + INVOICE_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squarePublishInvoiceTool: ToolConfig = { + id: 'square_publish_invoice', + name: 'Square Publish Invoice', + description: 'Publish a draft invoice so it is sent to the customer and becomes payable', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + invoiceId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the invoice to publish', + }, + version: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Current version of the invoice (use the version returned by Create Invoice)', + }, + idempotencyKey: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Unique key to make the request idempotent (auto-generated if omitted)', + }, + }, + + request: { + url: (params) => + `${SQUARE_BASE_URL}/v2/invoices/${encodeURIComponent(params.invoiceId)}/publish`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => ({ + version: params.version, + idempotency_key: params.idempotencyKey || generateId(), + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + const invoice = data.invoice ?? {} + return { + success: true, + output: { + invoice, + metadata: { + id: invoice.id, + status: invoice.status ?? null, + version: invoice.version ?? null, + }, + }, + } + }, + + outputs: { + invoice: { ...INVOICE_OUTPUT, description: 'The published invoice object' }, + metadata: { + type: 'json', + description: 'Invoice summary metadata', + properties: INVOICE_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/refund_payment.ts b/apps/sim/tools/square/refund_payment.ts new file mode 100644 index 0000000000..91cad5ce6a --- /dev/null +++ b/apps/sim/tools/square/refund_payment.ts @@ -0,0 +1,97 @@ +import { generateId } from '@sim/utils/id' +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { RefundPaymentParams, RefundResponse } from '@/tools/square/types' +import { + REFUND_METADATA_OUTPUT_PROPERTIES, + REFUND_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareRefundPaymentTool: ToolConfig = { + id: 'square_refund_payment', + name: 'Square Refund Payment', + description: 'Refund all or part of a completed payment', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + paymentId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the payment to refund', + }, + amount: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Amount to refund in the smallest currency denomination (e.g. 100 = $1.00)', + }, + currency: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Three-letter ISO 4217 currency code (e.g. USD)', + }, + idempotencyKey: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Unique key to make the request idempotent (auto-generated if omitted)', + }, + reason: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Reason for the refund', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/refunds`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = { + idempotency_key: params.idempotencyKey || generateId(), + payment_id: params.paymentId, + amount_money: { amount: params.amount, currency: params.currency }, + } + if (params.reason) body.reason = params.reason + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const refund = data.refund ?? {} + return { + success: true, + output: { + refund, + metadata: { + id: refund.id, + status: refund.status ?? null, + payment_id: refund.payment_id ?? null, + }, + }, + } + }, + + outputs: { + refund: { ...REFUND_OUTPUT, description: 'The created refund object' }, + metadata: { + type: 'json', + description: 'Refund summary metadata', + properties: REFUND_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/search_catalog_objects.ts b/apps/sim/tools/square/search_catalog_objects.ts new file mode 100644 index 0000000000..c0cbb73678 --- /dev/null +++ b/apps/sim/tools/square/search_catalog_objects.ts @@ -0,0 +1,96 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CatalogListResponse, SearchCatalogObjectsParams } from '@/tools/square/types' +import { + CATALOG_OBJECT_OUTPUT, + LIST_METADATA_OUTPUT_PROPERTIES, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareSearchCatalogObjectsTool: ToolConfig< + SearchCatalogObjectsParams, + CatalogListResponse +> = { + id: 'square_search_catalog_objects', + name: 'Square Search Catalog Objects', + description: 'Search catalog objects by type and query filters', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + objectTypes: { + type: 'array', + required: false, + visibility: 'user-or-llm', + description: 'Array of catalog object types to search (e.g. ["ITEM","CATEGORY"])', + }, + query: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'Square catalog query object (e.g. {"text_query":{"keywords":["coffee"]}} or {"prefix_query":{...}})', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of results to return per page', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/catalog/search`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = {} + if (params.objectTypes) body.object_types = params.objectTypes + if (params.query) body.query = params.query + if (params.limit !== undefined) body.limit = params.limit + if (params.cursor) body.cursor = params.cursor + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const objects = data.objects ?? [] + return { + success: true, + output: { + objects, + metadata: { + count: objects.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + objects: { + type: 'array', + description: 'Array of matching catalog objects', + items: CATALOG_OBJECT_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/search_customers.ts b/apps/sim/tools/square/search_customers.ts new file mode 100644 index 0000000000..55bdf1c498 --- /dev/null +++ b/apps/sim/tools/square/search_customers.ts @@ -0,0 +1,86 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CustomerListResponse, SearchCustomersParams } from '@/tools/square/types' +import { + CUSTOMER_OUTPUT, + LIST_METADATA_OUTPUT_PROPERTIES, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareSearchCustomersTool: ToolConfig = { + id: 'square_search_customers', + name: 'Square Search Customers', + description: 'Search customer profiles using filters such as email, phone, or creation date', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + query: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'Square customer query object with optional filter and sort (e.g. {"filter":{"email_address":{"exact":"a@b.com"}}})', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of results to return per page', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/customers/search`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = {} + if (params.query) body.query = params.query + if (params.limit !== undefined) body.limit = params.limit + if (params.cursor) body.cursor = params.cursor + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const customers = data.customers ?? [] + return { + success: true, + output: { + customers, + metadata: { + count: customers.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + customers: { + type: 'array', + description: 'Array of matching customer objects', + items: CUSTOMER_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/search_invoices.ts b/apps/sim/tools/square/search_invoices.ts new file mode 100644 index 0000000000..90fecaae2b --- /dev/null +++ b/apps/sim/tools/square/search_invoices.ts @@ -0,0 +1,88 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { InvoiceListResponse, SearchInvoicesParams } from '@/tools/square/types' +import { + INVOICE_OUTPUT, + LIST_METADATA_OUTPUT_PROPERTIES, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareSearchInvoicesTool: ToolConfig = { + id: 'square_search_invoices', + name: 'Square Search Invoices', + description: 'Search invoices across one or more locations', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + locationId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the location to search within (Square allows one location per search)', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of results to return per page', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/invoices/search`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = { + query: { + filter: { location_ids: [params.locationId] }, + }, + } + if (params.limit !== undefined) body.limit = params.limit + if (params.cursor) body.cursor = params.cursor + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const invoices = data.invoices ?? [] + return { + success: true, + output: { + invoices, + metadata: { + count: invoices.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + invoices: { + type: 'array', + description: 'Array of matching invoice objects', + items: INVOICE_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/search_orders.ts b/apps/sim/tools/square/search_orders.ts new file mode 100644 index 0000000000..07945aad0d --- /dev/null +++ b/apps/sim/tools/square/search_orders.ts @@ -0,0 +1,94 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { OrderListResponse, SearchOrdersParams } from '@/tools/square/types' +import { + LIST_METADATA_OUTPUT_PROPERTIES, + ORDER_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareSearchOrdersTool: ToolConfig = { + id: 'square_search_orders', + name: 'Square Search Orders', + description: 'Search orders across one or more locations using filters and sorting', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + locationIds: { + type: 'array', + required: true, + visibility: 'user-or-llm', + description: 'Array of location IDs to search within', + }, + query: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'Square order query object with optional filter and sort (e.g. {"filter":{"state_filter":{"states":["OPEN"]}}})', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of results to return per page', + }, + cursor: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from a previous response', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/orders/search`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = { + location_ids: params.locationIds, + } + if (params.query) body.query = params.query + if (params.limit !== undefined) body.limit = params.limit + if (params.cursor) body.cursor = params.cursor + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const orders = data.orders ?? [] + return { + success: true, + output: { + orders, + metadata: { + count: orders.length, + cursor: data.cursor ?? null, + }, + }, + } + }, + + outputs: { + orders: { + type: 'array', + description: 'Array of matching order objects', + items: ORDER_OUTPUT, + }, + metadata: { + type: 'json', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/types.ts b/apps/sim/tools/square/types.ts new file mode 100644 index 0000000000..ff230d7676 --- /dev/null +++ b/apps/sim/tools/square/types.ts @@ -0,0 +1,1077 @@ +import type { OutputProperty, ToolResponse } from '@/tools/types' + +/** + * Shared constants, output property definitions, and TypeScript interfaces for + * the Square API. Reused across all Square tools to keep request building and + * output shapes consistent. + * + * @see https://developer.squareup.com/reference/square + */ + +/** Square production API base URL. */ +export const SQUARE_BASE_URL = 'https://connect.squareup.com' + +/** + * Square API version pinned for every request via the `Square-Version` header. + * Square is a date-versioned API; pinning avoids silent breaking changes. + */ +export const SQUARE_API_VERSION = '2026-05-20' + +/** + * Standard headers for a JSON Square request authenticated with a personal + * access token (or any Square access token) as a bearer token. + */ +export function squareHeaders(apiKey: string): Record { + return { + Authorization: `Bearer ${apiKey}`, + 'Square-Version': SQUARE_API_VERSION, + 'Content-Type': 'application/json', + } +} + +/** + * Output definition for a Square Money object. + * @see https://developer.squareup.com/reference/square/objects/Money + */ +export const MONEY_OUTPUT_PROPERTIES = { + amount: { + type: 'number', + description: 'Amount in the smallest denomination of the currency (e.g. cents for USD)', + optional: true, + }, + currency: { + type: 'string', + description: 'Three-letter ISO 4217 currency code (e.g. USD)', + optional: true, + }, +} as const satisfies Record + +export const MONEY_OUTPUT: OutputProperty = { + type: 'object', + description: 'Monetary amount with a currency', + optional: true, + properties: MONEY_OUTPUT_PROPERTIES, +} + +/** + * Output definition for a Square Address object. + * @see https://developer.squareup.com/reference/square/objects/Address + */ +export const ADDRESS_OUTPUT_PROPERTIES = { + address_line_1: { type: 'string', description: 'First line of the address', optional: true }, + address_line_2: { type: 'string', description: 'Second line of the address', optional: true }, + address_line_3: { type: 'string', description: 'Third line of the address', optional: true }, + locality: { type: 'string', description: 'City or town', optional: true }, + sublocality: { type: 'string', description: 'Neighborhood or district', optional: true }, + administrative_district_level_1: { + type: 'string', + description: 'State, province, or region', + optional: true, + }, + postal_code: { type: 'string', description: 'Postal or ZIP code', optional: true }, + country: { + type: 'string', + description: 'Two-letter ISO 3166-1 alpha-2 country code', + optional: true, + }, + first_name: { type: 'string', description: 'First name of the addressee', optional: true }, + last_name: { type: 'string', description: 'Last name of the addressee', optional: true }, +} as const satisfies Record + +export const ADDRESS_OUTPUT: OutputProperty = { + type: 'object', + description: 'Physical address', + optional: true, + properties: ADDRESS_OUTPUT_PROPERTIES, +} + +/** + * Output definition for a Square Payment object. + * @see https://developer.squareup.com/reference/square/objects/Payment + */ +export const PAYMENT_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Unique ID for the payment' }, + status: { + type: 'string', + description: 'Payment status (APPROVED, PENDING, COMPLETED, CANCELED, or FAILED)', + optional: true, + }, + amount_money: MONEY_OUTPUT, + total_money: MONEY_OUTPUT, + approved_money: MONEY_OUTPUT, + app_fee_money: MONEY_OUTPUT, + refunded_money: MONEY_OUTPUT, + tip_money: MONEY_OUTPUT, + source_type: { + type: 'string', + description: 'Source of the payment (CARD, BANK_ACCOUNT, WALLET, etc.)', + optional: true, + }, + card_details: { type: 'json', description: 'Details about a card payment', optional: true }, + location_id: { + type: 'string', + description: 'ID of the location where the payment was taken', + optional: true, + }, + order_id: { type: 'string', description: 'ID of the associated order', optional: true }, + customer_id: { type: 'string', description: 'ID of the associated customer', optional: true }, + reference_id: { + type: 'string', + description: 'Optional external reference for the payment', + optional: true, + }, + receipt_number: { type: 'string', description: 'Receipt number for the payment', optional: true }, + receipt_url: { type: 'string', description: 'URL of the payment receipt', optional: true }, + note: { type: 'string', description: 'Optional note attached to the payment', optional: true }, + refund_ids: { + type: 'array', + description: 'IDs of refunds associated with the payment', + optional: true, + items: { type: 'string' }, + }, + processing_fee: { + type: 'array', + description: 'Processing fees applied to the payment', + optional: true, + items: { type: 'object' }, + }, + created_at: { type: 'string', description: 'Timestamp when the payment was created (RFC 3339)' }, + updated_at: { + type: 'string', + description: 'Timestamp when the payment was last updated (RFC 3339)', + optional: true, + }, + version_token: { + type: 'string', + description: 'Optimistic concurrency token for the payment', + optional: true, + }, +} as const satisfies Record + +export const PAYMENT_OUTPUT: OutputProperty = { + type: 'object', + description: 'Square Payment object', + properties: PAYMENT_OUTPUT_PROPERTIES, +} + +export const PAYMENT_METADATA_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Square payment ID' }, + status: { type: 'string', description: 'Current payment status', optional: true }, + order_id: { type: 'string', description: 'Associated order ID', optional: true }, +} as const satisfies Record + +/** + * Output definition for a Square PaymentRefund object. + * @see https://developer.squareup.com/reference/square/objects/PaymentRefund + */ +export const REFUND_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Unique ID for the refund' }, + status: { + type: 'string', + description: 'Refund status (PENDING, COMPLETED, REJECTED, or FAILED)', + optional: true, + }, + amount_money: MONEY_OUTPUT, + processing_fee: { + type: 'array', + description: 'Processing fees refunded', + optional: true, + items: { type: 'object' }, + }, + payment_id: { type: 'string', description: 'ID of the payment being refunded', optional: true }, + order_id: { type: 'string', description: 'ID of the associated order', optional: true }, + location_id: { type: 'string', description: 'ID of the associated location', optional: true }, + reason: { type: 'string', description: 'Reason for the refund', optional: true }, + created_at: { type: 'string', description: 'Timestamp when the refund was created (RFC 3339)' }, + updated_at: { + type: 'string', + description: 'Timestamp when the refund was last updated (RFC 3339)', + optional: true, + }, +} as const satisfies Record + +export const REFUND_OUTPUT: OutputProperty = { + type: 'object', + description: 'Square PaymentRefund object', + properties: REFUND_OUTPUT_PROPERTIES, +} + +export const REFUND_METADATA_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Square refund ID' }, + status: { type: 'string', description: 'Current refund status', optional: true }, + payment_id: { type: 'string', description: 'Refunded payment ID', optional: true }, +} as const satisfies Record + +/** + * Output definition for a Square Customer object. + * @see https://developer.squareup.com/reference/square/objects/Customer + */ +export const CUSTOMER_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Unique ID for the customer' }, + given_name: { type: 'string', description: 'First name of the customer', optional: true }, + family_name: { type: 'string', description: 'Last name of the customer', optional: true }, + nickname: { type: 'string', description: 'Nickname of the customer', optional: true }, + company_name: { type: 'string', description: 'Business name of the customer', optional: true }, + email_address: { type: 'string', description: 'Email address of the customer', optional: true }, + phone_number: { type: 'string', description: 'Phone number of the customer', optional: true }, + address: ADDRESS_OUTPUT, + birthday: { + type: 'string', + description: 'Birthday in YYYY-MM-DD or MM-DD format', + optional: true, + }, + reference_id: { + type: 'string', + description: 'Optional external reference for the customer', + optional: true, + }, + note: { type: 'string', description: 'Note about the customer', optional: true }, + creation_source: { + type: 'string', + description: 'How the customer profile was created', + optional: true, + }, + preferences: { type: 'json', description: 'Customer communication preferences', optional: true }, + group_ids: { + type: 'array', + description: 'IDs of customer groups the customer belongs to', + optional: true, + items: { type: 'string' }, + }, + segment_ids: { + type: 'array', + description: 'IDs of customer segments the customer belongs to', + optional: true, + items: { type: 'string' }, + }, + version: { + type: 'number', + description: 'Optimistic concurrency version of the customer', + optional: true, + }, + created_at: { type: 'string', description: 'Timestamp when the customer was created (RFC 3339)' }, + updated_at: { + type: 'string', + description: 'Timestamp when the customer was last updated (RFC 3339)', + optional: true, + }, +} as const satisfies Record + +export const CUSTOMER_OUTPUT: OutputProperty = { + type: 'object', + description: 'Square Customer object', + properties: CUSTOMER_OUTPUT_PROPERTIES, +} + +export const CUSTOMER_METADATA_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Square customer ID' }, + email_address: { type: 'string', description: 'Customer email address', optional: true }, + given_name: { type: 'string', description: 'Customer first name', optional: true }, + family_name: { type: 'string', description: 'Customer last name', optional: true }, +} as const satisfies Record + +/** + * Output definition for a Square Location object. + * @see https://developer.squareup.com/reference/square/objects/Location + */ +export const LOCATION_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Unique ID for the location' }, + name: { type: 'string', description: 'Name of the location', optional: true }, + address: ADDRESS_OUTPUT, + timezone: { type: 'string', description: 'IANA timezone of the location', optional: true }, + status: { type: 'string', description: 'Location status (ACTIVE or INACTIVE)', optional: true }, + type: { type: 'string', description: 'Location type (PHYSICAL or MOBILE)', optional: true }, + merchant_id: { + type: 'string', + description: 'ID of the merchant that owns the location', + optional: true, + }, + country: { type: 'string', description: 'Country code of the location', optional: true }, + language_code: { type: 'string', description: 'Language code of the location', optional: true }, + currency: { type: 'string', description: 'Currency used by the location', optional: true }, + phone_number: { type: 'string', description: 'Phone number of the location', optional: true }, + business_name: { + type: 'string', + description: 'Business name shown to customers', + optional: true, + }, + business_email: { type: 'string', description: 'Email of the business', optional: true }, + description: { type: 'string', description: 'Description of the location', optional: true }, + capabilities: { + type: 'array', + description: 'Capabilities of the location (e.g. CREDIT_CARD_PROCESSING)', + optional: true, + items: { type: 'string' }, + }, + created_at: { + type: 'string', + description: 'Timestamp when the location was created (RFC 3339)', + optional: true, + }, +} as const satisfies Record + +export const LOCATION_OUTPUT: OutputProperty = { + type: 'object', + description: 'Square Location object', + properties: LOCATION_OUTPUT_PROPERTIES, +} + +/** + * Output definition for a Square Order object. + * @see https://developer.squareup.com/reference/square/objects/Order + */ +export const ORDER_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Unique ID for the order' }, + location_id: { type: 'string', description: 'ID of the location for the order', optional: true }, + reference_id: { + type: 'string', + description: 'Optional external reference for the order', + optional: true, + }, + customer_id: { type: 'string', description: 'ID of the associated customer', optional: true }, + state: { + type: 'string', + description: 'Order state (OPEN, COMPLETED, or CANCELED)', + optional: true, + }, + version: { + type: 'number', + description: 'Optimistic concurrency version of the order', + optional: true, + }, + line_items: { + type: 'array', + description: 'Line items in the order', + optional: true, + items: { type: 'object' }, + }, + taxes: { + type: 'array', + description: 'Taxes applied to the order', + optional: true, + items: { type: 'object' }, + }, + discounts: { + type: 'array', + description: 'Discounts applied to the order', + optional: true, + items: { type: 'object' }, + }, + fulfillments: { + type: 'array', + description: 'Fulfillments for the order', + optional: true, + items: { type: 'object' }, + }, + net_amounts: { type: 'json', description: 'Net money amounts for the order', optional: true }, + total_money: MONEY_OUTPUT, + total_tax_money: MONEY_OUTPUT, + total_discount_money: MONEY_OUTPUT, + total_service_charge_money: MONEY_OUTPUT, + total_tip_money: MONEY_OUTPUT, + created_at: { + type: 'string', + description: 'Timestamp when the order was created (RFC 3339)', + optional: true, + }, + updated_at: { + type: 'string', + description: 'Timestamp when the order was last updated (RFC 3339)', + optional: true, + }, + closed_at: { + type: 'string', + description: 'Timestamp when the order was closed (RFC 3339)', + optional: true, + }, +} as const satisfies Record + +export const ORDER_OUTPUT: OutputProperty = { + type: 'object', + description: 'Square Order object', + properties: ORDER_OUTPUT_PROPERTIES, +} + +export const ORDER_METADATA_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Square order ID' }, + state: { type: 'string', description: 'Current order state', optional: true }, + location_id: { type: 'string', description: 'Order location ID', optional: true }, +} as const satisfies Record + +/** + * Output definition for a Square Invoice object. + * @see https://developer.squareup.com/reference/square/objects/Invoice + */ +export const INVOICE_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Unique ID for the invoice' }, + version: { + type: 'number', + description: 'Optimistic concurrency version of the invoice', + optional: true, + }, + location_id: { + type: 'string', + description: 'ID of the location for the invoice', + optional: true, + }, + order_id: { + type: 'string', + description: 'ID of the order the invoice bills for', + optional: true, + }, + status: { + type: 'string', + description: 'Invoice status (DRAFT, UNPAID, SCHEDULED, PARTIALLY_PAID, PAID, etc.)', + optional: true, + }, + invoice_number: { type: 'string', description: 'Human-readable invoice number', optional: true }, + title: { type: 'string', description: 'Title of the invoice', optional: true }, + description: { type: 'string', description: 'Description of the invoice', optional: true }, + public_url: { + type: 'string', + description: 'URL where the customer can view and pay the invoice', + optional: true, + }, + primary_recipient: { + type: 'json', + description: 'Primary recipient of the invoice', + optional: true, + }, + payment_requests: { + type: 'array', + description: 'Payment requests for the invoice', + optional: true, + items: { type: 'object' }, + }, + next_payment_amount_money: MONEY_OUTPUT, + scheduled_at: { + type: 'string', + description: 'Timestamp when the invoice is scheduled to be sent (RFC 3339)', + optional: true, + }, + timezone: { type: 'string', description: 'Timezone used for invoice dates', optional: true }, + delivery_method: { + type: 'string', + description: 'How the invoice is delivered (EMAIL, SHARE_MANUALLY, SMS)', + optional: true, + }, + created_at: { + type: 'string', + description: 'Timestamp when the invoice was created (RFC 3339)', + optional: true, + }, + updated_at: { + type: 'string', + description: 'Timestamp when the invoice was last updated (RFC 3339)', + optional: true, + }, +} as const satisfies Record + +export const INVOICE_OUTPUT: OutputProperty = { + type: 'object', + description: 'Square Invoice object', + properties: INVOICE_OUTPUT_PROPERTIES, +} + +export const INVOICE_METADATA_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Square invoice ID' }, + status: { type: 'string', description: 'Current invoice status', optional: true }, + version: { type: 'number', description: 'Invoice version', optional: true }, +} as const satisfies Record + +/** + * Output definition for a Square CatalogObject. + * Catalog objects are polymorphic; type-specific data lives in `*_data` fields. + * @see https://developer.squareup.com/reference/square/objects/CatalogObject + */ +export const CATALOG_OBJECT_OUTPUT_PROPERTIES = { + type: { + type: 'string', + description: 'Type of catalog object (ITEM, ITEM_VARIATION, CATEGORY, IMAGE, etc.)', + }, + id: { type: 'string', description: 'Unique ID for the catalog object' }, + version: { + type: 'number', + description: 'Optimistic concurrency version of the object', + optional: true, + }, + updated_at: { + type: 'string', + description: 'Timestamp when the object was last updated (RFC 3339)', + optional: true, + }, + is_deleted: { type: 'boolean', description: 'Whether the object is deleted', optional: true }, + present_at_all_locations: { + type: 'boolean', + description: 'Whether the object is present at all locations', + optional: true, + }, + item_data: { + type: 'json', + description: 'Item-specific data (when type is ITEM)', + optional: true, + }, + item_variation_data: { + type: 'json', + description: 'Variation-specific data (when type is ITEM_VARIATION)', + optional: true, + }, + category_data: { + type: 'json', + description: 'Category-specific data (when type is CATEGORY)', + optional: true, + }, + image_data: { + type: 'json', + description: 'Image-specific data (when type is IMAGE)', + optional: true, + }, +} as const satisfies Record + +export const CATALOG_OBJECT_OUTPUT: OutputProperty = { + type: 'object', + description: 'Square CatalogObject', + properties: CATALOG_OBJECT_OUTPUT_PROPERTIES, +} + +export const CATALOG_OBJECT_METADATA_OUTPUT_PROPERTIES = { + id: { type: 'string', description: 'Square catalog object ID' }, + type: { type: 'string', description: 'Catalog object type', optional: true }, + version: { type: 'number', description: 'Catalog object version', optional: true }, +} as const satisfies Record + +/** + * Output definition for a Square InventoryCount object. + * @see https://developer.squareup.com/reference/square/objects/InventoryCount + */ +export const INVENTORY_COUNT_OUTPUT_PROPERTIES = { + catalog_object_id: { + type: 'string', + description: 'ID of the catalog object (item variation) being counted', + optional: true, + }, + catalog_object_type: { + type: 'string', + description: 'Type of the counted catalog object (usually ITEM_VARIATION)', + optional: true, + }, + state: { + type: 'string', + description: 'Inventory state (e.g. IN_STOCK, SOLD, WASTE)', + optional: true, + }, + location_id: { type: 'string', description: 'ID of the location for this count', optional: true }, + quantity: { + type: 'string', + description: 'Number of units in the given state at the location', + optional: true, + }, + calculated_at: { + type: 'string', + description: 'Timestamp when the count was calculated (RFC 3339)', + optional: true, + }, +} as const satisfies Record + +export const INVENTORY_COUNT_OUTPUT: OutputProperty = { + type: 'object', + description: 'Square InventoryCount object', + properties: INVENTORY_COUNT_OUTPUT_PROPERTIES, +} + +/** + * Pagination metadata for cursor-paged Square list/search endpoints. + */ +export const LIST_METADATA_OUTPUT_PROPERTIES = { + count: { type: 'number', description: 'Number of items returned in this page' }, + cursor: { + type: 'string', + description: 'Pagination cursor to fetch the next page, if more results exist', + optional: true, + }, +} as const satisfies Record + +export const LIST_METADATA_OUTPUT: OutputProperty = { + type: 'object', + description: 'List pagination metadata', + properties: LIST_METADATA_OUTPUT_PROPERTIES, +} + +interface SquareMoney { + amount?: number + currency?: string +} + +interface SquareAddress { + address_line_1?: string + address_line_2?: string + locality?: string + administrative_district_level_1?: string + postal_code?: string + country?: string + [key: string]: unknown +} + +interface SquareListMetadata { + count: number + cursor?: string +} + +interface PaymentObject { + id: string + status?: string + amount_money?: SquareMoney + order_id?: string + created_at: string + [key: string]: unknown +} + +interface RefundObject { + id: string + status?: string + amount_money?: SquareMoney + payment_id?: string + created_at: string + [key: string]: unknown +} + +interface CustomerObject { + id: string + given_name?: string + family_name?: string + email_address?: string + created_at: string + [key: string]: unknown +} + +interface LocationObject { + id: string + name?: string + [key: string]: unknown +} + +interface OrderObject { + id: string + state?: string + location_id?: string + [key: string]: unknown +} + +interface InvoiceObject { + id: string + status?: string + version?: number + [key: string]: unknown +} + +interface CatalogObject { + id: string + type: string + version?: number + [key: string]: unknown +} + +interface InventoryCountObject { + catalog_object_id?: string + catalog_object_type?: string + state?: string + location_id?: string + quantity?: string + calculated_at?: string + [key: string]: unknown +} + +export interface CreatePaymentParams { + apiKey: string + sourceId: string + amount: number + currency: string + idempotencyKey?: string + customerId?: string + locationId?: string + orderId?: string + referenceId?: string + note?: string + autocomplete?: boolean +} + +export interface GetPaymentParams { + apiKey: string + paymentId: string +} + +export interface ListPaymentsParams { + apiKey: string + locationId?: string + beginTime?: string + endTime?: string + limit?: number + cursor?: string +} + +export interface RefundPaymentParams { + apiKey: string + paymentId: string + amount: number + currency: string + idempotencyKey?: string + reason?: string +} + +export interface CreateCustomerParams { + apiKey: string + givenName?: string + familyName?: string + companyName?: string + nickname?: string + emailAddress?: string + phoneNumber?: string + birthday?: string + note?: string + referenceId?: string + address?: SquareAddress + idempotencyKey?: string +} + +export interface GetCustomerParams { + apiKey: string + customerId: string +} + +export interface ListCustomersParams { + apiKey: string + limit?: number + cursor?: string + sortField?: string + sortOrder?: string +} + +export interface SearchCustomersParams { + apiKey: string + query?: Record + limit?: number + cursor?: string +} + +export interface UpdateCustomerParams { + apiKey: string + customerId: string + givenName?: string + familyName?: string + companyName?: string + nickname?: string + emailAddress?: string + phoneNumber?: string + birthday?: string + note?: string + referenceId?: string + address?: SquareAddress +} + +export interface DeleteCustomerParams { + apiKey: string + customerId: string +} + +export interface ListLocationsParams { + apiKey: string +} + +export interface CreateOrderParams { + apiKey: string + order: Record + idempotencyKey?: string +} + +export interface GetOrderParams { + apiKey: string + orderId: string +} + +export interface SearchOrdersParams { + apiKey: string + locationIds: string[] + query?: Record + limit?: number + cursor?: string +} + +export interface CreateInvoiceParams { + apiKey: string + invoice: Record + idempotencyKey?: string +} + +export interface GetInvoiceParams { + apiKey: string + invoiceId: string +} + +export interface ListInvoicesParams { + apiKey: string + locationId: string + limit?: number + cursor?: string +} + +export interface PublishInvoiceParams { + apiKey: string + invoiceId: string + version: number + idempotencyKey?: string +} + +export interface UpsertCatalogObjectParams { + apiKey: string + object: Record + idempotencyKey?: string +} + +export interface GetCatalogObjectParams { + apiKey: string + objectId: string + includeRelatedObjects?: boolean +} + +export interface ListCatalogParams { + apiKey: string + types?: string + cursor?: string +} + +export interface SearchCatalogObjectsParams { + apiKey: string + objectTypes?: string[] + query?: Record + limit?: number + cursor?: string +} + +export interface CreateCatalogImageParams { + apiKey: string + file?: unknown + fileName?: string + objectId?: string + caption?: string + idempotencyKey?: string +} + +export interface CancelPaymentParams { + apiKey: string + paymentId: string +} + +export interface CompletePaymentParams { + apiKey: string + paymentId: string + versionToken?: string +} + +export interface GetRefundParams { + apiKey: string + refundId: string +} + +export interface ListRefundsParams { + apiKey: string + locationId?: string + status?: string + beginTime?: string + endTime?: string + limit?: number + cursor?: string +} + +export interface PayOrderParams { + apiKey: string + orderId: string + orderVersion?: number + paymentIds?: string[] + idempotencyKey?: string +} + +export interface SearchInvoicesParams { + apiKey: string + locationId: string + limit?: number + cursor?: string +} + +export interface CancelInvoiceParams { + apiKey: string + invoiceId: string + version: number +} + +export interface DeleteInvoiceParams { + apiKey: string + invoiceId: string + version?: number +} + +export interface DeleteCatalogObjectParams { + apiKey: string + objectId: string +} + +export interface GetLocationParams { + apiKey: string + locationId: string +} + +export interface BatchRetrieveInventoryCountsParams { + apiKey: string + catalogObjectIds?: string[] + locationIds?: string[] + states?: string[] + updatedAfter?: string + limit?: number + cursor?: string +} + +export interface PaymentResponse extends ToolResponse { + output: { + payment: PaymentObject + metadata: { id: string; status?: string; order_id?: string } + } +} + +export interface PaymentListResponse extends ToolResponse { + output: { + payments: PaymentObject[] + metadata: SquareListMetadata + } +} + +export interface RefundResponse extends ToolResponse { + output: { + refund: RefundObject + metadata: { id: string; status?: string; payment_id?: string } + } +} + +export interface CustomerResponse extends ToolResponse { + output: { + customer: CustomerObject + metadata: { id: string; email_address?: string; given_name?: string; family_name?: string } + } +} + +export interface CustomerListResponse extends ToolResponse { + output: { + customers: CustomerObject[] + metadata: SquareListMetadata + } +} + +export interface CustomerDeleteResponse extends ToolResponse { + output: { + deleted: boolean + id: string + } +} + +export interface LocationListResponse extends ToolResponse { + output: { + locations: LocationObject[] + metadata: { count: number } + } +} + +export interface OrderResponse extends ToolResponse { + output: { + order: OrderObject + metadata: { id: string; state?: string; location_id?: string } + } +} + +export interface OrderListResponse extends ToolResponse { + output: { + orders: OrderObject[] + metadata: SquareListMetadata + } +} + +export interface InvoiceResponse extends ToolResponse { + output: { + invoice: InvoiceObject + metadata: { id: string; status?: string; version?: number } + } +} + +export interface InvoiceListResponse extends ToolResponse { + output: { + invoices: InvoiceObject[] + metadata: SquareListMetadata + } +} + +export interface CatalogObjectResponse extends ToolResponse { + output: { + object: CatalogObject + metadata: { id: string; type?: string; version?: number } + } +} + +export interface CatalogListResponse extends ToolResponse { + output: { + objects: CatalogObject[] + metadata: SquareListMetadata + } +} + +export interface RefundListResponse extends ToolResponse { + output: { + refunds: RefundObject[] + metadata: SquareListMetadata + } +} + +export interface LocationResponse extends ToolResponse { + output: { + location: LocationObject + metadata: { id: string; name?: string } + } +} + +export interface InvoiceDeleteResponse extends ToolResponse { + output: { + deleted: boolean + id: string + } +} + +export interface CatalogDeleteResponse extends ToolResponse { + output: { + deleted: boolean + deleted_object_ids: string[] + deleted_at: string | null + } +} + +export interface InventoryCountListResponse extends ToolResponse { + output: { + counts: InventoryCountObject[] + metadata: SquareListMetadata + } +} + +export type SquareResponse = + | PaymentResponse + | PaymentListResponse + | RefundResponse + | RefundListResponse + | CustomerResponse + | CustomerListResponse + | CustomerDeleteResponse + | LocationListResponse + | LocationResponse + | OrderResponse + | OrderListResponse + | InvoiceResponse + | InvoiceListResponse + | InvoiceDeleteResponse + | CatalogObjectResponse + | CatalogListResponse + | CatalogDeleteResponse + | InventoryCountListResponse diff --git a/apps/sim/tools/square/update_customer.ts b/apps/sim/tools/square/update_customer.ts new file mode 100644 index 0000000000..f41f3eb6c8 --- /dev/null +++ b/apps/sim/tools/square/update_customer.ts @@ -0,0 +1,138 @@ +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CustomerResponse, UpdateCustomerParams } from '@/tools/square/types' +import { + CUSTOMER_METADATA_OUTPUT_PROPERTIES, + CUSTOMER_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareUpdateCustomerTool: ToolConfig = { + id: 'square_update_customer', + name: 'Square Update Customer', + description: 'Update fields on an existing customer profile', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + customerId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'ID of the customer to update', + }, + givenName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'First name of the customer', + }, + familyName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Last name of the customer', + }, + companyName: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Business name of the customer', + }, + nickname: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Nickname of the customer', + }, + emailAddress: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Email address of the customer', + }, + phoneNumber: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Phone number of the customer', + }, + birthday: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Birthday in YYYY-MM-DD or MM-DD format', + }, + note: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Note about the customer', + }, + referenceId: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Optional external reference for the customer', + }, + address: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: 'Square address object for the customer', + }, + }, + + request: { + url: (params) => `${SQUARE_BASE_URL}/v2/customers/${encodeURIComponent(params.customerId)}`, + method: 'PUT', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => { + const body: Record = {} + if (params.givenName !== undefined) body.given_name = params.givenName + if (params.familyName !== undefined) body.family_name = params.familyName + if (params.companyName !== undefined) body.company_name = params.companyName + if (params.nickname !== undefined) body.nickname = params.nickname + if (params.emailAddress !== undefined) body.email_address = params.emailAddress + if (params.phoneNumber !== undefined) body.phone_number = params.phoneNumber + if (params.birthday !== undefined) body.birthday = params.birthday + if (params.note !== undefined) body.note = params.note + if (params.referenceId !== undefined) body.reference_id = params.referenceId + if (params.address !== undefined) body.address = params.address + return body + }, + }, + + transformResponse: async (response) => { + const data = await response.json() + const customer = data.customer ?? {} + return { + success: true, + output: { + customer, + metadata: { + id: customer.id, + email_address: customer.email_address ?? null, + given_name: customer.given_name ?? null, + family_name: customer.family_name ?? null, + }, + }, + } + }, + + outputs: { + customer: { ...CUSTOMER_OUTPUT, description: 'The updated customer object' }, + metadata: { + type: 'json', + description: 'Customer summary metadata', + properties: CUSTOMER_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/square/upsert_catalog_object.ts b/apps/sim/tools/square/upsert_catalog_object.ts new file mode 100644 index 0000000000..69d3731da5 --- /dev/null +++ b/apps/sim/tools/square/upsert_catalog_object.ts @@ -0,0 +1,78 @@ +import { generateId } from '@sim/utils/id' +import { ErrorExtractorId } from '@/tools/error-extractors' +import type { CatalogObjectResponse, UpsertCatalogObjectParams } from '@/tools/square/types' +import { + CATALOG_OBJECT_METADATA_OUTPUT_PROPERTIES, + CATALOG_OBJECT_OUTPUT, + SQUARE_BASE_URL, + squareHeaders, +} from '@/tools/square/types' +import type { ToolConfig } from '@/tools/types' + +export const squareUpsertCatalogObjectTool: ToolConfig< + UpsertCatalogObjectParams, + CatalogObjectResponse +> = { + id: 'square_upsert_catalog_object', + name: 'Square Upsert Catalog Object', + description: 'Create or update a catalog object such as an item, variation, or category', + version: '1.0.0', + errorExtractor: ErrorExtractorId.SQUARE_ERRORS, + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Square access token (personal access token)', + }, + object: { + type: 'json', + required: true, + visibility: 'user-or-llm', + description: + 'Square catalog object to create or update. Use ID "#name" for new objects (e.g. {"type":"ITEM","id":"#Coffee","item_data":{"name":"Coffee"}})', + }, + idempotencyKey: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Unique key to make the request idempotent (auto-generated if omitted)', + }, + }, + + request: { + url: () => `${SQUARE_BASE_URL}/v2/catalog/object`, + method: 'POST', + headers: (params) => squareHeaders(params.apiKey), + body: (params) => ({ + idempotency_key: params.idempotencyKey || generateId(), + object: params.object, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + const object = data.catalog_object ?? {} + return { + success: true, + output: { + object, + metadata: { + id: object.id, + type: object.type ?? null, + version: object.version ?? null, + }, + }, + } + }, + + outputs: { + object: { ...CATALOG_OBJECT_OUTPUT, description: 'The created or updated catalog object' }, + metadata: { + type: 'json', + description: 'Catalog object summary metadata', + properties: CATALOG_OBJECT_METADATA_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/scripts/check-api-validation-contracts.ts b/scripts/check-api-validation-contracts.ts index ed468073fe..2ca1801390 100644 --- a/scripts/check-api-validation-contracts.ts +++ b/scripts/check-api-validation-contracts.ts @@ -9,8 +9,8 @@ const QUERY_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/queries') const SELECTOR_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/selectors') const BASELINE = { - totalRoutes: 826, - zodRoutes: 826, + totalRoutes: 827, + zodRoutes: 827, nonZodRoutes: 0, } as const