Skip to main content
The status list itself is published in Payment lifecycle and order statuses and Data reference. This page is the operational half: which actions each status accepts, and what the three write endpoints — cancel, capture, refund — do when the order is not in the state you expected.

Are there statuses that are not in the published list?

Two, and both are worth knowing about because they explain confusing observations rather than being things you act on. The second one is the answer to a question merchants ask often, so it is worth stating plainly: AUTHORIZATION_REQUIRED covers both “the payment method is waiting for the user to authorize” and “nothing has happened on this order yet”. You cannot tell those apart from the status alone.

My order is stuck in AUTHORIZATION_REQUIRED. Did the user close the WebView?

Maybe — but the status does not tell you that, and it is not the only explanation. AUTHORIZATION_REQUIRED means no result has come back, which is consistent with all of:
  • The user never opened the payment page at all.
  • The user opened it and abandoned it — closed the WebView, killed the app, walked away.
  • The user is still on it, mid-authentication.
  • The payment attempt has not yet been made.
So it is not a diagnosis, and specifically it is not evidence of a failure you should report to the user. The correct handling is the same in every case: leave it open, let the order reach its expiry, and take the result from the webhook or Order Inquiry. Do not close it yourself on a timer — see Timeouts & When a Result Is Final. If it matters to you operationally to know whether the page was opened, that is a question for your own front-end instrumentation, not for the order status.

Which statuses are final, and can I store one as my outcome?

Two statuses are final: PAY_SUCCESS and ORDER_CLOSE. Everything else is transitional, and an order in a transitional status can still move. PAY_SUCCESS and ORDER_CLOSE do not flip into each other. Once an order is closed, a later success report from the payment method does not reopen it and does not rewrite it to PAY_SUCCESS; once it succeeded, it stays succeeded. So yes — you can persist a final status as your business outcome. The one thing that is not safe to persist is the assumption that a final status means nothing further can happen to the money. A successful order can still be refunded or disputed afterwards, and neither of those changes orderStatus — see the refund question below.

What can I do to an order in each status?

Read the two edges carefully, because they are where integrations get it wrong:
  • Refund is only possible from PAY_SUCCESS. There is no “refund a pending order” — if the money has not landed, the action you want is cancel.
  • Cancel is the way to release an authorization you are not going to capture, and it is materially better than authorizing, capturing and then refunding.

I called cancel and it was refused. What do the errors mean?

How to act on each:
  • A0013 is not an error to retry. The user paid. If you do not want to fulfil, the action is a refund, not a cancel.
  • A0015 is a fact about the payment method, not about your request. Some methods have no cancel operation at all; for those, the way an unpaid order ends is expiry. Design for “cancel may be unavailable” and let the expiry do the work.
  • A0016 came from the payment method’s side. A retry can be worth one attempt, but if it repeats, stop and let the order expire.
  • Cancelling an already-closed order succeeds and does nothing. That makes cancel safe to call from a cleanup job without checking the status first.
You may send either paymentRequestId or acquiringOrderId to identify the order, plus your merchantId; sending neither id is a validation failure.

After I cancel, can the user still pay on the payment method’s page?

Cancel puts the order into ORDER_CLOSE — a final status — and asks the payment method to cancel its side too. From that moment the order cannot complete: a success report arriving afterwards is not applied, so the order will not silently turn into a paid order behind your back. What cancel cannot guarantee is that a third-party payment page already open in front of the user stops accepting input. Where the payment method does not support cancellation at all (A0015), nothing was cancelled on their side by definition. So the honest answer to “can the user still pay?” is: they may be able to hand over money, and it will not become a completed order. Money that moves in that window is a recovery case, not a fulfilment case — the handling is described in Timeouts & When a Result Is Final. Practical rule: cancel when you have decided not to sell, and do not treat cancel as a way to close a checkout the user is still looking at.

Is “set a short expiry, then cancel when it passes” a good design?

It is a reasonable design, with one correction and one caveat.
  • The correction: you do not need the cancel call. An order that reaches its expiry without being paid is closed for you, and you are notified. Adding your own cancel afterwards is harmless — it is a no-op on a closed order — but it is not what makes the order end.
  • The caveat: a short expiry does not shorten the payment method’s own window, and it does not stop a late payment from being taken on their side. So a three-minute expiry buys you a three-minute checkout, not a three-minute guarantee that no money will move afterwards.
If your business needs a genuinely short window, set the expiry and build the late-payment recovery path. If you only need the checkout to stop looking live, the expiry alone is enough.

Will an order close exactly at the expiry I set?

