Skip to main content
Every Singapay transaction moves through a defined set of statuses. The transaction_status tracks the actual state of the payment — whether funds have moved, are in transit, or failed.
Transaction status vs. response code — These are two different things. The Response Code (response_code / SP code) tells you whether your API request was accepted by the server. The transaction status on this page tells you the actual outcome of the payment. A request can succeed (SP000) while the transaction is still Initiated or Pending.

Status codes

Terminal means the status will not change further. Non-terminal statuses may still transition to a final state — keep polling or wait for the webhook callback.

Status lifecycle


Handling each status

00 — Success

The transaction completed. Funds have been moved.
  • Update your records to mark the transaction as settled.
  • Reconcile against balance_after if provided in the webhook payload.

01 — Initiated

The transaction exists but hasn’t been sent to the provider yet.
  • Wait. The system will process the transaction automatically.
  • If the status doesn’t change within a few minutes, call the inquiry-status endpoint.

02 — Paying

The payment call is in progress with the upstream provider.
  • Do not retry or create a new transaction. The original may still succeed.
  • Poll the inquiry-status endpoint after 1–2 minutes.

03 — Pending (Suspect)

The provider acknowledged the transaction but hasn’t confirmed the final result.
  • Do not retry or create a new transaction.
  • Poll the inquiry-status endpoint every 2–5 minutes.
  • A webhook callback will fire when the final status is determined.
Pending ≠ Failed. Transactions in 02 (Paying) or 03 (Pending) may still settle successfully. Creating a duplicate transaction can result in double charges or double transfers.

04 — Refunded

The transaction was reversed after a successful payment.
  • Update your records to reflect the reversal.
  • Adjust the customer’s balance or order status accordingly.

05 — Canceled

The transaction was canceled before settlement.
  • No funds were moved.
  • You may create a new transaction with a new reference_number if needed.

06 — Failed

The transaction could not be completed.
  • Check failed_code and failed_reason in the response/webhook for the specific cause.
  • Common reasons: invalid beneficiary account, insufficient balance, provider downtime.
  • You may create a new transaction with a new reference_number after resolving the issue.

07 — Not Found

The transaction does not exist in the provider’s system.
  • This typically means the transaction was never submitted or was lost in transit.
  • Create a new transaction with a new reference_number.

Status by product

Transaction statuses are consistent across products, but not every product uses every status. Here’s which statuses apply to each product type:
Virtual Account transactions arrive as webhooks only after payment is confirmed, so you will typically only see status paid (00 equivalent) in VA webhook callbacks.

Polling best practices

For non-terminal statuses (01, 02, 03), use the inquiry-status endpoint to check for updates:
1

Wait before first poll

Allow at least 30 seconds after the initial API call before polling.
2

Use exponential backoff

Start with 30-second intervals, increasing to 2–5 minutes. Don’t poll more than once per 30 seconds.
3

Set a timeout

If a transaction remains in a non-terminal status for more than 30 minutes, flag it for manual review.
4

Prefer webhooks

Webhook callbacks are the most reliable way to receive final status. Use polling only as a fallback.