Easy Labs
SDKsJavaScript

Quickstart

Go from zero to a working JavaScript integration in five minutes.

This walkthrough takes a one-line product on your server and turns it into a working hosted-checkout iframe in the browser. By the end you'll have collected a real (sandbox) payment.

You'll need two pieces of code: a tiny server endpoint that mints a checkout session, and a browser page that mounts the iframe.

@easylabs/browser 0.2.0 ships three payment surfaces — Embedded Checkout, Elements, and Wallet buttons. This quickstart uses Embedded Checkout because it's the fastest path to a working payment. If you'd rather render your own card form, jump to the Elements page; the bootstrap (steps 1 and 2 below) is identical.

1. Get your API keys

Sign in to the Easy Labs dashboard and copy your sandbox secret key — it starts with sk_test_. The browser SDK auto-detects sandbox vs. production from this prefix; no environment flags needed.

The key in this quickstart is a server-side secret and must never ship to the browser. We use it on a server endpoint to create the checkout session, then hand the resulting client_secret (a short-lived, single-use credential) to the browser.

2. Initialize the SDK

On your server (using @easylabs/node or any HTTP client), create a checkout session:

// server.ts
import { createClient } from "@easylabs/node";

const easy = await createClient({ apiKey: process.env.EASY_API_KEY! });

app.post("/checkout/session", async (_req, res) => {
  const { data } = await easy.createEmbeddedCheckoutSession({
    mode: "payment",
    line_items: [{ price_id: "price_...", quantity: 1 }],
    success_url: "https://example.com/success",
    cancel_url: "https://example.com/cancel",
  });
  res.json({ clientSecret: data.client_secret });
});

In the browser, you don't need to construct an EasyApiClient at all for Embedded Checkout — the iframe authenticates against the short-lived client_secret your server just minted. Just import the mount helper directly:

// app.ts
import { mountEmbeddedCheckout } from "@easylabs/browser";

Never ship a secret key (sk_test_… / sk_live_…) to the browser. Anything that runs in a browser tab is publicly readable. When the SDK eventually exposes publishable keys, those are the only Easy Labs keys safe for client-side use; until then, do all secret-key work on your server and hand the browser a client_secret (Embedded Checkout) or a Basis Theory token reference (Elements).

You only need createEasyClient in the browser when you want the typed EasyApiClient surface for read-only utility flows — see Client for the trade-offs.

3. Make your first call

Fetch the session from your server, then mount the iframe into a container element:

const res = await fetch("/checkout/session", { method: "POST" });
const { clientSecret } = await res.json();

const handle = mountEmbeddedCheckout("#checkout", {
  clientSecret,
  onReady: () => console.log("checkout ready"),
  onCryptoConfirmed: (event) => console.log("crypto confirmed", event),
});

Drop a target into your HTML:

<div id="checkout" style="max-width: 480px; margin: 0 auto;"></div>

4. Handle the response

The iframe handles card entry, validation, 3DS, and confirmation internally. When the customer pays, Easy Labs redirects the iframe to your success_url (or cancel_url). For crypto payments specifically, the SDK also fires onCryptoConfirmed so you can react in-page without a redirect round-trip.

For everything else — fulfillment, receipts, downstream automations — listen for the checkout.session.completed webhook on your server. The browser is never the source of truth for "payment succeeded".

If createEasyClient throws, the API key is invalid or the network is unreachable. If mountEmbeddedCheckout throws synchronously, the selector or element you passed couldn't be resolved. Errors that come back from API calls on the client are instances of EasyApiError — check err.status and err.code to branch on them.

import { EasyApiError } from "@easylabs/browser";

try {
  await easy.getCustomer("cus_does_not_exist");
} catch (err) {
  if (err instanceof EasyApiError && err.status === 404) {
    // not found
  } else {
    throw err;
  }
}

What's next

  • Embedded Checkout — the full option surface for mountEmbeddedCheckout.
  • Elements — render your own card form with iframed PCI-isolated inputs and tokenize.
  • Wallet Checkout — drop-in Apple Pay and Google Pay buttons.
  • Client — every typed API method you can call from the browser.
  • Examples › Vanilla JS — a complete runnable example covering Embedded Checkout, Elements, and wallets.

On this page