> ## Documentation Index
> Fetch the complete documentation index at: https://supertab-feature-merchant-auth-change-again.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Supertab.createPurchase

> API reference for `supertabClient.createPurchase`

## Parameters

| Key                | Type                                                | Required | Description                                                         |
| :----------------- | :-------------------------------------------------- | :------- | :------------------------------------------------------------------ |
| `offeringId`       | `string`                                            | Yes      | ID of the offering created in the Business Portal                   |
| `merchantName`     | `string`                                            | No       | The name of the merchant to display in the purchase widget.         |
| `merchantLogoUrl`  | `string`                                            | No       | URL of the merchant's logo to display in the purchase widget.       |
| `purchaseMetadata` | `object`                                            | No       | Key-value pairs of custom information associated with the purchase. |
| `uiConfig`         | [`CreatePurchaseUiConfig`](#createpurchaseuiconfig) | No       | Custom 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`](#createpurchaseresult).

| Field           | Type                                  | Description                                             |
| :-------------- | :------------------------------------ | :------------------------------------------------------ |
| `startPurchase` | `() => Promise<PurchaseStateSummary>` | The startPurchase function to start the purchase flow.  |
| `destroy`       | `() => void`                          | Clean up and remove all Supertab elements from the DOM. |

## Example

```javascript theme={null}
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

```javascript theme={null}
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

<div
  style={{
display: "flex",
flexDirection: "row",
gap: "1rem",
marginBottom: "1rem",
flexWrap: "wrap",
}}
>
  {" "}

  <div style={{ flex: "1", minWidth: "300px" }}>
    <img
      src="https://mintcdn.com/supertab-feature-merchant-auth-change-again/B786G4ztkFXXa9gr/images/default-ui-config.png?fit=max&auto=format&n=B786G4ztkFXXa9gr&q=85&s=31c60296dce1041ba9a8071c4300256f"
      alt="Default colors"
      style={{
  width: "100%",
  height: "auto",
  borderRadius: "8px",
  border: "1px solid #e5e7eb",
}}
      width="786"
      height="598"
      data-path="images/default-ui-config.png"
    />

    <p
      style={{
  marginTop: "0.5rem",
  fontSize: "0.875rem",
  color: "#6b7280",
  textAlign: "center",
}}
    >
      Default widget appearance without custom uiConfig
    </p>
  </div>

  <div style={{ flex: "1", minWidth: "300px" }}>
    <img
      src="https://mintcdn.com/supertab-feature-merchant-auth-change-again/B786G4ztkFXXa9gr/images/custom-ui-config.png?fit=max&auto=format&n=B786G4ztkFXXa9gr&q=85&s=cee236015d2161fa878e18c7726be7bb"
      alt="Custom colors"
      style={{
    width: "100%",
    height: "auto",
    borderRadius: "8px",
    border: "1px solid #e5e7eb",
  }}
      width="786"
      height="606"
      data-path="images/custom-ui-config.png"
    />

    <p
      style={{
    marginTop: "0.5rem",
    fontSize: "0.875rem",
    color: "#6b7280",
    textAlign: "center",
  }}
    >
      Widget with custom colors: white text (#FFFFFF) and blue background
      (#0000FF)
    </p>
  </div>
</div>

<Note>
  The `uiConfig` always takes precedence over experience configuration colors.
  This ensures you have full control over the widget appearance when needed.
</Note>

<Warning>
  Ensure sufficient contrast between text and background colors for
  accessibility. Test your color combinations to verify readability.
</Warning>

## Types

### `PurchaseStateSummary`

```typescript PurchaseStateSummary type definition theme={null}
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`

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

### `CreatePurchaseUiConfig`

```typescript CreatePurchaseUiConfig type definition theme={null}
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

```javascript theme={null}
// 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

```javascript theme={null}
// 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

```javascript theme={null}
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);
  }
}
```
