Skip to content

Commit

Permalink
fix: don't update Org with subscription until payment succeeds
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Krick <matt.krick@gmail.com>
  • Loading branch information
mattkrick committed Jul 1, 2024
1 parent 50057a7 commit 56ec729
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ const stripeDeleteSubscription: MutationResolvers['stripeDeleteSubscription'] =
const org: Organization = await dataLoader.get('organizations').load(orgId)

const {stripeSubscriptionId} = org
if (!stripeSubscriptionId) return false

if (stripeSubscriptionId !== subscriptionId) {
throw new Error('Subscription ID does not match')
throw new Error(`Subscription ID does not match: ${stripeSubscriptionId} vs ${subscriptionId}`)
}

await r
Expand Down
29 changes: 8 additions & 21 deletions packages/server/graphql/private/mutations/upgradeToTeamTier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ const upgradeToTeamTier: MutationResolvers['upgradeToTeamTier'] = async (
const userId = getUserId(authToken)
const manager = getStripeManager()
const invoice = await manager.retrieveInvoice(invoiceId)
const customerId = invoice.customer as string
const customer = await manager.retrieveCustomer(customerId)
const stripeId = invoice.customer as string
const stripeSubscriptionId = invoice.subscription as string
const customer = await manager.retrieveCustomer(stripeId)

if (customer.deleted) {
return standardError(new Error('Customer has been deleted'), {userId})
}
Expand All @@ -51,24 +53,7 @@ const upgradeToTeamTier: MutationResolvers['upgradeToTeamTier'] = async (
dataLoader.get('users').loadNonNull(viewerId)
])

const {
stripeId,
tier,
activeDomain,
name: orgName,
stripeSubscriptionId,
trialStartDate
} = organization

if (!stripeId) {
return standardError(new Error('Organization does not have a stripe id'), {
userId: viewerId
})
}

if (!stripeSubscriptionId) {
return standardError(new Error('Organization does not have a subscription'), {userId: viewerId})
}
const {tier, activeDomain, name: orgName, trialStartDate} = organization

if (tier === 'enterprise') {
return standardError(new Error("Can not change an org's plan from enterprise to team"), {
Expand All @@ -93,7 +78,9 @@ const upgradeToTeamTier: MutationResolvers['upgradeToTeamTier'] = async (
scheduledLockAt: null,
lockedAt: null,
updatedAt: now,
trialStartDate: null
trialStartDate: null,
stripeId,
stripeSubscriptionId
})
}).run(),
pg
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Stripe from 'stripe'
import getRethink from '../../../database/rethinkDriver'
import {getUserId} from '../../../utils/authorization'
import {fromEpochSeconds} from '../../../utils/epochTime'
import standardError from '../../../utils/standardError'
import {getStripeManager} from '../../../utils/stripe'
import {MutationResolvers} from '../resolverTypes'
Expand All @@ -12,7 +11,6 @@ const createStripeSubscription: MutationResolvers['createStripeSubscription'] =
{authToken, dataLoader}
) => {
const viewerId = getUserId(authToken)
const now = new Date()
const r = await getRethink()

const [viewer, organization, orgUsersCount, organizationUser] = await Promise.all([
Expand Down Expand Up @@ -44,7 +42,7 @@ const createStripeSubscription: MutationResolvers['createStripeSubscription'] =
const {id: customerId} = customer
const res = await manager.attachPaymentToCustomer(customerId, paymentMethodId)
if (res instanceof Error) return standardError(res, {userId: viewerId})
// wait until the payment is attached to the customer before updating the default payment method
// cannot updateDefaultPaymentMethod until it is attached to the customer
await manager.updateDefaultPaymentMethod(customerId, paymentMethodId)
} else {
customer = await manager.createCustomer(orgId, email, paymentMethodId)
Expand All @@ -56,23 +54,6 @@ const createStripeSubscription: MutationResolvers['createStripeSubscription'] =
const paymentIntent = latestInvoice.payment_intent as Stripe.PaymentIntent
const clientSecret = paymentIntent.client_secret

const subscriptionFields = {
periodEnd: fromEpochSeconds(subscription.current_period_end),
periodStart: fromEpochSeconds(subscription.current_period_start),
stripeSubscriptionId: subscription.id
}

await r({
updatedOrg: r
.table('Organization')
.get(orgId)
.update({
...subscriptionFields,
stripeId: customer.id,
updatedAt: now
})
}).run()

const data = {stripeSubscriptionClientSecret: clientSecret}
return data
}
Expand Down

0 comments on commit 56ec729

Please sign in to comment.