ShopEazydevelopers
API referenceMerchant API BetaPoint Of Sale

Close the register by counting the drawer

Beta
Credentials, one of
  • Station token
  • OAuth access token
Scopes
orders:write
Subscription
Needs an active plan. Otherwise 403 subscription_locked.
Idempotency
Send an Idempotency-Key header. A retry with the same key does the work once.
POST
/v1/merchant/stores/{storeId}/registers/{registerId}/close

Freezes the shift's takings by payment method (net of refunds) and what the drawer should hold (the float plus every cash payment taken while it was open), beside countedMinor. The difference is over or short. A shift that is gone or already closed is 422 validation_error.

The call joins the Activity log, with the expected and counted cash.

Till PINs: as openRegister, a call without a valid cashierTicket is 403 cashier_required when the store uses PINs.

Access: OAuth scope orders:write; write-gated by the subscription.

Authorization

headerAuthorizationBearer <token>

It may call only the operations whose x-stations lists its kind, on its own store, and acts through the access of the owner or admin who paired it. Unpairing it, or that person leaving the business, ends it (401 station_revoked).

Path Parameters

storeId*string

A store the person can reach. Any other id answers 404, never 403.

registerId*string

The shift's id, from openRegister or getOpenRegister.

Header Parameters

Idempotency-Key*string

Required on every write. Minted on the device when the person taps, reused on every retry. A write without one, or with one that does not match the pattern, is refused with 422 validation_error. Scoped to the token's subject, remembered 24 hours. A replay returns the first 2xx response with Idempotent-Replay: true; a request still running answers 409 in_flight; the same key with a different method, path or body answers 409 idempotency_key_reused; non-2xx results are not remembered. If the key store cannot be read nothing is processed and the answer is 503 idempotency_unavailable: retry with the same key.

Match^[A-Za-z0-9_-]{8,128}$

Request Body

application/json
  1. body
countedMinor*integer

What was counted in the drawer, in cents.

Range0 <= value
note?string
Lengthlength <= 500
cashierTicket?string

Needed when the store uses till PINs.

Response Body

OK

application/json
  1. response
data*

One till shift. Opened with the cash float in the drawer, closed by counting it. What the drawer should hold is the float plus every cash payment taken while it was open.

Example Request
curl -X POST 'https://api.shopeazy.co/v1/merchant/stores/<storeId>/registers/<registerId>/close' \  -H 'Authorization: Bearer <access_token>' \  -H 'Idempotency-Key: <unique_key>' \  -H 'Content-Type: application/json' \  -d '{  "countedMinor": 1}'
Example Response
{  "data": {    "id": "string",    "status": "open",    "openedAt": 0,    "openedBy": "string",    "openedById": "string",    "floatMinor": 0,    "closedAt": 0,    "closedBy": "string",    "closedById": "string",    "countedMinor": 0,    "expectedCashMinor": 0,    "takings": {      "sales": 0,      "totalMinor": 0,      "refundedMinor": 0,      "byMethod": [        {          "method": "string",          "amountMinor": 0        }      ],      "byPerson": [        {          "id": "string",          "name": "string",          "sales": 0,          "amountMinor": 0        }      ]    },    "note": "string",    "createdAt": 0,    "updatedAt": 0  }}

Open the register with a cash float POST

Starts a till shift with `floatMinor` (cents) in the drawer. One shift is open at a time: opening another is 422 `validation_error` ("The register is already open."). Sales are not tagged with a register: the shift is the window of time since it opened, and every counter sale in it belongs to it. Cash handling is accountable: the shift records who opened it, and the call joins the Activity log. Without PINs it is the signed-in person. Access: OAuth scope `orders:write`; write-gated by the subscription. Any role that can sell, as in the console's Sell page.

Void a sale rung up at the till by mistake POST

Moves money. A full refund with the stock put back (the lines already handed over too: the goods come back across the counter), posted to the ledger like any refund: the same VAT, platform-fee and stock rules as `refundOrder`, which it runs. The `Idempotency-Key` is the refund's own key, so a retry books the money back once. Already voided is not an error: the order comes back with `alreadyVoided: true`. Only a till sale (channel `manual`), only within a day of being rung up, and only money taken at the counter (Cash, Card, EFT, SnapScan, Zapper, Other): a sale paid through the card partner (Scan to pay) is refunded with `refundOrder`, where the partner is asked to pay it back. Otherwise 422 `validation_error` with the sentence. An order that is not paid is 422. The order gets the note "Voided at the till" and the call joins the Activity log. No email goes to the customer, as at the console's till. Till PINs: when the store uses them, the cashier is the one `cashierTicket` names (403 `cashier_required` without one). Access: OAuth scope `orders:refund` (opt-in on the consent screen, owner/admin grants only, never in a preset); write-gated by the subscription. Unlike `refundOrder` a staff member can void at the till, as in the console.