Building FeaturesPayments & Checkout

Payments

Take payments in your app with Beam Checkout or Stripe Connect: cards on your own page, PromptPay QR, test payments in a playground, and going live.

Stardeck has two built-in providers: Beam Checkout and Stripe Connect. Manage them under Settings → Services → Payments. Your app calls them through @stardeck-customer-apps/payments-sdk, with no API keys in your code.

Using another gateway with your own keys (Stripe direct, Omise)? See Third-Party Payment Gateways.

To build a checkout, give your coding agent a prompt like the ones on this page. It works in your app's checkout and follows the SKILL.md inside node_modules/@stardeck-customer-apps/payments-sdk. If you build in the browser, give the same prompt to Starcat Developer in the app's Build tab.

Beam Checkout

Thai payment gateway: QR PromptPay, cards, e-wallets (LINE Pay, TrueMoney, ShopeePay), mobile banking, buy now pay later. Amounts are in satang (100 satang = 1 THB).

Start with Playground

Beam Playground is a shared test environment. No Beam account or keys needed.

  1. Open your project in the Stardeck dashboard
  2. Go to Settings → Services → Payments
  3. Under Choose a payment provider, select Beam Checkout, then select Enable payments
  4. Sandbox is on by default under Playground routing

Sandbox payment calls now go to Beam's test environment.

Playground routing

Choose which environments use Playground:

TargetDescription
SandboxYour development environment (enabled by default)
PreviewPreview deployments from branches
ProductionYour live production deployment

Toggle these in the Playground routing section. Sandbox changes apply when you save. Preview and production changes apply on that environment's next deploy.

Configuring Payment Methods

Under Allowed Payment Methods, pick what payment links offer. Applies to Playground and production.

  • Card Payments
  • QR PromptPay
  • E-Wallets (LINE Pay, TrueMoney, ShopeePay)
  • Mobile Banking
  • Buy Now Pay Later (Atome)
  • Card Installments (3, 4, 6, or 10 months)

Using the Payments SDK

@stardeck-customer-apps/payments-sdk is pre-installed in every app.

The customer pays on a Beam-hosted page, then returns to your app. Allowed Payment Methods controls what the page offers.

Create a checkout page for my online store using Beam payment links.

Requirements:
- Show the cart items and total before checkout
- Create a Beam payment link and redirect the customer to pay
- After payment, redirect back to an order confirmation page
- Store the order in the database with payment status

Direct Charges (API-Integrated)

Your server creates a charge and gets back a QR image (PromptPay) or a redirect URL. You own the payment UI.

Build an inline PromptPay payment flow for my restaurant POS.

Requirements:
- Create a direct charge with QR_PROMPT_PAY payment method
- Display the QR code image directly on the page (no redirect)
- Poll for payment status and show a success message when paid
- Store the transaction in the database

Methods include QR_PROMPT_PAY, LINE_PAY, TRUE_MONEY and SHOPEE_PAY. Branch on actionRequired, not on the method. Beam decides per charge.

actionRequiredDo this
ENCODED_IMAGEShow the returned QR code
REDIRECTSend the customer to the URL (e-wallets, mobile banking, 3-D Secure)
NONEPayment finished

Card Payments

The browser sends the card to Beam and gets a token. Your server charges the token. The card number never reaches your server.

"use client";
import { PaymentsClient, tokenizeBeamCard } from "@stardeck-customer-apps/payments-sdk/browser";

const payments = new PaymentsClient();

async function payByCard(form: CardForm) {
  // 1. Merchant ID + publishable key + Beam tokenize URL (live or Playground)
  const config = await payments.getCardTokenizationConfig();
  // 2. Browser → Beam. PAN accepts spaces/dashes; month/year accept form strings; year 30 or 2030.
  const { cardTokenId } = await tokenizeBeamCard(config, {
    pan: form.number,
    expiryMonth: form.month,
    expiryYear: form.year,
    cardHolderName: form.name,
  });
  // 3. Send cardTokenId and the CVV to your own server route, never the card number.
}

On your server, create the charge with the amount computed from the order:

const charge = await beam.createDirectCharge({
  amount: order.totalSatang,
  paymentMethod: "CARD_TOKEN", // or "CARD_TOKEN_INSTALLMENTS" with installmentPeriod: 3 | 4 | 6 | 10
  cardToken: { cardTokenId, securityCode: cvv },
  returnUrl: `${origin}/orders/${order.id}`, // where 3-D Secure lands the shopper
  referenceId: order.attemptId,
  idempotencyKey: order.attemptId,
});

If actionRequired is NONE, read the status with getCharge(). If it is REDIRECT, send the shopper to redirectUrl for the one-time password or 3-D Secure page.

  • Do not log or store the card number, and do not store the CVV.
  • CARD and CARD_INSTALLMENTS are refused on direct charges, because they would put raw card numbers on your server.
  • If the merchant has no publishable key, getCardTokenizationConfig() throws CARD_TOKENIZATION_NOT_CONFIGURED. Hide the card option when you see it.

Bolt Terminals (Physical Devices)

Send payment intents to paired terminals. See Bolt paired devices.

Build a POS checkout that sends a card payment to my Bolt terminal.

Requirements:
- Select a paired Bolt device from the list
- Send a payment intent for the order total
- Poll for charge status to confirm payment
- Print a receipt after successful payment

Testing in Playground

