Refactor billing gateway and enhance localization
Refactored the 'plan-picker' component in the billing gateway to remove unwanted line items and improve checkout session and subscription handling. Enhanced the localization support by adding translations in the plan picker and introduced a new function to check trial eligibility so that existing customers can't start a new trial period. These changes enhance the usability of the application across different regions and provide accurate trial period conditions.
This commit is contained in:
@@ -118,14 +118,14 @@ create type public.subscription_status as ENUM(
|
||||
'paused'
|
||||
);
|
||||
|
||||
/* Subscription Type
|
||||
- We create the subscription type for the Supabase MakerKit. These types are used to manage the type of the subscriptions
|
||||
- The types are 'ONE_OFF' and 'RECURRING'.
|
||||
- You can add more types as needed.
|
||||
/*
|
||||
Payment Status
|
||||
- We create the payment status for the Supabase MakerKit. These statuses are used to manage the status of the payments
|
||||
*/
|
||||
create type public.subscription_type as enum (
|
||||
'one-off',
|
||||
'recurring'
|
||||
create type public.payment_status as ENUM(
|
||||
'pending',
|
||||
'succeeded',
|
||||
'failed'
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -633,8 +633,6 @@ using (
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* -------------------------------------------------------
|
||||
* Section: Account Roles
|
||||
@@ -915,7 +913,8 @@ create table
|
||||
id serial primary key,
|
||||
email text,
|
||||
provider public.billing_provider not null,
|
||||
customer_id text not null
|
||||
customer_id text not null,
|
||||
unique (account_id, customer_id, provider)
|
||||
);
|
||||
|
||||
comment on table public.billing_customers is 'The billing customers for an account';
|
||||
@@ -959,8 +958,6 @@ create table if not exists public.subscriptions (
|
||||
account_id uuid references public.accounts (id) on delete cascade not null,
|
||||
billing_customer_id int references public.billing_customers on delete cascade not null,
|
||||
status public.subscription_status not null,
|
||||
type public.subscription_type not null default 'recurring',
|
||||
total_amount numeric not null,
|
||||
active bool not null,
|
||||
billing_provider public.billing_provider not null,
|
||||
cancel_at_period_end bool not null,
|
||||
@@ -979,8 +976,6 @@ comment on column public.subscriptions.account_id is 'The account the subscripti
|
||||
|
||||
comment on column public.subscriptions.billing_provider is 'The provider of the subscription';
|
||||
|
||||
comment on column public.subscriptions.total_amount is 'The total price amount for the subscription';
|
||||
|
||||
comment on column public.subscriptions.cancel_at_period_end is 'Whether the subscription will be canceled at the end of the period';
|
||||
|
||||
comment on column public.subscriptions.currency is 'The currency for the subscription';
|
||||
@@ -1018,17 +1013,16 @@ select
|
||||
|
||||
-- Functions
|
||||
create or replace function public.upsert_subscription (
|
||||
account_id uuid,
|
||||
subscription_id text,
|
||||
target_account_id uuid,
|
||||
target_customer_id varchar(255),
|
||||
target_subscription_id text,
|
||||
active bool,
|
||||
total_amount numeric,
|
||||
status public.subscription_status,
|
||||
billing_provider public.billing_provider,
|
||||
cancel_at_period_end bool,
|
||||
currency varchar(3),
|
||||
period_starts_at timestamptz,
|
||||
period_ends_at timestamptz,
|
||||
customer_id varchar(255),
|
||||
line_items jsonb,
|
||||
trial_starts_at timestamptz default null,
|
||||
trial_ends_at timestamptz default null,
|
||||
@@ -1039,7 +1033,7 @@ declare
|
||||
new_billing_customer_id int;
|
||||
begin
|
||||
insert into public.billing_customers(account_id, provider, customer_id)
|
||||
values (account_id, billing_provider, customer_id)
|
||||
values (target_account_id, billing_provider, target_customer_id)
|
||||
on conflict (account_id, provider, customer_id) do update
|
||||
set provider = excluded.provider
|
||||
returning id into new_billing_customer_id;
|
||||
@@ -1049,7 +1043,6 @@ begin
|
||||
billing_customer_id,
|
||||
id,
|
||||
active,
|
||||
total_amount,
|
||||
status,
|
||||
type,
|
||||
billing_provider,
|
||||
@@ -1060,11 +1053,10 @@ begin
|
||||
trial_starts_at,
|
||||
trial_ends_at)
|
||||
values (
|
||||
account_id,
|
||||
target_account_id,
|
||||
new_billing_customer_id,
|
||||
subscription_id,
|
||||
active,
|
||||
total_amount,
|
||||
status,
|
||||
type,
|
||||
billing_provider,
|
||||
@@ -1125,23 +1117,21 @@ $$ language plpgsql;
|
||||
|
||||
grant execute on function public.upsert_subscription (
|
||||
uuid,
|
||||
varchar,
|
||||
text,
|
||||
bool,
|
||||
numeric,
|
||||
public.subscription_status,
|
||||
public.billing_provider,
|
||||
bool,
|
||||
varchar,
|
||||
timestamptz,
|
||||
timestamptz,
|
||||
varchar,
|
||||
jsonb,
|
||||
timestamptz,
|
||||
timestamptz,
|
||||
public.subscription_type
|
||||
) to service_role;
|
||||
|
||||
|
||||
/* -------------------------------------------------------
|
||||
* Section: Subscription Items
|
||||
* We create the schema for the subscription items. Subscription items are the items in a subscription.
|
||||
@@ -1149,7 +1139,6 @@ grant execute on function public.upsert_subscription (
|
||||
* -------------------------------------------------------
|
||||
*/
|
||||
create table if not exists public.subscription_items (
|
||||
id text not null primary key,
|
||||
subscription_id text references public.subscriptions (id) on delete cascade not null,
|
||||
product_id varchar(255) not null,
|
||||
variant_id varchar(255) not null,
|
||||
@@ -1158,7 +1147,8 @@ create table if not exists public.subscription_items (
|
||||
interval varchar(255) not null,
|
||||
interval_count integer not null check (interval_count > 0),
|
||||
created_at timestamptz not null default current_timestamp,
|
||||
updated_at timestamptz not null default current_timestamp
|
||||
updated_at timestamptz not null default current_timestamp,
|
||||
unique (subscription_id, product_id, variant_id)
|
||||
);
|
||||
|
||||
comment on table public.subscription_items is 'The items in a subscription';
|
||||
@@ -1188,6 +1178,147 @@ select
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------
|
||||
* Section: Orders
|
||||
* We create the schema for the subscription items. Subscription items are the items in a subscription.
|
||||
* For example, a subscription might have a subscription item with the product ID 'prod_123' and the variant ID 'var_123'.
|
||||
* -------------------------------------------------------
|
||||
*/
|
||||
create table if not exists public.orders (
|
||||
id text not null primary key,
|
||||
account_id uuid references public.accounts (id) on delete cascade not null,
|
||||
billing_customer_id int references public.billing_customers on delete cascade not null,
|
||||
status public.payment_status not null,
|
||||
billing_provider public.billing_provider not null,
|
||||
total_amount numeric not null,
|
||||
currency varchar(3) not null,
|
||||
created_at timestamptz not null default current_timestamp,
|
||||
updated_at timestamptz not null default current_timestamp
|
||||
);
|
||||
|
||||
-- Open up access to subscription_items table for authenticated users and service_role
|
||||
grant select on table public.orders to authenticated, service_role;
|
||||
grant insert, update, delete on table public.orders to service_role;
|
||||
|
||||
-- RLS
|
||||
alter table public.orders enable row level security;
|
||||
|
||||
-- SELECT
|
||||
-- Users can read orders on an account they are a member of or the account is their own
|
||||
create policy orders_read_self on public.orders for
|
||||
select
|
||||
to authenticated using (
|
||||
account_id = auth.uid () or has_role_on_account (account_id)
|
||||
);
|
||||
|
||||
/**
|
||||
* -------------------------------------------------------
|
||||
* Section: Order Items
|
||||
* We create the schema for the order items. Order items are the items in an order.
|
||||
* -------------------------------------------------------
|
||||
*/
|
||||
create table if not exists public.order_items (
|
||||
order_id text references public.orders (id) on delete cascade not null,
|
||||
product_id text not null,
|
||||
variant_id text not null,
|
||||
price_amount numeric,
|
||||
quantity integer not null default 1,
|
||||
created_at timestamptz not null default current_timestamp,
|
||||
updated_at timestamptz not null default current_timestamp,
|
||||
unique (order_id, product_id, variant_id)
|
||||
);
|
||||
|
||||
-- Open up access to order_items table for authenticated users and service_role
|
||||
grant select on table public.order_items to authenticated, service_role;
|
||||
|
||||
-- RLS
|
||||
alter table public.order_items enable row level security;
|
||||
|
||||
-- SELECT
|
||||
-- Users can read order items on an order they are a member of
|
||||
create policy order_items_read_self on public.order_items for
|
||||
select
|
||||
to authenticated using (
|
||||
exists (
|
||||
select 1 from public.orders where id = order_id and (account_id = auth.uid () or has_role_on_account (account_id))
|
||||
)
|
||||
);
|
||||
|
||||
-- Functions
|
||||
create or replace function public.upsert_order(
|
||||
target_account_id uuid,
|
||||
target_customer_id varchar(255),
|
||||
order_id text,
|
||||
status public.payment_status,
|
||||
billing_provider public.billing_provider,
|
||||
total_amount numeric,
|
||||
currency varchar(3),
|
||||
line_items jsonb
|
||||
) returns public.orders as $$
|
||||
declare
|
||||
new_order public.orders;
|
||||
new_billing_customer_id int;
|
||||
begin
|
||||
insert into public.billing_customers(account_id, provider, customer_id)
|
||||
values (target_account_id, target_billing_provider, target_customer_id)
|
||||
on conflict (account_id, provider, customer_id) do update
|
||||
set provider = excluded.provider
|
||||
returning id into new_billing_customer_id;
|
||||
|
||||
insert into public.orders(
|
||||
account_id,
|
||||
billing_customer_id,
|
||||
id,
|
||||
status,
|
||||
billing_provider,
|
||||
total_amount,
|
||||
currency)
|
||||
values (
|
||||
target_account_id,
|
||||
new_billing_customer_id,
|
||||
order_id,
|
||||
status,
|
||||
billing_provider,
|
||||
total_amount,
|
||||
currency)
|
||||
on conflict (id) do update
|
||||
set status = excluded.status,
|
||||
total_amount = excluded.total_amount,
|
||||
currency = excluded.currency
|
||||
returning * into new_order;
|
||||
|
||||
insert into public.order_items(
|
||||
order_id,
|
||||
product_id,
|
||||
variant_id,
|
||||
price_amount,
|
||||
quantity)
|
||||
select
|
||||
target_order_id,
|
||||
(line_item ->> 'product_id')::varchar,
|
||||
(line_item ->> 'variant_id')::varchar,
|
||||
(line_item ->> 'price_amount')::numeric,
|
||||
(line_item ->> 'quantity')::integer
|
||||
from jsonb_array_elements(line_items) as line_item
|
||||
on conflict (order_id, product_id, variant_id) do update
|
||||
set price_amount = excluded.price_amount,
|
||||
quantity = excluded.quantity;
|
||||
|
||||
return new_order;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
grant execute on function public.upsert_order (
|
||||
uuid,
|
||||
varchar,
|
||||
text,
|
||||
public.payment_status,
|
||||
public.billing_provider,
|
||||
numeric,
|
||||
varchar,
|
||||
jsonb
|
||||
) to service_role;
|
||||
/*
|
||||
* -------------------------------------------------------
|
||||
* Section: Functions
|
||||
|
||||
Reference in New Issue
Block a user