From 4e500948083e2f7d8f9e6129fe055fc618d1d2fa Mon Sep 17 00:00:00 2001 From: Giancarlo Buomprisco Date: Wed, 15 May 2024 11:08:19 +0700 Subject: [PATCH] Fix upsert billing (#24) This commit updates the product_id and variant_id in both the subscription_items and order_items in the billing tests. Updates also include adding new checks to verify these changes. Changes are reflected in corresponding SQL files for personal and team billing subscriptions/orders tests. --- apps/web/config/billing.sample.config.ts | 22 +---------------- .../migrations/20221215192558_schema.sql | 9 ++++++- .../database/personal-billing-orders.test.sql | 17 ++++++++++--- .../personal-billing-subscriptions.test.sql | 9 ++++++- .../database/team-billing-orders.test.sql | 24 ++++++++++++++----- .../team-billing-subscriptions.test.sql | 13 +++++++--- .../lemon-squeezy-billing-strategy.service.ts | 4 ++-- .../stripe-billing-strategy.service.ts | 4 ++-- 8 files changed, 63 insertions(+), 39 deletions(-) diff --git a/apps/web/config/billing.sample.config.ts b/apps/web/config/billing.sample.config.ts index 5083c1543..23bac72b0 100644 --- a/apps/web/config/billing.sample.config.ts +++ b/apps/web/config/billing.sample.config.ts @@ -35,26 +35,6 @@ export default createBillingSchema({ cost: 9.99, type: 'flat' as const, }, - { - id: 'price_1P8N0zI1i3VnbZTqtUPc1Zvr', - name: 'Addon 3', - cost: 0, - type: 'per_seat' as const, - tiers: [ - { - upTo: 1, - cost: 0, - }, - { - upTo: 5, - cost: 4, - }, - { - upTo: 'unlimited', - cost: 3, - }, - ], - }, ], }, { @@ -89,7 +69,7 @@ export default createBillingSchema({ interval: 'month', lineItems: [ { - id: 'price_pro', + id: 'price_1PGOAVI1i3VnbZTqc69xaypm', name: 'Base', cost: 19.99, type: 'flat', diff --git a/apps/web/supabase/migrations/20221215192558_schema.sql b/apps/web/supabase/migrations/20221215192558_schema.sql index 211f0c8cf..be3cddcaf 100644 --- a/apps/web/supabase/migrations/20221215192558_schema.sql +++ b/apps/web/supabase/migrations/20221215192558_schema.sql @@ -1645,9 +1645,12 @@ on conflict ( item_data on conflict (id) do update set + product_id = excluded.product_id, + variant_id = excluded.variant_id, price_amount = excluded.price_amount, quantity = excluded.quantity, interval = excluded.interval, + type = excluded.type, interval_count = excluded.interval_count; return new_subscription; @@ -2018,6 +2021,8 @@ on conflict ( on conflict (id) do update set price_amount = excluded.price_amount, + product_id = excluded.product_id, + variant_id = excluded.variant_id, quantity = excluded.quantity; return new_order; @@ -2486,7 +2491,9 @@ returns table ( primary_owner_user_id uuid, subscription_status public.subscription_status, permissions public.app_permissions[] -) as $$ +) +set search_path to '' +as $$ begin return QUERY select diff --git a/apps/web/supabase/tests/database/personal-billing-orders.test.sql b/apps/web/supabase/tests/database/personal-billing-orders.test.sql index f1ec6c4ba..d37106cbf 100644 --- a/apps/web/supabase/tests/database/personal-billing-orders.test.sql +++ b/apps/web/supabase/tests/database/personal-billing-orders.test.sql @@ -12,7 +12,10 @@ INSERT INTO public.billing_customers(account_id, provider, customer_id) VALUES (tests.get_supabase_uid('primary_owner'), 'stripe', 'cus_test'); -- Call the upsert_order function -SELECT public.upsert_order(tests.get_supabase_uid('primary_owner'), 'cus_test', 'order_test', 'pending', 'stripe', 100, 'usd', '[{"id":"order_item_1", "product_id": "prod_test", "variant_id": "var_test", "price_amount": 100, "quantity": 1}, {"id":"order_item_2", "product_id": "prod_test", "variant_id": "var_test_2", "price_amount": 100, "quantity": 1}]'); +SELECT public.upsert_order(tests.get_supabase_uid('primary_owner'), 'cus_test', 'order_test', 'pending', 'stripe', 100, 'usd', '[ + {"id":"order_item_1", "product_id": "prod_test", "variant_id": "var_test", "price_amount": 100, "quantity": 1}, + {"id":"order_item_2", "product_id": "prod_test", "variant_id": "var_test_2", "price_amount": 100, "quantity": 10} +]'); -- Verify that the order was created correctly SELECT is( @@ -29,7 +32,9 @@ SELECT row_eq( ); -- Call the upsert_order function again to update the order -select public.upsert_order(tests.get_supabase_uid('primary_owner'), 'cus_test', 'order_test', 'succeeded', 'stripe', 100, 'usd', '[{"id":"order_item_1", "product_id": "prod_test", "variant_id": "var_test", "price_amount": 100, "quantity": 10}]'); +select public.upsert_order(tests.get_supabase_uid('primary_owner'), 'cus_test', 'order_test', 'succeeded', 'stripe', 100, 'usd', '[ + {"id":"order_item_1", "product_id": "prod_test_2", "variant_id": "var_test", "price_amount": 100, "quantity": 10} +]'); -- Verify that the order was updated correctly select is( @@ -41,7 +46,7 @@ select is( select row_eq( $$ select quantity from order_items where variant_id = 'var_test' $$, row(10::int), - 'The subscription items should be updated' + 'The order items should be updated' ); select is_empty( @@ -49,6 +54,12 @@ select is_empty( 'The order item should be deleted when the order is updated' ); +select row_eq( + $$ select product_id from order_items where id = 'order_item_1' $$, + row('prod_test_2'::text), + 'The order item should be deleted when the order is updated' +); + select tests.authenticate_as('primary_owner'); -- account can read their own subscription diff --git a/apps/web/supabase/tests/database/personal-billing-subscriptions.test.sql b/apps/web/supabase/tests/database/personal-billing-subscriptions.test.sql index 00007af91..73e99c942 100644 --- a/apps/web/supabase/tests/database/personal-billing-subscriptions.test.sql +++ b/apps/web/supabase/tests/database/personal-billing-subscriptions.test.sql @@ -80,7 +80,7 @@ SELECT public.upsert_subscription(tests.get_supabase_uid('primary_owner'), 'cus_ }, { "id": "sub_456", - "product_id": "prod_test_2", + "product_id": "prod_test_3", "variant_id": "var_test_2", "type": "flat", "price_amount": 2000, @@ -97,6 +97,13 @@ SELECT row_eq( 'The subscription items should be updated' ); +-- Verify that the subscription items were updated correctly +SELECT row_eq( + $$ select product_id from subscription_items where id = 'sub_456' $$, + row('prod_test_3'::varchar), + 'The subscription items should be updated' +); + -- Verify that the subscription items were updated correctly SELECT row_eq( $$ select interval from subscription_items where variant_id = 'var_test_2' $$, diff --git a/apps/web/supabase/tests/database/team-billing-orders.test.sql b/apps/web/supabase/tests/database/team-billing-orders.test.sql index bfb578ad5..f863a7035 100644 --- a/apps/web/supabase/tests/database/team-billing-orders.test.sql +++ b/apps/web/supabase/tests/database/team-billing-orders.test.sql @@ -35,8 +35,8 @@ SELECT row_eq( -- Call the upsert_order function again to update the order SELECT public.upsert_order(makerkit.get_account_id_by_slug('makerkit'), 'cus_test', 'order_test', 'succeeded', 'stripe', 100, 'usd', '[ - {"id":"order_item_1", "product_id": "prod_test", "variant_id": "var_test", "price_amount": 100, "quantity": 10}, - {"id":"order_item_2", "product_id": "prod_test", "variant_id": "var_test_2", "price_amount": 200, "quantity": 1} + {"id":"order_item_1", "product_id": "prod_test", "variant_id": "var_test", "price_amount": 100, "quantity": 1}, + {"id":"order_item_2", "product_id": "prod_test_2", "variant_id": "var_test_4", "price_amount": 200, "quantity": 10} ]'); -- Verify that the subscription items were created correctly @@ -54,15 +54,27 @@ SELECT is( ); SELECT row_eq( - $$ select quantity from order_items where variant_id = 'var_test' $$, + $$ select quantity from order_items where variant_id = 'var_test_4' $$, row(10::int), - 'The subscription items should be updated' + 'The subscription items quantity should be updated' ); SELECT row_eq( - $$ select price_amount from order_items where variant_id = 'var_test_2' $$, + $$ select variant_id from order_items where id = 'order_item_2' $$, + row('var_test_4'::text), + 'The subscription items variant_id should be updated' +); + +SELECT row_eq( + $$ select product_id from order_items where id = 'order_item_2' $$, + row('prod_test_2'::text), + 'The subscription items prod_test_2 should be updated' +); + +SELECT row_eq( + $$ select price_amount from order_items where variant_id = 'var_test_4' $$, row(200::numeric), - 'The subscription items should be updated' + 'The subscription items price_amount should be updated' ); select tests.authenticate_as('member'); diff --git a/apps/web/supabase/tests/database/team-billing-subscriptions.test.sql b/apps/web/supabase/tests/database/team-billing-subscriptions.test.sql index b69e59fcf..c54a91b11 100644 --- a/apps/web/supabase/tests/database/team-billing-subscriptions.test.sql +++ b/apps/web/supabase/tests/database/team-billing-subscriptions.test.sql @@ -80,7 +80,7 @@ SELECT public.upsert_subscription(makerkit.get_account_id_by_slug('makerkit'), ' }, { "id": "sub_456", - "product_id": "prod_test_2", + "product_id": "prod_test_3", "variant_id": "var_test_2", "type": "flat", "price_amount": 2000, @@ -100,14 +100,21 @@ SELECT row_eq( SELECT row_eq( $$ select price_amount from subscription_items where variant_id = 'var_test' $$, row('2000'::numeric), - 'The subscription items should be updated' + 'The subscription items price_amount should be updated' ); -- Verify that the subscription items were updated correctly SELECT row_eq( $$ select interval from subscription_items where variant_id = 'var_test_2' $$, row('year'::varchar), - 'The subscription items should be updated' + 'The subscription items interval should be updated' +); + +-- Verify that the subscription items were updated correctly +SELECT row_eq( + $$ select product_id from subscription_items where id = 'sub_456' $$, + row('prod_test_3'::varchar), + 'The subscription items product_id should be updated' ); -- Verify that the subscription was updated correctly diff --git a/packages/billing/lemon-squeezy/src/services/lemon-squeezy-billing-strategy.service.ts b/packages/billing/lemon-squeezy/src/services/lemon-squeezy-billing-strategy.service.ts index ddf688acd..bf95e41ff 100644 --- a/packages/billing/lemon-squeezy/src/services/lemon-squeezy-billing-strategy.service.ts +++ b/packages/billing/lemon-squeezy/src/services/lemon-squeezy-billing-strategy.service.ts @@ -148,10 +148,10 @@ export class LemonSqueezyBillingStrategyService ...ctx, error: (error as Error)?.message, }, - 'Failed to cancel subscription', + 'Failed to cancel subscription. It may have already been cancelled.', ); - throw new Error('Failed to cancel subscription'); + return { success: false }; } } diff --git a/packages/billing/stripe/src/services/stripe-billing-strategy.service.ts b/packages/billing/stripe/src/services/stripe-billing-strategy.service.ts index 4281cad22..331c23607 100644 --- a/packages/billing/stripe/src/services/stripe-billing-strategy.service.ts +++ b/packages/billing/stripe/src/services/stripe-billing-strategy.service.ts @@ -123,10 +123,10 @@ export class StripeBillingStrategyService ...ctx, error, }, - 'Failed to cancel subscription', + 'Failed to cancel subscription. It may have already been cancelled.', ); - throw new Error('Failed to cancel subscription'); + return { success: false }; } }