Skip to content

feat(square): add Square integration with 34 commerce operations#5053

Merged
waleedlatif1 merged 7 commits into
stagingfrom
feat/square-integration
Jun 15, 2026
Merged

feat(square): add Square integration with 34 commerce operations#5053
waleedlatif1 merged 7 commits into
stagingfrom
feat/square-integration

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Add a Square integration (API-key auth via personal access token) with 34 operations across Payments, Refunds, Customers, Locations, Orders, Invoices, Catalog, and Inventory
  • Catalog image upload routes through an internal API endpoint (/api/tools/square/catalog-image) using the shared UserFile download + multipart pattern (same as Box)
  • Add a dedicated square-errors extractor (errors[].detail + code) so Square API errors surface cleanly
  • Block uses an operation dropdown with conditional fields, JSON/number/boolean coercion in tools.config.params, and a SquareBlockMeta with 7 templates + 4 skills
  • Icon added (black tile per brand), tools/blocks registries wired, docs generated

Operations

  • Payments: create, get, list, cancel, complete
  • Refunds: refund, get, list
  • Customers: create, get, list, search, update, delete
  • Locations: list, get
  • Orders: create, get, search, pay
  • Invoices: create, get, list, search, publish, cancel, delete
  • Catalog: upsert object, get object, list, search, create image (file upload), delete object
  • Inventory: batch retrieve counts

Type of Change

  • New feature

Testing

Tested manually; typecheck clean, bun run check:api-validation:strict passes, docs regenerated.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Add a Square integration (API-key auth via personal access token) covering
payments, refunds, customers, locations, orders, invoices, catalog, and
inventory. Catalog image upload routes through an internal API endpoint using
the shared UserFile handling pattern. Adds a dedicated square-errors extractor.
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 15, 2026 8:15am

Request Review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@cursor

cursor Bot commented Jun 15, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
New payment/refund and money-moving operations plus server-side handling of Square access tokens and file uploads, but changes are additive and follow existing integration patterns.

Overview
Adds a new Square commerce integration authenticated with a personal access token, exposed as a workflow block with an operation dropdown and 34 mapped tools (payments, refunds, customers, locations, orders, invoices, catalog, inventory).

Most calls hit Square’s REST API directly from tool configs; catalog image upload is the exception—a new internal POST /api/tools/square/catalog-image route downloads the user’s file from storage (with auth and file access checks), then forwards multipart data to Square.

Docs, SquareIcon, integration metadata, block registry, tool registry, and a square-errors API error extractor are wired in alongside templates/skills on the block.

Reviewed by Cursor Bugbot for commit 6b161a7. Configure here.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 339ec6e. Configure here.

@greptile-apps

greptile-apps Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a comprehensive Square commerce integration with 34 operations across Payments, Refunds, Customers, Locations, Orders, Invoices, Catalog, and Inventory. The implementation follows established patterns in the codebase — a multi-operation block with per-field conditions and a shared params coercion function, individual tool files for each operation, a dedicated square-errors extractor, and a specialized internal API route for multipart catalog image uploads.

  • Block (square.ts): Uses a robust parseJsonField / coerceNumber / coerceBoolean helper pattern with per-field error messages so users know exactly which input is malformed; all 34 tools are wired to the registry and the block operation selector.
  • Route (catalog-image/route.ts): Follows the same Box-style file-download-then-multipart pattern, properly checks response.ok before parsing the body, preserves Square's HTTP status code on errors, and uses assertToolFileAccess for authorization.
  • Types (types.ts): Shared output-property constants and TypeScript interfaces are thorough and consistently used across all 34 tool files.

Confidence Score: 5/5

Safe to merge — the integration is additive (no changes to existing paths) and follows established tool/block patterns throughout.

All 34 tools correctly use encodeURIComponent on path parameters, auto-generate idempotency keys, set visibility: 'user-only' on credentials, and wire into the registry. The catalog-image route properly handles auth, file authorization, MIME type derivation, and Square error forwarding. The single observation (search_invoices not exposing its filter/sort surface) is cosmetic and does not affect correctness or security.

apps/sim/tools/square/search_invoices.ts — the exposed interface is more limited than the underlying Square Search Invoices endpoint allows.

Important Files Changed

