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

CodeStatusTerminal?Description
00SuccessYesTransaction completed successfully. Funds have been transferred.
01InitiatedNoThe transaction has been created but the payment provider has not been called yet.
02PayingNoThe payment call is in progress. The provider is processing the transaction.
03PendingNoThe transaction is awaiting confirmation from the provider. This is a suspect state.
04RefundedYesThe transaction was reversed. Funds have been returned to the source.
05CanceledYesThe transaction was canceled before completion.
06FailedYesThe transaction failed. Check failed_code and failed_reason for details.
07Not FoundYesThe transaction does not exist in the provider’s system.
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:
StatusDisbursementVirtual AccountQRISE-WalletCardSubscription
00 SuccessYesYesYesYesYesYes
01 InitiatedYesYesYes
02 PayingYesYesYesYesYes
03 PendingYesYesYesYesYes
04 RefundedYesYes
05 CanceledYesYesYesYes
06 FailedYesYesYesYesYes
07 Not FoundYes
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.