> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stigg.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Customer portal

## Overview

Stigg's customer portal widget allows you to introduce self-service and drive in-app expansions using only a few lines of codes.

The customer portal:

1. Provides customers with visibility to their current subscription details - subscribed plan, purchased add-ons, granted promotional entitlements.
2. Provides customers with visibility to the usage of their subscription's features.
3. Allows customers to upgrade and downgrade their subscription in a self-served manner - when you update your pricing model in Stigg, customers will auto-magically be able to upgrade or downgrade their subscription according to the updated pricing model 😎.
4. Allows customers to view their billing and payment information - when Stigg is integrated with a billing solution (such as Stripe), customers can also update this information and view previous invoices directly from the billing solution's billing portal.

<img src="https://mintcdn.com/stigg/tWlJkHU9GfoKBEmJ/images/docs/55ae4d3-Frame_18882.png?fit=max&auto=format&n=tWlJkHU9GfoKBEmJ&q=85&s=2a363d95305b8fd8089f10e5d92da299" alt="" width="1102" height="2634" data-path="images/docs/55ae4d3-Frame_18882.png" />

## Customer portal sections

Stigg's customer portal widget is composed of the following sections.

### Subscription overview

The Subscription Overview section provides customers with visibility to their current subscription details - subscribed plan, purchased add-ons, granted promotional entitlements.

<img src="https://mintcdn.com/stigg/fP4soQQ7PxwZeQ0V/images/docs/ec4f76d-image.png?fit=max&auto=format&n=fP4soQQ7PxwZeQ0V&q=85&s=8f46587d5646d5f14ac4ec863a882e1f" alt="" width="1102" height="564" data-path="images/docs/ec4f76d-image.png" />

### Usage

The Usage section provides customers with visibility to the usage of their subscription's features.

<img src="https://mintcdn.com/stigg/tWlJkHU9GfoKBEmJ/images/docs/579dccc-image.png?fit=max&auto=format&n=tWlJkHU9GfoKBEmJ&q=85&s=88fef1cd0b55f4b1092c1eadc251a567" alt="" width="1102" height="639" data-path="images/docs/579dccc-image.png" />

### Plan picker

The Plan Picker section allows customers to upgrade and downgrade their subscription in a self-served manner.

When you update your pricing model in Stigg, customers will auto-magically be able to upgrade or downgrade their subscription according to the updated pricing model 😎.

Behind the scenes, this section leverages the [Stigg Pricing Table widget](./pricing-table).

<img src="https://mintcdn.com/stigg/cwvUR-sZ1iKIoz2m/images/docs/b2f1007-image.png?fit=max&auto=format&n=cwvUR-sZ1iKIoz2m&q=85&s=c93aaea40e703d62e05d178f8644c6f5" alt="" width="1102" height="821" data-path="images/docs/b2f1007-image.png" />

### Payment details

The Payment Details section allows customers to view their billing and payment information.

Customers that have a an active paid subscription can update their billing details (name, address) and payment method in the Stripe Billing Portal via link from the Stigg Customer Portal.

<img src="https://mintcdn.com/stigg/rbfzdbhZ6y5pB9n-/images/docs/a218189-image.png?fit=max&auto=format&n=rbfzdbhZ6y5pB9n-&q=85&s=1d6be930deaabed9ec329149c462d01f" alt="" width="1102" height="322" data-path="images/docs/a218189-image.png" />

