Skip to main content

Payment Statuses Reference

Complete reference of all order, payment, and payment link statuses.

Complete reference of all statuses used in Paysera Checkout. There are three distinct status types that track different aspects of the payment flow.

Important Distinction

Do not confuse these status types - they track different entities:

  • Order Status - Tracks the overall order state
  • Payment Status - Tracks individual payment attempts
  • Payment Link Status - Tracks the payment link availability

Order Statuses​

Orders track the overall transaction state. An order can have multiple payment attempts.

StatusCodeDescriptionTerminal
Pending Paymentpending_paymentOrder created, awaiting payment completionNo
PaidpaidOrder total amount equals amount paid (fully paid)No
CanceledcanceledOrder was canceled before anything was paidYes
ClosedclosedReserved, not currently usedYes

Only a pending_payment order with nothing paid can be canceled — by the merchant in the Paysera Merchant Portal, or by Paysera support. Its active payment links are canceled as well, and an order canceled webhook is sent, with the status spelled cancelled (double "l"). A resent webhook carries the full order snapshot, where it is spelled canceled, so match both.

Order Status Transitions​

Key Transition: pending_payment → paid​

An order transitions from pending_payment to paid when:

  • Order Amount Paid equals Order Total Amount to Pay

This happens when one or more payments settle and their total reaches the order amount.

Payment Statuses​

Payments track individual payment attempts through the payment provider flow.

#StatusCodeDescriptionTerminal
1InitiatedinitiatedPayment request created after payer clicks "Pay"No
2Awaiting Authorizationawaiting_authorizationRequires Strong Customer Authentication (SCA/3DS)No
3AuthorizedauthorizedBank authorized the payment, funds not yet movedNo
4ProcessingprocessingMoving through internal processing stepsNo
5Pending Settlementpending_settlementIn clearing/batch processing stageNo
6On Holdon_holdPaused for compliance or fraud reviewNo
7SettledsettledFunds reached merchant accountNo*
8FailedfailedTechnical failure occurredYes
9RejectedrejectedBank explicitly refused the paymentYes
10CanceledcanceledPayment canceled before settlementYes
11ExpiredexpiredAuthorization or session expiredYes
12RefundedrefundedPayment partially or fully returned to payerYes
13ChargebackchargebackDispute/chargeback initiated by cardholderYes

*settled can transition to refunded or chargeback

How payment statuses reach you

Payment statuses surface in two places, with one spelling difference:

  • Thin payment webhook (event.type = "payment") — payment.status carries only the notifiable statuses: pending_settlement, settled, failed, rejected, cancelled, expired, refunded, chargeback. In-flight statuses (initiated, awaiting_authorization, authorized, processing, on_hold) do not trigger a payment webhook.
  • Order snapshot (event.type = "order") — the same payment appears under order.payment_links[].payments[].status using the raw status code, including the in-flight ones.

Spelling: in the thin payment webhook the canceled status is delivered as cancelled (double "l"); in the order snapshot it appears as canceled (single "l"). Match both if you branch on it.

Split payments add one more case. When only part of a split reaches its recipients, the payment-executor holds the payment in a partially_distributed state: the payer paid in full, but one distribution leg was returned or is still held. The thin payment webhook delivers that state as settled — the payer's side of the transaction is complete and the order is settled — and it is sent once: the later move to a fully settled payment does not repeat it. The order snapshot is the exception, and carries the raw partially_distributed string, so treat any status outside the table above as informational rather than failing on it.

For the per-recipient breakdown — which leg was returned, and how much of it stayed with the recipient — read distributions[] on Get a Payment, where delivered_amount is the part the recipient kept, or watch for the recipient.returned webhook.

While a payment is in this state a refund is not yet possible: the refund eligibility endpoint reports eligible: false with reason PAYMENT_NOT_SETTLED. Every leg has already resolved by then, so the payment leaves this state only once the returned leg is re-sent and delivered; until that happens it stays partially_distributed and stays unrefundable.

