Skip to main content

Payment States

Every payment in Ottu has two levels: a payment transaction (the top-level entity with amount, currency, customer data) and one or more payment attempts (individual interactions with the payment gateway). The payment transaction tracks the overall lifecycle — from created through paid, expired, or refunded. Each payment attempt tracks a single gateway interaction — from pending through success or failed.

This two-level model exists because a single payment transaction can involve multiple payment attempts. The customer might fail on the first try (wrong card, insufficient funds) and succeed on the second — the payment transaction stays open while individual payment attempts come and go.

Quick Reference

For most integrations, check the state field in webhook payloads or the Checkout API response. The success states are paid, authorized, and cod. Everything else means the payment is incomplete or failed.

Payment Transaction States

StateDescriptionTerminal?Available Operations
createdPayment transaction created via the Checkout API. Customer has not yet opened the payment link.NoCancel, Expire
pendingCustomer opened the payment link; request sent to the payment gateway.NoCancel, Expire
attemptedCustomer tried to pay but the payment attempt failed. Payment transaction remains open for retry (see Multi-Attempt Logic).NoCancel, Expire
authorizedFunds reserved on the customer's bank account but not yet captured. Merchant must capture or void.YesCapture, Void
paidPayment successful. Funds collected.YesRefund
codCash on Delivery — payment marked as offline/cash.YesCancel
failedPayment failed definitively. No retry possible (multi-attempt exhausted or disabled).Yes
canceledAdministratively canceled by staff or via the Operations API.Yes
expiredNot paid before expiration date, or customer canceled on gateway page.Yes
invalidedConfiguration change made the payment transaction unprocessable (missing currency, disabled gateway).Yes
refundedRefund operation completed. This is a child payment transaction state.Yes
refund_queuedRefund sent to the payment gateway, awaiting confirmation. The gateway will send a webhook when the refund is processed.NoAwaiting gateway confirmation
refund_rejectedGateway rejected the refund request.Yes
voidedAuthorization reversed before the acquirer sent it for processing. Child payment transaction state.Yes

Payment Transaction Lifecycle

The diagram below shows the most common state transitions. For the complete list of all possible transitions, see the State Groups table.

tip

Dashed arrows show that even failed and expired payment transactions can receive a delayed successful payment from the gateway (e.g., via automatic inquiry). Always handle webhook updates for payment transactions you consider "failed."

Payment Attempt States

Each payment attempt represents a single interaction with a payment gateway. A payment transaction can have one or many payment attempts.

StateDescriptionTriggered By
pendingPayment attempt created; request about to be sent to the payment gateway.Customer initiates payment on checkout page
successPayment gateway confirmed the payment succeeded.Gateway returns successful response
failedPayment attempt failed (insufficient funds, card declined, 3DS failure).Gateway returns failure; or payment attempt times out
canceledCustomer canceled on the payment gateway page (e.g., clicked "Back" on KNET).Customer navigates away from gateway
errorError occurred creating the payment gateway link (connectivity, invalid config).PSP link creation fails
codCash on Delivery payment acknowledged.CoD gateway confirms offline payment

How Payment Transactions and Payment Attempts Interact

When Payment Attempts Are Created

A new payment attempt is created each time the customer submits a payment on the checkout page. The payment attempt captures gateway-specific details: gateway_response, amount, fees, and reference_number. Each payment attempt belongs to exactly one payment transaction (accessed via payment_transaction.attempts).

How Payment Attempt Results Affect the Payment Transaction

warning

Payment attempt state changes trigger payment transaction state changes, but the mapping is not 1:1. A failed payment attempt does not always mean a failed payment transaction.

Payment Attempt OutcomeMulti-Attempt EnabledMulti-Attempt Disabled
success (purchase operation)Payment transaction → paidPayment transaction → paid
success (authorize operation)Payment transaction → authorizedPayment transaction → authorized
codPayment transaction → codPayment transaction → cod
failedPayment transaction → attempted (retry available)Payment transaction → failed (terminal)
canceledPayment transaction → attempted (retry available)Payment transaction → expired
errorInquiry may resolve laterPayment transaction → failed

Multi-Attempt Logic

Payment transactions created via the Checkout API or Invoice API support multiple payment attempts by default. When a payment attempt fails, the payment transaction moves to attempted and the customer can retry with a different card or payment method.

Multi-attempt behavior is controlled by two factors:

  1. How the payment transaction was created — payment transactions created via the Checkout API or Invoice API are eligible for multi-attempt. Those created via legacy APIs are not.
  2. MID configuration — each payment gateway has a can_have_multiple_attempts setting (enabled by default). If disabled, the payment transaction reaches a final state on the first payment attempt result, regardless of how it was created.

When multi-attempt is disabled (or the payment transaction was created via a legacy API), a failed or canceled payment attempt immediately transitions the payment transaction to a terminal state (failed or expired) — no retry.

tip

The attempted state exists specifically for multi-attempt payment transactions. It signals "at least one payment attempt was made, but none succeeded yet — the customer can try again."

Type vs Payment Type

Payment transaction type (e.g., e_commerce, payment_request) determines the business flow. payment_type (e.g., one_off, auto_debit, save_card) determines the payment method behavior. Both types can use any payment_type — for example, both e_commerce and payment_request payment transactions can be auto_debit.

State Groups

These groupings are used by the Operations API, Webhooks, and Payment Status Query API to determine which actions are valid.

GroupStatesUsed By
Success statespaid, authorized, codTrigger post-payment logic (webhooks, fulfillment)
Terminal statespaid, authorized, cod, failed, canceled, expired, invalidedNo further customer action possible
Cancelablecreated, pending, attempted, codCancel operation
Expirablecreated, pending, attemptedExpire operation or automatic expiration
Can acknowledge paymentcreated, pending, attempted, failed, expiredGateway can still report success (delayed callback)
Inquirablepending, attempted, failed, expiredPayment Status Query to check latest status
Child payment transaction statespaid, refunded, refund_queued, refund_rejected, voidedCreated by operations on a parent payment transaction

Child Payment Transactions

When an external operation (refund, capture, void) succeeds, Ottu creates a child payment transaction linked to the original parent. Child payment transactions have their own session_id, state, amount, and gateway response.

  • Refund → child in refunded state. If the gateway queues the refund (pending confirmation), the child is created in refund_queued state and transitions to refunded when the gateway confirms via webhook, or to refund_rejected if the gateway rejects it.
  • Capture → child in paid state
  • Void → child in voided state

Child payment transactions appear in the parent's webhook payload and can be retrieved via the Payment Status Query API. See Operation Events for webhook payloads.

FAQ

What's Next?

  • Checkout API — Create payment transactions and track their state
  • Payment Status Query — Check the latest payment transaction status with the gateway
  • Operations — Refund, capture, void, cancel, and expire payment transactions
  • Payment Events — Webhook payloads delivered on state changes
  • Error Codes — Error responses from the API