Playground charges no real money. Use Beam's test cards and QR codes. Branch previews only take test payments; publish to production for real ones.

Go live

  1. Create a Beam merchant account at Beam Lighthouse
  2. In the Go live with Beam card on the Payments tab, add your production merchant
  3. In the Production section, enter your API Key (found in Beam Lighthouse under Developers)
  4. Under Webhooks, copy the webhook URL. It points at Stardeck, not your app's domain. Register it in Beam Lighthouse under Developers → Webhooks, then paste the HMAC key Beam gives you back into the webhook secret field
  5. Turn Production off under Playground routing

Sandbox and preview can stay on Playground while production uses real credentials.

Bolt paired devices

Under Bolt+ Paired Devices on the Payments tab, pair a terminal with its 8-character code (e.g. 4TY9JDH2), check its status, or remove it. Pair in sandbox or production mode.

Terminals paired under Bolt+ terminals on a Beam account in the organization's Settings → Payments are available to every app attached to that account.

Payment accounts

Beam and Stripe accounts can be shared across apps. Create them under Payment accounts in the organization's Settings → Payments. In an app, use Attach from organization. Requests that don't name an account use the default.

Stripe Connect

Take payments through your own Stripe account: cards (with Apple Pay and Google Pay on supported devices), PromptPay QR for Thai baht, and subscriptions. Stardeck never holds funds. Payouts, branding and the Stripe dashboard stay yours. Amounts are in the currency's smallest unit (satang for THB, cents for USD; whole yen for JPY).

Start with Playground

Stripe Playground is Stardeck's shared Stripe test account. No Stripe account needed.

  1. Open your project in the Stardeck dashboard
  2. Go to Settings → Services → Payments
  3. Under Choose a payment provider, select Stripe Connect, then Enable payments
  4. Sandbox is on by default under Playground routing

Payments from your sandbox now land on the test account, and no real money moves.

Playground routing

Choose which environments use Playground instead of your own Stripe account:

TargetDescription
SandboxYour development environment (enabled by default)
PreviewPreview deployments from branches
ProductionYour live production deployment

Changes take effect on the next payment in that environment. You don't need to redeploy.

Payment methods

Under Payment methods, choose what your app offers. Keep at least one on.

  • Card: Visa, Mastercard and other cards, plus Apple Pay and Google Pay where the device supports them
  • PromptPay: the customer scans a QR code with their banking app. Thai baht only

The setting applies to every environment from the next payment on. Your app only offers a method your Stripe account can take, so PromptPay appears once it is active on a Thai Stripe account.

Using the Payments SDK

@stardeck-customer-apps/payments-sdk is pre-installed in every app. Your app marks an order paid when Stripe's payment_intent.succeeded event reaches it, not when the browser says so.

Card on your page

The card form is Stripe's Payment Element, shown inside your own checkout. Card details go from the browser straight to Stripe and never touch your server. 3-D Secure opens in place when the bank asks for it.

Add card payments to my storefront checkout using Stripe's Payment Element.

Requirements:
- Keep the customer on my checkout page, with the card form under the order summary
- Create the payment on the server with the amount from the order, not from the browser
- Handle 3-D Secure, and show a clear message when a card is declined
- Mark the order paid only when the payment_intent.succeeded event arrives, then show the order page

PromptPay QR

Your server creates the payment and gets back a QR code to show. The customer scans it with any Thai banking app.

Add a PromptPay QR option to my restaurant's checkout using Stripe.

Requirements:
- Show the QR code on the page with the amount in baht and a countdown until it expires
- Poll the payment and switch to a "Paid" screen as soon as it succeeds
- Let the customer cancel and pick card instead
- Store the payment on the order and mark it paid from the payment_intent.succeeded event

Hosted Checkout

The customer pays on a Stripe-hosted page, then returns to your app. Use this for subscriptions.

Create a checkout flow for my SaaS app using Stripe.

Requirements:
- Monthly subscription at $29/mo
- Annual plan at $290/year
- Redirect to dashboard after successful payment
- Show billing portal link for managing subscriptions

Testing in Playground

Playground takes no real money. Use Stripe's test cards:

Card numberWhat happens
4242 4242 4242 4242Succeeds
4000 0027 6000 3184Asks for 3-D Secure, then succeeds if approved
4000 0000 0000 0002Declined

Use any future expiry date and any CVC. For PromptPay, open the QR's test payment page and approve or fail the payment there. Webhook events from test payments appear under Webhook logs on the Payments tab.

Go live

  1. In the Go live with Stripe card on the Payments tab, select Connect with Stripe, sign in to Stripe and authorize. There is no API key to paste, and you can create a Stripe account during this step
  2. Connecting turns Production off under Playground routing, so your live app takes real payments straight away. Sandbox and preview stay on Playground
  3. Check that Charges Enabled shows on the Payments tab. If it doesn't, finish your business, bank and identity details in the Stripe dashboard
  4. Make one small real payment in your live app and check it shows as paid

Status

  • Charges Enabled: ready to take payments.
  • Payouts Enabled: Stripe can pay your bank.

If charges are off, finish business, bank and identity details in the Stripe dashboard, then refresh the Payments tab.

Products

With charges enabled, the Products section creates products and one-time or recurring prices on your Stripe account.

Disconnect

Disconnect from the Payments tab. This revokes Stardeck's access on Stripe's side. Your Stripe account and data are untouched.

Need help, or had Stripe connected by our team? Contact support@stardeck.ai.