Subhendu Kundu
Subhendu Kundu

Reputation: 3856

Add stipe stripe subscriptions for different projects of each user

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

  1. On user create, adding a customer.
  2. On project create add a product with prices.
  3. The checkout
  4. Session
  5. Subscriptions/ checkout completed
  6. update DB

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

Answers (2)

nico
nico

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

floatingLomas
floatingLomas

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

Related Questions