diff --git a/ghost/portal/src/actions.js b/ghost/portal/src/actions.js
index 65318692db..a62d065f70 100644
--- a/ghost/portal/src/actions.js
+++ b/ghost/portal/src/actions.js
@@ -111,11 +111,12 @@ async function signup({data, state, api}) {
             lastPage: 'signup'
         };
     } catch (e) {
+        const message = e?.message || 'Failed to sign up, please try again';
         return {
             action: 'signup:failed',
             popupNotification: createPopupNotification({
                 type: 'signup:failed', autoHide: false, closeable: true, state, status: 'error',
-                message: 'Failed to sign up, please try again'
+                message
             })
         };
     }
diff --git a/ghost/portal/src/components/common/ProductsSection.js b/ghost/portal/src/components/common/ProductsSection.js
index c1bebd1b73..edb8125559 100644
--- a/ghost/portal/src/components/common/ProductsSection.js
+++ b/ghost/portal/src/components/common/ProductsSection.js
@@ -624,7 +624,9 @@ function ProductCard({product, products, selectedInterval, handleChooseSignup})
     const {action} = useContext(AppContext);
 
     const cardClass = selectedProduct === product.id ? 'gh-portal-product-card checked' : 'gh-portal-product-card';
-    const noOfProducts = products.length;
+    const noOfProducts = products?.filter((d) => {
+        return d.type === 'paid';
+    })?.length;
 
     let disabled = (['signup:running', 'checkoutPlan:running'].includes(action)) ? true : false;
 
diff --git a/ghost/portal/src/components/pages/SignupPage.test.js b/ghost/portal/src/components/pages/SignupPage.test.js
index 22f1b2b5f0..e4e557a405 100644
--- a/ghost/portal/src/components/pages/SignupPage.test.js
+++ b/ghost/portal/src/components/pages/SignupPage.test.js
@@ -29,11 +29,12 @@ const setup = (overrides) => {
 
 describe('SignupPage', () => {
     test('renders', () => {
-        const {nameInput, emailInput, chooseButton, signinButton} = setup();
+        const {nameInput, emailInput, queryAllByRole, signinButton} = setup();
+        const chooseButton = queryAllByRole('button', {name: 'Continue'});
 
         expect(nameInput).toBeInTheDocument();
         expect(emailInput).toBeInTheDocument();
-        expect(chooseButton).toHaveLength(2);
+        expect(chooseButton).toHaveLength(1);
         expect(signinButton).toBeInTheDocument();
     });
 
diff --git a/ghost/portal/src/tests/SignupFlow.test.js b/ghost/portal/src/tests/SignupFlow.test.js
index 3f6f7d5736..e124ec1f60 100644
--- a/ghost/portal/src/tests/SignupFlow.test.js
+++ b/ghost/portal/src/tests/SignupFlow.test.js
@@ -185,7 +185,7 @@ describe('Signup', () => {
             } = await setup({
                 site: FixtureSite.singleTier.basic
             });
-
+            const continueButton = within(popupIframeDocument).queryAllByRole('button', {name: 'Continue'});
             expect(popupFrame).toBeInTheDocument();
             expect(triggerButtonFrame).toBeInTheDocument();
             expect(siteTitle).toBeInTheDocument();
@@ -197,7 +197,8 @@ describe('Signup', () => {
             // expect(fullAccessTitle).toBeInTheDocument();
             expect(signinButton).toBeInTheDocument();
             // expect(submitButton).toBeInTheDocument();
-            expect(chooseBtns).toHaveLength(2);
+            expect(chooseBtns).toHaveLength(1);
+            expect(continueButton).toHaveLength(1);
 
             fireEvent.change(nameInput, {target: {value: 'Jamie Larsen'}});
             fireEvent.change(emailInput, {target: {value: 'jamie@example.com'}});
@@ -232,7 +233,7 @@ describe('Signup', () => {
             expect(yearlyPlanTitle).toBeInTheDocument();
             // expect(fullAccessTitle).toBeInTheDocument();
             expect(signinButton).toBeInTheDocument();
-            expect(chooseBtns).toHaveLength(2);
+            expect(chooseBtns).toHaveLength(1);
 
             fireEvent.change(emailInput, {target: {value: 'jamie@example.com'}});
 
@@ -294,7 +295,7 @@ describe('Signup', () => {
         test('with default settings on monthly plan', async () => {
             const {
                 ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, signinButton, chooseBtns,
-                siteTitle, popupIframeDocument, freePlanTitle, monthlyPlanTitle, yearlyPlanTitle
+                siteTitle, popupIframeDocument, freePlanTitle, monthlyPlanTitle, yearlyPlanTitle, submitButton
             } = await setup({
                 site: FixtureSite.singleTier.basic
             });
@@ -308,7 +309,7 @@ describe('Signup', () => {
             expect(monthlyPlanTitle).toBeInTheDocument();
             expect(yearlyPlanTitle).toBeInTheDocument();
             expect(signinButton).toBeInTheDocument();
-            expect(chooseBtns).toHaveLength(2);
+            expect(chooseBtns).toHaveLength(1);
 
             const monthlyPlanContainer = within(popupIframeDocument).queryByText(/Monthly$/);
             const singleTierProduct = FixtureSite.singleTier.basic.products.find(p => p.type === 'paid');
@@ -322,7 +323,7 @@ describe('Signup', () => {
             await within(popupIframeDocument).findByText(benefitText);
             expect(emailInput).toHaveValue('jamie@example.com');
             expect(nameInput).toHaveValue('Jamie Larsen');
-            fireEvent.click(chooseBtns[1]);
+            fireEvent.click(submitButton);
             expect(ghostApi.member.checkoutPlan).toHaveBeenLastCalledWith({
                 email: 'jamie@example.com',
                 name: 'Jamie Larsen',
@@ -335,8 +336,7 @@ describe('Signup', () => {
 
         test('with default settings on yearly plan', async () => {
             const {
-                ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, signinButton, chooseBtns,
-                siteTitle, popupIframeDocument, freePlanTitle, monthlyPlanTitle, yearlyPlanTitle
+                ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, signinButton, chooseBtns, submitButton, siteTitle, popupIframeDocument, freePlanTitle, monthlyPlanTitle, yearlyPlanTitle
             } = await setup({
                 site: FixtureSite.singleTier.basic
             });
@@ -350,7 +350,7 @@ describe('Signup', () => {
             expect(monthlyPlanTitle).toBeInTheDocument();
             expect(yearlyPlanTitle).toBeInTheDocument();
             expect(signinButton).toBeInTheDocument();
-            expect(chooseBtns).toHaveLength(2);
+            expect(chooseBtns).toHaveLength(1);
 
             const yearlyPlanContainer = within(popupIframeDocument).queryByText(/Yearly$/);
             const singleTierProduct = FixtureSite.singleTier.basic.products.find(p => p.type === 'paid');
@@ -364,7 +364,7 @@ describe('Signup', () => {
             await within(popupIframeDocument).findByText(benefitText);
             expect(emailInput).toHaveValue('jamie@example.com');
             expect(nameInput).toHaveValue('Jamie Larsen');
-            fireEvent.click(chooseBtns[1]);
+            fireEvent.click(submitButton);
             expect(ghostApi.member.checkoutPlan).toHaveBeenLastCalledWith({
                 email: 'jamie@example.com',
                 name: 'Jamie Larsen',
@@ -380,7 +380,7 @@ describe('Signup', () => {
         test('without name field on monthly plan', async () => {
             const {
                 ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, signinButton, chooseBtns,
-                siteTitle, popupIframeDocument, freePlanTitle, monthlyPlanTitle, yearlyPlanTitle
+                siteTitle, popupIframeDocument, freePlanTitle, monthlyPlanTitle, yearlyPlanTitle, submitButton
             } = await setup({
                 site: FixtureSite.singleTier.withoutName
             });
@@ -398,7 +398,7 @@ describe('Signup', () => {
             expect(monthlyPlanTitle).toBeInTheDocument();
             expect(yearlyPlanTitle).toBeInTheDocument();
             expect(signinButton).toBeInTheDocument();
-            expect(chooseBtns).toHaveLength(2);
+            expect(chooseBtns).toHaveLength(1);
 
             fireEvent.change(emailInput, {target: {value: 'jamie@example.com'}});
 
@@ -406,7 +406,7 @@ describe('Signup', () => {
             await within(popupIframeDocument).findByText(benefitText);
 
             expect(emailInput).toHaveValue('jamie@example.com');
-            fireEvent.click(chooseBtns[1]);
+            fireEvent.click(submitButton);
 
             expect(ghostApi.member.checkoutPlan).toHaveBeenLastCalledWith({
                 email: 'jamie@example.com',
diff --git a/ghost/portal/src/utils/api.js b/ghost/portal/src/utils/api.js
index fb4bcc1ba4..83c1db7f0e 100644
--- a/ghost/portal/src/utils/api.js
+++ b/ghost/portal/src/utils/api.js
@@ -354,9 +354,11 @@ function setupGhostApi({siteUrl = window.location.origin, apiUrl, apiKey}) {
                     'Content-Type': 'application/json'
                 },
                 body: JSON.stringify(body)
-            }).then(function (res) {
+            }).then(async function (res) {
                 if (!res.ok) {
-                    throw new Error('Could not create stripe checkout session');
+                    const errData = await res.json();
+                    const errMssg = errData?.errors?.[0]?.message || 'Failed to signup, please try again.';
+                    throw new Error(errMssg);
                 }
                 return res.json();
             }).then(function (result) {
@@ -402,7 +404,7 @@ function setupGhostApi({siteUrl = window.location.origin, apiUrl, apiKey}) {
                 })
             }).then(function (res) {
                 if (!res.ok) {
-                    throw new Error('Could not create stripe checkout session');
+                    throw new Error('Unable to create stripe checkout session');
                 }
                 return res.json();
             }).then(function (result) {