Skip to main content

Test Square Payments — location_id and Idempotency

Every Square request needs
a location_id — even when
you only have one location.

Square has three payment APIs — Payments, Orders, and Terminal. Each serves a different use case. All three require a location_id on every request.

Required on every request

Square requires a location_id on every payment. Get it wrong and every request fails with a 400 before it even validates your card nonce.

Square has three distinct payment APIs. The Payments API handles single-transaction card payments — you provide a source_id from the Web Payments SDK, an amount in cents, and a location_id. The Orders API is for cart-based flows with line items, tax, and discounts. The Terminal API is for in-person card readers. You pick based on your use case.

The location_id requirement catches most developers off guard. In Square's model, every business operation belongs to a location — even if you only have one. You get your location_id from the Locations API or the Square dashboard. If you omit it or use a wrong value, Square returns a 400 on every payment request with a vague error message.

Idempotency keys are required on payment creation. If a network timeout causes your client to retry, the same idempotency_key returns the original payment result rather than creating a duplicate charge. Without it, you can end up with a customer charged twice for the same order. This mock enforces the same behavior so you can test your retry logic before going live.

Which Square payment API do you need?

They are not interchangeable. Pick based on what you are building.

Payments APIMost common

Use when: Single online card transactions

The straightforward path: one payment object, one card charge, one response. Use this when you have a fixed total and just need to charge a card. Every request requires a location_id and an idempotency_key.

amount_moneysource_ididempotency_keylocation_id
Orders APICart-based

Use when: Line items, tax, discounts

Create an order with individual line items and let Square calculate tax and apply discounts. Generates a proper itemized receipt. Use this for anything with a cart — multiple items, promo codes, or in-person POS-style receipts.

line_itemstaxesdiscountslocation_id
Terminal APIIn-person

Use when: Physical card readers

Send a checkout request to a Square Terminal device. The device handles card dip, tap, or swipe. Your server gets a webhook when the reader completes the transaction. Not relevant for most online integrations.

device_idamount_moneyreference_idlocation_id

location_id

Why does every Square payment request need a location_id?

This is not optional. There is no default. Leave it out and you get a 400 before any other validation runs.

What is a location_id?

Square maps every payment to a business location. This comes from Square's physical POS roots — every sale happened at a physical store. For online businesses, you create a virtual location in the Square dashboard. The location_id is the ID of that location (starts with a letter, ~12 chars). You get it from GET /locations or from the dashboard.

// Real location_id looks like:

LPFNZD7QACQ9A

Error if you forget it

400 Bad Request

{

"errors": [{

"category": "INVALID_REQUEST_ERROR",

"code": "MISSING_REQUIRED_PARAMETER",

"field": "location_id"

}]

}

The mock returns the same error shape as the real Square API. Fix: always pass location_id in the request body.

idempotency_key

Also required on every payment. Generate a UUID per attempt. If your request times out and you retry with the same key, Square returns the original payment instead of charging twice. If the customer retries after a failure, generate a new key — they want a new charge.

Integration code

curl -X POST https://mockgateway.com/api/base/square/v2/payments \
  -H "Authorization: Bearer YOUR_MOCK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "a7c3f2e1-9b8d-4a5e-bf62-1d3e7c9f0a2b",
    "source_id": "cnon:card-nonce-ok",
    "location_id": "MOCK_LOCATION_001",
    "amount_money": {
      "amount": 4999,
      "currency": "USD"
    },
    "note": "Acme Pro subscription"
  }'

Request parameters

Sent to POST /api/base/square/v2/payments

Request parameters
ParameterTypeRequiredDescription
idempotency_keystringrequired

Unique per create. Retrying with the same key returns the link already made.

e.g. a7f3c1e0-2b44-4c9a-9f10-7d2e5b8c4a61
quick_pay.namestringrequired

What the buyer sees on the checkout page.

e.g. Auto Detailing
quick_pay.price_money.amountintegerrequired

Amount in the smallest currency unit (10000 = $100.00).

e.g. 10000
quick_pay.price_money.currencystringrequired

Three-letter ISO currency code.

e.g. USD
quick_pay.location_idstringrequired

The seller location the link belongs to.

e.g. S8GWD5R9QB376
descriptionstringoptional

Your own note against the link.

e.g. Order #12345

Response fields

Response fields
FieldTypeDescription
idstringSquare payment ID
statusenumPayment status
created_atdatetime
order_idstringIdentifier of the order the payment link was created against

Questions about Square

Other gateway templates

Looking for a different provider?