Filename Overview
apps/sim/blocks/blocks/square.ts Large block definition for 34 Square operations; uses operation dropdown with per-field conditions/required guards, robust JSON/number/boolean coercion helpers with per-field error messages, and correct file normalization for catalog image upload.
apps/sim/app/api/tools/square/catalog-image/route.ts New internal API route for multipart catalog image upload to Square; correctly checks auth, validates file access, reads MIME type from UserFile, and handles Square error responses with proper status code forwarding.
apps/sim/tools/square/types.ts Comprehensive shared type definitions, output property constants, and API constants for all Square tools; well-organized with JSDoc links to Square API reference docs.
apps/sim/tools/square/create_catalog_image.ts Routes catalog image upload through internal API endpoint (same pattern as Box); error handling via transformResponse checking data.success; intentionally omits errorExtractor since errors surface through the internal route's JSON envelope.
apps/sim/tools/square/search_invoices.ts Wraps Square's search invoices endpoint but only exposes location filtering (no customer_id, status, or sort params); works correctly but the "search" label overstates its flexibility compared to the underlying API's full filter/sort capability.
apps/sim/tools/square/create_payment.ts Correctly builds payment body with required fields (source_id, amount_money) and optional fields; uses generateId() idempotency fallback; extracts payment and metadata from response.
apps/sim/tools/square/refund_payment.ts Correctly POSTs to /v2/refunds with required payment_id, amount_money, and idempotency_key; optional reason field handled cleanly.
apps/sim/tools/square/delete_customer.ts DELETE /v2/customers/{id} tool; transformResponse discards the empty response body and returns {deleted: true, id}; errorExtractor is set so non-2xx responses are handled by the framework before transformResponse is called.
apps/sim/tools/error-extractors.ts Adds square-errors extractor combining errors[0].detail and errors[0].code for clean error messages; properly registered in ErrorExtractorId enum.
apps/sim/lib/api/contracts/tools/square.ts Zod contract for catalog image route with correct body schema and opaque response.output.object (polymorphic Square CatalogObject); file field correctly marked optional in schema while the route enforces presence at runtime.
apps/sim/tools/square/batch_retrieve_inventory_counts.ts Correctly uses POST /v2/inventory/counts/batch-retrieve with optional catalogObjectIds, locationIds, states, updatedAfter filters; proper cursor pagination support.
scripts/check-api-validation-contracts.ts Baseline updated from 826 to 827 routes/zodRoutes to account for the new catalog-image route; correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Block["Square Block\n(operation dropdown)"] --> Coerce["tools.config.params\nJSON parse · number coerce · boolean coerce"]
    Coerce --> ToolSel["tools.config.tool\nsquare_\${operation}"]

    ToolSel --> PayTools["Payment Tools\ncreate / get / list / cancel / complete"]
    ToolSel --> RefTools["Refund Tools\nrefund / get / list"]
    ToolSel --> CustTools["Customer Tools\ncreate / get / list / search / update / delete"]
    ToolSel --> LocTools["Location Tools\nlist / get"]
    ToolSel --> OrdTools["Order Tools\ncreate / get / search / pay"]
    ToolSel --> InvTools["Invoice Tools\ncreate / get / list / search / publish / cancel / delete"]
    ToolSel --> CatTools["Catalog Tools\nupsert / get / list / search / delete"]
    ToolSel --> ImgTool["Catalog Image\n(create_catalog_image)"]
    ToolSel --> InvCounts["Inventory\nbatch_retrieve_counts"]

    PayTools --> SquareAPI["Square REST API\nconnect.squareup.com\n+ Square-Version header"]
    RefTools --> SquareAPI
    CustTools --> SquareAPI
    LocTools --> SquareAPI
    OrdTools --> SquareAPI
    InvTools --> SquareAPI
    CatTools --> SquareAPI
    InvCounts --> SquareAPI

    ImgTool --> InternalRoute["/api/tools/square/catalog-image\nDownload file · Build multipart form"]
    InternalRoute --> SquareCatImg["Square Catalog Images API\nPOST /v2/catalog/images"]

    SquareAPI --> ErrExt["square-errors extractor\nerrors[0].detail + code"]
Loading

Reviews (11): Last reviewed commit: "fix(square): validate parsed JSON field ..." | Re-trigger Greptile

Comment thread apps/sim/app/api/tools/square/catalog-image/route.ts Outdated
Comment thread apps/sim/blocks/blocks/square.ts
Comment thread apps/sim/blocks/blocks/square.ts Outdated
@greptile-apps

greptile-apps Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a complete Square integration with 34 operations spanning Payments, Refunds, Customers, Locations, Orders, Invoices, Catalog, and Inventory. Authentication uses a personal access token (PAT) via user-only visibility, consistent with the project's credential policy.

  • Adds 34 tool files, a multi-operation block with conditional subfields, a square-errors extractor, and an internal catalog-image route that follows the established Box upload pattern with UserFile + multipart forwarding.
  • Wires the block and tools into their respective registries, adds the Square integration to integrations.json, and updates the API validation contract baseline.
  • Includes 7 block templates and 4 agent skills in SquareBlockMeta, plus full docs and icon additions across both the sim and docs apps.

Confidence Score: 4/5

  • The Square integration is a well-structured addition that faithfully follows established codebase patterns for tool definitions, block configs, error extraction, and file-upload proxying. Auth is handled correctly (user-only PAT, internal route guard, file-access assertions), URL parameters are encoded properly, and idempotency keys are auto-generated where needed. The two issues found are edge-case UX/diagnostic concerns rather than correctness problems.
  • The catalog-image route parses the Square response body as JSON before checking whether the response was successful, which can mask upstream HTTP status codes in rare error conditions. The block's JSON-parsing try-catch collapses all nine JSON fields into one error message, making it hard for users to identify which field is malformed. Neither issue causes incorrect behaviour under normal operation, but both would frustrate debugging in production.
  • apps/sim/app/api/tools/square/catalog-image/route.ts (parse-order issue) and apps/sim/blocks/blocks/square.ts (single try-catch across all JSON fields).

