Skip to main content
Docs

usePaymentAttempts()

Warning

Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend pinning your SDK and clerk-js package versions.

The usePaymentAttempts() hook provides access to the payment attempts associated with a user or organization. It returns a paginated list of payment attempts and includes methods for managing them.

Parameters

usePaymentAttempts() accepts a single optional object with the following properties:

  • Name
    enabled?
    Type
    boolean
    Description

    If true, a request will be triggered when the hook is mounted. Defaults to true.

  • Name
    for?
    Type
    "user" | "organization"
    Description

    Specifies whether to fetch for the current user or organization. Defaults to 'user'.

  • Name
    infinite?
    Type
    boolean
    Description

    If true, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to false.

  • Name
    initialPage?
    Type
    number
    Description

    A number that specifies which page to fetch. For example, if initialPage is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to 1.

  • Name
    keepPreviousData?
    Type
    boolean
    Description

    If true, the previous data will be kept in the cache until new data is fetched. Defaults to false.

  • Name
    pageSize?
    Type
    number
    Description

    A number that specifies the maximum number of results to return per page. Defaults to 10.

Returns

usePaymentAttempts() returns an object with the following properties:

  • Name
    count
    Type
    number
    Description

    The total count of data that exist remotely.

  • Name
    data
    Type
    BillingPaymentResourceJavaScript Icon[]
    Description

    An array that contains the fetched data. For example, for the memberships attribute, data will be an array of OrganizationMembershipJavaScript Icon objects.

  • Name
    error
    Type
    null | ClerkAPIResponseError
    Description

    Clerk's API response error object.

  • Name
    fetchNext
    Type
    () => void
    Description

    A function that triggers the next page to be loaded. This is the same as fetchPage(page => Math.min(pageCount, page + 1)).

  • Name
    fetchPage
    Type
    ValueOrSetter<number>
    Description

    A function that triggers a specific page to be loaded.

  • Name
    fetchPrevious
    Type
    () => void
    Description

    A function that triggers the previous page to be loaded. This is the same as fetchPage(page => Math.max(0, page - 1)).

  • Name
    hasNextPage
    Type
    boolean
    Description

    A boolean that indicates if there are available pages to be fetched.

  • Name
    hasPreviousPage
    Type
    boolean
    Description

    A boolean that indicates if there are available pages to be fetched.

  • Name
    isError
    Type
    boolean
    Description

    A boolean that indicates the request failed.

  • Name
    isFetching
    Type
    boolean
    Description

    A boolean that is true if there is an ongoing request or a revalidation.

  • Name
    isLoading
    Type
    boolean
    Description

    A boolean that is true if there is an ongoing request and there is no fetched data.

  • Name
    page
    Type
    number
    Description

    The current page.

  • Name
    pageCount
    Type
    number
    Description

    The total amount of pages. It is calculated based on count, initialPage, and pageSize.

  • Name
    revalidate
    Type
    () => Promise<void>
    Description

    A function that triggers a revalidation of the current page.

  • Name
    setData
    Type
    CacheSetter<undefined | ClerkPaginatedResponseJavaScript Icon<BillingPaymentResourceJavaScript Icon>>
    Description

    A function that allows you to set the data manually.

Examples

Basic usage

The following example demonstrates how to fetch and display a user's payment attempts.

app/billing/payment-attempts/page.tsx
'use client'

import { usePaymentAttempts } from '@clerk/nextjs/experimental'

export default function PaymentAttemptsList() {
  const { data, isLoading } = usePaymentAttempts({
    for: 'user',
    pageSize: 10,
  })

  if (isLoading) {
    return <div>Loading payment attempts...</div>
  }

  if (!data || data.length === 0) {
    return <div>No payment attempts found.</div>
  }

  return (
    <ul>
      {data?.map((attempt) => (
        <li key={attempt.id}>
          Payment #{attempt.id} - {attempt.status}
          <br />
          Amount: {attempt.amount.amountFormatted} on {new Date(attempt.updatedAt).toLocaleString()}
        </li>
      ))}
    </ul>
  )
}

Infinite pagination

The following example demonstrates how to implement infinite scrolling with payment attempts.

app/billing/payment-attempts/page.tsx
'use client'

import { usePaymentAttempts } from '@clerk/nextjs/experimental'

export default function InfinitePaymentAttempts() {
  const { data, isLoading, hasNextPage, fetchNext } = usePaymentAttempts({
    for: 'user',
    infinite: true,
    pageSize: 20,
  })

  if (isLoading) {
    return <div>Loading...</div>
  }

  if (!data || data.length === 0) {
    return <div>No payment attempts found.</div>
  }

  return (
    <div>
      <ul>
        {data?.map((attempt) => (
          <li key={attempt.id}>
            Payment attempt for {attempt.amount.amountFormatted}
            <br />
            Status: {attempt.status}
            <br />
            {attempt.status === 'failed' && attempt.failedAt && (
              <span>Failed At: {new Date(attempt.failedAt).toLocaleString()}</span>
            )}
          </li>
        ))}
      </ul>

      {hasNextPage && <button onClick={() => fetchNext()}>Load more payment attempts</button>}
    </div>
  )
}

Payment attempts history table

The following example demonstrates how to use usePaymentAttempts() to display a detailed payment history table.

app/billing/payment-attempts-history/page.tsx
'use client'

import { usePaymentAttempts } from '@clerk/nextjs/experimental'

export default function PaymentAttemptsHistory() {
  const { data, isLoading } = usePaymentAttempts({ for: 'user' })

  if (isLoading) {
    return <div>Loading payment attempts...</div>
  }

  if (!data || data.length === 0) {
    return <div>No payment attempts found.</div>
  }

  const getStatusColor = (status: string) => {
    switch (status) {
      case 'paid':
        return 'green'
      case 'failed':
        return 'red'
      case 'pending':
        return 'orange'
      default:
        return 'gray'
    }
  }

  return (
    <table>
      <thead>
        <tr>
          <th>Payment ID</th>
          <th>Amount</th>
          <th>Status</th>
          <th>Date</th>
          <th>Payment Method</th>
        </tr>
      </thead>
      <tbody>
        {data?.map((attempt) => (
          <tr key={attempt.id}>
            <td>{attempt.id}</td>
            <td>{attempt.amount.amountFormatted}</td>
            <td style={{ color: getStatusColor(attempt.status) }}>{attempt.status}</td>
            <td>{attempt.paidAt ? new Date(attempt.paidAt).toLocaleDateString() : '-'}</td>
            <td>
              {attempt.paymentSource.cardType} ****{attempt.paymentSource.last4}
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  )
}

Feedback

What did you think of this content?

Last updated on