diff --git a/apps/api/src/app/subscription/subscription.controller.ts b/apps/api/src/app/subscription/subscription.controller.ts index 244a6b806..e1c705fdd 100644 --- a/apps/api/src/app/subscription/subscription.controller.ts +++ b/apps/api/src/app/subscription/subscription.controller.ts @@ -5,7 +5,10 @@ import { DEFAULT_LANGUAGE_CODE, PROPERTY_COUPONS } from '@ghostfolio/common/config'; -import { Coupon } from '@ghostfolio/common/interfaces'; +import { + Coupon, + CreateStripeCheckoutSessionResponse +} from '@ghostfolio/common/interfaces'; import type { RequestWithUser } from '@ghostfolio/common/types'; import { @@ -111,11 +114,11 @@ export class SubscriptionController { @Post('stripe/checkout-session') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) - public async createCheckoutSession( + public createStripeCheckoutSession( @Body() { couponId, priceId }: { couponId?: string; priceId: string } - ) { + ): Promise { try { - return this.subscriptionService.createCheckoutSession({ + return this.subscriptionService.createStripeCheckoutSession({ couponId, priceId, user: this.request.user diff --git a/apps/api/src/app/subscription/subscription.service.ts b/apps/api/src/app/subscription/subscription.service.ts index 9574d17e9..37ab1c0f6 100644 --- a/apps/api/src/app/subscription/subscription.service.ts +++ b/apps/api/src/app/subscription/subscription.service.ts @@ -6,7 +6,10 @@ import { PROPERTY_STRIPE_CONFIG } from '@ghostfolio/common/config'; import { parseDate } from '@ghostfolio/common/helper'; -import { SubscriptionOffer } from '@ghostfolio/common/interfaces'; +import { + CreateStripeCheckoutSessionResponse, + SubscriptionOffer +} from '@ghostfolio/common/interfaces'; import { SubscriptionOfferKey, UserWithSettings @@ -38,7 +41,7 @@ export class SubscriptionService { } } - public async createCheckoutSession({ + public async createStripeCheckoutSession({ couponId, priceId, user @@ -46,7 +49,7 @@ export class SubscriptionService { couponId?: string; priceId: string; user: UserWithSettings; - }) { + }): Promise { const subscriptionOffers: { [offer in SubscriptionOfferKey]: SubscriptionOffer; } = @@ -58,33 +61,34 @@ export class SubscriptionService { } ); - const checkoutSessionCreateParams: Stripe.Checkout.SessionCreateParams = { - cancel_url: `${this.configurationService.get('ROOT_URL')}/${ - user.settings.settings.language - }/account`, - client_reference_id: user.id, - line_items: [ - { - price: priceId, - quantity: 1 - } - ], - locale: - (user.settings?.settings - ?.language as Stripe.Checkout.SessionCreateParams.Locale) ?? - DEFAULT_LANGUAGE_CODE, - metadata: subscriptionOffer - ? { subscriptionOffer: JSON.stringify(subscriptionOffer) } - : {}, - mode: 'payment', - payment_method_types: ['card'], - success_url: `${this.configurationService.get( - 'ROOT_URL' - )}/api/v1/subscription/stripe/callback?checkoutSessionId={CHECKOUT_SESSION_ID}` - }; + const stripeCheckoutSessionCreateParams: Stripe.Checkout.SessionCreateParams = + { + cancel_url: `${this.configurationService.get('ROOT_URL')}/${ + user.settings.settings.language + }/account`, + client_reference_id: user.id, + line_items: [ + { + price: priceId, + quantity: 1 + } + ], + locale: + (user.settings?.settings + ?.language as Stripe.Checkout.SessionCreateParams.Locale) ?? + DEFAULT_LANGUAGE_CODE, + metadata: subscriptionOffer + ? { subscriptionOffer: JSON.stringify(subscriptionOffer) } + : {}, + mode: 'payment', + payment_method_types: ['card'], + success_url: `${this.configurationService.get( + 'ROOT_URL' + )}/api/v1/subscription/stripe/callback?checkoutSessionId={CHECKOUT_SESSION_ID}` + }; if (couponId) { - checkoutSessionCreateParams.discounts = [ + stripeCheckoutSessionCreateParams.discounts = [ { coupon: couponId } @@ -92,7 +96,7 @@ export class SubscriptionService { } const session = await this.stripe.checkout.sessions.create( - checkoutSessionCreateParams + stripeCheckoutSessionCreateParams ); return { diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts index f2f63b32b..025ec0f7a 100644 --- a/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts @@ -108,7 +108,10 @@ export class GfUserAccountMembershipComponent implements OnDestroy { public onCheckout() { this.dataService - .createCheckoutSession({ couponId: this.couponId, priceId: this.priceId }) + .createStripeCheckoutSession({ + couponId: this.couponId, + priceId: this.priceId + }) .pipe( catchError((error) => { this.notificationService.alert({ @@ -117,7 +120,7 @@ export class GfUserAccountMembershipComponent implements OnDestroy { throw error; }), - switchMap(({ sessionId }: { sessionId: string }) => { + switchMap(({ sessionId }) => { return this.stripeService.redirectToCheckout({ sessionId }); }) ) diff --git a/apps/client/src/app/pages/pricing/pricing-page.component.ts b/apps/client/src/app/pages/pricing/pricing-page.component.ts index 8bc3e3a67..82560246f 100644 --- a/apps/client/src/app/pages/pricing/pricing-page.component.ts +++ b/apps/client/src/app/pages/pricing/pricing-page.component.ts @@ -134,9 +134,12 @@ export class GfPricingPageComponent implements OnDestroy, OnInit { public onCheckout() { this.dataService - .createCheckoutSession({ couponId: this.couponId, priceId: this.priceId }) + .createStripeCheckoutSession({ + couponId: this.couponId, + priceId: this.priceId + }) .pipe( - switchMap(({ sessionId }: { sessionId: string }) => { + switchMap(({ sessionId }) => { return this.stripeService.redirectToCheckout({ sessionId }); }), catchError((error) => { diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index 549675f7f..a32bc6d3e 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -31,6 +31,7 @@ import { AssetResponse, BenchmarkMarketDataDetailsResponse, BenchmarkResponse, + CreateStripeCheckoutSessionResponse, DataProviderHealthResponse, ExportResponse, Filter, @@ -168,17 +169,20 @@ export class DataService { return params; } - public createCheckoutSession({ + public createStripeCheckoutSession({ couponId, priceId }: { couponId?: string; priceId: string; }) { - return this.http.post('/api/v1/subscription/stripe/checkout-session', { - couponId, - priceId - }); + return this.http.post( + '/api/v1/subscription/stripe/checkout-session', + { + couponId, + priceId + } + ); } public fetchAccount(aAccountId: string) { diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index e3c2c2038..828a65974 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -43,6 +43,7 @@ import type { ApiKeyResponse } from './responses/api-key-response.interface'; import type { AssetResponse } from './responses/asset-response.interface'; import type { BenchmarkMarketDataDetailsResponse } from './responses/benchmark-market-data-details-response.interface'; import type { BenchmarkResponse } from './responses/benchmark-response.interface'; +import type { CreateStripeCheckoutSessionResponse } from './responses/create-stripe-checkout-session-response.interface'; import type { DataEnhancerHealthResponse } from './responses/data-enhancer-health-response.interface'; import type { DataProviderGhostfolioAssetProfileResponse } from './responses/data-provider-ghostfolio-asset-profile-response.interface'; import type { DataProviderGhostfolioStatusResponse } from './responses/data-provider-ghostfolio-status-response.interface'; @@ -100,6 +101,7 @@ export { BenchmarkProperty, BenchmarkResponse, Coupon, + CreateStripeCheckoutSessionResponse, DataEnhancerHealthResponse, DataProviderGhostfolioAssetProfileResponse, DataProviderGhostfolioStatusResponse, diff --git a/libs/common/src/lib/interfaces/responses/create-stripe-checkout-session-response.interface.ts b/libs/common/src/lib/interfaces/responses/create-stripe-checkout-session-response.interface.ts new file mode 100644 index 000000000..18c9e4400 --- /dev/null +++ b/libs/common/src/lib/interfaces/responses/create-stripe-checkout-session-response.interface.ts @@ -0,0 +1,3 @@ +export interface CreateStripeCheckoutSessionResponse { + sessionId: string; +}