> For the complete documentation index, see [llms.txt](https://developers.bead.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.bead.xyz/reference-guide/payment-scenarios/tracking-reclaim-status.md).

# Tracking Reclaim Status

When a payment ends as `overpaid`, `underpaid`, `expired`, `invalid`, or `cancelled`, Bead returns crypto to the payer through the reclaim flow. For `overpaid`, only the excess is returned. This page explains how to see where a reclaim stands and how to tell when the return is complete.

### Summary

* Reclaim progress is on the payment, in `refundLifecycleStatus`, `refundInitiatedAt`, `refundCompletedAt`, and `refundFailureReason`.
* Bead sends a payment webhook each time `refundLifecycleStatus` changes.
* When Bead completes the return, `refundLifecycleStatus` becomes `completed` and `refundCompletedAt` is set. `statusCode` does not change. `overpaid`, `underpaid`, `expired`, `invalid`, and `cancelled` are final statuses.
* A completed reclaim does not change the fulfillment decision. An `overpaid` payment is a paid order before and after the excess is returned.
* The field name `refundLifecycleStatus` describes the reclaim return to the payer. It does not describe a merchant initiated refund. There is no refund endpoint. See [Refunds for Crypto and Wallet Payments](/reference-guide/payment-scenarios/refunds-for-crypto-and-wallet-payments.md).

### Where to read reclaim status

| Source                                 | Refund lifecycle fields | Notes                                                                                                                                                                                |
| -------------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Payment webhooks                       | Included                | Sent each time `refundLifecycleStatus` changes, to the terminal webhook URL and any `webhookUrls` on the payment. See [Payment Webhooks](/payments/payment-webhooks.md).             |
| `reclaimStatusChanged` partner webhook | Included                | Optional partner level event for every merchant under the partner. See [Partner Webhooks](/onboarding/partner-webhooks.md).                                                          |
| `GET /Payments/{paymentId}/tracking`   | Returned                | Status payload for one payment, same shape as the payment webhook.                                                                                                                   |
| `GET /Payments/{paymentId}`            | Returned                | Full record for one payment.                                                                                                                                                         |
| `GET /Merchants/{id}/payments`         | Returned                | Payment history for a merchant. Filter with `StatusCode=overpaid` and `StatusCode=underpaid` (and `expired`, `invalid`, `cancelled` if relevant), then read `refundLifecycleStatus`. |
| `GET /Partners/{id}/payments`          | Returned                | Payment history across a partner's merchants. Same schema as merchant scope.                                                                                                         |
| `GET /Terminals/{id}/payments`         | Not returned            | Terminal scope uses a different schema without the refund fields. Use merchant scope, partner scope, or a single payment read.                                                       |

Authenticate single payment reads the same way you authenticate your other Payments reads, with your terminal API key in the `X-Api-Key` header. Reporting endpoints accept `X-Api-Key` as described on [Merchant Payments](/reporting/merchant-payments.md) and [Partner Payments](/reporting/partner-payments.md).

```bash
curl "https://api.test.devs.beadpay.io/Payments/{paymentId}/tracking" \
  -H "X-Api-Key: {apiKey}" \
  -H "Accept: application/json"
```

### Reclaim fields

| Field                   | Type              | Meaning                                                                                                                                                                                                              |
| ----------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `refundLifecycleStatus` | string or null    | Where the reclaim stands. See the lifecycle values below. A value of `null` means the same as `notStarted`.                                                                                                          |
| `refundInitiatedAt`     | date-time or null | The first time Bead emailed the payer reclaim instructions or the payer started a claim, whichever happened first. It is set once and is not changed afterward. It does not mean the return transaction has started. |
| `refundCompletedAt`     | date-time or null | When Bead confirmed the return to the payer. Null until the return is confirmed.                                                                                                                                     |
| `refundFailureReason`   | string or null    | Populated when a return attempt failed.                                                                                                                                                                              |

The response does not include a field for the amount returned. The payer receives a receipt by email when the return completes.

### Lifecycle values

| `refundLifecycleStatus` | What it means                                                                                                                     | Who acts next                                  |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| `notStarted`            | No reclaim is in progress.                                                                                                        | Nothing is due.                                |
| `emailSent`             | Bead emailed the payer reclaim instructions.                                                                                      | The payer opens the link and starts the claim. |
| `customerClaimed`       | The payer started the claim and provided where to send the funds.                                                                 | Bead completes the return.                     |
| `processing`            | The return is being processed. On Bitcoin payments, a claim can stay in `processing` until the funds to return are ready to send. | Bead completes the return.                     |
| `completed`             | Bead confirmed the return to the payer. `refundCompletedAt` is set.                                                               | Nothing is due.                                |
| `failed`                | The return attempt failed. `refundFailureReason` is populated.                                                                    | Contact Bead support with the `paymentId`.     |
| `rejected`              | The return request was rejected during Bead's verification review.                                                                | Contact Bead support with the `paymentId`.     |

### What a completed return means

| `statusCode` (unchanged)          | What `refundLifecycleStatus` = `completed` means                             |
| --------------------------------- | ---------------------------------------------------------------------------- |
| `overpaid`                        | The excess went back to the payer. The payment is paid and the order stands. |
| `underpaid`                       | The full amount sent went back to the payer. The payment was not paid.       |
| `expired`, `invalid`, `cancelled` | The funds received went back to the payer. The payment was not paid.         |

Use `refundLifecycleStatus` equal to `completed` together with `refundCompletedAt` as your completion signal.

If no return happens, `refundLifecycleStatus` does not reach `completed`. This is the case when the payer never claims, or when the reclaimable amount is below the minimum that can be transferred on that network. See [Reclaiming Unconverted Crypto](/reference-guide/payment-scenarios/reclaiming-unconverted-crypto.md).

### Example responses

The examples are abbreviated to the fields that matter for reclaim.

An overpaid payment where the payer has been emailed reclaim instructions for the excess:

```json
{
  "paymentId": "c10b29e3c8104e0f8dc139c20d9eeb6c",
  "paymentCode": "PMT-10452",
  "statusCode": "overpaid",
  "amounts": {
    "requested": { "inPaymentCurrency": { "amount": 100 } },
    "paid": { "inPaymentCurrency": { "amount": 105 } }
  },
  "refundLifecycleStatus": "emailSent",
  "refundInitiatedAt": "2026-10-06T13:57:20.207Z",
  "refundCompletedAt": null,
  "refundFailureReason": null
}
```

The same payment after the excess is returned:

```json
{
  "paymentId": "c10b29e3c8104e0f8dc139c20d9eeb6c",
  "paymentCode": "PMT-10452",
  "statusCode": "overpaid",
  "refundLifecycleStatus": "completed",
  "refundInitiatedAt": "2026-10-06T13:57:20.207Z",
  "refundCompletedAt": "2026-10-06T14:20:41.000Z",
  "refundFailureReason": null
}
```

An underpaid payment after the amount sent is returned:

```json
{
  "paymentId": "7a41d2f0b9e84c51a3f6e2d9c8b7a610",
  "paymentCode": "PMT-10488",
  "statusCode": "underpaid",
  "refundLifecycleStatus": "completed",
  "refundInitiatedAt": "2026-10-06T16:02:11.430Z",
  "refundCompletedAt": "2026-10-06T16:31:05.000Z",
  "refundFailureReason": null
}
```

### Using webhooks and reads together

* Listen for payment webhooks. Each change to `refundLifecycleStatus` arrives as a payment webhook with the full payload.
* Update your records from each event. Do not reverse a fulfillment decision because of a reclaim event.
* If you missed an event, read `GET /Payments/{paymentId}/tracking` for a single payment, or filter merchant or partner payment history by `StatusCode` (for example `overpaid` and `underpaid`) and read `refundLifecycleStatus`.
* If you poll instead of using webhooks: while `refundLifecycleStatus` is `emailSent`, the next step belongs to the payer, so check infrequently. While it is `customerClaimed` or `processing`, check more often, with backoff. Stop when it is `completed`, `failed`, or `rejected`.
* Bead does not publish a fixed return time. Completion depends on the payer starting the claim and on the return being confirmed.
* Reclaim must be started within 30 days of the payment's last updated timestamp. See [Reclaiming Unconverted Crypto](/reference-guide/payment-scenarios/reclaiming-unconverted-crypto.md).

### Suggested customer messaging

| `refundLifecycleStatus`           | Suggested message                                                                                         |
| --------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `emailSent`                       | We emailed instructions to return your funds. Open the link in that email and confirm where to send them. |
| `customerClaimed` or `processing` | Your return is being processed.                                                                           |
| `completed`                       | Your funds have been returned to the wallet address you provided. A receipt was emailed to you.           |
| `failed` or `rejected`            | We could not complete your return. Please contact support and give them your payment code.                |

### Frequently asked questions

**Can I get a webhook when the reclaim completes?**

Yes. Bead sends a payment webhook each time `refundLifecycleStatus` changes, including when it becomes `completed`. `statusCode` in that webhook is unchanged.

**Does a completed reclaim on an `overpaid` payment mean the order was returned?**

No. It means Bead returned the excess of an overpayment to the payer. The merchant was settled the requested amount and the order stands.

**Does a completed reclaim mean the merchant refunded the customer?**

No. It means Bead returned funds the payer sent that were not part of a paid amount. Merchant return policy for paid orders is separate. See [Refunds for Crypto and Wallet Payments](/reference-guide/payment-scenarios/refunds-for-crypto-and-wallet-payments.md).

**Why is `refundInitiatedAt` set when the payer has not done anything yet?**

It is set when Bead first emails the payer reclaim instructions, so it marks the start of the reclaim, not the start of the return transaction.

**Where do I find the amount that was returned?**

The payment record does not carry a returned amount. For an overpaid payment, the reclaimable amount is `amounts.paid` minus `amounts.requested`, in the payment currency. For the other statuses, it is `amounts.paid`. The network cost of the return transfer can reduce what arrives. The payer receives a receipt by email showing the amount returned.

### Related pages

* [Reclaiming Unconverted Crypto](/reference-guide/payment-scenarios/reclaiming-unconverted-crypto.md)
* [Under and Over Payment Handling](/reference-guide/payment-scenarios/under-and-over-payment-handling.md)
* [Payment Statuses](/payments/payment-statuses.md)
* [Payment Webhooks](/payments/payment-webhooks.md)
* [Merchant Payments](/reporting/merchant-payments.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://developers.bead.xyz/reference-guide/payment-scenarios/tracking-reclaim-status.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
