Skip to content

Commit

Permalink
Send Payment method id in checkout session (#9932)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrFlashAccount authored May 13, 2024
1 parent ff28737 commit 2ed83f2
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 13 deletions.
2 changes: 1 addition & 1 deletion app/ide-desktop/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export default [
eslintJs.configs.recommended,
{
// Playwright build cache.
ignores: ['**/.cache/**', '**/playwright-report'],
ignores: ['**/.cache/**', '**/playwright-report', 'dist'],
},
{
settings: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ import * as backendModule from '#/services/Backend'
import * as components from './components'
import * as componentForPlan from './getComponentForPlan'

/**
* The mutation data for the `onCompleteMutation` mutation.
*/
interface CreateCheckoutSessionMutation {
readonly plan: backendModule.Plan
readonly paymentMethodId: string
}

/** A page in which the currently active payment plan can be changed.
*
* This page can be in one of several states:
Expand Down Expand Up @@ -74,13 +82,16 @@ export function Subscribe() {
})

const onCompleteMutation = reactQuery.useMutation({
mutationFn: async (userSelectedPlan: backendModule.Plan) => {
const { id } = await backend.createCheckoutSession(userSelectedPlan)
mutationFn: async (mutationData: CreateCheckoutSessionMutation) => {
const { id } = await backend.createCheckoutSession({
plan: mutationData.plan,
paymentMethodId: mutationData.paymentMethodId,
})
return backend.getCheckoutSession(id)
},
onSuccess: (data, userSelectedPlan) => {
onSuccess: (data, mutationData) => {
if (data.status === 'complete') {
navigate({ pathname: appUtils.SUBSCRIBE_SUCCESS_PATH, search: `plan=${userSelectedPlan}` })
navigate({ pathname: appUtils.SUBSCRIBE_SUCCESS_PATH, search: `plan=${mutationData.plan}` })
return
} else {
throw new Error(
Expand Down Expand Up @@ -128,8 +139,11 @@ export function Subscribe() {
title={planProps.title}
submitButton={
<planProps.submitButton
onSubmit={async () => {
await onCompleteMutation.mutateAsync(newPlan)
onSubmit={async paymentMethodId => {
await onCompleteMutation.mutateAsync({
plan: newPlan,
paymentMethodId,
})
}}
elements={elements}
stripe={stripeInstance}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import * as ariaComponents from '#/components/AriaComponents'
export interface SubscribeFormProps {
readonly stripe: stripeJs.Stripe
readonly elements: stripeJs.StripeElements
readonly onSubmit: (paymentMethod: stripeJs.PaymentMethod) => Promise<void>
readonly onSubmit: (paymentMethodId: stripeJs.PaymentMethod['id']) => Promise<void>
}

/**
Expand Down Expand Up @@ -49,7 +49,7 @@ export function SubscribeForm(props: SubscribeFormProps) {
}
},
onSuccess: async paymentMethod => {
await onSubmit(paymentMethod.paymentMethod)
await onSubmit(paymentMethod.paymentMethod.id)
cardElement?.clear()
},
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import * as components from './components'
* The props for the submit button.
*/
interface SubmitButtonProps {
readonly onSubmit: () => Promise<void>
readonly onSubmit: (paymentMethodId: string) => Promise<void>
readonly elements: stripeJs.StripeElements
readonly stripe: stripeJs.Stripe
readonly plan: backendModule.Plan
Expand Down
13 changes: 12 additions & 1 deletion app/ide-desktop/lib/dashboard/src/services/Backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,7 @@ export interface CreateUserGroupRequestBody {
/** HTTP request body for the "create checkout session" endpoint. */
export interface CreateCheckoutSessionRequestBody {
readonly plan: Plan
readonly paymentMethodId: string
}

/** URL query string parameters for the "list directory" endpoint. */
Expand Down Expand Up @@ -1119,6 +1120,14 @@ export interface ListVersionsRequestParams {
readonly default: boolean
}

/**
* POST request body for the "create checkout session" endpoint.
*/
export interface CreateCheckoutSessionRequestParams {
readonly plan: Plan
readonly paymentMethodId: string
}

// ==============================
// === detectVersionLifecycle ===
// ==============================
Expand Down Expand Up @@ -1346,7 +1355,9 @@ export default abstract class Backend {
/** Return a list of backend or IDE versions. */
abstract listVersions(params: ListVersionsRequestParams): Promise<Version[]>
/** Create a payment checkout session. */
abstract createCheckoutSession(plan: Plan): Promise<CheckoutSession>
abstract createCheckoutSession(
params: CreateCheckoutSessionRequestParams
): Promise<CheckoutSession>
/** Get the status of a payment checkout session. */
abstract getCheckoutSession(sessionId: CheckoutSessionId): Promise<CheckoutSessionStatus>
/** List events in the organization's audit log. */
Expand Down
8 changes: 6 additions & 2 deletions app/ide-desktop/lib/dashboard/src/services/RemoteBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -934,10 +934,14 @@ export default class RemoteBackend extends Backend {

/** Create a payment checkout session.
* @throws An error if a non-successful status code (not 200-299) was received. */
override async createCheckoutSession(plan: backend.Plan): Promise<backend.CheckoutSession> {
override async createCheckoutSession(
params: backend.CreateCheckoutSessionRequestParams
): Promise<backend.CheckoutSession> {
const { plan, paymentMethodId } = params

const response = await this.post<backend.CheckoutSession>(
remoteBackendPaths.CREATE_CHECKOUT_SESSION_PATH,
{ plan } satisfies backend.CreateCheckoutSessionRequestBody
{ plan, paymentMethodId } satisfies backend.CreateCheckoutSessionRequestBody
)
if (!responseIsSuccessful(response)) {
return await this.throw(response, 'createCheckoutSessionBackendError', plan)
Expand Down

0 comments on commit 2ed83f2

Please sign in to comment.