PricingTable
The PricingTable component is a flexible UI element designed to display subscription plans and pricing options in a structured, user-friendly table. It allows users to browse different plans, switch between billing cycles (e.g., monthly, yearly), select a currency, and proceed to checkout by selecting a plan.
This component is intended to be used within the context of a PaymentProvider, as it relies on the provider for payment settings and currency information. For more details, refer to the PaymentProvider documentation.
Props#
The PricingTable component accepts the following props to customize its behavior and appearance:
Prop | Type | Required | Default | Description |
|---|---|---|---|---|
|
| Yes | - | An object containing the pricing table data, including a list of items (plans) to display. |
|
| Yes | - | A callback function that is invoked when a user clicks the action button for a plan. |
|
| No |
| Controls the horizontal alignment of the pricing plans and controls. |
|
| No |
| Determines the behavior and text of the action button. |
|
| No |
| The initially selected billing interval (e.g., 'month-1', 'year-1'). If empty, the first available interval is used. |
|
| No |
| If |
Usage Scenarios#
Basic Checkout Table#
This is the default mode. The component displays plans with a subscription button. When a user clicks the button, the onSelect callback is triggered, which you can use to initiate a checkout session.
import PricingTable from '@blocklet/payment-react/lib/components/pricing-table';
// Assume 'myPricingTableData' is fetched from your backend and conforms to TPricingTableExpanded
// Assume 'handleSubscription' is your function to process the checkout
function MyPricingPage() {
const handleSubscription = async (priceId, currencyId) => {
console.log(`Starting subscription for price: ${priceId} with currency: ${currencyId}`);
// Add your logic to create a checkout session and redirect the user
};
return (
<PricingTable
table={myPricingTableData}
onSelect={handleSubscription}
/>
);
}Plan Selection Mode#
By setting mode='select', the component can be used as part of a larger form where the user selects a plan before proceeding. The action button text changes to "Select" or "Selected", and selected items are highlighted.
In this mode, you might manage the selected plan in your parent component's state.
import React, { useState } from 'react';
import PricingTable from '@blocklet/payment-react/lib/components/pricing-table';
function PlanSelectionForm() {
const [selectedPriceId, setSelectedPriceId] = useState(null);
const handlePlanSelect = (priceId, currencyId) => {
setSelectedPriceId(priceId);
console.log(`User selected price: ${priceId}`);
};
// Add is_selected property to the items based on the current state
const tableDataWithSelection = {
...myPricingTableData,
items: myPricingTableData.items.map(item => ({
...item,
is_selected: item.price_id === selectedPriceId,
})),
};
return (
<div>
<h2>Choose Your Plan</h2>
<PricingTable
table={tableDataWithSelection}
onSelect={handlePlanSelect}
mode="select"
alignItems="left"
/>
<button disabled={!selectedPriceId}>Continue</button>
</div>
);
}Data Structure for table prop#
The table prop expects an object with a specific structure, TPricingTableExpanded. Here's a simplified overview of what it contains:
id: A unique identifier for the pricing table.livemode: A boolean indicating if the table is in live or test mode.currency: A default currency object.items: An array ofTPricingTableItemobjects. Each item represents a single plan and contains:price_id: The unique ID for the price.product: An object with product details likename,description, and an array offeatures.price: An object with pricing details, includingunit_amount,currency_options, and arecurringobject that specifies the billinginterval(e.g., 'month', 'year') andinterval_count.is_highlight(optional): A boolean to highlight a specific plan.highlight_text(optional): Text to display in the highlight chip (e.g., "Most Popular").
Example table Object#
{
"id": "pt_12345",
"livemode": true,
"currency": { "id": "usd", "symbol": "$" },
"items": [
{
"price_id": "price_basic_monthly",
"product": {
"name": "Basic Plan",
"description": "For individuals and small teams.",
"features": [
{ "name": "5 Projects" },
{ "name": "Basic Analytics" },
{ "name": "24/7 Support" }
],
"unit_label": "user"
},
"price": {
"unit_amount": "1000", // in cents
"currency_options": [{ "currency_id": "usd", "unit_amount": "1000" }],
"recurring": { "interval": "month", "interval_count": 1 }
},
"is_highlight": false
},
{
"price_id": "price_pro_monthly",
"product": {
"name": "Pro Plan",
"description": "For growing businesses.",
"features": [
{ "name": "Unlimited Projects" },
{ "name": "Advanced Analytics" },
{ "name": "Priority Support" }
],
"unit_label": "user"
},
"price": {
"unit_amount": "2500",
"currency_options": [{ "currency_id": "usd", "unit_amount": "2500" }],
"recurring": { "interval": "month", "interval_count": 1 }
},
"is_highlight": true,
"highlight_text": "Popular"
}
]
}This component streamlines the creation of dynamic and interactive pricing pages. Once the user selects a plan, you can use the onSelect callback to guide them to the next step, which is often displaying a PaymentSummary.