Close to it, but not to the second. Closing is performed by a periodic sweep, so an order can remain technically open for a short interval after its nominal expiry, and under high volume a batch of due orders can spill to the next pass. Before closing, the payment method is checked, and an order with a payment already in flight is left alone rather than being closed underneath the payment. What this means for you:
  • Do not use “the order is closed” as a clock. If your fulfilment logic needs a deadline, use your own timer against the expiry you sent; use the order status to learn the outcome, not the time.
  • Do not treat a slightly-late close as an incident. It is the design.
  • An expiry in the past is not rejected — it is discarded. If orderExpiredAt is already behind the clock when the order is created, the value is dropped and the order gets the payment method’s default expiry instead. So a clock bug on your side does not fail loudly; it produces an order that stays open longer than you intended. Check the timestamp before you send it.
If you send no orderExpiredAt at all, the order still gets closed eventually, but the time is not a value you set or should depend on. Send an explicit expiry whenever the window matters to your business.

Do I get a notification when an order is closed on timeout?

Yes. A closed order produces the ordinary payment notification — PAYMENT_NOTIFICATION, carrying the same order structure as Order Inquiry, with orderStatus = ORDER_CLOSE and the reason in orderFailedReason. There is no separate “order expired” event type to subscribe to, and there is nothing extra to enable. So an integration that handles PAYMENT_NOTIFICATION and branches on orderStatus already handles timeout closes. If you are not receiving them, that is a webhook delivery question — see Portal webhook log and Webhook retry.

Can I look up orderFailedReason.orderFailedCode in the error code table?

No — it is a different set of codes. The Axxxx codes are what an API call returns to you synchronously when your request is wrong or refused. The code inside orderFailedReason describes why an order ended the way it did, and it is a separate, reason-oriented namespace. Looking one up in the other’s table is why merchants conclude the code “does not exist”. Can you automate on it? Partly, and carefully:
  • Do branch on the broad distinction you can rely on — a timeout close is a different business event from a payment refusal, and both differ from a cancellation.
  • Do always store orderFailedDescription next to the code, because it is the part that stays readable when a code you have never seen arrives.
  • Do not build an exhaustive switch that treats an unrecognised reason as a failure of your own code. The set is larger than the handful you will see in testing, and new reasons appear as payment methods change. Default to “closed, not paid, reason recorded” and alert a human rather than guessing.
There are two distinct timeout reasons — one for an order that never reached a payment method, one for an order that did — and Confirming Payment Results explains the practical difference.

Can I capture less than I authorized?

Yes. A capture amount may be anything greater than zero and up to the authorized amount; the remainder of the authorization is released rather than held. Capturing more than was authorized is refused. That last row is the one that surprises people. Capture only exists for orders created in manual-capture mode — you opt in at order creation with paymentInfo.captureMode, and the only value accepted there is manualCapture. An ordinary order is captured automatically and there is nothing for you to call. The published product behaviour matches the code on the point that matters most: capture is effectively single — once you capture, even partially, the rest of the authorization is released, so you cannot draw down an authorization in instalments. For usage-based billing, the pattern is a stored token and periodic charges, not repeated captures. See Auth-Capture and Tokenization.

How long do I have to capture?

The window is counted in whole days from when the order was created, not from when you noticed the authorization. It is a single platform-wide setting, applied to every merchant alike — it is not negotiated per account, and the wording of the refusal message is not a reliable guide to the current figure. Confirm the window with support before you design a fulfilment process around it. After the window lapses two things happen, and you should build for both:
  • Your capture call starts failing. It is refused as unsupported, not queued.
  • The authorization is released for you. Expired authorizations are cancelled proactively, so the customer’s funds do not stay held because you forgot.
So an authorization is not a promise you can hold indefinitely, and a capture is not something to leave in a retry queue with no deadline. If your fulfilment can take longer than your capture window, capture on shipment rather than on delivery, or use a stored token and charge when you are ready.

Why is refundExpiryAt empty on some of my orders?

refundExpiryAt is the point after which the order can no longer be refunded. It is derived from the refund window in your agreement for that payment method, counted from the order’s creation date — not from the moment the payment succeeded — and it lands at the end of that day. Two consequences:
  • A window expressed in days is a calendar window. An order created late in the day gets a slightly shorter usable window than one created early, because the boundary is the end of a day either way.
  • The clock does not restart when the payment succeeds. An order paid a long time after it was created has already spent part of its refund window.
It is empty — null — in every case where the question does not apply: So do not read a missing refundExpiryAt as “refundable forever”. Read it as “no deadline is being published for this order”, check Refund Limits by Payment Method for what applies, and use remainingRefundAmount on the refund APIs to decide what is still refundable.

Does a refund change the original order’s status?

No — and this is the single most common false alarm on this endpoint. A refund never rewrites orderStatus; a fully refunded order still reports PAY_SUCCESS. Refund progress lives on the refund record and on the order’s separate refund-status field, not on the payment status. If your bookkeeping keys refund state off orderStatus, it will look permanently stuck. Key it off the refund record instead — Refund Limits by Payment Method sets out where to look for each question.
Stuck on a status that will not move? Contact support with the acquiringOrderId and the status you are seeing.