Reputation: 3856
The use case I am working on which is common but I need some suggestions to visualize it. Each user can have multiple projects to which they can subscribe to.
So for example, the User has two projects in his name, Project X and Project Y. Now each has its own subscriptions.
For each project-specific payment how can I tag the customer -> project -> subscription?
I am able to tag customers with subscriptions but not sure how to go about tagging the subscription to a project.
I was thinking something like
Problem with this one I see, if I change the price plans, I will have to update in all the places. :(
What are the best/other alternatives to achieve this? I am using Nextjs with Supabase for this. Following this example. https://github.com/vercel/nextjs-subscription-payments
Upvotes: 0
Views: 1493
Reputation: 413
First, you should create a single product
and some prices
for your subscription plans. The price
represents the entity of your subscription plan.
A lookup_key
is used to retrieve prices dynamically from a static string and if transfer_lookup_key
is set to true, will atomically remove the lookup key from the existing price, and assign it to this price. So you can always retrieve a newest price of the plan by using lookup_key
and set transfer_lookup_key
true.
const product = await stripe.products.create({
name: 'MyService', // your service name
});
const beginnerPrice = await stripe.prices.create({
unit_amount: 5,
currency: 'usd',
recurring: {interval: 'month'},
product: product.id,
lookup_key: 'beginner',
transfer_lookup_key: true,
});
const proPrice = await stripe.prices.create({
unit_amount: 20,
currency: 'usd',
recurring: {interval: 'month'},
product: product.id,
lookup_key: 'pro',
transfer_lookup_key: true,
});
And here is the db schema I assumed to.
// db schema
interface IUser{
id: string
stripeCustomerId: string
}
interface IProject{
id: string
userId: string
}
interface IProjectSubscription{
id: string
projectId: string
stripeSubscriptionId: string // or/and stripeCheckoutSessionId, it's up to your use case
}
When a user create new project and select his/her subscription plan, you will create new checkout.session
and pass corresponding line item with price
. You can get current price
of selected plan by using lookup_key
.
const prices = await stripe.prices.list({
lookup_keys: ['pro'],
type: 'recurring',
limit: 1,
});
const session = await stripe.checkout.sessions.create({
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
payment_method_types: ['card'],
line_items: [
{price: prices[0].id, quantity: 1},
],
mode: 'subscription',
});
Then on checkout.session.completed
, you can receive checkout.session
object and migrate your db in webhook.
Next, let's say you want to change the price of 'pro' plan 20$ to 30$. In that case, you will create new price
with same lookup_key
. By doing so, you can change the subscription price for new subscribers without changing the amount charged to existing subscribers.
const newProPrice = await stripe.prices.create({
unit_amount: 30,
currency: 'usd',
recurring: {interval: 'month'},
product: product.id,
lookup_key: 'pro',
transfer_lookup_key: true,
});
Upvotes: 2
Reputation: 8747
You can use metadata to 'tag' the things in Stripe to map to things in your data model.
If you want to change prices, yes, you'd have to update all the Subscriptions. Instead you might want to look at either using quantities or metered billing. https://stripe.com/docs/billing/subscriptions/model
Upvotes: 1