Set Up Square Payments
If you already take payments in person with Square, a second processor for the online store means two payout schedules, two dashboards and customer cards saved in one place but not the other.
The Square module puts the card form from Square’s Web Payments SDK on the classic and block checkout, with Apple Pay and Google Pay above it. Cards are saved on file with Square for one-click payments and automatic subscription renewals, and the webhook that keeps refunds and card changes in sync is created for you when you save the settings.
Turn On the Gateway
- Switch on the Square module under Stackless → Dashboard.
- Go to WooCommerce → Settings → Payments → Square (Stackless).
- Tick Enable (Accept payments with Square).
Stackless → Settings → Square only shows a link to that screen and your webhook URL. Square stays off the checkout until the selected mode has an application ID, an access token and a location.
Connect Your Square Application
In the Square Developer Console, open your application (or create one) and go to its Credentials page. Choose Production at the top and copy the application ID and access token, then do the same for Sandbox. The Open the Square Developer Console button on the settings screen goes there. Then fill in:
- Sandbox: on by default. Uses the Square sandbox, so no real money moves.
- Production application ID, Production access token, Production location ID and Production webhook signature key
- Sandbox application ID, Sandbox access token, Sandbox location ID and Sandbox webhook signature key
Leave the location IDs and webhook signature keys empty: saving fills them in. The access token on the Credentials page is a personal access token, which Stackless needs to create the webhook.
You can also set these as wp-config.php constants, which win over saved settings and hide their fields: STACKLESS_SQUARE_LIVE_APP_ID, STACKLESS_SQUARE_LIVE_ACCESS_TOKEN, STACKLESS_SQUARE_LIVE_LOCATION_ID, STACKLESS_SQUARE_LIVE_WEBHOOK_SIGNATURE_KEY and the same four with SANDBOX in place of LIVE.
What Saving Sets Up
Saving with an access token does two things for each mode:
- Location and currency: Stackless reads the location you entered, or your main location when the field is empty, and fills in its ID. It must be an active location with card processing. The Checkout section then shows “Charging through [location] in [currency].”
- Webhook: with the signature key empty, Stackless creates a webhook subscription named “Stackless for WooCommerce” for
https://yoursite.com/wp-json/stackless/v1/square/webhookand saves its signature key. If one for this URL already exists, it gets a fresh key, since Square only shows a key when it’s made. The screen confirms with “Square Production webhook connected and its signature key saved.”
The webhook is only created on a public HTTPS site. On a local site the settings show a note, and you add it by hand once the site is live: in your application, open Webhooks → Subscriptions, add your webhook URL with these events, and paste its signature key into the matching field:
payment.updated
refund.created
refund.updated
card.disabled
card.forgotten
card.automatically_updated
Square signs each delivery over the webhook URL plus the body (x-square-hmacsha256-signature). Both signature keys are tried, and the one that matches decides the mode. Each event is applied once. If your site address changes, empty the signature key fields and save again, so a webhook is created for the new address.
The Location Currency Rule
Square charges only in the currency of your Square location, which follows the seller’s country. Square takes online payments in USD, CAD, GBP, AUD, JPY and EUR.
- Square hides itself when the cart or order is in another currency.
- With multi-currency, Square tells Currency-Aware Payment Gateways that it takes the location’s currency only.
- Billing Health shows a note when your store currency differs from the location’s.
What Buyers See
At checkout, Square shows with the title “Card, Apple Pay or Google Pay” and the description “Pay securely with your card through Square.” It works on the classic and block checkout, the order payment page and Add payment method.
- Square’s card form loads from Square, and card details go from the browser to Square. Your store only receives a one-time token.
- Square’s buyer verification runs with the billing details when the buyer places the order, so banks that want 3-D Secure get it.
- Google Pay and Apple Pay buttons show above the card form on one-time orders, set by Wallets (both on by default).
- Signed-in customers see their saved cards and, with Saved cards on, a checkbox to save a new one.
- The payment is taken right away. A payment that doesn’t match the order total puts the order on hold with a note.
- Declines show a plain message, such as “Your card has insufficient funds.”
- Sandbox adds “Sandbox: use Square’s test cards; no real payment will be taken.”
Apple Pay and Google Pay
Apple Pay needs your domain registered with Square. In the Developer Console, open your application in Production, choose Apple Pay in the left pane, then Add Domain and follow the steps. Apple Pay only works on an HTTPS domain, not localhost.
Wallet payments can’t be saved, so subscription checkouts and My Account → Payment methods show the card form only.
Saved Cards and Subscriptions
- A subscription checkout always saves the card on file with a Square customer. The card is saved from the payment before the order is marked paid, so the subscription has it from the start.
- A free trial with nothing to pay today saves the card without charging it.
- Renewals charge the saved card as merchant-initiated, without the customer present. If Square can’t be reached, the charge is retried up to 3 more times, 15, 30 and 45 minutes apart, with the same idempotency key so the customer isn’t charged twice.
- A declined renewal is marked Failed with Square’s reason, and your retry schedule takes over. Renewals, Failed Payments and Retries covers what happens next.
- A saved card picked at checkout is charged without a new verification step. When the bank asks for one, the buyer sees “Your bank needs you to verify this payment. Enter your card details again to continue.”
- Saved cards also pay for Post-Purchase Offers. If the bank wants verification there, the buyer is sent to the order payment page to enter the card.
- Customers can add cards from My Account → Payment methods and change a subscription’s card from My Account.
- Deleting a saved card in My Account disables it at Square.
- When Square disables or forgets a card, the saved card is removed in WooCommerce. When Square’s card updater changes a card, its expiry date and last four digits are updated.
- Sandbox and production cards are kept apart.
Refunds
Refund from the WooCommerce order screen, in full or in part. The refund is made in Square, and the order gets a note with the Square refund id. Refunds made in the Square Dashboard are recorded on the order through the webhook, and a refund Square rejects adds a note.
Billing Health
Square reports to Billing Health: a missing application ID, access token or location for the selected mode, a missing webhook signature key, a store currency that differs from the location’s, sandbox mode, and webhooks that failed recently. Square retries a failed delivery for 24 hours.
Limits
- Square takes one currency, the location’s. Carts in other currencies don’t see it.
- Apple Pay and Google Pay payments can’t be saved, so subscriptions need a card.
- Apple Pay needs your domain registered in the Square Developer Console.
- A saved card at checkout isn’t verified again. When the bank asks for verification, the buyer enters the card again.
- The webhook is created automatically only on a public HTTPS site with a personal access token.
- A copy of your store, such as a staging site, never charges saved payment methods.
- Turn on Debug log to write Square activity to WooCommerce → Status → Logs (
stackless-square_gateway). Tokens and card data are never logged.
For Developers
stackless_square_gateway_webhook runs after each webhook event is applied, with the event type, the event and the mode:
add_action('stackless_square_gateway_webhook', function ($type, $event, $mode) {
if ($type === 'refund.created' && $mode === 'live') {
// Notify your accounting tool.
}
}, 10, 3);
Copy templates/square_gateway/payment-fields.php to yourtheme/stackless/square_gateway/payment-fields.php to change the card form. Keep its element ids and the data-config attribute, which the script reads.