7. Local API - HTTP: the /blocked endpoint

GET /blocked tells the ECR which Local API endpoints still hold an unfinished HTTP exchange, so that a result started before a crash or a lost connection can be read before any new request is sent. This article explains what the endpoint reports, what it does not report, and how to use it in a recovery routine.

What it reports

The terminal's HTTP server runs one exchange per asynchronous endpoint (/payment, /acquisition, /reversal, /update, /balanceinquiry, /giftcard). An exchange opens when the POST is accepted (202) and closes when the ECR reads its final answer with GET: the final response (200) or, when the Payment Application did not answer within the endpoint timeout, a 408. Until that read, the endpoint is listed by GET /blocked and a new POST on it is refused with 403. A final answer waits until it is read; it does not expire and survives a terminal restart. A payment interrupted by a restart before it produced a result leaves nothing on the endpoint (GET → 423): log in again and use /status.

GET http://<terminal-ip>:8080/blocked

200 {"blocked":[]}
200 {"blocked":["/payment"]}
200 {"blocked":["/payment","/update"]}

The request has no body and the answer is plain JSON, without a Nexo envelope. Over a LAN the terminal address is the one assigned by the network (for example 192.168.1.24); over USB tethering it is 192.168.42.129.

Note

/blocked describes the HTTP server of the terminal, not the Payment Application. It is a read-only view: calling it triggers nothing, frees nothing and does not change the state of any exchange.

When to call it

  • At ECR start-up, before the first sale: the previous session may have ended in the middle of a payment.
  • After a transport error or a timeout while polling an operation.
  • When a POST answers 403 Forbidden: an exchange is still open on that endpoint.

For each endpoint listed, send a bare GET on that path until it answers 200. That 200 carries the final response of the interrupted operation (for example the PaymentResponse): process it exactly as if it had arrived normally. The next GET /blocked no longer lists the endpoint.

GET on the listed endpoint answers Meaning ECR action
200 Final response Process it, the exchange is closed.
201 Intermediate message, nothing more to read for now Show it to the cashier if it is a DisplayRequest, keep polling.
204 Operation running, nothing to read yet Keep polling.
206 A message is returned and more are waiting Process it and call GET again immediately.
408 The Payment Application did not answer within the endpoint timeout Reading the 408 closes the exchange; the operation itself continues on the terminal. /status answers InProgress until it ends, then returns its result. A new POST sent meanwhile is accepted (202) but answered at once with Failure, ErrorCondition: Busy, TransactionInProgress.
423 No open exchange on this endpoint Nothing to read. Check /status if you still need a result.

Only 200 closes the exchange. Stopping on 204 or 206 leaves the endpoint blocked and the next POST is refused with 403.

What it does not tell you

Question Where the answer is
Is the terminal free to take a new payment? POST /diagnosis: POIStatus.GlobalStatus is OK or Busy. It works without a session.
What was the result of an exchange that is already closed? POST /status: returns the last completed Payment, CardAcquisition or Reversal.
Can I force the terminal back to idle? No endpoint does that. A running payment can only be cancelled with /abort; a stuck Payment Application needs a terminal restart.

There are therefore two different "blocked" situations, and /blocked only sees the first one:

Situation GET /blocked POST /diagnosis ECR action
An HTTP exchange is open (result not yet read) Lists the endpoint Busy while the operation runs, OK once the result is ready GET the endpoint until 200.
The Payment Application is busy with no open exchange (a 408 was read while the operation was running, or the application is stuck) Empty list Busy (and /status answers InProgress) Wait and re-check; beyond your payment window, send one /abort; still Busy, treat the sale as unresolved and restart the terminal.

Endpoint timeout

Each endpoint has its own timeout in the terminal's HTTP server configuration (<Endpoint Name="/payment" TimeoutMillis="180000"/>): 180 s for /payment, the same on every terminal. It is the time the HTTP server waits for the Payment Application's final response. Past it, the exchange's final answer becomes 408; the endpoint stays in /blocked and refuses new POSTs until that 408 is read. Keep the ECR payment window below this value (120 s recommended) so that a normal payment never reaches it.

Synchronous endpoints (/login, /logout, /diagnosis, /status, /abort) have shorter timeouts and answer 408 on the POST itself when the Payment Application does not respond in time, typically right after a power-on while the application is still starting. Retry a few seconds later. While such a POST is pending, the endpoint appears in /blocked and a second POST answers 403; there is nothing to read on it with GET (405).

Common mistakes

  • Using /blocked as a terminal availability check. An empty list only means that no result is waiting to be read. Use /diagnosis.
  • Calling /status while an endpoint is listed. /status returns the previous completed transaction, not the one still open. Drain the endpoint first.
  • Polling /blocked instead of the operation endpoint during a payment. During a payment, poll GET /payment; /blocked is for recovery.

For the full recovery logic (transaction journal, ServiceID rules, consistency check on /status), see the article "Prevent duplicate payments from the ECR". Need help? Contact Market Pay support at assist.market-pay.com.

Was this article helpful?

0 out of 0 found this helpful