> 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-flows/in-person-payments-physical-terminals.md).

# In-Person Payments (Physical Terminals)

This page is for integrators building an in-person, customer-present checkout, where the payment is presented on a screen the consumer does not own: a dedicated consumer-facing display, or a cashier point-of-sale screen turned to face the consumer. It pulls together the guidance that matters most in that environment and links to the pages that cover each topic in detail.

#### The integration is the same

There is no separate in-person API. Payments on a physical terminal use the same endpoint, request fields, hosted payment page, webhooks, and status checks as any other Bead payment. If you have built an online checkout on Bead, you have already built most of an in-person one.

What changes the experience is the terminal type. A terminal created with a `type` of `physical` gives the consumer an in-person experience: each tender is presented as a QR code that the consumer scans and completes on their own phone. Getting the terminal type right is the most important configuration decision for an in-person integration.

Two things to know about terminal type:

* `type` is set when the terminal is created and cannot be changed later. A merchant that already accepts online payments on a `virtual` terminal needs a separate `physical` terminal for in-person acceptance. See [Terminal type: physical vs. virtual](/entity-management/terminal-management/terminal-lifecycle-concepts.md#terminal-type-physical-vs-virtual) and [Create Terminal](/entity-management/terminal-management/create-terminal.md).
* Physical terminals have lighter request requirements. `customer` and `refundEmail` are optional on physical terminals. See the terminal type considerations on [Create Payment](/payments/create-payment.md).

#### How the in-person experience works

* **Nothing to type on the shared screen.** The consumer is not asked to sign in or key in personal details on a device they do not own.
* **Every tender is a QR code.** For each tender enabled on the terminal, the hosted payment page presents a QR code. The consumer scans it and completes the payment in the wallet or payment app of their choice on their own phone.
* **Status can move straight to a final state.** Because the consumer completes the payment on their own device, Bead may not observe an in-progress step, so a payment can move from `created` directly to a final status without `processing`. See [Why is the processing status missing for some payments, especially on physical terminals?](/faqs-and-troubleshooting/payments-faqs/why-is-the-processing-status-missing-for-some-payments-especially-on-physical-terminals.md)

#### Things to think through for in-person payments

None of the items below change the integration. They are considerations to layer on top of it for an in-person environment. Bead does not prescribe how to build the client side of an in-person checkout; the goal here is to name the concepts to raise with your own engineers.

**Tender selection in your own interface**

Many in-person integrations show tender-specific options on their own screen, for example PayPal, Venmo, or crypto, and let the consumer choose before the payment is created. Pass the consumer's choice in `tenderTypes` so the hosted page opens directly on that tender.

To decide which options to show, read the terminal's current `tenderTypes` from `GET /Terminals/{terminalId}`. Some integrations show only the tenders that are currently available; others show every supported tender and disable the ones that are not currently active. Either approach works. See [Reading Tender Availability at Runtime](/reference-guide/payment-flows/reading-tender-availability-at-runtime.md) and the tender type selection guidance on [Create Payment](/payments/create-payment.md).

**Embedding the hosted page and knowing when it is done**

Load the first URL in `paymentUrls` in the web view or embedded browser your device app uses to show web content. The hosted payment page, including the QR code, renders inside it.

There are two common ways for your app to know the payment has finished:

* **Webhooks.** The standard approach, the same as any other environment, and the source of truth for the final status. See [Payment Webhooks](/payments/payment-webhooks.md).
* **A redirect your app watches for.** Set `redirectUrl` to an `https` URL you control, and have your app watch the embedded view for navigation to that URL. When it appears, close the view and show your own finalization screen.

A redirect is a signal for your user interface, not a payment confirmation. Always confirm the final status through a webhook or the tracking endpoint before completing the sale. See [Payment Statuses](/payments/payment-statuses.md).

**Email addresses are often unavailable**

In person, it is common to have no email address for the consumer. For most payments that does not matter. For crypto exception outcomes such as `underpaid` or `overpaid`, Bead needs an email address to send reclaim instructions. If none was provided, the hosted payment page prompts the consumer to enter one at that point.

If your point-of-sale system does have the consumer's email address, send it on the payment request, either as `refundEmail` or within a complete `customer` object. This avoids the prompt and gives the consumer a smoother experience. See [Under and Over Payment Handling](/reference-guide/payment-scenarios/under-and-over-payment-handling.md) and [Reclaiming Unconverted Crypto](/reference-guide/payment-scenarios/reclaiming-unconverted-crypto.md).

**Pass cart items when you have them**

Some tenders give a better consumer experience and better approval rates when line-item detail is provided. When your system has SKU-level cart data, send it in `cartItems` rather than sending only the total. See the cart items guidance on [Create Payment](/payments/create-payment.md).

**Consumer fees are yours to size and disclose**

Bead has no consumer fee capability. If your solution charges the consumer a fee, you calculate it, disclose it, and include it in the `requestedAmount` you send. Because fee cost and permissibility vary by tender, fees need to be sized per tender. Knowing the consumer's tender in your own interface before you create the payment is what makes that possible. See [Consumer Fee Passthrough for Wallet and Crypto Tenders](/faqs-and-troubleshooting/payments-faqs/consumer-fee-passthrough-for-wallet-and-crypto-tenders.md).

**Receipt requirements do not change**

In-person receipts follow the same rules as online receipts: show the payment method and final status, and show the exchange rate whenever a crypto-to-fiat conversion occurred. See [Receipts](/payments/receipts.md).

**BTC (on-chain) needs a deliberate decision**

BTC (on-chain) is disabled by default on physical terminals because on-chain confirmation is long-running. Decide first whether it fits the environment: it is a poor fit for a fast checkout line and can work for high-ticket or high-touch sales. If you enable it, a payment can stay in `processing` for several minutes or longer, so your solution needs a way to alert staff or the consumer when the payment reaches `completed`. Do not release goods until then. See [Choosing Tender Types by Payment Environment](/reference-guide/payment-flows/choosing-tender-types-by-payment-environment.md) and [Why do BTC (on-chain) payments take longer?](/faqs-and-troubleshooting/payments-faqs/why-do-btc-on-chain-payments-take-longer.md)

#### Related pages

* [Create Payment](/payments/create-payment.md)
* [Terminal Lifecycle (Concepts)](/entity-management/terminal-management/terminal-lifecycle-concepts.md)
* [Choosing Tender Types by Payment Environment](/reference-guide/payment-flows/choosing-tender-types-by-payment-environment.md)
* [Reading Tender Availability at Runtime](/reference-guide/payment-flows/reading-tender-availability-at-runtime.md)
* [Managing Tender Types](/entity-management/terminal-management/managing-tender-types.md)
* [Payment Statuses](/payments/payment-statuses.md)
* [Payment Webhooks](/payments/payment-webhooks.md)
* [Receipts](/payments/receipts.md)
* [Consumer Fee Passthrough for Wallet and Crypto Tenders](/faqs-and-troubleshooting/payments-faqs/consumer-fee-passthrough-for-wallet-and-crypto-tenders.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-flows/in-person-payments-physical-terminals.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.
