> ## Documentation Index
> Fetch the complete documentation index at: https://docs.singapay.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Transaction Status

> Lifecycle of a Singapay transaction — status codes, transitions, and recommended handling for each state.

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.

<Info>
  **Transaction status vs. response code** — These are two different things. The [Response Code](/api-reference/references/response-codes) (`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`.
</Info>

***

## Status codes

| Code | Status    | Terminal? | Description                                                                          |
| :--: | --------- | :-------: | ------------------------------------------------------------------------------------ |
| `00` | Success   |    Yes    | Transaction completed successfully. Funds have been transferred.                     |
| `01` | Initiated |     No    | The transaction has been created but the payment provider has not been called yet.   |
| `02` | Paying    |     No    | The payment call is in progress. The provider is processing the transaction.         |
| `03` | Pending   |     No    | The transaction is awaiting confirmation from the provider. This is a suspect state. |
| `04` | Refunded  |    Yes    | The transaction was reversed. Funds have been returned to the source.                |
| `05` | Canceled  |    Yes    | The transaction was canceled before completion.                                      |
| `06` | Failed    |    Yes    | The transaction failed. Check `failed_code` and `failed_reason` for details.         |
| `07` | Not Found |    Yes    | The transaction does not exist in the provider's system.                             |

<Info>
  **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.
</Info>

***

## Status lifecycle

```mermaid theme={null}
stateDiagram-v2
    [*] --> Initiated : Transaction created
    Initiated --> Paying : Provider called
    Paying --> Pending : Awaiting confirmation
    Paying --> Success : Provider confirmed
    Paying --> Failed : Provider rejected
    Pending --> Success : Confirmed
    Pending --> Failed : Rejected / Timeout
    Success --> Refunded : Reversal processed
    Initiated --> Canceled : Canceled by merchant
    Paying --> Canceled : Canceled before settlement
    Initiated --> NotFound : Not found at provider
```

***

## 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.

<Warning>
  **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.
</Warning>

### `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:

| Status         | Disbursement | Virtual Account | QRIS | E-Wallet | Card | Subscription |
| -------------- | :----------: | :-------------: | :--: | :------: | :--: | :----------: |
| `00` Success   |      Yes     |       Yes       |  Yes |    Yes   |  Yes |      Yes     |
| `01` Initiated |      Yes     |        —        |   —  |    Yes   |   —  |      Yes     |
| `02` Paying    |      Yes     |        —        |  Yes |    Yes   |  Yes |      Yes     |
| `03` Pending   |      Yes     |        —        |  Yes |    Yes   |  Yes |      Yes     |
| `04` Refunded  |      Yes     |        —        |   —  |     —    |  Yes |       —      |
| `05` Canceled  |      Yes     |        —        |   —  |    Yes   |  Yes |      Yes     |
| `06` Failed    |      Yes     |        —        |  Yes |    Yes   |  Yes |      Yes     |
| `07` Not Found |      Yes     |        —        |   —  |     —    |   —  |       —      |

<Info>
  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.
</Info>

***

## Polling best practices

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

<Steps>
  <Step title="Wait before first poll">
    Allow at least **30 seconds** after the initial API call before polling.
  </Step>

  <Step title="Use exponential backoff">
    Start with 30-second intervals, increasing to 2–5 minutes. Don't poll more than once per 30 seconds.
  </Step>

  <Step title="Set a timeout">
    If a transaction remains in a non-terminal status for more than **30 minutes**, flag it for manual review.
  </Step>

  <Step title="Prefer webhooks">
    Webhook callbacks are the most reliable way to receive final status. Use polling only as a fallback.
  </Step>
</Steps>

***

## Related

* [Response Codes](/api-reference/references/response-codes) — full dictionary of `SP` response codes
* [Webhook Overview](/api-reference/webhooks/introduction) — real-time status notifications
* [Webhook Retry Mechanism](/api-reference/webhooks/retry-mechanism) — what happens when your endpoint is unreachable
