Starter Tier: Add plans and Mix tasks (#5392)

* fix sandbox plans v4 to be in sync with prod ones

* sync sandbox plans + unify formatting

* create v5 plans in paddle prod + sandbox + Mix.tasks

* add teams and shared links features

* remove unused line of code

* paddle credentials as module attrs

* remove teams and shared links as growth benefits for time being
This commit is contained in:
RobertJoonas 2025-05-15 11:02:43 +01:00 committed by GitHub
parent b64c3a20ce
commit 18907aef63
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 2615 additions and 904 deletions

View File

@ -0,0 +1,342 @@
defmodule Mix.Tasks.CreatePaddleProdPlans do
@moduledoc """
## Utility for creating Paddle plans for production use.
Takes a single `filename` argument which should be of format
`input_plans_v*.json`. That file should live in the `/priv` directory next
to all other plans and it should contain the necessary information about
the production plans to be created.
In order to create the input file:
* Copy an existing `plans_v*.json` (latest recommended) into the new
`input_plans_v*.json` file.
* For every plan object:
* Adjust the generation, limits, features, etc as desired
* Replace `monthly_product_id` with a `monthly_price` (integer)
* Replace `yearly_product_id` with a `yearly_price` (integer)
After this task is finished successfully, the plans will be created in Paddle
with the prices given in the input file. With the creation, every plan gets an
autoincremented ID in Paddle. We will then fetch those exact plans from Paddle
in an API call and use their monthly and yearly product_id's to write
`plans_v*.json`. It will be written taking the input file as the "template"
and replacing the monthly/yearly prices with monthly/yearly product_id's.
The prices will be written into `/priv/plan_prices.json` (instead of the
prod plans output file). Note that this separation is intentional - we only
store prices locally to not rely on Paddle in the dev environment. Otherwise,
Paddle is considered the "source of truth" of plan prices.
## Usage example:
```
mix create_paddle_prod_plans input_plans_v5.json
```
## Requirement 1: Replace the curl command
Unfortunately, there's no API in Paddle that would allow "bulk creating"
plans - it has to be done through the UI. As a hack though, we can automate
the process by copying the curl request with the help of browser devtools.
Therefore, this Mix.Task **does not work out of the box** and the actual curl
command that it executes must be replaced by the developer. Here's how:
0) Access required to the production Paddle account
1) Navigate to https://vendors.paddle.com/subscriptions/plans. Chrome or
Firefox recommended (need to copy a POST request as cURL in a later step)
2) Click the "+ New Plan" button (top right of the screen) to open the form
3) Open browser devtools, fill in the required fields and submit the form.
No need to worry about the form fields since they're provided in this task
(except `_token`) and they *should work* as long as nothing has changed.
4) Find the POST request from the "Network" tab and copy it as cURL
5) Come back here and paste it into the `create_paddle_plan` function
6) Replace the params within the string with the real params (these should
be available in the function already)
## Requirement 2: Paddle production credentials
You also need to obtain the Paddle credentials from prod environment and
replace them into the module attributes. See `@paddle_vendor_id` and
`@paddle_vendor_auth_code`. Those are needed to fetch the plans via an
actual API call after the plans have been created in Paddle.
"""
use Mix.Task
@requirements ["app.config"]
@paddle_vendor_id "REPLACE ME"
@paddle_vendor_auth_code "REPLACE ME"
def run([filename]) do
{:ok, _} = Application.ensure_all_started(:telemetry)
Finch.start_link(name: MyFinch)
if not Regex.match?(~r/^input_plans_v(\d+)\.json$/, filename) do
raise ArgumentError,
"Invalid filename argument. Note the strict format - e.g.: \"input_plans_v5.json\""
end
input_plans =
Application.app_dir(:plausible, ["priv", filename])
|> File.read!()
|> JSON.decode!()
to_be_created_in_paddle =
input_plans
|> Enum.flat_map(fn plan ->
[
create_paddle_plan_attrs(plan, "monthly"),
create_paddle_plan_attrs(plan, "yearly")
]
end)
user_input =
"""
\n
##########################################################################
# #
# !WARNING! #
# #
# You're about to create production plans in Paddle. Multiple #
# consecutive executions will create the same plans again. #
# Please make sure to not leave duplicates behind! #
# #
##########################################################################
* 'y' - proceed and create all plans
* 't' - test only with two plans
* 'h' - halt
What would you like to do?
"""
|> IO.gets()
|> String.trim()
|> String.upcase()
test_run? =
case user_input do
"Y" ->
IO.puts("Creating all plans...")
false
"T" ->
IO.puts("Creating 2 plans just for testing. Make sure to delete them manually!")
true
_ ->
IO.puts("Halting execution per user request.")
System.halt()
end
{paddle_create_count, create_count} =
if test_run? do
{2, 1}
else
{length(to_be_created_in_paddle), length(input_plans)}
end
to_be_created_in_paddle
|> Enum.take(paddle_create_count)
|> Enum.each(&create_paddle_plan/1)
IO.puts("⏳ waiting 3s before fetching the newly created plans...")
Process.sleep(3000)
IO.puts("Fetching the #{create_count} plans created a moment ago...")
created_paddle_plans =
fetch_all_prod_plans()
|> Enum.sort_by(& &1["id"])
|> Enum.take(-paddle_create_count)
file_path_to_write = Path.join("priv", String.replace(filename, "input_", ""))
prod_plans_with_ids_and_prices =
input_plans
|> Enum.take(create_count)
|> write_prod_plans_json_file(file_path_to_write, created_paddle_plans)
IO.puts("✅ Wrote #{create_count} new plans into #{file_path_to_write}!")
if not test_run? do
write_prices(prod_plans_with_ids_and_prices)
IO.puts("✅ Updated `plan_prices.json`.")
end
IO.puts("✅ All done!")
end
defp create_paddle_plan(%{name: name, price: price, type: type, interval_index: interval_index}) do
your_unique_token = "abc"
# Replace this curl command. You should be able to reuse
# the request body after replacing your unique token.
curl_command = """
... REPLACE ME
--data-raw '_token=#{your_unique_token}&plan-id=&default-curr=USD&tmpicon=false&name=#{name}&checkout_custom_message=&taxable_type=standard&interval=#{interval_index}&period=1&type=#{type}&trial_length=&price_USD=#{price}&active_EUR=on&price_EUR=#{price}&active_GBP=on&price_GBP=#{price}'
"""
case curl_quietly(curl_command) do
:ok ->
IO.puts("✅ Created #{name}")
{:error, reason} ->
IO.puts("❌ Halting. The plan #{name} could not be created. Error: #{reason}")
System.halt(1)
end
end
@paddle_interval_indexes %{"monthly" => 2, "yearly" => 5}
defp create_paddle_plan_attrs(plan_with_price, type) do
%{
name: plan_name(plan_with_price, type),
price: plan_with_price["#{type}_price"],
type: type,
interval_index: @paddle_interval_indexes[type]
}
end
defp fetch_all_prod_plans() do
"https://vendors.paddle.com/api/2.0/subscription/plans"
|> fetch_all_paddle_plans(%{
vendor_id: @paddle_vendor_id,
vendor_auth_code: @paddle_vendor_auth_code
})
end
@paddle_plans_api_pagination_limit 500
def fetch_all_paddle_plans(url, paddle_credentials, page \\ 0, fetched \\ 0) do
body =
paddle_credentials
|> Map.merge(%{
limit: @paddle_plans_api_pagination_limit,
offset: page * @paddle_plans_api_pagination_limit
})
|> JSON.encode!()
headers = [
{"Content-type", "application/json"},
{"Accept", "application/json"}
]
request = Finch.build(:post, url, headers, body)
with {:ok, response} <- Finch.request(request, MyFinch),
{:ok, %{"success" => true, "response" => plans} = body} <- JSON.decode(response.body) do
fetched = body["count"] + fetched
total = body["total"]
IO.puts("✅ Successfully fetched #{fetched}/#{body["total"]} plans")
if fetched == total do
plans
else
plans ++ fetch_all_paddle_plans(url, paddle_credentials, page + 1, fetched)
end
else
error ->
IO.puts("❌ Failed to fetch plans from Paddle - #{inspect(error)}")
System.halt(1)
end
end
defp write_prod_plans_json_file(input_plans, filepath, paddle_plans) do
prod_plans_with_prices =
input_plans
|> Enum.map(fn input_plan ->
monthly_plan_name = plan_name(input_plan, "monthly")
yearly_plan_name = plan_name(input_plan, "yearly")
%{"id" => monthly_product_id} =
Enum.find(paddle_plans, &(&1["name"] == monthly_plan_name))
%{"id" => yearly_product_id} =
Enum.find(paddle_plans, &(&1["name"] == yearly_plan_name))
input_plan
|> Map.merge(%{
"monthly_product_id" => to_string(monthly_product_id),
"yearly_product_id" => to_string(yearly_product_id)
})
end)
content =
prod_plans_with_prices
|> Enum.map(fn plan ->
plan
|> Map.drop(["monthly_price", "yearly_price"])
|> order_keys()
end)
|> Jason.encode!(pretty: true)
File.write!(filepath, content)
prod_plans_with_prices
end
@plan_prices_filepath Application.app_dir(:plausible, ["priv", "plan_prices.json"])
defp write_prices(prod_plans_with_ids_and_prices) do
current_prices = File.read!(@plan_prices_filepath) |> JSON.decode!()
new_prices =
prod_plans_with_ids_and_prices
|> Enum.reduce(current_prices, fn plan, prices ->
prices
|> Map.put_new(plan["monthly_product_id"], plan["monthly_price"])
|> Map.put_new(plan["yearly_product_id"], plan["yearly_price"])
end)
|> Enum.sort()
|> Jason.OrderedObject.new()
|> Jason.encode!(pretty: true)
File.write(@plan_prices_filepath, new_prices)
end
@plan_key_order [
"kind",
"generation",
"monthly_pageview_limit",
"monthly_product_id",
"yearly_product_id",
"site_limit",
"team_member_limit",
"features"
]
def order_keys(plan) do
plan
|> Map.to_list()
|> Enum.sort_by(fn {key, _value} ->
Enum.find_index(@plan_key_order, fn ordered_key -> ordered_key == key end) || 99
end)
|> Jason.OrderedObject.new()
end
defp plan_name(plan, type) do
kind = plan["kind"] |> String.capitalize()
type = type |> String.capitalize()
volume =
plan["monthly_pageview_limit"]
|> PlausibleWeb.StatsView.large_number_format(capitalize_k?: true)
"Plausible #{kind} #{type} Plan (#{volume})"
end
def curl_quietly(cmd) do
cmd = String.replace(cmd, "curl", ~s|curl -s -o /dev/null -w "%{http_code}"|)
case System.cmd("sh", ["-c", cmd], stderr_to_stdout: true) do
{"302", 0} ->
:ok
{http_status, 0} ->
{:error, "unexpected HTTP response status (#{http_status}). Expected 302."}
{_, exit_code} ->
{:error, "curl command exited with exit code #{exit_code}"}
end
end
end

View File

@ -1,31 +1,35 @@
defmodule Mix.Tasks.CreatePaddleSandboxPlans do
@moduledoc """
Utility for creating Sandbox plans that are used on staging. The `filename`
argument should be the name of the JSON file containing the production plans.
E.g.: `plans_v4.json`.
Utility for creating Sandbox plans that are used on staging. The product of
this task is a `sandbox_plans_v*.json` file matching with the production
plans, just with the monthly/yearly product_id's of the sandbox plans.
Unfortunately, there's no API in Paddle that would allow "bulk creating"
plans - it has to be done through the UI. As a hack though, we can automate
the process by copying the curl request with the help of browser devtools.
In principle, this task works like `Mix.Tasks.CreatePaddleProdPlans`, with
the following differences:
Therefore, this Mix.Task **does not work out of the box** and the actual curl
command that it executes must be replaced by the developer. Here's how:
* The `filename` argument should be the name of the JSON file containing the
production plans (meaning that those should be created as the first step).
No special "input file" required.
0) Obtain access to the Sandbox Paddle account and log in
1) Navigate to https://sandbox-vendors.paddle.com/subscriptions/plans
2) Click the "+ New Plan" button to open the form
3) Open browser devtools, fill in the required fields and submit the form
4) Find the POST request from the "Network" tab and copy it as cURL
5) Come back here and paste it into the `create_paddle_plan` function
6) Replace the params within the string with the real params (these should
be available in the function already)
* To copy the curl command from the browser, you need to add a plan from
https://sandbox-vendors.paddle.com/subscriptions/plans. Everything else is
the same - please see `create_paddle_prod_plans.ex` for instructions.
Once the plans are created successfully, the task will also fetch the IDs
(i.e. paddle_plan_id's) and write the `sandbox_plans_v*.json` file (which is
basically the same set of production plans but with `monthly_product_id` and
`yearly_product_id` replaced with the sandbox ones).
* This task can be executed multiple times in a row - it will not create
duplicates in Sandbox Paddle. On staging we can use a specific plan-naming
structure to determine whether a plan has been created already. On prod we
cannot do that since the plan names need to look nice.
* No need to copy paddle API credentials.
## Usage example:
```
mix create_paddle_sandbox_plans plans_v5.json
```
"""
alias Mix.Tasks.CreatePaddleProdPlans
use Mix.Task
@requirements ["app.config"]
@ -76,7 +80,7 @@ defmodule Mix.Tasks.CreatePaddleSandboxPlans do
file_path_to_write = Path.join("priv", "sandbox_" <> filename)
create_local_sandbox_plans_json_file(prod_plans, file_path_to_write, paddle_plans_after)
write_sandbox_plans_json_file(prod_plans, file_path_to_write, paddle_plans_after)
IO.puts("✅ All done! Wrote #{length(prod_plans)} new plans into #{file_path_to_write}!")
end
@ -91,7 +95,7 @@ defmodule Mix.Tasks.CreatePaddleSandboxPlans do
--data-raw '_token=#{your_unique_token}&plan-id=&default-curr=USD&tmpicon=false&name=#{name}&checkout_custom_message=&taxable_type=standard&interval=#{interval_index}&period=1&type=#{type}&trial_length=&price_USD=#{price}&active_EUR=on&price_EUR=#{price}&active_GBP=on&price_GBP=#{price}'
"""
case curl_quietly(curl_command) do
case CreatePaddleProdPlans.curl_quietly(curl_command) do
:ok ->
IO.puts("✅ Created #{name}")
@ -101,6 +105,19 @@ defmodule Mix.Tasks.CreatePaddleSandboxPlans do
end
end
defp fetch_all_sandbox_plans() do
url = "https://sandbox-vendors.paddle.com/api/2.0/subscription/plans"
paddle_config = Application.get_env(:plausible, :paddle)
paddle_credentials = %{
vendor_id: paddle_config[:vendor_id],
vendor_auth_code: paddle_config[:vendor_auth_code]
}
CreatePaddleProdPlans.fetch_all_paddle_plans(url, paddle_credentials)
end
@paddle_interval_indexes %{"monthly" => 2, "yearly" => 5}
defp create_paddle_plan_attrs(plan_with_price, type) do
@ -112,36 +129,15 @@ defmodule Mix.Tasks.CreatePaddleSandboxPlans do
}
end
defp fetch_all_sandbox_plans() do
paddle_config = Application.get_env(:plausible, :paddle)
defp plan_name(plan, type) do
generation = "v#{plan["generation"]}"
kind = plan["kind"]
volume = plan["monthly_pageview_limit"] |> PlausibleWeb.StatsView.large_number_format()
url = "https://sandbox-vendors.paddle.com/api/2.0/subscription/plans"
body =
JSON.encode!(%{
vendor_id: paddle_config[:vendor_id],
vendor_auth_code: paddle_config[:vendor_auth_code]
})
headers = [
{"Content-type", "application/json"},
{"Accept", "application/json"}
]
request = Finch.build(:post, url, headers, body)
with {:ok, response} <- Finch.request(request, MyFinch),
{:ok, %{"success" => true, "response" => plans} = body} <- JSON.decode(response.body) do
IO.puts("✅ Successfully fetched #{body["count"]}/#{body["total"]} sandbox plans")
plans
else
error ->
IO.puts("❌ Failed to fetch plans from Paddle - #{inspect(error)}")
System.halt(1)
end
[generation, type, kind, volume] |> Enum.join("_")
end
defp create_local_sandbox_plans_json_file(prod_plans, filepath, paddle_plans) do
defp write_sandbox_plans_json_file(prod_plans, filepath, paddle_plans) do
sandbox_plans =
prod_plans
|> Enum.map(fn prod_plan ->
@ -158,9 +154,11 @@ defmodule Mix.Tasks.CreatePaddleSandboxPlans do
"monthly_product_id" => to_string(sandbox_monthly_product_id),
"yearly_product_id" => to_string(sandbox_yearly_product_id)
})
|> CreatePaddleProdPlans.order_keys()
end)
File.write!(filepath, JSON.encode!(sandbox_plans))
content = Jason.encode!(sandbox_plans, pretty: true)
File.write!(filepath, content)
end
defp put_prices(plans) do
@ -177,27 +175,4 @@ defmodule Mix.Tasks.CreatePaddleSandboxPlans do
})
end)
end
defp plan_name(plan, type) do
generation = "v#{plan["generation"]}"
kind = plan["kind"]
volume = plan["monthly_pageview_limit"] |> PlausibleWeb.StatsView.large_number_format()
[generation, type, kind, volume] |> Enum.join("_")
end
defp curl_quietly(cmd) do
cmd = String.replace(cmd, "curl", ~s|curl -s -o /dev/null -w "%{http_code}"|)
case System.cmd("sh", ["-c", cmd], stderr_to_stdout: true) do
{"302", 0} ->
:ok
{http_status, 0} ->
{:error, "unexpected HTTP response status (#{http_status}). Expected 302."}
{_, exit_code} ->
{:error, "curl command exited with exit code #{exit_code}"}
end
end
end

View File

@ -72,6 +72,8 @@ defmodule Plausible.Billing.Feature do
@features [
Plausible.Billing.Feature.Props,
Plausible.Billing.Feature.Teams,
Plausible.Billing.Feature.SharedLinks,
Plausible.Billing.Feature.Funnels,
Plausible.Billing.Feature.Goals,
Plausible.Billing.Feature.RevenueGoals,
@ -198,6 +200,20 @@ defmodule Plausible.Billing.Feature.Props do
toggle_field: :props_enabled
end
defmodule Plausible.Billing.Feature.Teams do
@moduledoc false
use Plausible.Billing.Feature,
name: :teams,
display_name: "Team Accounts"
end
defmodule Plausible.Billing.Feature.SharedLinks do
@moduledoc false
use Plausible.Billing.Feature,
name: :shared_links,
display_name: "Shared Links"
end
defmodule Plausible.Billing.Feature.SiteSegments do
@moduledoc false
use Plausible.Billing.Feature,

View File

@ -114,6 +114,8 @@ defmodule PlausibleWeb.Components.Billing.PlanBenefits do
Enum.flat_map(plan.features, fn feature_mod ->
case feature_mod.name() do
:goals -> ["Goals and custom events"]
:teams -> []
:shared_links -> []
:stats_api -> ["Stats API (600 requests per hour)", "Looker Studio Connector"]
:revenue_goals -> ["Ecommerce revenue attribution"]
_ -> [feature_mod.display_name()]

View File

@ -34,7 +34,9 @@ defmodule PlausibleWeb.Plugins.API.Schemas.Capabilities do
RevenueGoals: false,
StatsAPI: false,
SitesAPI: false,
SiteSegments: false
SiteSegments: false,
Teams: false,
SharedLinks: false
}
}
})

View File

@ -6,15 +6,17 @@ defmodule PlausibleWeb.StatsView do
PlausibleWeb.Endpoint.url()
end
def large_number_format(n) do
def large_number_format(n, opts \\ []) do
k = if Keyword.get(opts, :capitalize_k?, false), do: "K", else: "k"
cond do
n >= 1_000 && n < 1_000_000 ->
thousands = trunc(n / 100) / 10
if thousands == trunc(thousands) || n >= 100_000 do
"#{trunc(thousands)}k"
"#{trunc(thousands)}" <> k
else
"#{thousands}k"
"#{thousands}" <> k
end
n >= 1_000_000 && n < 1_000_000_000 ->

View File

@ -1,33 +1,31 @@
{
"558746": 36,
"590753": 288,
"648089": 4800,
"558018": 6,
"572810": 48,
"558745": 12,
"558746": 36,
"572810": 48,
"590752": 96,
"590753": 288,
"597309": 69,
"597310": 552,
"597311": 99,
"597312": 792,
"597485": 18,
"597486": 144,
"597487": 27,
"597488": 216,
"597642": 48,
"597643": 384,
"597309": 69,
"597310": 552,
"597311": 99,
"597312": 792,
"642352": 150,
"642354": 1200,
"642355": 225,
"642356": 1800,
"648089": 4800,
"650652": 330,
"650653": 2640,
"654177": 6,
"653232": 60,
"654178": 12,
"653234": 120,
"653237": 20,
"653236": 200,
"653237": 20,
"653238": 30,
"653239": 300,
"653240": 50,
@ -36,12 +34,14 @@
"653254": 700,
"653255": 100,
"653256": 1000,
"654181": 150,
"653257": 1500,
"654182": 225,
"653258": 2250,
"654183": 330,
"653259": 3300,
"654177": 6,
"654178": 12,
"654181": 150,
"654182": 225,
"654183": 330,
"749342": 9,
"749343": 90,
"749344": 19,
@ -58,6 +58,38 @@
"749357": 1290,
"749358": 169,
"749359": 1690,
"857079": 90,
"857080": 190,
"857081": 290,
"857082": 490,
"857083": 690,
"857084": 890,
"857085": 1290,
"857086": 1690,
"857087": 190,
"857088": 390,
"857089": 590,
"857090": 990,
"857091": 1390,
"857092": 1790,
"857093": 2590,
"857094": 3390,
"857097": 9,
"857098": 19,
"857099": 29,
"857100": 49,
"857101": 69,
"857102": 89,
"857103": 129,
"857104": 169,
"857105": 19,
"857106": 39,
"857107": 59,
"857108": 99,
"857109": 139,
"857110": 179,
"857111": 259,
"857112": 339,
"857481": 19,
"857482": 190,
"857483": 39,
@ -74,36 +106,52 @@
"857500": 2590,
"857501": 339,
"857502": 3390,
"857097": 9,
"857079": 90,
"857098": 19,
"857080": 190,
"857099": 29,
"857081": 290,
"857100": 49,
"857082": 490,
"857101": 69,
"857083": 690,
"857102": 89,
"857084": 890,
"857103": 129,
"857085": 1290,
"857104": 169,
"857086": 1690,
"857105": 19,
"857087": 190,
"857106": 39,
"857088": 390,
"857107": 59,
"857089": 590,
"857108": 99,
"857090": 990,
"857109": 139,
"857091": 1390,
"857110": 179,
"857092": 1790,
"857111": 259,
"857093": 2590,
"857112": 339,
"857094": 3390
"910413": 9,
"910414": 90,
"910415": 19,
"910416": 190,
"910417": 29,
"910418": 290,
"910419": 49,
"910420": 490,
"910421": 69,
"910422": 690,
"910423": 89,
"910424": 890,
"910425": 129,
"910426": 1290,
"910427": 169,
"910428": 1690,
"910429": 14,
"910430": 140,
"910431": 29,
"910432": 290,
"910433": 44,
"910434": 440,
"910435": 74,
"910436": 740,
"910437": 104,
"910438": 1040,
"910439": 134,
"910440": 1340,
"910441": 194,
"910442": 1940,
"910443": 254,
"910444": 2540,
"910445": 19,
"910446": 190,
"910447": 39,
"910448": 390,
"910449": 59,
"910450": 590,
"910451": 99,
"910452": 990,
"910453": 139,
"910454": 1390,
"910455": 179,
"910456": 1790,
"910457": 259,
"910458": 2590,
"910459": 339,
"910460": 3390
}

View File

@ -1,102 +1,162 @@
[
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":10000,
"monthly_product_id":"558018",
"yearly_product_id":"572810",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 10000,
"monthly_product_id": "558018",
"yearly_product_id": "572810",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":100000,
"monthly_product_id":"558745",
"yearly_product_id":"590752",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 100000,
"monthly_product_id": "558745",
"yearly_product_id": "590752",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":200000,
"monthly_product_id":"597485",
"yearly_product_id":"597486",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 200000,
"monthly_product_id": "597485",
"yearly_product_id": "597486",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":500000,
"monthly_product_id":"597487",
"yearly_product_id":"597488",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 500000,
"monthly_product_id": "597487",
"yearly_product_id": "597488",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":1000000,
"monthly_product_id":"597642",
"yearly_product_id":"597643",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "597642",
"yearly_product_id": "597643",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":2000000,
"monthly_product_id":"597309",
"yearly_product_id":"597310",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "597309",
"yearly_product_id": "597310",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":5000000,
"monthly_product_id":"597311",
"yearly_product_id":"597312",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "597311",
"yearly_product_id": "597312",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":10000000,
"monthly_product_id":"642352",
"yearly_product_id":"642354",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "642352",
"yearly_product_id": "642354",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":20000000,
"monthly_product_id":"642355",
"yearly_product_id":"642356",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 20000000,
"monthly_product_id": "642355",
"yearly_product_id": "642356",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":1,
"monthly_pageview_limit":50000000,
"monthly_product_id":"650652",
"yearly_product_id":"650653",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 50000000,
"monthly_product_id": "650652",
"yearly_product_id": "650653",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
}
]

View File

@ -1,102 +1,162 @@
[
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":10000,
"monthly_product_id":"654177",
"yearly_product_id":"653232",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 10000,
"monthly_product_id": "654177",
"yearly_product_id": "653232",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":100000,
"monthly_product_id":"654178",
"yearly_product_id":"653234",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 100000,
"monthly_product_id": "654178",
"yearly_product_id": "653234",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":200000,
"monthly_product_id":"653237",
"yearly_product_id":"653236",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 200000,
"monthly_product_id": "653237",
"yearly_product_id": "653236",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":500000,
"monthly_product_id":"653238",
"yearly_product_id":"653239",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 500000,
"monthly_product_id": "653238",
"yearly_product_id": "653239",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":1000000,
"monthly_product_id":"653240",
"yearly_product_id":"653242",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "653240",
"yearly_product_id": "653242",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":2000000,
"monthly_product_id":"653253",
"yearly_product_id":"653254",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "653253",
"yearly_product_id": "653254",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":5000000,
"monthly_product_id":"653255",
"yearly_product_id":"653256",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "653255",
"yearly_product_id": "653256",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":10000000,
"monthly_product_id":"654181",
"yearly_product_id":"653257",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "654181",
"yearly_product_id": "653257",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":20000000,
"monthly_product_id":"654182",
"yearly_product_id":"653258",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 20000000,
"monthly_product_id": "654182",
"yearly_product_id": "653258",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":2,
"monthly_pageview_limit":50000000,
"monthly_product_id":"654183",
"yearly_product_id":"653259",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 50000000,
"monthly_product_id": "654183",
"yearly_product_id": "653259",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
}
]

View File

@ -1,162 +1,282 @@
[
{
"kind":"growth",
"generation":3,
"monthly_pageview_limit":10000,
"monthly_product_id":"749342",
"yearly_product_id":"749343",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 10000,
"monthly_product_id": "749342",
"yearly_product_id": "749343",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":3,
"monthly_pageview_limit":100000,
"monthly_product_id":"749344",
"yearly_product_id":"749345",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 100000,
"monthly_product_id": "749344",
"yearly_product_id": "749345",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":3,
"monthly_pageview_limit":200000,
"monthly_product_id":"749346",
"yearly_product_id":"749347",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 200000,
"monthly_product_id": "749346",
"yearly_product_id": "749347",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":3,
"monthly_pageview_limit":500000,
"monthly_product_id":"749348",
"yearly_product_id":"749349",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 500000,
"monthly_product_id": "749348",
"yearly_product_id": "749349",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":3,
"monthly_pageview_limit":1000000,
"monthly_product_id":"749350",
"yearly_product_id":"749352",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "749350",
"yearly_product_id": "749352",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":3,
"monthly_pageview_limit":2000000,
"monthly_product_id":"749353",
"yearly_product_id":"749355",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "749353",
"yearly_product_id": "749355",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":3,
"monthly_pageview_limit":5000000,
"monthly_product_id":"749356",
"yearly_product_id":"749357",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "749356",
"yearly_product_id": "749357",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"growth",
"generation":3,
"monthly_pageview_limit":10000000,
"monthly_product_id":"749358",
"yearly_product_id":"749359",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","stats_api"]
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "749358",
"yearly_product_id": "749359",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
},
{
"kind":"business",
"generation":3,
"monthly_pageview_limit":10000,
"monthly_product_id":"857481",
"yearly_product_id":"857482",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"]
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 10000,
"monthly_product_id": "857481",
"yearly_product_id": "857482",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
]
},
{
"kind":"business",
"generation":3,
"monthly_pageview_limit":100000,
"monthly_product_id":"857483",
"yearly_product_id":"857484",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"]
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 100000,
"monthly_product_id": "857483",
"yearly_product_id": "857484",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
]
},
{
"kind":"business",
"generation":3,
"monthly_pageview_limit":200000,
"monthly_product_id":"857486",
"yearly_product_id":"857487",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"]
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 200000,
"monthly_product_id": "857486",
"yearly_product_id": "857487",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
]
},
{
"kind":"business",
"generation":3,
"monthly_pageview_limit":500000,
"monthly_product_id":"857490",
"yearly_product_id":"857491",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"]
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 500000,
"monthly_product_id": "857490",
"yearly_product_id": "857491",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
]
},
{
"kind":"business",
"generation":3,
"monthly_pageview_limit":1000000,
"monthly_product_id":"857493",
"yearly_product_id":"857494",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"]
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "857493",
"yearly_product_id": "857494",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
]
},
{
"kind":"business",
"generation":3,
"monthly_pageview_limit":2000000,
"monthly_product_id":"857495",
"yearly_product_id":"857496",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"]
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "857495",
"yearly_product_id": "857496",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
]
},
{
"kind":"business",
"generation":3,
"monthly_pageview_limit":5000000,
"monthly_product_id":"857498",
"yearly_product_id":"857500",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"]
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "857498",
"yearly_product_id": "857500",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
]
},
{
"kind":"business",
"generation":3,
"monthly_pageview_limit":10000000,
"monthly_product_id":"857501",
"yearly_product_id":"857502",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"]
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "857501",
"yearly_product_id": "857502",
"site_limit": 50,
"team_member_limit": "unlimited",
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
]
}
]

View File

@ -1,178 +1,282 @@
[
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":10000,
"monthly_product_id":"857097",
"yearly_product_id":"857079",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 10000,
"monthly_product_id": "857097",
"yearly_product_id": "857079",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":100000,
"monthly_product_id":"857098",
"yearly_product_id":"857080",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 100000,
"monthly_product_id": "857098",
"yearly_product_id": "857080",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":200000,
"monthly_product_id":"857099",
"yearly_product_id":"857081",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 200000,
"monthly_product_id": "857099",
"yearly_product_id": "857081",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":500000,
"monthly_product_id":"857100",
"yearly_product_id":"857082",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 500000,
"monthly_product_id": "857100",
"yearly_product_id": "857082",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":1000000,
"monthly_product_id":"857101",
"yearly_product_id":"857083",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "857101",
"yearly_product_id": "857083",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":2000000,
"monthly_product_id":"857102",
"yearly_product_id":"857084",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "857102",
"yearly_product_id": "857084",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":5000000,
"monthly_product_id":"857103",
"yearly_product_id":"857085",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "857103",
"yearly_product_id": "857085",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":10000000,
"monthly_product_id":"857104",
"yearly_product_id":"857086",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "857104",
"yearly_product_id": "857086",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":10000,
"monthly_product_id":"857105",
"yearly_product_id":"857087",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 10000,
"monthly_product_id": "857105",
"yearly_product_id": "857087",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":100000,
"monthly_product_id":"857106",
"yearly_product_id":"857088",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 100000,
"monthly_product_id": "857106",
"yearly_product_id": "857088",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":200000,
"monthly_product_id":"857107",
"yearly_product_id":"857089",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 200000,
"monthly_product_id": "857107",
"yearly_product_id": "857089",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":500000,
"monthly_product_id":"857108",
"yearly_product_id":"857090",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 500000,
"monthly_product_id": "857108",
"yearly_product_id": "857090",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":1000000,
"monthly_product_id":"857109",
"yearly_product_id":"857091",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "857109",
"yearly_product_id": "857091",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":2000000,
"monthly_product_id":"857110",
"yearly_product_id":"857092",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "857110",
"yearly_product_id": "857092",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":5000000,
"monthly_product_id":"857111",
"yearly_product_id":"857093",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "857111",
"yearly_product_id": "857093",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":10000000,
"monthly_product_id":"857112",
"yearly_product_id":"857094",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "857112",
"yearly_product_id": "857094",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
}
]

394
priv/plans_v5.json Normal file
View File

@ -0,0 +1,394 @@
[
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 10000,
"monthly_product_id": "910413",
"yearly_product_id": "910414",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 100000,
"monthly_product_id": "910415",
"yearly_product_id": "910416",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 200000,
"monthly_product_id": "910417",
"yearly_product_id": "910418",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 500000,
"monthly_product_id": "910419",
"yearly_product_id": "910420",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "910421",
"yearly_product_id": "910422",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "910423",
"yearly_product_id": "910424",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "910425",
"yearly_product_id": "910426",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "910427",
"yearly_product_id": "910428",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 10000,
"monthly_product_id": "910429",
"yearly_product_id": "910430",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 100000,
"monthly_product_id": "910431",
"yearly_product_id": "910432",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 200000,
"monthly_product_id": "910433",
"yearly_product_id": "910434",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 500000,
"monthly_product_id": "910435",
"yearly_product_id": "910436",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "910437",
"yearly_product_id": "910438",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "910439",
"yearly_product_id": "910440",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "910441",
"yearly_product_id": "910442",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "910443",
"yearly_product_id": "910444",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 10000,
"monthly_product_id": "910445",
"yearly_product_id": "910446",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 100000,
"monthly_product_id": "910447",
"yearly_product_id": "910448",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 200000,
"monthly_product_id": "910449",
"yearly_product_id": "910450",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 500000,
"monthly_product_id": "910451",
"yearly_product_id": "910452",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "910453",
"yearly_product_id": "910454",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "910455",
"yearly_product_id": "910456",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "910457",
"yearly_product_id": "910458",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "910459",
"yearly_product_id": "910460",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
}
]

View File

@ -1,142 +1,162 @@
[
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 10000,
"monthly_product_id": "78008",
"yearly_product_id": "78009",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78009"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 100000,
"monthly_product_id": "78010",
"yearly_product_id": "78011",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78011"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 200000,
"monthly_product_id": "78012",
"yearly_product_id": "78013",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78013"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 500000,
"monthly_product_id": "78014",
"yearly_product_id": "78015",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78015"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "78016",
"yearly_product_id": "78017",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78017"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "78018",
"yearly_product_id": "78019",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78019"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "78020",
"yearly_product_id": "78021",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78021"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "78022",
"yearly_product_id": "78023",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78023"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 20000000,
"monthly_product_id": "78024",
"yearly_product_id": "78025",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78025"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 1,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 1,
"monthly_pageview_limit": 50000000,
"monthly_product_id": "78026",
"yearly_product_id": "78027",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78027"
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
}
]

View File

@ -1,142 +1,162 @@
[
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 10000,
"monthly_product_id": "78053",
"yearly_product_id": "78054",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78054"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 100000,
"monthly_product_id": "78055",
"yearly_product_id": "78056",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78056"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 200000,
"monthly_product_id": "78057",
"yearly_product_id": "78058",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78058"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 500000,
"monthly_product_id": "78059",
"yearly_product_id": "78060",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78060"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "78061",
"yearly_product_id": "78062",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78062"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "78063",
"yearly_product_id": "78064",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78064"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "78065",
"yearly_product_id": "78066",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78066"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "78067",
"yearly_product_id": "78068",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78068"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 20000000,
"monthly_product_id": "78069",
"yearly_product_id": "78070",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78070"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 2,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 2,
"monthly_pageview_limit": 50000000,
"monthly_product_id": "78071",
"yearly_product_id": "78072",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78072"
"features": [
"goals",
"props",
"stats_api",
"teams",
"shared_links"
]
}
]

View File

@ -1,250 +1,282 @@
[
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 3,
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 10000,
"monthly_product_id": "78073",
"yearly_product_id": "78074",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78074"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 3,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 100000,
"monthly_product_id": "78075",
"yearly_product_id": "78076",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78076"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 3,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 200000,
"monthly_product_id": "78077",
"yearly_product_id": "78078",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78078"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 3,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 500000,
"monthly_product_id": "78079",
"yearly_product_id": "78080",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78080"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 3,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "78081",
"yearly_product_id": "78082",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78082"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 3,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "78083",
"yearly_product_id": "78084",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78084"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 3,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "78085",
"yearly_product_id": "78086",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78086"
},
{
"features": [
"goals",
"props",
"stats_api"
],
"generation": 3,
"stats_api",
"teams",
"shared_links"
]
},
{
"kind": "growth",
"generation": 3,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "78087",
"yearly_product_id": "78088",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78088"
},
{
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments"
],
"generation": 3,
"teams",
"shared_links"
]
},
{
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 10000,
"monthly_product_id": "78089",
"yearly_product_id": "78090",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78090"
},
{
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments"
],
"generation": 3,
"site_segments",
"teams",
"shared_links"
]
},
{
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 100000,
"monthly_product_id": "78091",
"yearly_product_id": "78092",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78092"
},
{
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments"
],
"generation": 3,
"site_segments",
"teams",
"shared_links"
]
},
{
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 200000,
"monthly_product_id": "78093",
"yearly_product_id": "78094",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78094"
},
{
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments"
],
"generation": 3,
"site_segments",
"teams",
"shared_links"
]
},
{
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 500000,
"monthly_product_id": "78095",
"yearly_product_id": "78096",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78096"
},
{
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments"
],
"generation": 3,
"site_segments",
"teams",
"shared_links"
]
},
{
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "78097",
"yearly_product_id": "78098",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78098"
},
{
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments"
],
"generation": 3,
"site_segments",
"teams",
"shared_links"
]
},
{
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "78099",
"yearly_product_id": "78100",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78100"
},
{
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments"
],
"generation": 3,
"site_segments",
"teams",
"shared_links"
]
},
{
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "78101",
"yearly_product_id": "78102",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78102"
},
{
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments"
],
"generation": 3,
"site_segments",
"teams",
"shared_links"
]
},
{
"kind": "business",
"generation": 3,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "78107",
"yearly_product_id": "78109",
"site_limit": 50,
"team_member_limit": "unlimited",
"yearly_product_id": "78109"
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
]
}
]

View File

@ -1,178 +1,282 @@
[
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":10000,
"monthly_product_id":"63842",
"yearly_product_id":"63859",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 10000,
"monthly_product_id": "63842",
"yearly_product_id": "63859",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":100000,
"monthly_product_id":"63843",
"yearly_product_id":"63860",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 100000,
"monthly_product_id": "63843",
"yearly_product_id": "63860",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":200000,
"monthly_product_id":"63844",
"yearly_product_id":"63861",
"site_limit":50,
"team_member_limit":"unlimited",
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 200000,
"monthly_product_id": "63844",
"yearly_product_id": "63861",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":500000,
"monthly_product_id":"63845",
"yearly_product_id":"63862",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 500000,
"monthly_product_id": "63845",
"yearly_product_id": "63862",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":1000000,
"monthly_product_id":"63846",
"yearly_product_id":"63863",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "63846",
"yearly_product_id": "63863",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":2000000,
"monthly_product_id":"63847",
"yearly_product_id":"63864",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "63847",
"yearly_product_id": "63864",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":5000000,
"monthly_product_id":"63848",
"yearly_product_id":"63865",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "63848",
"yearly_product_id": "63865",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"growth",
"generation":4,
"monthly_pageview_limit":10000000,
"monthly_product_id":"63849",
"yearly_product_id":"63866",
"site_limit":10,
"team_member_limit":3,
"features":["goals"],
"kind": "growth",
"generation": 4,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "63849",
"yearly_product_id": "63866",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":10000,
"monthly_product_id":"63850",
"yearly_product_id":"63867",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 10000,
"monthly_product_id": "63850",
"yearly_product_id": "63867",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":100000,
"monthly_product_id":"63851",
"yearly_product_id":"63868",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 100000,
"monthly_product_id": "63851",
"yearly_product_id": "63868",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":200000,
"monthly_product_id":"63852",
"yearly_product_id":"63869",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 200000,
"monthly_product_id": "63852",
"yearly_product_id": "63869",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":500000,
"monthly_product_id":"63853",
"yearly_product_id":"63870",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 500000,
"monthly_product_id": "63853",
"yearly_product_id": "63870",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":1000000,
"monthly_product_id":"63854",
"yearly_product_id":"63871",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "63854",
"yearly_product_id": "63871",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":2000000,
"monthly_product_id":"63855",
"yearly_product_id":"63872",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "63855",
"yearly_product_id": "63872",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":5000000,
"monthly_product_id":"63856",
"yearly_product_id":"63873",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "63856",
"yearly_product_id": "63873",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind":"business",
"generation":4,
"monthly_pageview_limit":10000000,
"monthly_product_id":"63857",
"yearly_product_id":"63874",
"site_limit":50,
"team_member_limit":10,
"features":["goals","props","revenue_goals","funnels","stats_api","site_segments"],
"kind": "business",
"generation": 4,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "63857",
"yearly_product_id": "63874",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"revenue_goals",
"funnels",
"stats_api",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
}
]

394
priv/sandbox_plans_v5.json Normal file
View File

@ -0,0 +1,394 @@
[
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 10000,
"monthly_product_id": "78943",
"yearly_product_id": "78944",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 100000,
"monthly_product_id": "78945",
"yearly_product_id": "78946",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 200000,
"monthly_product_id": "78947",
"yearly_product_id": "78948",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 500000,
"monthly_product_id": "78949",
"yearly_product_id": "78950",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "78951",
"yearly_product_id": "78952",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "78953",
"yearly_product_id": "78954",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "78955",
"yearly_product_id": "78956",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "starter",
"generation": 5,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "78957",
"yearly_product_id": "78958",
"site_limit": 3,
"team_member_limit": 1,
"features": [
"goals"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 10000,
"monthly_product_id": "78959",
"yearly_product_id": "78960",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 100000,
"monthly_product_id": "78961",
"yearly_product_id": "78962",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 200000,
"monthly_product_id": "78963",
"yearly_product_id": "78964",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 500000,
"monthly_product_id": "78965",
"yearly_product_id": "78966",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "78967",
"yearly_product_id": "78968",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "78969",
"yearly_product_id": "78970",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "78971",
"yearly_product_id": "78972",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "growth",
"generation": 5,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "78973",
"yearly_product_id": "78974",
"site_limit": 10,
"team_member_limit": 3,
"features": [
"goals",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 3
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 10000,
"monthly_product_id": "78975",
"yearly_product_id": "78976",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 100000,
"monthly_product_id": "78977",
"yearly_product_id": "78978",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 200000,
"monthly_product_id": "78979",
"yearly_product_id": "78980",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 500000,
"monthly_product_id": "78981",
"yearly_product_id": "78982",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 1000000,
"monthly_product_id": "78983",
"yearly_product_id": "78984",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 2000000,
"monthly_product_id": "78985",
"yearly_product_id": "78986",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 5000000,
"monthly_product_id": "78987",
"yearly_product_id": "78988",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
},
{
"kind": "business",
"generation": 5,
"monthly_pageview_limit": 10000000,
"monthly_product_id": "78989",
"yearly_product_id": "78990",
"site_limit": 50,
"team_member_limit": 10,
"features": [
"goals",
"props",
"stats_api",
"revenue_goals",
"funnels",
"site_segments",
"teams",
"shared_links"
],
"data_retention_in_years": 5
}
]

View File

@ -3,7 +3,7 @@ defmodule Plausible.Billing.QuotaTest do
use Plausible.DataCase, async: true
use Plausible
alias Plausible.Billing.{Quota, Plans}
alias Plausible.Billing.Feature.{Goals, Props, SitesAPI, StatsAPI}
alias Plausible.Billing.Feature.{Goals, Props, SitesAPI, StatsAPI, Teams, SharedLinks}
use Plausible.Teams.Test
@ -581,9 +581,14 @@ defmodule Plausible.Billing.QuotaTest do
team_on_v2 = new_user() |> subscribe_to_plan(@v2_plan_id) |> team_of()
team_on_v3 = new_user() |> subscribe_to_plan(@v3_plan_id) |> team_of()
assert [Goals, Props, StatsAPI] == Plausible.Teams.Billing.allowed_features_for(team_on_v1)
assert [Goals, Props, StatsAPI] == Plausible.Teams.Billing.allowed_features_for(team_on_v2)
assert [Goals, Props, StatsAPI] == Plausible.Teams.Billing.allowed_features_for(team_on_v3)
assert [Goals, Props, StatsAPI, Teams, SharedLinks] ==
Plausible.Teams.Billing.allowed_features_for(team_on_v1)
assert [Goals, Props, StatsAPI, Teams, SharedLinks] ==
Plausible.Teams.Billing.allowed_features_for(team_on_v2)
assert [Goals, Props, StatsAPI, Teams, SharedLinks] ==
Plausible.Teams.Billing.allowed_features_for(team_on_v3)
end
test "returns [Goals, Props, StatsAPI] when user is on free_10k plan" do
@ -625,7 +630,8 @@ defmodule Plausible.Billing.QuotaTest do
team = team_of(user)
assert [Goals, Props, StatsAPI] == Plausible.Teams.Billing.allowed_features_for(team)
assert [Goals, Props, StatsAPI, Teams, SharedLinks] ==
Plausible.Teams.Billing.allowed_features_for(team)
end
test "returns all features for enterprise users who have not upgraded yet and are on trial" do

View File

@ -263,7 +263,7 @@ defmodule PlausibleWeb.AdminControllerTest do
conn = get(conn, "/crm/billing/team/#{team.id}/current_plan")
assert json_response(conn, 200) == %{
"features" => ["goals"],
"features" => ["goals", "teams", "shared_links"],
"monthly_pageview_limit" => 10_000_000,
"site_limit" => 10,
"team_member_limit" => 3

View File

@ -31,7 +31,9 @@ defmodule PlausibleWeb.Plugins.API.Controllers.CapabilitiesTest do
"RevenueGoals" => false,
"StatsAPI" => false,
"SitesAPI" => false,
"SiteSegments" => false
"SiteSegments" => false,
"Teams" => false,
"SharedLinks" => false
}
}
@ -57,7 +59,9 @@ defmodule PlausibleWeb.Plugins.API.Controllers.CapabilitiesTest do
"RevenueGoals" => false,
"StatsAPI" => false,
"SitesAPI" => false,
"SiteSegments" => false
"SiteSegments" => false,
"Teams" => false,
"SharedLinks" => false
}
}
@ -85,7 +89,9 @@ defmodule PlausibleWeb.Plugins.API.Controllers.CapabilitiesTest do
"RevenueGoals" => true,
"StatsAPI" => true,
"SitesAPI" => false,
"SiteSegments" => true
"SiteSegments" => true,
"Teams" => true,
"SharedLinks" => true
}
}
@ -115,7 +121,9 @@ defmodule PlausibleWeb.Plugins.API.Controllers.CapabilitiesTest do
"RevenueGoals" => false,
"StatsAPI" => false,
"SitesAPI" => false,
"SiteSegments" => false
"SiteSegments" => false,
"Teams" => true,
"SharedLinks" => true
}
}
@ -148,7 +156,9 @@ defmodule PlausibleWeb.Plugins.API.Controllers.CapabilitiesTest do
"RevenueGoals" => false,
"StatsAPI" => true,
"SitesAPI" => true,
"SiteSegments" => false
"SiteSegments" => false,
"Teams" => false,
"SharedLinks" => false
}
}