For the complete documentation index, see llms.txt. This page is also available as Markdown.

Expired Payment Handling

Purpose

This page explains what happens when a payment reaches the expired status, how to handle it in your integration, and what the customer experiences.

Use this page when a payment status check or webhook returns expired and you need to know what to do next.

Scope note: the mechanism described below, a crypto quote window, governs crypto tenders. Klarna (and other non crypto hosted checkout tenders) expire differently. See "Expiry for Klarna and other non crypto tenders" near the end of this page.

What causes an expired payment?

Each Bead payment is backed by a crypto quote: a fixed conversion rate valid for a limited window. If the customer does not complete the wallet transfer before the quote window closes, the payment moves to expired.

The hosted payment page gives the customer a short window to request a new quote before the session ends. If the customer does not act within that window, the payment is automatically marked expired.

Expiry is not caused by merchant or integrator action. It is driven entirely by the quote window timing out.

Abandoned versus expired

A payment that is created but never started is not expired. It is abandoned.

  • abandoned: the payment was created, but the customer never began a payment attempt. No quote, deposit address, or checkout was ever issued for it. Bead closes these payments automatically once the hosted payment session lifetime has passed. There is nothing to reclaim, and the status never changes.

  • expired: a payment attempt was started (for example a crypto quote was issued) but it was not completed before the window closed. Funds sent after expiry are handled through reclaim, as described below. expired is a final status: a reclaim does not change it.

Neither is a paid outcome. Do not fulfill the order for either, and create a new payment if the customer wants to try again.

Webhook behavior: when Bead closes a payment automatically after the hosted payment session lifetime, neither abandoned nor expired is currently delivered as a payment webhook event. Both are available from GET /Payments/{paymentId}/tracking. If a payment stays in created or processing in your system, reconcile it with the tracking endpoint rather than waiting for a notification. See Payment Webhooks and Why is my payment still Created or In Progress?.

What happens to funds sent after expiry?

If a customer sends funds after the payment has expired:

  • the funds are not converted

  • they remain unconverted and are returned to the payer through Bead's reclaim process

  • Bead emails reclaim instructions to the payer if an email address is available

  • Bead sends a payment webhook each time refundLifecycleStatus changes, and statusCode stays expired

The integrator does not need to implement the crypto return flow. See Reclaiming Unconverted Crypto for full details on reclaim timing, windows, and the customer experience.

Integrator handling

Order and fulfillment

  • Treat expired as not paid.

  • Do not fulfill the order.

  • Do not reuse the expired payment URL. It cannot be resumed or extended.

  • If the customer still wants to pay, create a new payment and direct them to the new hosted payment URL.

Internal state mapping

Map expired to a not paid internal state such as:

  • Payment expired

  • Session timed out

  • Awaiting new payment

Do not map expired to paid, approved, or any fulfillable state.

Webhook handling

When your webhook consumer receives a payload with statusCode: "expired":

  1. Verify the webhook signature.

  2. Persist the event.

  3. Update your internal order or invoice to a not paid state.

  4. Surface appropriate messaging to the customer.

  5. Return 2xx promptly.

Use paymentId + statusCode + refundLifecycleStatus as your idempotency key, so that reclaim progress events on an expired payment are not treated as duplicates. trackingId is a legacy identifier and should not be used for de-duplication. See Payment Webhooks for signature verification and processing guidance.

Do not rely on this webhook alone. Payments that Bead closes automatically after the session lifetime are not currently sent as webhook events, so also reconcile any payment still open after your own timeout with GET /Payments/{paymentId}/tracking.

Customer experience

In the hosted UI

When the quote is about to expire, the hosted payment page gives the customer a short window to request a new quote. If no action is taken, the session ends and the payment moves to expired.

The customer cannot resume the expired session. They must start a new payment.

If funds were sent after expiry

Bead initiates reclaim after the payment expires if funds are received. If a refundEmail was included in the original payment request, Bead emails the customer reclaim instructions automatically. If no email was provided, the hosted page prompts the customer for an email when reclaim is required.

The reclaim window is 30 days from the payment's last-updated timestamp. Customers who miss that window should contact support. See Reclaiming Unconverted Crypto.

Suggested UI messaging

Use clear, direct messaging so the customer knows what happened and what to do next.

When the payment expires before the customer pays:

When the customer may have sent funds after expiry:

Scenario routing

Situation
What to do

Payment reached expired, no funds sent

Create a new payment if the customer wants to try again

Payment reached expired, customer may have sent funds late

Direct customer to check for a reclaim email; create a new payment if they want to try again

Payment reached abandoned

No funds were requested; create a new payment if the customer wants to pay

Customer sent funds just before expiry but payment still shows expired

Funds are handled through reclaim; create a new payment for the purchase

Customer wants to resume the expired session

Not possible. Create a new payment

Expiry for Klarna and other non crypto tenders

Klarna checkouts are not backed by a crypto quote, so the quote window mechanism described above does not apply to them. A Klarna payment expires instead when the hosted payment page session ends. That session currently lasts 24 hours. This is an operational setting, so it can change over time. If your integration depends on the exact value, confirm the current setting with your Bead partner contact.

A further difference from crypto tenders: for a Klarna checkout, Bead does not always receive a distinct signal when the customer declines or abandons the checkout. In that case, the payment surfaces as expired once the session lifetime elapses, the same as a plain timeout. There is currently no separate status or reason code to distinguish a customer decline or abandonment from a simple timeout for these tenders. Because expiry is detected on a periodic check rather than immediately, the status can lag slightly behind the moment the session actually ended.

Integrator handling is otherwise the same as above: treat expired as not paid, do not fulfill, and create a new payment if the customer wants to retry. There is no crypto reclaim flow for these tenders, since no crypto was received.

Last updated