The payment-executor also has internal payout statuses (error, blocked, pending_retry) that are never delivered to merchant webhooks.

Payment Status Flow​

Payment links control access to the payment flow. They have their own lifecycle independent of payment status.

StatusCodeDescriptionTerminal
ActiveactiveLink is valid and can initiate a payment sessionNo
CompletedcompletedPayment settled successfully via this linkYes
ExpiredexpiredLink lifetime (TTL) passedQuasi*
CanceledcanceledLink was invalidated by order update or manual cancelYes

*expired is quasi-terminal: it can still transition to completed if a payment that was started before expiration settles during the bank flow.

Important Notes​

  1. No failed status for payment links - Payment links do not have a failed status. If a payment attempt fails, the link remains active (unless expired or canceled), allowing the customer to retry.

  2. Expired links can complete - If a customer starts a payment flow before the link expires, and that payment settles after expiration, the link transitions from expired to completed.

Status Mapping Between Entities​

Order StatusTypical Payment StatusPayment Link Status
pending_paymentinitiated, processing, failedactive
paidsettledcompleted
-refunded, chargeback-

Where Statuses Surface​

Webhooks are the recommended way to track status: every status transition is delivered to your callback_url, and the payload carries the full order snapshot — including nested payment links and individual payment attempts. You can also read current state on demand with GET /merchant-order/integration/v1/orders/{id} and GET /checkout-payment-link/integration/v1/payment-links/{id} (useful for reconciliation or as a backup), but you should not poll them in a tight loop in place of handling webhooks.

Order status appears as the top-level order.status field. Payment status appears for each attempt under order.payment_links[].payments[].status. See Webhooks and the webhook event reference for full payload shapes.

Webhook Payload Snippet (snake_case)​

{
"event": { "name": "amount_paid_updated", "type": "order" },
"order": {
"paysera_order_id": "a6f2b8e3-5e5f-47d9-b13f-87ed2db2938a",
"merchant_order_id": "ORDER-12345",
"amount": 2500,
"amount_paid": 2500,
"currency": "EUR",
"status": "paid",
"created_at": 1736433270,
"updated_at": 1736433500,
"payment_links": [
{
"id": "c8d9e0f1-2a3b-4c5d-6e7f-8a9b0c1d2e3f",
"name": "Order #12345",
"payments": [
{
"id": "p-1",
"method": "swedbank",
"status": "settled",
"payment_currency": "EUR",
"payment_amount": 2500
}
]
}
]
}
}

Status Handling Examples​

PHP​

<?php

class OrderStatusHandler
{
public function handleOrderStatus(string $status, string $reference): void
{
match ($status) {
'pending_payment' => $this->awaitPayment($reference),
'paid' => $this->fulfillOrder($reference),
'canceled' => $this->handleCancellation($reference),
'closed' => $this->handleClosure($reference),
default => $this->logUnknownStatus($status, $reference),
};
}
}

class PaymentLinkStatusHandler
{
public function handleLinkStatus(string $status, string $linkId): void
{
match ($status) {
'active' => $this->trackActiveLink($linkId),
'completed' => $this->confirmPayment($linkId),
'expired' => $this->handleExpiredLink($linkId),
'canceled' => $this->handleCanceledLink($linkId),
default => $this->logUnknownStatus($status, $linkId),
};
}
}

JavaScript​

const orderStatusHandlers = {
pending_payment: (reference) => awaitPayment(reference),
paid: (reference) => fulfillOrder(reference),
canceled: (reference) => handleCancellation(reference),
closed: (reference) => handleClosure(reference),
};

const paymentLinkStatusHandlers = {
active: (linkId) => trackActiveLink(linkId),
completed: (linkId) => confirmPayment(linkId),
expired: (linkId) => handleExpiredLink(linkId),
canceled: (linkId) => handleCanceledLink(linkId),
};

function handleOrderStatus(status, reference) {
const handler = orderStatusHandlers[status];
if (handler) {
handler(reference);
} else {
console.warn(`Unknown order status: ${status}`);
}
}