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

# usePaymentStatus

> React hook for polling and tracking payment confirmation status.

`usePaymentStatus` polls the TapRails backend for payment confirmation. Use this after initiating a payment to know when it's been confirmed on-chain.

## Import

```ts theme={null}
import { usePaymentStatus } from '@taprails/tap-to-pay';
```

## Usage

```tsx theme={null}
const {
  startPolling,
  stopPolling,
  fetchStatus,
  isPolling,
  status,
  isConfirmed,
  isFailed,
  txHash,
  confirmedAt,
  error,
  clearError,
  reset,
} = usePaymentStatus({
  paymentId: 'pay_abc123',  // optional — can also pass to startPolling()
  pollingInterval: 2000,    // ms between polls (default: 2000)
  autoStart: false,         // start polling immediately (default: false)
});
```

## Options

<ParamField path="paymentId" type="string">
  The payment ID to poll. Can also be passed to `startPolling()` instead.
</ParamField>

<ParamField path="pollingInterval" type="number">
  Interval between status checks in milliseconds. Default: `2000` (2 seconds).
</ParamField>

<ParamField path="autoStart" type="boolean">
  If `true`, polling starts immediately on mount using the provided `paymentId`. Default: `false`.
</ParamField>

## Return Value

<ResponseField name="startPolling" type="(paymentId?: string) => void">
  Starts polling. Optionally accepts a `paymentId` to override the one from options.
</ResponseField>

<ResponseField name="stopPolling" type="() => void">
  Stops the polling interval.
</ResponseField>

<ResponseField name="fetchStatus" type="(paymentId: string) => Promise<PaymentStatusResponse>">
  One-shot status fetch without starting continuous polling.
</ResponseField>

<ResponseField name="isPolling" type="boolean">
  `true` while the polling interval is active.
</ResponseField>

<ResponseField name="status" type="PaymentStatusResponse | null">
  The latest status response from the backend.
</ResponseField>

<ResponseField name="isConfirmed" type="boolean">
  `true` when `status.status === 'confirmed'`.
</ResponseField>

<ResponseField name="isFailed" type="boolean">
  `true` when `status.status === 'failed'`.
</ResponseField>

<ResponseField name="txHash" type="string | undefined">
  On-chain transaction hash once confirmed.
</ResponseField>

<ResponseField name="confirmedAt" type="number | undefined">
  Unix timestamp (ms) of confirmation.
</ResponseField>

<ResponseField name="error" type="APIError | null">
  Error from the most recent poll.
</ResponseField>

<ResponseField name="clearError" type="() => void">
  Clears the `error` state.
</ResponseField>

<ResponseField name="reset" type="() => void">
  Stops polling and clears all state.
</ResponseField>

***

## Example

```tsx theme={null}
import { useEffect } from 'react';
import { usePaymentStatus } from '@taprails/tap-to-pay';

export function PaymentConfirmation({ paymentId }: { paymentId: string }) {
  const { startPolling, stopPolling, isConfirmed, isFailed, txHash, isPolling } =
    usePaymentStatus({ pollingInterval: 3000 });

  useEffect(() => {
    startPolling(paymentId);
    return () => stopPolling();
  }, [paymentId]);

  useEffect(() => {
    if (isConfirmed) {
      stopPolling();
      console.log('Confirmed! tx:', txHash);
    }
    if (isFailed) {
      stopPolling();
      console.log('Payment failed');
    }
  }, [isConfirmed, isFailed]);

  if (isConfirmed) return <Text>✅ Confirmed — {txHash?.slice(0, 10)}…</Text>;
  if (isFailed) return <Text>❌ Payment failed</Text>;
  if (isPolling) return <ActivityIndicator />;

  return null;
}
```
