Create Payment
Create a payment with POST /Payments/crypto to generate one or more hosted payment URLs. The hosted payment page handles the checkout experience for supported crypto and digital wallet tenders. Optional tender preselection is available for advanced integrations that want to direct the shopper into a specific tender flow or a curated tender subset, but it is not required.
Overview
Endpoint:
POST /Payments/cryptoSandbox base:https://api.test.devs.beadpay.ioSupports crypto and digital wallet tenders
Returns one or more hosted payment URLs you can embed or open
Optionally redirects the shopper to
redirectUrlSupports optional per-payment webhooks via
webhookUrls, in addition to the terminal’s default webhook
For an end-to-end Sandbox flow, see Quick Start.
Step 1: Authenticate
Payments use header-based authentication with a terminal API key.
The terminal API key is the secret credential used to authenticate requests. The masked API key is a display value only and cannot be used to authenticate.
Required headers
X-Api-Key: {apiKey}
Content-Type: application/json
Accept: application/jsonAuthentication guidance
Preferred for new integrations: use
X-Api-KeySupported for existing legacy Payments integrations: OAuth password grant with
Authorization: Bearer {access_token}Do not place the API key in the request body or URL
Do not expose the API key in browser or mobile client code
See Authentication for full token and legacy OAuth details.
Step 2: Create a hosted payment URL
Send a request to create a payment. The response includes trackingId, paymentPageId, and paymentUrls.
Endpoint
Headers
Request shape guidance
Required fields can vary depending on terminal configuration, terminal type, and tender-specific requirements.
At a minimum, all payment creation requests should include:
terminalIdmerchantIdrequestedAmount
Other common fields include:
referencedescriptionredirectUrlemailReceiptsmsReceiptrefundEmailwebhookUrlscustomer
Minimum payment amounts
Minimum payment amounts can vary by tender.
For USDC on Base and USDC on Solana, the minimum Bead payment amount is $1.00 USD. If a payment request is limited to either of these tenders, or if the hosted payment experience is expected to present either of these tenders as an available option, use a requestedAmount of 1.00 or higher.
This minimum is separate from any network fee the payer’s wallet may require to submit the transaction.
Terminal type considerations
type considerationsFor some payment flows, required fields differ depending on the terminal type.
Terminal type = virtual
For flows such as Klarna testing, terminals with type = virtual may require:
merchantIdterminalIdrequestedAmountrefundEmailcustomer
Terminal type = physical
For flows such as Klarna testing, terminals with type = physical may require:
merchantIdterminalIdrequestedAmountcustomer
Important note
The exact minimum request body is not universal across all tenders and terminal setups.
Examples:
some payment flows only require the basic payment fields
some flows require the full
customerobjectsome flows require
refundEmail, especially for terminals withtype=virtualterminals with
type=physicalmay allow a different minimum request shape
When documenting or testing a specific tender, use a request example that matches that tender and terminal type.
Example request body: basic
Use this as a basic hosted payment example. It is not a guaranteed universal minimum for every payment flow.
Example request body for terminal type = virtual
type = virtualThis example is appropriate for flows that require customer details and refundEmail, such as certain digital wallet or Klarna-related scenarios.
Example request body for terminal type = physical
type = physicalThis example is appropriate for flows that require customer details but do not require refundEmail.
Example request body: expanded
Notes
refundEmailis recommended when you have a payer email available. It is used to send reclaim instructions if the payment ends asunderpaid,overpaid,expired,invalid, orcancelled.The
customerobject may be required depending on terminal configuration and tender flow.If you include the
customerobject, provide all required customer fields.
Example response
Key fields
terminalId— Terminal identifier in Bead. Determines device-level settings such as tender configuration and terminal default webhook.merchantId— Merchant identifier. Used for reporting and settlement.requestedAmount— Amount in the requested currency. For USDC on Base and USDC on Solana, use1.00or higher.tenderTypes— Optional array used to limit the payment to specific tenders. When you limit a payment to USDC on Base or USDC on Solana, therequestedAmountmust be at least1.00.reference— Merchant-side reference such as an order or invoice number.description— Description that may be shown to the customer and in reporting.customer— Customer object when required by the payment flow.redirectUrl— Optional URL Bead redirects to after checkout completes or is cancelled.emailReceipt,smsReceipt— Optional receipt delivery settings.refundEmail— Optional email used for reclaim instructions when unconverted crypto must be returned to the payer.webhookUrls— Optional array of additional webhook endpoints for this payment.
Underpayments and overpayments
In wallet-based crypto payments, the customer typically scans a QR code to set the destination and then manually enters the amount in their wallet app. If they mistype the amount, the payment can end in one of these outcomes:
underpaid— The customer sent less than requestedoverpaid— The customer sent more than requested
Recommended handling
Underpaid: treat as unsuccessful. Do not fulfill. If the customer still wants to pay, create a new payment and start a new hosted checkout.
Overpaid: treat as successful for the requested amount. You may fulfill once confirmed. The overage is returned to the payer through the reclaim flow.
Email behavior for reclaim
If you provide
refundEmail, Bead emails reclaim instructions when reclaim is required.If
refundEmailis not provided, the hosted payment page prompts the payer to enter an email address when an underpaid or overpaid outcome occurs, then Bead emails reclaim instructions.
Webhooks
If you include webhookUrls, Bead sends payment lifecycle events to both:
the terminal’s default webhook
each URL in the
webhookUrlsarray
Configure at least one webhook endpoint before you depend on webhooks in production. See Payment Webhooks for payload and retry details.
Customer data rule
If your payment flow requires a customer object, include all required customer fields.
Typical required fields are:
firstNamelastNameemailaddressaddress2citystatepostalCodecountryCode
If you send a partial customer object, the API may return 400 Bad Request with validation errors.
Step 3: Present the hosted page
Use the first URL in paymentUrls to start checkout.
Common patterns
Web or SPA: embed the URL in an iframe or open a new tab or window
Native app: load the URL in an in-app browser or webview
Redirect behavior
If
redirectUrlis provided, Bead redirects the browser toredirectUrlafter success or cancel and includes context in the query string.If
redirectUrlis not provided, Bead displays a hosted confirmation page that indicates success or cancellation.
Regardless of redirect choice, always confirm the final status via webhooks or status polling before shipping goods or granting access.
Step 4: Confirm payment status
You can confirm payment status using webhooks or polling.
Option A: Webhooks
Configure a terminal-level webhook and optionally supply
webhookUrlsper paymentYour server receives JSON payloads whenever
statusCodechangesRespond with
200 OKas soon as you have persisted or queued the event
Option B: Polling
Endpoint:
Headers:
Example curl:
Use the trackingId returned from the Create Payment response.
Typical statuses
createdandprocessingwhile the customer is payingcompletedwhen the payment has fully succeededunderpaid,overpaid,expired,invalid, orcancelledfor non-happy-path outcomes
For full status details, see Payment Statuses.
Troubleshooting
401 Unauthorized
API key is missing, invalid, or sent using the wrong header name. The header must be exactly
X-Api-Key.
Hosted page will not load
Confirm you are using a URL from the
paymentUrlsarray returned by the create payment response.Confirm the terminal is configured for at least one tender in the environment you are testing.
Validation error on payment creation
Confirm you are using a request shape that matches the terminal
typeand tender requirements.If testing USDC on Base or USDC on Solana, confirm
requestedAmountis at least1.00.If using
tenderTypes, confirm the selected tenders are enabled for the terminal and merchant.If using a terminal with
type=virtual, confirm whetherrefundEmailis required for the flow you are testing.If using a flow that requires
customer, confirm that all required customer fields are present.
No status change
Confirm you are polling the correct
trackingId.If using webhooks, confirm your endpoint is reachable and returns HTTP 200 quickly.
Next steps
After you can create and complete a payment in Sandbox:
Configure Payment Webhooks and verify your endpoint receives status events
Use Payment Statuses for ad hoc queries and troubleshooting
Explore Reporting and Settlement to build payment history and reconciliation jobs
When ready for Production, request production credentials and switch API base URLs to Production
Legacy authentication
Some existing integrations authenticate Payments using OAuth 2.0 password grant with a terminal username and password. New Payments integrations should use the terminal API key method described above.
If you are using legacy OAuth for Payments, obtain an access token using the password grant and send:
See the Authentication page for token endpoint details, realms, and refresh token usage.
Last updated