JavaScript SDK (FastStar.js)

FastStar.js is a zero-dependency, single-file browser SDK (UMD). It opens the hosted checkout in a centered overlay so buyers never leave your site, and provides a secure popup flow for saving cards to the vault.

Including the SDK

Add the script at the bottom of your page, or in <head> with defer:

<script src="https://cashier.faststarpay.com/sdk/v1/faststar.min.js" defer></script>

The SDK also works in CommonJS/AMD environments via its UMD wrapper (require('./faststar.js')). FastStar.init() is optional — calling FastStar.checkout.open() directly initializes the SDK with defaults.

Subresource Integrity (SRI)

The SDK is served from a versioned path (/sdk/v1/). If your security policy requires it, you can pin the exact file with Subresource Integrity: compute the hash of the file you verified (for example openssl dgst -sha384 -binary faststar.min.js | openssl base64 -A) and add integrity="sha384-..." together with crossorigin="anonymous" to the script tag. Re-generate the hash whenever you adopt a new SDK build.

Fixed cashier domain & origin whitelist

Since v1.1.0 the cashier domain is pinned to https://cashier.faststarpay.com and cannot be configured. A configurable base URL would be a phishing and overlay-hijacking surface: any page could point a FastStar-looking overlay at an arbitrary domain.

For the same reason, FastStar.checkout.open({ url }) only opens URLs on the platform's whitelisted origins — https://cashier.faststarpay.com and https://merchant.faststarpay.com. Any other URL is rejected. Only http(s) URLs are accepted, so pseudo-protocols such as javascript: cannot be injected.

Opening the checkout

The recommended flow is a Checkout Session: your server creates the session with your API key and returns its url to the browser:

// presentation: 'iframe' — SDK overlay (buyer stays on your site)
FastStar.checkout.open({ url: data.url });

// presentation: 'link' — full-page redirect
window.location.href = data.url;

Payment links are also supported, by full URL or by id:

// full payment link URL
FastStar.checkout.open({ url: 'https://cashier.faststarpay.com/pay/plink_abc123' });

// linkId only — the SDK builds {cashier}/pay/{linkId}
FastStar.checkout.open({ linkId: 'plink_abc123' });

The SDK renders a full-screen translucent backdrop with a centered iframe (the checkout URL automatically gets an embedded=1 query parameter). The overlay has a close button, closes on backdrop click or ESC, shows a CSS-only loading spinner, and goes full-screen on mobile (width ≤ 640px). Close it programmatically with FastStar.checkout.close().

Events

The checkout page reports results back to your page via postMessage; the SDK wraps them as events:

EventWhenExample data
checkout.successPayment succeeded (the overlay closes automatically){ payment_intent_id: 'pi_xxx' }
checkout.cancelBuyer closed the overlay or canceled on the checkout page{ reason: 'user_closed' }
checkout.errorPayment failed (overlay stays open so the buyer can retry){ message: '...' }
checkout.open / checkout.loaded / checkout.closeOverlay lifecycle
function onSuccess(data) {
  console.log('Paid, payment_intent_id =', data.payment_intent_id);
  // Note: always fulfill based on the server-side webhook, not this event
}

FastStar.on('checkout.success', onSuccess);
FastStar.on('checkout.cancel', function (data) { console.log('Canceled', data); });
FastStar.on('checkout.error',  function (data) { console.warn('Failed', data); });

// Unbind: pass the callback to remove one listener,
// or omit it to remove all listeners for that event
FastStar.off('checkout.success', onSuccess);

For Checkout Sessions the event data also carries the checkout_session_id.

Auto-binding with data-faststar-checkout

Add the data-faststar-checkout attribute to any element and a click opens the overlay. The value can be a full URL or a linkId:

<!-- full URL -->
<a href="#" data-faststar-checkout="https://cashier.faststarpay.com/pay/plink_abc123">Buy now</a>

<!-- linkId only -->
<button data-faststar-checkout="plink_abc123">Buy now</button>

<!-- empty value: falls back to the <a> tag's href -->
<a href="https://cashier.faststarpay.com/pay/plink_abc123" data-faststar-checkout>Buy now</a>

Binding is implemented with event delegation, so dynamically inserted elements work without re-initialization.

Saving cards: FastStar.cards.add

FastStar.cards.add(session, callbacks) opens a secure popup that saves a buyer's card to the FastStar vault for later off-session charges. The flow is an iframe inside an iframe:

your site → (SDK overlay iframe) → FastStar card page (our domain) → processor's secure iframe

The card number only ever enters the payment processor's secure iframe — it never touches your servers or FastStar's. You receive only a FastStar token (pm_xxx) plus masked card details.

Sequence (follow exactly)

  1. Your server creates a SetupIntent with your API key (never expose the key in the browser):
    POST /api/v1/public/customers/:id/setup-intent
    → data: { client_secret, publishable_key, setup_intent_id, provider }
  2. Your server sends that result — together with the attach endpoint URL and a short-lived auth token it issues — to the browser, which calls:
    FastStar.cards.add(
      {
        customerId: 'cus_xxx',
        clientSecret: 'seti_xxx_secret_xxx',     // from setup-intent
        publishableKey: 'pk_live_xxx',           // from setup-intent
        attachUrl: 'https://api.faststarpay.com/api/v1/public/customers/cus_xxx/payment-methods',
        authToken: 'SHORT_LIVED_TOKEN'           // issued by your server, used to call attachUrl
      },
      {
        onSuccess: function (card) {
          // card = { payment_method_id: 'pm_xxx', brand, last4, exp_month, exp_year, is_default }
          console.log('Card saved', card.payment_method_id);
        },
        onError: function (err) { console.warn('Card save failed', err.message); }, // popup stays open for retry
        onCancel: function () { console.log('Buyer canceled'); }
      }
    );
  3. The SDK opens a centered popup iframe at cards/add?embedded=1 on the cashier domain. When the card page signals it is ready, the SDK passes the session in via postMessage — credentials never appear in the URL, so the authToken is not exposed.
  4. The buyer enters the card in the processor's secure inputs and saves. The card page completes tokenization, then calls attachUrl with { setup_intent_id } to attach the payment method.
  5. The card page posts the masked card back to the SDK, which fires onSuccess(card) and closes the popup automatically.

Card events

The same results are also emitted as events you can observe with FastStar.on:

EventMeaningdata
card.addedCard saved (popup closes automatically){ payment_method_id, brand, last4, exp_month, exp_year, is_default }
card.errorTokenization or attach failed (popup stays open for retry){ message }
card.cancelBuyer closed the popup or canceled
card.readyCard page ready (the SDK uses this internally to inject the session)

FastStar.cards.close() closes the popup without firing callbacks — useful for cleanup inside your own handlers.

Security notes

  • The overlay iframe runs with sandbox (allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation); allow-top-navigation-by-user-activation and allow-popups exist to support 3-D Secure bank redirects.
  • The SDK only accepts postMessage payloads whose body is { source: 'faststar', ... } and whose origin matches the current checkout/card page. Everything else is ignored.
  • checkout.success is for front-end interaction only (closing the overlay, showing a thank-you page). Fulfillment must rely on server-side webhooks.
  • During card saving, the card number never passes through your servers or FastStar's; the authToken travels via postMessage, never in a URL.