MCPcopy Index your code
hub / github.com/simstudioai/sim / purchaseCredits

Function purchaseCredits

apps/sim/lib/billing/credits/purchase.ts:105–233  ·  view source on GitHub ↗
(params: PurchaseCreditsParams)

Source from the content-addressed store, hash-verified

103}
104
105export async function purchaseCredits(params: PurchaseCreditsParams): Promise<PurchaseResult> {
106 const { userId, amountDollars, requestId } = params
107
108 if (amountDollars < 10 || amountDollars > 1000) {
109 return { success: false, error: 'Amount must be between $10 and $1000' }
110 }
111
112 const canPurchase = await canPurchaseCredits(userId)
113 if (!canPurchase) {
114 return { success: false, error: 'Only Pro and Team users can purchase credits' }
115 }
116
117 const subscription = await getHighestPrioritySubscription(userId)
118 if (!subscription || !subscription.stripeSubscriptionId) {
119 return { success: false, error: 'No active subscription found' }
120 }
121
122 // Enterprise users must contact support
123 if (isEnterprise(subscription.plan)) {
124 return { success: false, error: 'Enterprise users must contact support to purchase credits' }
125 }
126
127 let entityType: 'user' | 'organization' = 'user'
128 let entityId = userId
129
130 // Org-scoped subs route credit purchases to the organization and must be authorized
131 // by an org owner/admin. We've already rejected enterprise above.
132 if (isOrgScopedSubscription(subscription, userId)) {
133 const isAdmin = await isOrganizationOwnerOrAdmin(userId, subscription.referenceId)
134 if (!isAdmin) {
135 return { success: false, error: 'Only organization owners and admins can purchase credits' }
136 }
137 entityType = 'organization'
138 entityId = subscription.referenceId
139 }
140
141 try {
142 const stripe = requireStripeClient()
143
144 const stripeSub = await stripe.subscriptions.retrieve(subscription.stripeSubscriptionId)
145 const customerId = getCustomerId(stripeSub.customer)
146 if (!customerId) {
147 return { success: false, error: 'Subscription missing customer' }
148 }
149
150 const { paymentMethodId: defaultPaymentMethod } = await resolveDefaultPaymentMethod(
151 stripe,
152 subscription.stripeSubscriptionId,
153 customerId
154 )
155
156 if (!defaultPaymentMethod) {
157 return {
158 success: false,
159 error: 'No payment method on file. Please update your billing info.',
160 }
161 }
162

Callers 1

route.tsFile · 0.90

Calls 12

canPurchaseCreditsFunction · 0.90
isEnterpriseFunction · 0.90
isOrgScopedSubscriptionFunction · 0.90
requireStripeClientFunction · 0.90
getCustomerIdFunction · 0.90
getErrorMessageFunction · 0.90
infoMethod · 0.80
errorMethod · 0.80
toStringMethod · 0.45

Tested by

no test coverage detected