Checkout SDK

Configuration and lifecycle

Configure checkout, callbacks, redirects, theming, and destroy().

Configuration reference

Pass options to ZippyPay.create() or use theme-* attributes on <zippy-pay-checkout>.

ZippyPayConfig

typescript
type ZippyPayConfig = {
  // Required
  environment: "production" | "staging" | "development";
  sessionId: string;       // UUID v4
  clientToken: string;     // zps_…

  // Embed
  mode?: "inline" | "modal";              // default: "inline"
  container?: HTMLElement | string;       // required for inline

  // Appearance
  theme?: ZippyTheme;
  appLinks?: { ios?: string; android?: string };
  locale?: "en";                          // reserved — currently only "en"

  // Checkout methods (SDK >= 1.1.0; default mobileApp.policy enforce in 1.2.0+)
  checkoutPolicy?: "QR" | "MANUAL";       // omit for full chooser
  mobileApp?: { policy?: "off" | "option" | "enforce" }; // phone only; default enforce (1.2.0+)

  // Redirects (after terminal screen countdown)
  redirectOnComplete?: boolean;
  redirectOnFailure?: boolean;

  // Modal only
  closeOnBackdropClick?: boolean;         // default: false
  closeOnEscape?: boolean;                // default: false

  // Callbacks
  onReady?: (session: PaymentSession) => void;
  onSessionUpdate?: (session: PaymentSession) => void;
  onComplete?: (session: PaymentSession) => void;
  onExpired?: (session: PaymentSession) => void;
  onError?: (error: ZippyPayError) => void;
  onClose?: () => void;                  // modal only
};

Required and embed fields

NameTypeRequiredDescription
environmentproduction | staging | developmentRequiredResolves the API base URL. Must match where the session was created.
sessionIdUUID v4RequiredInvalid format throws at init: Zippy Pay: sessionId must be a UUID v4.
clientTokenzps_…RequiredPayment session token from your server. Authorizes checkout for this session only.
modeinline | modalOptionalEmbed mode. Defaults to "inline".
containerstring | HTMLElementOptionalRequired for inline mode. CSS selector or DOM element. Throws if not found.

Optional behavior

NameTypeDescription
checkoutPolicy"QR" | "MANUAL"Restrict web checkout methods. Omit for full chooser (QR + manual). Affects fallback options after failed mobile app handoff.
mobileApp.policyoff | option | enforcePhone only — ignored on desktop. Default enforce (SDK 1.2.0+): auto-start Pay with Zippy. option: chooser + Pay with Zippy. off: web-only (QR/manual per checkoutPolicy).
redirectOnCompletebooleanAfter success screen countdown, redirect to session.successUrl.
redirectOnFailurebooleanAfter failure or expiry screen countdown, redirect to session.failureUrl.
appLinks{ ios?, android? }Override App Store / Google Play URLs in the checkout footer.
closeOnBackdropClickbooleanModal only. Default: false.
closeOnEscapebooleanModal only. Default: false.

Web component checkout attributes

NameTypeDescription
checkout-policyQR | MANUALSame as checkoutPolicy.
mobile-app-policyoff | option | enforceSame as mobileApp.policy. Default enforce (SDK 1.2.0+). Supports off, option, enforce.

Default — Pay with Zippy on phone (SDK 1.2.0+)

typescript
// Omitting mobileApp is equivalent to { policy: 'enforce' } on phone
ZippyPay.create({
  environment: "production",
  sessionId: "550e8400-e29b-41d4-a716-446655440000",
  clientToken: "zps_REDACTED",
  mode: "inline",
  container: "#zippy-checkout",
});

Web-only on phone (pre-1.2.0 behavior)

typescript
ZippyPay.create({
  environment: "production",
  sessionId: "550e8400-e29b-41d4-a716-446655440000",
  clientToken: "zps_REDACTED",
  mode: "inline",
  container: "#zippy-checkout",
  mobileApp: { policy: "off" },
});

Chooser + Pay with Zippy

typescript
ZippyPay.create({
  environment: "production",
  sessionId: "550e8400-e29b-41d4-a716-446655440000",
  clientToken: "zps_REDACTED",
  mode: "inline",
  container: "#zippy-checkout",
  mobileApp: { policy: "option" },
  checkoutPolicy: "QR", // optional — restrict web fallbacks after failed handoff
});

Web component

html
<!-- Default: enforce on phone (SDK 1.2.0+) -->
<zippy-pay-checkout
  environment="production"
  session-id="550e8400-e29b-41d4-a716-446655440000"
></zippy-pay-checkout>

<!-- Web-only on phone -->
<zippy-pay-checkout
  environment="production"
  session-id="550e8400-e29b-41d4-a716-446655440000"
  mobile-app-policy="off"
></zippy-pay-checkout>

Example

typescript
import { ZippyPay } from "@zippypay/checkout";