Important Files Changed

Filename Overview
apps/sim/app/api/tools/square/catalog-image/route.ts New internal proxy route for Square catalog image uploads; correctly checks auth, validates file access, and forwards multipart to Square. Minor: response.json() is called before !response.ok is checked, which can obscure non-JSON upstream errors.
apps/sim/blocks/blocks/square.ts Large block definition with 34 operations, correct conditional subfields, and type coercions. All JSON params are parsed in a single try-catch, making the resulting error message ambiguous when multiple JSON fields are present.
apps/sim/tools/square/types.ts Comprehensive shared type file for all Square tools; output property definitions, parameter interfaces, and response types are consistent and well-structured.
apps/sim/tools/square/create_payment.ts Correct Square Payments API integration with proper idempotency key auto-generation and SQUARE_ERRORS extractor; follows established tool patterns.
apps/sim/tools/square/create_catalog_image.ts Correctly delegates to the internal catalog-image route; transformResponse checks data.success for internal-route error cases; consistent with Box file-upload pattern.
apps/sim/tools/error-extractors.ts Adds square-errors extractor that combines errors[0].detail and errors[0].code; correctly registered and exported.
apps/sim/lib/api/contracts/tools/square.ts Zod contract for the catalog-image route; schema is correctly typed and nullable fields are handled appropriately.
apps/sim/tools/square/batch_retrieve_inventory_counts.ts Uses the correct Square Inventory API endpoint /v2/inventory/counts/batch-retrieve and properly handles optional filter params.

Sequence Diagram

sequenceDiagram
    participant UI as Block UI
    participant Exec as Tool Executor (index.ts)
    participant Proxy as /api/tools/square/catalog-image
    participant Square as Square API

    UI->>Exec: "run square_${operation}"
    Exec->>Exec: check !response.ok → errorExtractor(SQUARE_ERRORS)
    alt Direct Square tool (e.g. create_payment)
        Exec->>Square: POST /v2/payments (Bearer token)
        Square-->>Exec: "200 OK {payment}"
        Exec->>Exec: transformResponse → return output
    else Catalog image upload
        Exec->>Proxy: POST /api/tools/square/catalog-image
        Proxy->>Proxy: checkInternalAuth + assertToolFileAccess
        Proxy->>Proxy: downloadFileFromStorage
        Proxy->>Square: POST /v2/catalog/images (multipart)
        Square-->>Proxy: "200 OK {image}"
        Proxy-->>Exec: "200 {success:true, output:{object, metadata}}"
        Exec->>Exec: transformResponse checks data.success
    end
    Exec-->>UI: tool output
Loading

Reviews (2): Last reviewed commit: "feat(square): add Square integration wit..." | Re-trigger Greptile

Comment thread apps/sim/app/api/tools/square/catalog-image/route.ts
Comment thread apps/sim/blocks/blocks/square.ts Outdated
- Fix catalog image upload: Square's multipart part for the binary is `file`,
  not `image_file` (per the live API cURL examples); this would have caused
  upload failures
- Catalog image route: check response.ok before parsing, drop the unreachable
  legacy base64 path, derive MIME from the uploaded file
- Block: split the search query field per operation so placeholders match each
  endpoint's schema; parse each JSON field individually so errors name the field
- Round out coverage: complete_payment version_token; customer nickname/birthday;
  batch inventory states/updated_after/limit
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile recheck

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 81d5107. Configure here.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

- Read the catalog image file from the canonical `params.file` (the basic/advanced
  inputs are collapsed before the params function runs) instead of the raw
  uploadFile/fileRef ids, which no longer exist at that point — fixes the
  Canonical Param Validation test and a latent upload bug
- Revert the per-operation query split: canonicalParamId is only valid for
  basic/advanced pairs under one condition. Use a single query field with a
  schema-neutral placeholder and a wand prompt that covers each search operation
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 4c7ea07. Configure here.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

Comment thread apps/sim/blocks/blocks/square.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/tools/square/search_invoices.ts
Comment thread apps/sim/blocks/blocks/square.ts Outdated
- SearchInvoices: Square's invoice filter accepts only one location, so take a
  single locationId (string) instead of an array and wrap it as
  query.filter.location_ids: [locationId]
- Block: fail locally with a clear "<field> must be a valid number" error when
  amount/limit/version/orderVersion are non-numeric instead of forwarding NaN
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/blocks/blocks/square.ts
Coerce these from both the dropdown's string values and actual booleans
(which can arrive via connected blocks or templated inputs), so true is not
silently flipped to false.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/blocks/blocks/square.ts
parseJsonField now enforces the expected shape so a valid-but-wrong-type value
(e.g. a JSON string where an array is expected for locationIds/objectTypes/
paymentIds/catalogObjectIds/states, or a non-object for order/invoice/etc.)
fails locally with a clear message instead of a confusing Square API error.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 6b161a7. Configure here.

@waleedlatif1 waleedlatif1 merged commit 940506a into staging Jun 15, 2026
15 checks passed
@waleedlatif1 waleedlatif1 deleted the feat/square-integration branch June 15, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant