From a411fecd1a79119930a049292ef89f53c03fdafd Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Thu, 15 Feb 2024 10:47:53 +0000 Subject: [PATCH 1/6] fix: slef-hosted trying to access billing --- src/routes/console/onboarding/+page.svelte | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/routes/console/onboarding/+page.svelte b/src/routes/console/onboarding/+page.svelte index c4cda0b74..af2a1e2ba 100644 --- a/src/routes/console/onboarding/+page.svelte +++ b/src/routes/console/onboarding/+page.svelte @@ -25,16 +25,18 @@ let showCustomId = false; let plan: Tier; - const options = [ - { - value: BillingPlan.STARTER, - label: `Starter - ${formatCurrency($plansInfo.get(BillingPlan.STARTER).price)}/month` - }, - { - value: BillingPlan.PRO, - label: `Pro - ${formatCurrency($plansInfo.get(BillingPlan.PRO).price)}/month + add-ons` - } - ]; + const options = isCloud + ? [ + { + value: BillingPlan.STARTER, + label: `Starter - ${formatCurrency($plansInfo.get(BillingPlan.STARTER).price)}/month` + }, + { + value: BillingPlan.PRO, + label: `Pro - ${formatCurrency($plansInfo.get(BillingPlan.PRO).price)}/month + add-ons` + } + ] + : []; onMount(() => { if (isCloud) { From 7757d8dbb8468e95b60a4a369e052c00ee890175 Mon Sep 17 00:00:00 2001 From: Arman Date: Thu, 15 Feb 2024 11:55:41 +0100 Subject: [PATCH 2/6] feat: missing payment method alert banner --- .../alerts/missingPaymentMethod.svelte | 27 +++++++++++++++++++ src/lib/stores/billing.ts | 20 +++++++++++++- src/routes/console/+layout.svelte | 4 ++- src/routes/console/store.ts | 2 ++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/lib/components/billing/alerts/missingPaymentMethod.svelte diff --git a/src/lib/components/billing/alerts/missingPaymentMethod.svelte b/src/lib/components/billing/alerts/missingPaymentMethod.svelte new file mode 100644 index 000000000..54689ac48 --- /dev/null +++ b/src/lib/components/billing/alerts/missingPaymentMethod.svelte @@ -0,0 +1,27 @@ + + +{#if ($orgMissingPaymentMethod.billingPlan === BillingPlan.PRO || $orgMissingPaymentMethod.billingPlan === BillingPlan.SCALE) && !$orgMissingPaymentMethod.paymentMethodId && !$orgMissingPaymentMethod.backupPaymentMethodId && !$page.url.pathname.includes('/console/account')} + + + Add a payment method to {$orgMissingPaymentMethod.name} before {toLocaleDate( + $orgMissingPaymentMethod.billingCurrentInvoiceDate + )} to avoid service interruptions to your projects. + + + + + +{/if} diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index 22b873828..f05d13381 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -11,9 +11,10 @@ import PaymentAuthRequired from '$lib/components/billing/alerts/paymentAuthRequi import { addNotification, notifications } from './notifications'; import { goto } from '$app/navigation'; import { base } from '$app/paths'; -import { activeHeaderAlert } from '$routes/console/store'; +import { activeHeaderAlert, orgMissingPaymentMethod } from '$routes/console/store'; import MarkedForDeletion from '$lib/components/billing/alerts/markedForDeletion.svelte'; import { BillingPlan } from '$lib/constants'; +import MissingPaymentMethod from '$lib/components/billing/alerts/missingPaymentMethod.svelte'; export type Tier = 'tier-0' | 'tier-1' | 'tier-2'; @@ -265,3 +266,20 @@ export function checkForMarkedForDeletion(org: Organization) { }); } } + +export async function checkForMissingPaymentMethod() { + const orgs = await sdk.forConsole.teams.list([ + Query.notEqual('billingPlan', BillingPlan.STARTER), + Query.isNull('paymentMethodId'), + Query.isNull('backupPaymentMethodId') + ]); + if (orgs?.total) { + orgMissingPaymentMethod.set(orgs.teams[0] as Organization); + headerAlert.add({ + id: 'missingPaymentMethod', + component: MissingPaymentMethod, + show: true, + importance: 8 + }); + } +} diff --git a/src/routes/console/+layout.svelte b/src/routes/console/+layout.svelte index dccfe71a4..2bca1c71d 100644 --- a/src/routes/console/+layout.svelte +++ b/src/routes/console/+layout.svelte @@ -19,7 +19,8 @@ checkPaymentAuthorizationRequired, calculateTrialDay, paymentExpired, - checkForMarkedForDeletion + checkForMarkedForDeletion, + checkForMissingPaymentMethod } from '$lib/stores/billing'; import { goto } from '$app/navigation'; import { CommandCenter, registerCommands, registerSearchers } from '$lib/commandCenter'; @@ -245,6 +246,7 @@ if (isCloud && hasStripePublicKey) { $stripe = await loadStripe(VARS.STRIPE_PUBLIC_KEY); + await checkForMissingPaymentMethod(); } }); diff --git a/src/routes/console/store.ts b/src/routes/console/store.ts index 3dabf7951..662572c6f 100644 --- a/src/routes/console/store.ts +++ b/src/routes/console/store.ts @@ -1,5 +1,6 @@ import { page } from '$app/stores'; import type { HeaderAlert } from '$lib/stores/headerAlert'; +import type { Organization } from '$lib/stores/organization'; import type { Models } from '@appwrite.io/console'; import { derived, writable } from 'svelte/store'; @@ -10,3 +11,4 @@ export const consoleVariables = derived( ); export const activeHeaderAlert = writable(null); +export const orgMissingPaymentMethod = writable(null); From 5a6dce9351da266ced55e55f75dcd55cd93cd759 Mon Sep 17 00:00:00 2001 From: Arman Date: Fri, 16 Feb 2024 09:44:13 +0100 Subject: [PATCH 3/6] fix: add list orgs endpoint --- src/lib/sdk/billing.ts | 18 +++++++++++++++++- src/lib/stores/billing.ts | 4 ++-- src/lib/stores/organization.ts | 5 +++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/lib/sdk/billing.ts b/src/lib/sdk/billing.ts index 698f78377..66bab7a38 100644 --- a/src/lib/sdk/billing.ts +++ b/src/lib/sdk/billing.ts @@ -1,5 +1,5 @@ import type { Client, Models, Query } from '@appwrite.io/console'; -import type { Organization } from '../stores/organization'; +import type { Organization, OrganizationList } from '../stores/organization'; import type { PaymentMethod } from '@stripe/stripe-js'; import type { Tier } from '$lib/stores/billing'; @@ -274,6 +274,22 @@ export class Billing { this.client = client; } + async listOrganization(queries: Query[] = []): Promise { + const path = `/organizations`; + const params = { + queries + }; + const uri = new URL(this.client.config.endpoint + path); + return await this.client.call( + 'GET', + uri, + { + 'content-type': 'application/json' + }, + params + ); + } + async createOrganization( organizationId: string, name: string, diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index f05d13381..9eddc4f45 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -268,13 +268,13 @@ export function checkForMarkedForDeletion(org: Organization) { } export async function checkForMissingPaymentMethod() { - const orgs = await sdk.forConsole.teams.list([ + const orgs = await sdk.forConsole.billing.listOrganization([ Query.notEqual('billingPlan', BillingPlan.STARTER), Query.isNull('paymentMethodId'), Query.isNull('backupPaymentMethodId') ]); if (orgs?.total) { - orgMissingPaymentMethod.set(orgs.teams[0] as Organization); + orgMissingPaymentMethod.set(orgs.organizations[0]); headerAlert.add({ id: 'missingPaymentMethod', component: MissingPaymentMethod, diff --git a/src/lib/stores/organization.ts b/src/lib/stores/organization.ts index 38914e5b0..1a532458a 100644 --- a/src/lib/stores/organization.ts +++ b/src/lib/stores/organization.ts @@ -22,6 +22,11 @@ export type Organization = Models.Team> & { billingPlanDowngrade?: string; }; +export type OrganizationList = { + organizations: Organization[]; + total: number; +}; + export type BillingLimits = { bandwidth: number; documents: number; From 135ebed1880c8c43f4619d59f3c966dbf8035434 Mon Sep 17 00:00:00 2001 From: Arman Date: Fri, 16 Feb 2024 09:54:23 +0100 Subject: [PATCH 4/6] fix: types --- src/lib/stores/billing.ts | 2 +- src/lib/stores/organization.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/stores/billing.ts b/src/lib/stores/billing.ts index 9eddc4f45..141b31f93 100644 --- a/src/lib/stores/billing.ts +++ b/src/lib/stores/billing.ts @@ -274,7 +274,7 @@ export async function checkForMissingPaymentMethod() { Query.isNull('backupPaymentMethodId') ]); if (orgs?.total) { - orgMissingPaymentMethod.set(orgs.organizations[0]); + orgMissingPaymentMethod.set(orgs.teams[0]); headerAlert.add({ id: 'missingPaymentMethod', component: MissingPaymentMethod, diff --git a/src/lib/stores/organization.ts b/src/lib/stores/organization.ts index 1a532458a..2beb13b03 100644 --- a/src/lib/stores/organization.ts +++ b/src/lib/stores/organization.ts @@ -23,7 +23,7 @@ export type Organization = Models.Team> & { }; export type OrganizationList = { - organizations: Organization[]; + teams: Organization[]; total: number; }; From d8c3510ee51ad3cf76a13d6d761390b3adf39b44 Mon Sep 17 00:00:00 2001 From: Arman Date: Fri, 16 Feb 2024 09:59:41 +0100 Subject: [PATCH 5/6] fix: date --- src/lib/components/billing/alerts/missingPaymentMethod.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/billing/alerts/missingPaymentMethod.svelte b/src/lib/components/billing/alerts/missingPaymentMethod.svelte index 54689ac48..312349355 100644 --- a/src/lib/components/billing/alerts/missingPaymentMethod.svelte +++ b/src/lib/components/billing/alerts/missingPaymentMethod.svelte @@ -13,7 +13,7 @@ title={`Payment method required for ${$orgMissingPaymentMethod.name}`}> Add a payment method to {$orgMissingPaymentMethod.name} before {toLocaleDate( - $orgMissingPaymentMethod.billingCurrentInvoiceDate + $orgMissingPaymentMethod.billingNextInvoiceDate )} to avoid service interruptions to your projects. From b03adf5890fa74731387196dc003d3dbbea169c5 Mon Sep 17 00:00:00 2001 From: Arman Date: Fri, 16 Feb 2024 10:06:40 +0100 Subject: [PATCH 6/6] fix: copy --- .../components/billing/alerts/missingPaymentMethod.svelte | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib/components/billing/alerts/missingPaymentMethod.svelte b/src/lib/components/billing/alerts/missingPaymentMethod.svelte index 312349355..b39fd7508 100644 --- a/src/lib/components/billing/alerts/missingPaymentMethod.svelte +++ b/src/lib/components/billing/alerts/missingPaymentMethod.svelte @@ -2,7 +2,6 @@ import { page } from '$app/stores'; import { BillingPlan } from '$lib/constants'; import { Button } from '$lib/elements/forms'; - import { toLocaleDate } from '$lib/helpers/date'; import { HeaderAlert } from '$lib/layout'; import { orgMissingPaymentMethod } from '$routes/console/store'; @@ -12,9 +11,8 @@ type="error" title={`Payment method required for ${$orgMissingPaymentMethod.name}`}> - Add a payment method to {$orgMissingPaymentMethod.name} before {toLocaleDate( - $orgMissingPaymentMethod.billingNextInvoiceDate - )} to avoid service interruptions to your projects. + Add a payment method to {$orgMissingPaymentMethod.name} to avoid service interruptions to + your projects.