diff --git a/packages/backend/server/src/modules/payment/resolver.ts b/packages/backend/server/src/modules/payment/resolver.ts index a7ef4b7cc4..653cd06466 100644 --- a/packages/backend/server/src/modules/payment/resolver.ts +++ b/packages/backend/server/src/modules/payment/resolver.ts @@ -194,8 +194,7 @@ export class SubscriptionResolver { const session = await this.service.createCheckoutSession({ user, recurring, - // TODO: replace with frontend url - redirectUrl: `${this.config.baseUrl}/api/stripe/success`, + redirectUrl: `${this.config.baseUrl}/upgrade-success`, }); if (!session.url) { diff --git a/packages/backend/server/src/modules/payment/webhook.ts b/packages/backend/server/src/modules/payment/webhook.ts index 1fda0b6411..13f692132d 100644 --- a/packages/backend/server/src/modules/payment/webhook.ts +++ b/packages/backend/server/src/modules/payment/webhook.ts @@ -1,20 +1,16 @@ import type { RawBodyRequest } from '@nestjs/common'; import { Controller, - Get, Logger, NotAcceptableException, Post, Req, } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; -import type { User } from '@prisma/client'; import type { Request } from 'express'; import Stripe from 'stripe'; import { Config } from '../../config'; -import { PrismaService } from '../../prisma'; -import { Auth, CurrentUser } from '../auth'; @Controller('/api/stripe') export class StripeWebhook { @@ -24,23 +20,11 @@ export class StripeWebhook { constructor( config: Config, private readonly stripe: Stripe, - private readonly event: EventEmitter2, - private readonly db: PrismaService + private readonly event: EventEmitter2 ) { this.config = config.payment; } - // just for test - @Auth() - @Get('/success') - async handleSuccess(@CurrentUser() user: User) { - return this.db.userSubscription.findUnique({ - where: { - userId: user.id, - }, - }); - } - @Post('/webhook') async handleWebhook(@Req() req: RawBodyRequest) { // Check if webhook signing is configured. diff --git a/packages/frontend/core/src/pages/upgrade-success.css.ts b/packages/frontend/core/src/pages/upgrade-success.css.ts new file mode 100644 index 0000000000..4183c5ae7f --- /dev/null +++ b/packages/frontend/core/src/pages/upgrade-success.css.ts @@ -0,0 +1,93 @@ +import { style } from '@vanilla-extract/css'; + +export const root = style({ + height: '100vh', + width: '100vw', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + fontSize: 'var(--affine-font-base)', + position: 'relative', +}); + +export const affineLogo = style({ + color: 'inherit', +}); + +export const topNav = style({ + position: 'absolute', + top: 0, + left: 0, + right: 0, + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + padding: '16px 120px', +}); + +export const topNavLinks = style({ + display: 'flex', + columnGap: 4, +}); + +export const topNavLink = style({ + color: 'var(--affine-text-primary-color)', + fontSize: 'var(--affine-font-sm)', + fontWeight: 500, + textDecoration: 'none', + padding: '4px 18px', +}); + +export const tryAgainLink = style({ + color: 'var(--affine-link-color)', + fontWeight: 500, + textDecoration: 'none', + fontSize: 'var(--affine-font-sm)', +}); + +export const centerContent = style({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + marginTop: 40, +}); + +export const prompt = style({ + marginTop: 20, + marginBottom: 12, +}); + +export const body = style({ + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + width: '100%', + flexWrap: 'wrap', + gap: '48px', + padding: '0 20px', +}); + +export const leftContainer = style({ + display: 'flex', + flexDirection: 'column', + width: '548px', + gap: '28px', +}); +export const leftContentTitle = style({ + fontSize: 'var(--affine-font-title)', + fontWeight: 700, + minHeight: '44px', +}); +export const leftContentText = style({ + fontSize: 'var(--affine-font-base)', + fontWeight: 400, + lineHeight: '1.6', +}); + +export const mail = style({ + color: 'var(--affine-link-color)', + textDecoration: 'none', + ':visited': { + color: 'var(--affine-link-color)', + }, +}); diff --git a/packages/frontend/core/src/pages/upgrade-success.tsx b/packages/frontend/core/src/pages/upgrade-success.tsx new file mode 100644 index 0000000000..a8af870ead --- /dev/null +++ b/packages/frontend/core/src/pages/upgrade-success.tsx @@ -0,0 +1,105 @@ +import { Empty } from '@affine/component'; +import { Trans } from '@affine/i18n'; +import { useAFFiNEI18N } from '@affine/i18n/hooks'; +import { Logo1Icon } from '@blocksuite/icons'; +import { Button } from '@toeverything/components/button'; +import { useCallback } from 'react'; + +import { useNavigateHelper } from '../hooks/use-navigate-helper'; +import * as styles from './upgrade-success.css'; + +export const UpgradeSuccess = () => { + const t = useAFFiNEI18N(); + + const openDownloadLink = useCallback(() => { + const url = `https://affine.pro/download`; + open(url, '_blank'); + }, []); + + const { jumpToIndex } = useNavigateHelper(); + const openAffine = useCallback(() => { + jumpToIndex(); + }, [jumpToIndex]); + + return ( +
+
+ + + + +
+ + {t['com.affine.other-page.nav.official-website']()} + + + {t['com.affine.other-page.nav.affine-community']()} + + + {t['com.affine.other-page.nav.blog']()} + + + {t['com.affine.other-page.nav.contact-us']()} + +
+ + +
+
+
+
+ {t['com.affine.payment.upgrade-success-page.title']()} +
+
+ {t['com.affine.payment.upgrade-success-page.text']()} +
+ + ), + }} + /> +
+
+
+ +
+
+ +
+
+ ); +}; + +export const Component = () => { + return ; +}; diff --git a/packages/frontend/core/src/router.ts b/packages/frontend/core/src/router.ts index b067d9d7e8..944bbded39 100644 --- a/packages/frontend/core/src/router.ts +++ b/packages/frontend/core/src/router.ts @@ -52,6 +52,10 @@ export const routes = [ path: '/open-app/:action', lazy: () => import('./pages/open-app'), }, + { + path: '/upgrade-success', + lazy: () => import('./pages/upgrade-success'), + }, { path: '/desktop-signin', lazy: () => import('./pages/desktop-signin'), diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index 52fad8b4fb..813d159582 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -712,5 +712,14 @@ "com.affine.payment.billing-setting.no-invoice": "There are no invoices to display.", "com.affine.payment.billing-setting.paid": "Paid", "com.affine.payment.billing-setting.view-invoice": "View Invoice", + "com.affine.payment.upgrade-success-page.title": "Upgrade Successful!", + "com.affine.payment.upgrade-success-page.text": "Congratulations! Your AFFiNE account has been successfully upgraded to a Pro account.", + "com.affine.payment.upgrade-success-page.support": "If you have any questions, please contact our <1> customer support.", + "com.affine.other-page.nav.official-website": "Official Website", + "com.affine.other-page.nav.affine-community": "AFFiNE Community", + "com.affine.other-page.nav.blog": "Blog", + "com.affine.other-page.nav.contact-us": "Contact us", + "com.affine.other-page.nav.download-app": "Download App", + "com.affine.other-page.nav.open-affine": "Open AFFiNE", "com.affine.payment.member.description": "Manage members here. {{planName}} Users can invite up to {{memberLimit}}" }