Skip to main content

Parameters

KeyTypeRequiredDescription
offeringIdstringYesID of the offering created in the Business Portal
merchantNamestringNoThe name of the merchant to display in the purchase widget.
merchantLogoUrlstringNoURL of the merchant’s logo to display in the purchase widget.
purchaseMetadataobjectNoKey-value pairs of custom information associated with the purchase.
uiConfigCreatePurchaseUiConfigNoCustom color configuration for the purchase widget.

Returns

An object containing a startPurchase function and a destroy method to control the purchase widget programmatically. Type of the response is CreatePurchaseResult.
FieldTypeDescription
startPurchase() => Promise<PurchaseStateSummary>The startPurchase function to start the purchase flow.
destroy() => voidClean up and remove all Supertab elements from the DOM.

Example

const supertabClient = new Supertab({ clientId: "client.your_client" });

const { startPurchase, destroy } = await supertabClient.createPurchase({
  offeringId: "offering.your-offering-id",
});

const result = await startPurchase();

// Then you can handle the result
if (result.purchase?.status === "completed") {
  console.log("Purchase completed successfully:", result.purchase);
} else if (result.purchase?.status === "abandoned") {
  console.log("Purchase cancelled:", result.purchase);
} else if (result.priorEntitlement) {
  console.log("User already has entitlement:", result.priorEntitlement);
}

UI Configuration

The uiConfig parameter allows you to customize the visual appearance of the purchase widget by overriding the default color scheme.

Color Priority System

The purchase widget determines which colors to use based on a priority system:
  1. Highest Priority: uiConfig passed directly to createPurchase()
  2. Medium Priority: Experience configuration colors (if the offering is associated with an experience)
  3. Lowest Priority: Default Supertab colors (#ffffff for text, #000000 for background)

Example with Custom Colors

const { startPurchase, destroy } = await supertabClient.createPurchase({
  offeringId: "offering.premium-access",
  merchantName: "Demo Merchant",
  merchantLogoUrl: "https://example.com/logo.png",
  uiConfig: {
    colors: {
      text: "#FFFFFF", // White text
      background: "#0000FF", // Blue background
    },
  },
});

How Colors Affect the Widget

colors.text controls:
  • Button text (e.g., “Continue” button label)
  • Text color contrast on colored backgrounds
  • Any text overlaid on colored elements
colors.background controls:
  • Primary action button background (e.g., “Continue” button)
  • Progress indicator ring (Omega ring showing Tab balance)
  • Visual accents and highlights throughout the widget

Visual Examples

Default colors

Default widget appearance without custom uiConfig

Custom colors

Widget with custom colors: white text (#FFFFFF) and blue background (#0000FF)

The uiConfig always takes precedence over experience configuration colors. This ensures you have full control over the widget appearance when needed.
Ensure sufficient contrast between text and background colors for accessibility. Test your color combinations to verify readability.

Types

PurchaseStateSummary

PurchaseStateSummary type definition
interface PurchaseStateSummary {
  priorEntitlement: EntitlementStatus[] | null;
  authStatus: AuthStatus;
  purchase: Purchase | null;
  purchasedOffering: Offering | null;
  tab: Tab | null;
  paymentResult: boolean;
}

type EntitlementStatus = {
  contentKey: string;
  hasEntitlement: boolean;
  expires: string; // ISO 8601 date string (e.g., "2023-11-07T05:31:56Z")
  recursAt: string | null; // ISO 8601 date string when not null (e.g., "2023-11-07T05:31:56Z")
};

enum AuthStatus {
  MISSING = "missing",
  EXPIRED = "expired",
  VALID = "valid",
}

type Purchase = {
  id: string;
  offeringId?: string | null;
  purchasedAt: string | null; // ISO 8601 date string when not null
  completedAt: string | null; // ISO 8601 date string when not null
  description: string;
  price: Price;
  status: PurchaseStatus;
  metadata: Metadata;
  entitlementStatus: EntitlementStatus | null;
};

type Metadata = Record<string, string | number | boolean | null>;

enum PurchaseStatus {
  PENDING = "pending",
  COMPLETED = "completed",
  ABANDONED = "abandoned",
}

type Price = {
  amount: number;
  currency: Currency;
};

type Currency = {
  code: string;
  symbol: string;
  name: string;
  baseUnit: number;
};

type Offering = {
  id: string;
  description: string;
  entitlementDetails: EntitlementDetails;
  price: Price;
  isPayNow: boolean;
};

type EntitlementDetails = {
  contentKey: string;
  duration: string;
  isRecurring: boolean;
};

type Tab = {
  testMode: boolean;
  currency: Currency;
  total: Price;
  limit: Price;
  purchases: Purchase[];
};

CreatePurchaseResult

CreatePurchaseResult type definition
interface CreatePurchaseResult {
  startPurchase: () => Promise<PurchaseStateSummary>;
  destroy: () => void;
}

CreatePurchaseUiConfig

CreatePurchaseUiConfig type definition
interface CreatePurchaseUiConfig {
  colors: {
    text: string; // Text color for all text elements
    background: string; // Background color for buttons and interactive elements
  };
}

Advanced Examples

Override Experience Colors

// Even if this offering has yellow/black theme in the experience configuration,
// the custom uiConfig colors will be used instead
const { startPurchase, destroy } = await supertabClient.createPurchase({
  offeringId: "offering.premium-access",
  merchantName: "My Publication",
  uiConfig: {
    colors: {
      text: "#FFFFFF", // White text
      background: "#FF6B6B", // Coral background
    },
  },
});

Conditional Color Theming

// Apply different themes based on user preferences or context
const isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;

const { startPurchase, destroy } = await supertabClient.createPurchase({
  offeringId: "offering.premium-access",
  uiConfig: isDarkMode
    ? {
        colors: {
          text: "#FFFFFF",
          background: "#1E90FF", // Dodger blue
        },
      }
    : {
        colors: {
          text: "#000000",
          background: "#FFD700", // Gold
        },
      },
});

Full Implementation Example

async function initializePurchase() {
  const supertabClient = new Supertab({ clientId: "client.your_client" });

  try {
    const { startPurchase, destroy } = await supertabClient.createPurchase({
      offeringId: "offering.premium-article",
      merchantName: "Tech News Daily",
      merchantLogoUrl: "https://example.com/logo.png",
      purchaseMetadata: {
        articleId: "article-123",
        section: "technology",
        author: "Jane Doe",
      },
      uiConfig: {
        colors: {
          text: "#2C3E50", // Dark blue-gray text
          background: "#3498DB", // Bright blue background
        },
      },
    });

    const result = await startPurchase();

    if (result.purchase?.status === "completed") {
      // Unlock the content
      unlockPremiumContent();

      // Clean up the widget
      destroy();

      // Track the conversion
      analytics.track("Purchase Completed", {
        purchaseId: result.purchase.id,
        offeringId: "offering.premium-article",
      });
    } else if (result.priorEntitlement) {
      // User already has access
      unlockPremiumContent();
      destroy();
    }
  } catch (error) {
    console.error("Purchase initialization failed:", error);
  }
}
I