Quick Start
This guide walks you through creating a crypto payment, launching the hosted payment page, and confirming the final outcome. It also includes the required behavior for underpayments and overpayments.
What you will build
Create a hosted crypto payment session
Present the hosted payment page to a customer
Confirm payment completion using webhooks or status polling
Handle
underpaidandoverpaidoutcomes correctlyUnderstand the reclaim flow for any unconverted crypto
Prerequisites
You will need:
A sandbox terminal API key (the secret
apiKey, not a masked value)A sandbox
merchantIdandterminalIdA server or tool capable of making HTTPS requests (curl, Postman, your backend)
Optional but recommended:
A webhook endpoint for payment status updates
Environment and base URLs
Common sandbox base URL:
https://api.test.devs.beadpay.io
Payments endpoints used in this quick start:
POST /payments/cryptoGET /payments/tracking/{trackingId}
Authentication used in this quick start:
X-Api-Key: {apiKey}
Step 1: Create a payment
Create a hosted payment session and receive a trackingId plus one or more hosted paymentUrls.
Request
POST https://api.test.devs.beadpay.io/payments/crypto
Headers:
X-Api-Key: {apiKey}Content-Type: application/jsonAccept: application/json
Minimal body:
Recommended additions:
refundEmail: If you have an email address for the payer, include it. This is the email Bead uses to send reclaim instructions when reclaim is required.redirectUrl: If you want the hosted experience to return the shopper to your confirmation page.webhookUrls: If you want webhooks for this payment in addition to any terminal level webhook configuration.
Example expanded body:
Example curl
Response
You will receive a response similar to:
Save:
trackingId: your lookup key for status, webhooks, reporting, and supportpaymentUrls[0]: the hosted payment page URL to present to the customer
Step 2: Present the hosted payment page
Open the hosted page URL from paymentUrls.
Common options:
Web: open in a new tab or window, or embed (if allowed in your flow)
Mobile: open in an in app browser or webview
POS or terminal assisted: display the hosted page on a customer facing device
What the customer will do (typical crypto wallet flow):
Select an asset (example: BTC, USDC)
View a QR code or payment details
Open their wallet app and scan the QR code
Manually enter the crypto amount in their wallet app
Submit the transfer
Important: because the wallet requires the payer to enter an amount manually, miskeyed amounts can result in underpaid or overpaid.
Step 3: Confirm the final result
You should always confirm the final status before fulfilling an order. Use either webhooks or status polling.
Option A: Webhooks (recommended)
If you configured webhooks (terminal level and or per payment webhookUrls), your server will receive events when the payment status changes.
Recommended handling:
Verify the webhook signature if your configuration supports it
Persist the event quickly
Return
200 OKpromptlyTreat the webhook as the primary status signal
Option B: Polling
Use the tracking endpoint with the trackingId until the payment reaches a terminal status.
Request:
GET https://api.test.devs.beadpay.io/payments/tracking/{trackingId}
Example curl:
Recommended polling behavior:
Use a reasonable interval (example: 2 seconds) during an active checkout
Stop polling once a terminal status is returned
Prefer webhooks for production scale
Step 4: Handle status outcomes
The payment status is returned in statusCode.
Non terminal statuses
created
Payment created, waiting for customer action
processing
Funds detected and processing is in progress
Terminal statuses
completed
Customer paid the requested amount
Fulfill and mark as paid
underpaid
Customer sent less than requested
Treat as not successful payment, do not fulfill
overpaid
Customer sent more than requested
Treat as successful payment for the requested amount
expired
Payment window ended without a valid completion
Treat as not successful payment, do not fulfill
invalid
Irregular condition, funds not eligible for conversion
Treat as not successful payment, do not fulfill
cancelled
Payment cancelled
Treat as not successful payment, do not fulfill
Underpayments and overpayments
Underpayments and overpayments occur because the payer manually enters the crypto amount in their wallet app.
Underpaid
Definition: the payer sent less than the requested amount.
Integrator behavior:
Treat as not successful payment
Do not fulfill the order
If the customer still wants to pay, create a new payment and start a new hosted checkout session
What Bead does:
The crypto received remains unconverted
The full amount received is returned to the payer through the reclaim process
Overpaid
Definition: the payer sent more than the requested amount.
Integrator behavior:
Treat as successful payment for the requested amount
Fulfill once you confirm the terminal status
Do not attempt to refund the overage yourself
What Bead does:
The requested portion is processed and settled
The overage remains unconverted and is returned to the payer through the reclaim process
Reclaiming unconverted crypto
Reclaim is how Bead returns any unconverted crypto to the payer.
Reclaim can occur when the payment is:
underpaidoverpaid(overage only)expiredinvalidcancelled
Email behavior for reclaim
If you provided
refundEmailin the Create Payment request, Bead emails reclaim instructions to that address when reclaim is required.If
refundEmailwas not provided, the hosted payment page prompts the payer to enter an email address in underpaid and overpaid outcomes so Bead can send reclaim instructions.
Recommended best practice:
Provide
refundEmailwhenever you have it, especially for digital and virtual checkout flows.
Troubleshooting
401 Unauthorized
Common causes:
Missing
X-Api-KeyheaderUsing a masked value instead of the real
apiKeyUsing a key from the wrong environment
Hosted payment page does not load
Common causes:
Using an old or incorrect
paymentUrlsvalueTerminal is not configured for the tender types you are testing
Environment mismatch between API base URL and hosted page environment
Status never reaches a terminal state
Common causes:
Customer did not complete the wallet transfer
Customer sent funds after the payment expired
Webhook endpoint is failing and you are relying only on webhooks without polling
Next steps
After you complete this quick start in sandbox:
Review Payment Statuses for full status definitions and guidance
Review Under and Over Payment Handling for detailed integrator workflows
Review Reclaiming Unconverted Crypto to understand reclaim timing and payer experience
Implement production grade webhooks and internal state mapping before going live
Last updated