<Warning>
  1. Stigg must be integrated with [Stripe](../../documentation/native-integrations/billing/stripe/integration-when-using-stripe-elements-for-checkout)
  2. To ensure that the functionality of Stigg's Customer Portal doesn't collide with Stripe's Billing Portal, ensure that [Stripe's Billing Portal is configured correctly](../../documentation/native-integrations/billing/stripe/integration-when-using-stripe-elements-for-checkout#integration-with-stripes-billing-portal).
</Warning>

### Invoices

Customers that have a an active paid subscription or had one in the past can view past invoices in the Stripe Billing Portal via a link from the Stigg Customer Portal.

<img src="https://mintcdn.com/stigg/zZAY_sXPTSVMcwio/images/docs/cad3eea-image.png?fit=max&auto=format&n=zZAY_sXPTSVMcwio&q=85&s=7940cfa17cec24d2836ee951022efa30" alt="" width="1102" height="171" data-path="images/docs/cad3eea-image.png" />

<Warning>
  Stigg must be integrated with [Stripe](../../documentation/native-integrations/billing/stripe/integration-when-using-stripe-elements-for-checkout) to allow customers to view past invoices.
</Warning>

<Note>
  Visibility for invoices directly in the Stigg Customer Portal is on our roadmap.
</Note>

<Warning>
  When integrating Stigg widgets into your application, it's highly recommended to [enable client-side security enforcement](/api-and-sdks/integration/frontend/hardening-client-side-access), especially in production environments.
</Warning>

## Rendering a customer portal

To render customer portals inside your application, when a customer signs-in or restores their session set the customer ID:

<CodeGroup>
  ```typescript React theme={null}
  import { StiggProvider } from '@stigg/react-sdk';

  export function App() {
    return (
      <StiggProvider apiKey="<STIGG_CLIENT_API_KEY>" customerId="<LOGGED_IN_CUSTOMER_ID>">
        <NestedComponents />
      </StiggProvider>
    );
  }
  ```

  ```typescript Vue.js theme={null}
  <script setup lang="ts">
  import { StiggProvider, StiggProviderProps } from '@stigg/vue-sdk';

  const stiggProvider: StiggProviderProps = {
    apiKey: "<STIGG_CLIENT_API_KEY>",
    customerId: "<LOGGED_IN_CUSTOMER_ID>",
  };

  </script>

  <template>
     <StiggProvider v-bind="stiggProvider">
        <NestedComponents />
     </StiggProvider>
  </template>
  ```
</CodeGroup>

Use the `CustomerPortal` component to render the customer portal.

The CustomerPortal component support [component composition](https://reactjs.org/docs/composition-vs-inheritance.html) so it's possible to pass as a parameter the Paywall component and it will be rendered inside the customer portal.

<CodeGroup>
  ```typescript React theme={null}
  <CustomerPortal
  	paywallComponent={<Paywall />}
  	theme={...}
  	textOverrides={...}
  />
  ```

  ```typescript Vue.js theme={null}
  <script setup lang="ts">
  import { CustomerPortal, CustomerPortalProps, Paywall, PaywallProps } from '@stigg/vue-sdk';

  const customerPortal: CustomerPortalProps = {
     onManageSubscription: () => {
       console.log('Manage subscription');
     }
  };

  const paywall: PaywallProps = {
    onPlanSelected: ({plan}) => {
      console.log(`Selected plan: ${plan.displayName}`);
    }
  };

  </script>

  <template>
    <CustomerPortal v-bind="customerPortal">
      <template v-slot:paywall-component>
        <Paywall v-bind="paywall" />
      </template>
    </CustomerPortal>
  </template>
  ```
</CodeGroup>

<Note>
  Learn more on how to [refresh Stigg cache](../../api-and-sdks/integration/frontend/react#refreshing-the-cache) after performing an operation that modifies the customer to immediately reflect the customer changes on the customer portal
</Note>

## Widget modularity

The `CustomerPortal` component is just an opinionated way to render the customer portal in a specific layout which is based on our experience after reviewing many customer portals, but if you need more flexibility in how the customer portal is rendered, you can integrate directly each of its sections separately.

To do so, wrap all the section components with `CustomerPortalProvider` which will pass the necessary data to each component:

<CodeGroup>
  ```javascript React theme={null}
  import { 
    CustomerPortalProvider,
    CustomerUsageData,
    PaymentDetailsSection,
    /* more components that can be used as standalone
    SubscriptionsOverview,
    AddonsList,
    Promotions,
    InvoicesSection
    */
  } from '@stigg/react-sdk"

  function App() {
   	return (
  		<CustomerPortalProvider theme={...} textOverrides={...}>
  			<CustomerUsageData />
  			<PaymentDetailsSection />
  		</CustomerPortalProvider>    
    )
  }
  ```
</CodeGroup>

## Subscriptions with a custom price

Customers that are subscribed to a subscription with a custom price can't upgrade on downgrade their subscription in a self-served manner using the customer portal widget. Instead, you can handle the `onContactSupport` method to allow customers contact a sales or customer success representative that can do so on their behalf.

<img src="https://mintcdn.com/stigg/rbfzdbhZ6y5pB9n-/images/docs/9cabf08-Frame_18882_1.png?fit=max&auto=format&n=rbfzdbhZ6y5pB9n-&q=85&s=f642f3055c2fba10547a58ca91ffedf6" alt="" width="1102" height="1824" data-path="images/docs/9cabf08-Frame_18882_1.png" />

## Customization

### No-code widget designer

The Stigg app offers a no-code widget designer, which allows you to control the widget colors, typography and layout.

<img src="https://mintcdn.com/stigg/UlAt5XRaB6FPzp-f/images/docs/0952528-Screenshot_2023-09-12_at_1.33.06.png?fit=max&auto=format&n=UlAt5XRaB6FPzp-f&q=85&s=6872d55c127d8b87a415afd1593d586b" alt="" width="3828" height="1756" data-path="images/docs/0952528-Screenshot_2023-09-12_at_1.33.06.png" />

### Custom CSS

For more advanced customization, custom CSS can be applied using the widget designer of the Stigg app. Alternatively, custom CSS can also be applied using code.

Below you can find a list of the supported CSS classes:

| Class name                                | Description                                                           |
| ----------------------------------------- | --------------------------------------------------------------------- |
| stigg-payment-details-section-layout      | Styles applied to billing information title                           |
| stigg-payment-details-section-header      | Styles applied to payment details title layout                        |
| stigg-payment-details-section-title       | Styles applied to payment details title                               |
| stigg-customer-name                       | Styles applied to payment details customer name                       |
| stigg-customer-email                      | Styles applied to payment details customer email                      |
| stigg-credit-card                         | Styles applied to payment details credit card                         |
| stigg-credit-card-expiration              | Styles applied to payment details credit card expiration date         |
| stigg-invoices-section-layout             | Styles applied to invoice section layout                              |
| stigg-invoices-section-header             | Styles applied to invoice section title layout                        |
| stigg-invoices-section-title              | Styles applied to invoice section title                               |
| stigg-view-invoice-history-button         | Styles applied to invoice history button                              |
| stigg-edit-payment-details-button         | Styles applied to update payment details button                       |
| stigg-user-information-layout             | Styles applied to user information                                    |
| stigg-customer-portal-usage-section-title | Styles applied to the Usage section title                             |
| stigg-entitlement-usage-`{featureID}`     | Styles applied to the feature usage according to their unique ID      |
| stigg-`{plan.id}`                         | Styles applied to the plan container by its plan ID                   |
| stigg-compatible-addon-`{addon.id}`       | Styles applied to a specific add-on row by its add-on ID              |
| stigg-entitlement-feature-`{feature.id}`  | Styles applied to a specific entitlement row by the feature ID (slug) |

<Note>
  `{feature.id}` is the feature’s slug (lowercase; spaces and special characters become `-`).\
  This class is added **in addition to** `stigg-entitlement-row-container`, so you can safely target one entitlement without affecting others.\
  Mirrors the existing patterns: `stigg-{plan.id}` (plan) and `stigg-compatible-addon-{addon.id}` (add-on).
</Note>

In addition, since the Plans section of the customer portal can include the Stigg pricing table widget you can leverage [its CSS classes](../snap-in-widgets/pricing-table#custom-css) to customize its styling.

### Texts

The default widget texts can currently be overridden using code:

<CodeGroup>
  ```javascript React theme={null}
  const textOverrides = {  
  	manageSubscription: 'Manage',
  	usageTabTitle: 'Usage',
  	addonsTabTitle: 'Add-ons',
  	promotionsTabTitle: 'Promotions',
  	promotionsSubtitle: 'You were granted access to additional functionality at no additional cost.',
    contactSupportTitle: 'Have questions about your subscription?',
    contactSupportLink: 'Contact support',
    editBilling: 'Edit billing details',
    invoicesTitle: 'Invoices',
    viewInvoiceHistory: 'View invoice history',
    editPaymentDetails: 'Edit',
    paywallSectionTitle: 'Plans',
    cancelScheduledUpdatesButtonTitle: 'Cancel update',
  }

  <CustomerPortal
      textOverrides={textOverrides}
      paywallComponent={<Paywall />}
  />
  ```

  ```typescript Vue.js theme={null}
  <script setup lang="ts">
  import { CustomerPortal, CustomerPortalProps, Paywall, PaywallProps } from '@stigg/vue-sdk';

  const textOverrides = {
    manageSubscription: 'Manage',
    usageTabTitle: 'Usage',
    addonsTabTitle: 'Add-ons',
    promotionsTabTitle: 'Promotions',
    promotionsSubtitle: 'You were granted access to additional functionality at no additional cost.',
    contactSupportTitle: 'Have questions about your subscription?',
    contactSupportLink: 'Contact support',
    editBilling: 'Edit billing details',
    invoicesTitle: 'Invoices',
    viewInvoiceHistory: 'View invoice history',
    editPaymentDetails: 'Edit',
    paywallSectionTitle: 'Plans',
    cancelScheduledUpdatesButtonTitle: 'Cancel update',
  }

  const customerPortal: CustomerPortalProps = {
     textOverrides,
     onManageSubscription: () => {
       console.log('Manage subscription');
     }
  };

  const paywall: PaywallProps = {
    onPlanSelected: ({plan}) => {
      console.log(`Selected plan: ${plan.displayName}`);
    }
  };

  </script>

  <template>
    <CustomerPortal v-bind="customerPortal">
      <template v-slot:paywall-component>
        <Paywall v-bind="paywall" />
      </template>
    </CustomerPortal>
  </template>
  ```
</CodeGroup>

<Note>
  You can find more text overrides options [here](https://react-sdk-docs.stigg.io/types/customerportalprops)
</Note>

## Additional resources

<Card title="Customer Portal Properties" icon="sliders" href="https://react-sdk-docs.stigg.io/types/customerportalprops" horizontal />

<Card title="Global Theming Customization" icon="palette" href="https://docs.stigg.io/docs/react-sdk#global-theming" horizontal />

## Related SDKs

<CardGroup cols={2}>
  <Card title="" href="/api-and-sdks/integration/frontend/react" horizontal>
    <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
      <img src="https://mintcdn.com/stigg/FZ_ywutvYHnQbKpn/images/react.svg?fit=max&auto=format&n=FZ_ywutvYHnQbKpn&q=85&s=75e8661a7d87b8e2b3493d7fdfb33db9" alt="React" style={{ width: '32px' }} width="23" height="20" data-path="images/react.svg" />

      <span>React</span>
    </div>
  </Card>

  <Card title="" href="/api-and-sdks/integration/frontend/vuejs" horizontal>
    <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
      <img src="https://mintcdn.com/stigg/qpsRT7dNo0hXTxnb/images/vue.svg?fit=max&auto=format&n=qpsRT7dNo0hXTxnb&q=85&s=c861442fd84f9822a716d778b10a8dba" alt="Vue.js" style={{ width: '32px' }} width="800" height="800" data-path="images/vue.svg" />

      <span>Vue.js</span>
    </div>
  </Card>

  <Card title="" href="/api-and-sdks/integration/frontend/nextjs" horizontal>
    <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
      <img src="https://mintcdn.com/stigg/FZ_ywutvYHnQbKpn/images/next.svg?fit=max&auto=format&n=FZ_ywutvYHnQbKpn&q=85&s=7fea95b3e8f678015cb8b8d58d1e7886" alt="Next.js" style={{ width: '32px' }} width="16" height="16" data-path="images/next.svg" />

      <span>Next.js</span>
    </div>
  </Card>

  <Card title="" href="/api-and-sdks/integration/frontend/html" horizontal>
    <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
      <img src="https://mintcdn.com/stigg/aJeGPh9dwMpK_Kcr/images/html.svg?fit=max&auto=format&n=aJeGPh9dwMpK_Kcr&q=85&s=ae948dc9e5ca66cf75892b94859954a0" alt="Webflow, Wordpress, HTML" style={{ width: '32px' }} width="800" height="800" data-path="images/html.svg" />

      <span>Webflow, Wordpress, HTML</span>
    </div>
  </Card>
</CardGroup>
