Square
Accept and process payments with Square
@weareseeed/medusa-square-plugin
A full-featured Square integration plugin for Medusa v2. Handles payment processing, OAuth account linking, bidirectional catalog/customer/inventory sync, and Apple Pay domain registration — all configurable from the admin dashboard at runtime.
Table of Contents
- Features
- Prerequisites
- Installation
- Configuration
- Admin UI
- Storefront Integration
- Data Synchronization
- API Reference
- Workflows
- Usage
Features
- OAuth 2.0 — Secure merchant account linking via Square OAuth with encrypted token storage and automatic refresh
- Payment Processing — Full authorize → capture → cancel → refund flow via Copy to clipboard
AbstractPaymentProvider - Location Support — List and select which Square location processes payments
- Bidirectional Sync — Sync products, categories, customers, and inventory between Medusa and Square
- Order Sync — Create Square orders from Medusa cart data at payment time
- Apple Pay — Register a domain for Apple Pay support
- Sandbox & Production — Toggle between environments without redeployment
- Database-driven Config — All settings stored in the database; no restart required after changes
Prerequisites
- Node.js >= 20
- Medusa v2.x (peer dependency)
- PostgreSQL (for plugin configuration table)
- Redis (recommended, for caching)
- A Square Account
Installation
1234yarn add @weareseeed/medusa-square-plugin# ornpm install @weareseeed/medusa-square-plugin
Register in Copy to clipboardmedusa-config.ts
1234567891011121314151617181920import { defineConfig } from "@medusajs/framework/utils"export default defineConfig({modules: [// Register Square as a payment provider{resolve: "@medusajs/medusa/payment",options: {providers: [{resolve: "@weareseeed/medusa-square-plugin/providers/square-payment",id: "square",},],},},],plugins: [{resolve: "@weareseeed/medusa-square-plugin",
No options are required. All configuration is managed through the Admin UI.
Run Migrations
12npx medusa db:migrate
This creates the Copy to clipboardsquare_configuration table used by the plugin.
Configuration
Environment Variables
Variable Description Default Required Copy to clipboardMEDUSA_BACKEND_URL Public URL of your Medusa backend, used as the OAuth redirect base Copy to clipboardhttp://localhost:9000 Yes (production)
123456# .env (development)MEDUSA_BACKEND_URL=http://localhost:9000# .env (production)MEDUSA_BACKEND_URL=https://api.yourdomain.com
The OAuth callback will be registered at Copy to clipboard{MEDUSA_BACKEND_URL}/admin/square/oauth.
Admin UI
After installing, a Square section appears under your Medusa Admin settings. It has three tabs:
Account Tab
- Connect / Disconnect your Square account via OAuth
- Toggle between Sandbox and Production environments
- View linked account status
- List your Square locations and select which one processes payments
Apple Pay Tab
- Register your storefront domain for Apple Pay
- View the currently registered domain
Settings Tab
- Choose sync source of truth: Medusa or Square
- Orders (auto-created in Square at payment time)
- Toggle individual sync features:
- Catalog (products and categories)
- Customers
- Trigger a manual sync workflow
- Stop an in-progress sync
Storefront Integration
Use Copy to clipboardreact-square-web-payments-sdk — the official React wrapper around the Square Web Payments SDK, built by the same team — to collect payment details on your storefront.
Install
1234yarn add react-square-web-payments-sdk# ornpm install react-square-web-payments-sdk
Fetch Public Config
Before rendering the payment form, fetch the public Square config from the store endpoint to get the Copy to clipboardapplication_id and Copy to clipboardlocation_id:
12GET /store/square/config
Response:
12345678910{"location_id": "XXXXXXXXX","application_id": "xxxxx-xxxxxx-xxxxxxxxx","currency": "XXX","capabilities": ["CREDIT_CARD_PROCESSING","AUTOMATIC_TRANSFERS"]}
Basic Credit Card Form
Wrap your checkout with Copy to clipboardPaymentForm and drop in the Copy to clipboardCreditCard component. The SDK handles input rendering and tokenization.
1234567891011121314151617181920import { PaymentForm, CreditCard } from "react-square-web-payments-sdk"import { CartDTO } from "@medusajs/types";const PAYMENT_PROVIDER_SQUARE = "pp_square_square";interface SquareConfig {application_id: stringlocation_id: stringcurrency: string}export function SquareCheckout({ config , cart }: { config: SquareConfig , cart: CartDTO }) {return (<PaymentFormapplicationId={config.application_id}locationId={config.location_id}cardTokenizeResponseReceived={async (token, buyer) => {// Pass it to your Medusa payment sessionawait initiatePaymentSession(cart, {provider_id: PAYMENT_PROVIDER_SQUARE,
Data Synchronization
The plugin supports bidirectional sync between Medusa and Square.
Automatic (Real-time)
Event subscribers listen for Medusa events and push updates to Square:
Medusa Event Syncs To Square Copy to clipboardproduct.created / Copy to clipboardproduct.updated Catalog item Copy to clipboardproduct_variant.created / Copy to clipboardproduct_variant.updated Catalog item variation Copy to clipboardproduct_category.created / Copy to clipboardproduct_category.updated Catalog category Copy to clipboardcustomer.created / Copy to clipboardcustomer.updated Customer
These run only when Copy to clipboardsync_catalog / Copy to clipboardsync_customers are enabled in the config.
Manual (Workflow-based)
Trigger from the Admin UI or programmatically:
Medusa → Square (Copy to clipboardsync-medusa-square-workflow)
- Syncs customers
- Syncs product categories
- Syncs products with images
- Syncs inventory levels per location
Square → Medusa (Copy to clipboardsync-square-medusa-workflow)
- Pulls catalog from Square
- Transforms and upserts products/categories into Medusa
- Updates inventory
Using Workflows Programmatically
123456789import {syncMedusaSquareWorkflow,syncSquareMedusaWorkflow,} from "@weareseeed/medusa-square-plugin/workflows"// Inside a Medusa workflow or API route:await syncMedusaSquareWorkflow(container).run()await syncSquareMedusaWorkflow(container).run()
API Reference
All routes are prefixed with your Medusa backend URL.
Admin Routes
Require admin authentication.
Method Path Description Copy to clipboardGET Copy to clipboard/admin/square/config Get active Square configuration Copy to clipboardPOST Copy to clipboard/admin/square/config Update metadata/settings Copy to clipboardGET Copy to clipboard/admin/square/locations List available Square locations Copy to clipboardPOST Copy to clipboard/admin/square/locations Set active location Copy to clipboardGET Copy to clipboard/admin/square/oauth/start Start OAuth flow (redirect to Square) Copy to clipboardGET Copy to clipboard/admin/square/oauth OAuth callback handler Copy to clipboardDELETE Copy to clipboard/admin/square/oauth/revoke Disconnect Square account Copy to clipboardPOST Copy to clipboard/admin/square/config/apple Register Apple Pay domain
Store Routes
Public endpoints for storefront use.
Method Path Description Copy to clipboardGET Copy to clipboard/store/square/config Get public Square config (application ID, location, currency, capabilities) Copy to clipboardGET Copy to clipboard/store/square/plugin Check plugin availability
Workflows
The plugin exports Medusa v2 workflows that can be composed into your own workflows:
12345import { getSquareConfigWorkflow } from "@weareseeed/medusa-square-plugin/workflows"// Retrieve the active Square configurationconst { result } = await getSquareConfigWorkflow(container).run()
Export Description Copy to clipboardgetSquareConfigWorkflow Returns the active Copy to clipboardsquare_configuration record Copy to clipboardsyncMedusaSquareWorkflow Full Medusa → Square data sync Copy to clipboardsyncSquareMedusaWorkflow Full Square → Medusa data sync
Usage
Connect Your Square Account
- Log in to your Medusa Admin dashboard
- Navigate to Settings → Square
- Toggle Sandbox on if you are testing, or leave it off for production
- Click Connect Square Account — you will be redirected to Square's OAuth page
- Authorize the connection — you are redirected back to the admin dashboard
Make sure Copy to clipboardMEDUSA_BACKEND_URL is set to your publicly accessible backend URL before starting the OAuth flow, otherwise the redirect will fail.Select a Location
After connecting:
- In the Account tab, your Square locations are listed automatically
- Click a location row to set it as the active location for payment processing
- The selected location ID is stored in the database and used for all subsequent payments
Configure Sync (Optional)
In the Settings tab:
- Choose whether Medusa or Square is the source of truth for catalog data
- Enable the sync features you need:
- Sync Catalog — keeps products and categories in sync
- Sync Customers — mirrors customer records to Square
- Click Sync Now to run a full manual sync, or let the real-time subscribers handle incremental updates
Accept Payments on the Storefront
- Install Copy to clipboard
react-square-web-payments-sdkin your storefront (see Storefront Integration) - Fetch Copy to clipboard
/store/square/configto get Copy to clipboardapplication_id, Copy to clipboardlocation_id, and Copy to clipboardcurrency - Render Copy to clipboard
<PaymentForm>with Copy to clipboard<CreditCard />(or another payment method component) at checkout - On tokenization, call Copy to clipboard
initiatePaymentSessionwith Copy to clipboardprovider_id: "pp_square_square"and pass Copy to clipboardtoken, Copy to clipboardbuyer, and Copy to clipboardcart_idin the Copy to clipboarddatafield - Complete the cart — the plugin will authorize and capture the payment automatically
Register Apple Pay Domain (Optional)
- In the Apple Pay tab, enter your storefront domain (e.g. Copy to clipboard
store.yourdomain.com) - Click Register — the plugin calls Square's domain registration API and stores the domain
- Download the Copy to clipboard
Square's verification file - Make sure your storefront serves Square's domain verification file at Copy to clipboard
/.well-known/apple-developer-merchantid-domain-association
Payment Status Mapping
Square Status Medusa Status Copy to clipboardAPPROVED Copy to clipboardauthorized Copy to clipboardPENDING Copy to clipboardpending Copy to clipboardCOMPLETED Copy to clipboardcaptured Copy to clipboardCANCELED Copy to clipboardcanceled Copy to clipboardFAILED Copy to clipboarderror