ZippyPay.create({
  environment: "production",
  sessionId: "550e8400-e29b-41d4-a716-446655440000",
  clientToken: "zps_REDACTED",
  mode: "inline",
  container: "#zippy-checkout",
  redirectOnComplete: true,
  redirectOnFailure: true,
  theme: { primary: "#1a56db", mode: "auto" },
  onReady: (session) => console.log(session.amount),
  onComplete: (session) => console.log(session.transactionId),
});

Instance lifecycle

ZippyPay.create(config) returns an instance with open(), close(), and destroy().

Instance methods

NameTypeDescription
open()voidOpen modal checkout. No-op for inline mode.
close()voidClose modal without destroying. Session stays alive. No-op for inline.
destroy()voidStop polling, remove UI, clean up timers and listeners. Idempotent.

Callbacks and events

Imperative API callbacks

NameTypeDescription
onReady(session)PaymentSessionFires once after the session loads successfully.
onSessionUpdate(session)PaymentSessionFires on every poll update and session change.
onComplete(session)PaymentSessionFires when status === 'COMPLETED'.
onExpired(session)PaymentSessionFires when session expires (status === 'EXPIRED').
onError(error)ZippyPayErrorFires on API or terminal errors.
onClose()Modal only. Fires when modal is closed.

Web component events

NameTypeDescription
zippy-readyPaymentSessionInitial load complete.
zippy-session-updatePaymentSessionSession state changed.
zippy-completePaymentSessionPayment succeeded.
zippy-expiredPaymentSessionSession expired.
zippy-errorZippyPayErrorRecoverable or terminal error.
zippy-closenullModal closed.

ZippyPayError

typescript
class ZippyPayError extends Error {
  readonly code: string;
  readonly status: number;
  readonly detail: string;
  readonly correlationId?: string;
}

Redirect behavior

When checkout reaches a terminal state, the SDK shows a result screen with a 7-second countdown, then:

Terminal exit behavior

NameTypeDescription
Success + redirectOnComplete + successUrlredirectRedirect to success URL with query params.
Failure/expiry + redirectOnFailure + failureUrlredirectRedirect to failure URL.
Otherwise (inline)destroyRemoves checkout UI.
Otherwise (modal)close + destroyCloses modal then destroys instance.

Success redirect query params

text
?sessionId=550e8400-e29b-41d4-a716-446655440000&status=COMPLETED&transactionId=…

Expired redirect query params

text
?sessionId=550e8400-e29b-41d4-a716-446655440000&status=EXPIRED

Other failure types redirect to failureUrl without extra query params.

Theming

Pass a partial theme object — unset tokens use SDK defaults. When mode: 'auto', the SDK follows prefers-color-scheme: dark.

Theme tokens

NameTypeDescription
primaryCSS colorButtons, links, accents. Default: #3f63f3.
primaryForegroundCSS colorText on primary buttons. Default: #ffffff.
backgroundCSS colorMain background. Default: #ffffff (#0f172a in dark).
surfaceCSS colorCards and inputs. Default: #ffffff (#1e293b in dark).
textCSS colorPrimary text.
textMutedCSS colorSecondary text.
borderCSS colorBorders.
errorCSS colorError states. Default: #dc2626.
successCSS colorSuccess states. Default: #059669.
borderRadiusCSS lengthCard corner radius. Default: 20px.
fontFamilyfont stackFont family. Default: 'DM Sans', system-ui, …
modelight | dark | autoColor scheme. Default: "light".

Web component theme attributes

NameTypeDescription
theme-primaryattributeprimary
theme-primary-foregroundattributeprimaryForeground
theme-backgroundattributebackground
theme-surfaceattributesurface
theme-textattributetext
theme-text-mutedattributetextMuted
theme-borderattributeborder
theme-errorattributeerror
theme-successattributesuccess
theme-border-radiusattributeborderRadius
theme-font-familyattributefontFamily
theme-modeattributemode

Theme example

typescript
ZippyPay.create({
  theme: {
    primary: "#1a56db",
    primaryForeground: "#ffffff",
    borderRadius: "12px",
    fontFamily: "'Inter', sans-serif",
    mode: "auto",
  },
  // …session + token…
});

Security checklist

  • Never bundle X-Api-Key in browser code.
  • Keep clientToken in memory only — not localStorage, cookies, query strings, or analytics.
  • Encode only sessionId in QR codes and deep links — never the client token.
  • Display amount from onReady / onSessionUpdate, not from page props or URL params.
  • Register the page origin under Integrations → Allowed browser origins in the portal. Unregistered domains return 403 payment-session.origin-not-allowed.
  • Origin allowlisting applies to embedded checkout. Authenticate server-side session create with X-Api-Key on your backend only.
  • Create a new session when the client token is invalid (401) — do not retry blindly.
  • Use HTTPS in production for your checkout page.
  • Call destroy() on SPA navigation to stop polling and remove UI.