#brian_docs

1 messages Β· Page 1 of 1 (latest)

lost leafBOT
#

πŸ‘‹ Welcome to your new thread!

⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

πŸ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1341232945138110656

πŸ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

mental schooner
median herald
mental schooner
median herald
mental schooner
#

maybe can you elaborate more on what you mean by doing everything at an app level?

median herald
#

if (workSpace.usageLimit >= subscription.usageLimit) {
//change plan or charge extra
}```
mental schooner
#

if you're going to add/remove team members, this is feels more suited for a per-seat plan and not metered usage. For metered usage, you don't really have the concept of removal (unless you made a mistake)

#

maybe it'll be best if you can explain your pricing model so that I can better understand what you're looking for

median herald
mental schooner
#

it'll be better if you share the snippets here so that if you come back at a later point, my colleagues can also view what was shared if necessary

median herald
# mental schooner it'll be better if you share the snippets here so that if you come back at a lat...

sure thing;

https://gist.github.com/Astrect/97aab284dd10cd0b9eab2be2a4caa649

so this is a relatively loose implementation of what we currently are doing for meter-based usage, but I guess our current concern is optimizing it further in regards to not relying on so many database lookups to handle quotas and things of that nature;

our pricing model is essentially something along the lines of:

(using an example):

basic: $9/month

  • 3 team members, $10 per team member added
  • 10k events tracked per month, $1 per 5k after
mental schooner
#

alright, gimme a few minutes to go through this and get back to you!

median herald
mental schooner
#

So it seems that you need to have 3 products and prices,

  • one for the $9 / month
  • one for the team members
  • and one for the events
#

how does the team member one work? Is it free for the first 3, then $10 per team member added? Based off what you mention, a team member can be added / removed. Do you intend to prorate? Or charge for the number of team members at the end of the month, or....?

median herald
# mental schooner how does the team member one work? Is it free for the first 3, then $10 per team...

yup you're right on that, base plan includes (let's say 3) team members, and then a charge for additional ones, applied at next billing cycle, we haven't fully decided if we want to charge-immediately or do it at the next cycle, but we can consider next-cycle for this use-case example;

otherwise, from that snippet, the idea is every time that events endpoint is triggered we add +1 to their events created, and after the pro-quota limit rather than restrict usage, just bill for additional usage

mental schooner
#

so right now, just off the top of my head, it looks like you want a tiered pricing model for the team member

#

for the team members, probably something like this

#

thinking about the metered events πŸ€”

median herald
# mental schooner for the team members, probably something like this

that makes sense to me for team members, I was actually just thinking about doing it that way, as it seems like the easiest/least-messy way to approach it;

the main concern we have with the usage-based billing is something along the lines of:

export async function GET(req: NextRequest) {
  const apikey = req.headers.get("x-api-key");

  if (!apikey) {
    return NextResponse.json({ error: "No API key provided" }, { status: 401 });
  }

  const hashedAPIKey = hashAPIKey(apikey);
  const user = await prismadb.user.findUnique({
    where: { apiKey: hashedAPIKey },
  });

  if (!user || !user.active) {
    return NextResponse.json(
      { error: "Invalid API Key / Inactive" },
      { status: 401 }
    );
  }

  const record = await stripe.subscriptionItems.createUsageRecord(user.itemId, {
    quantity: 1,
    timestamp: "now",
    action: "increment",
  });
  
  return NextResponse.json({ data: "πŸ”₯πŸ”₯πŸ”₯πŸ”₯πŸ”₯" });
}```

I know this will work, but correct me if i'm wrong I believe I saw something that stated the usage records have an API rate limit of 1k requests/minute
mental schooner
#

it's higher than that if you use the v2 endpoint : https://docs.stripe.com/api/v2/billing/meter-event/create

Supports up to 1,000 events per second in livemode.

If you need even higher rates, our docs mention to use https://docs.stripe.com/api/v2/billing-meter-stream

#

do you recall where you saw the 1k / minute from?

median herald
# mental schooner it's higher than that if you use the v2 endpoint : https://docs.stripe.com/api/v...

ah yeah, I misread that! πŸ˜… so given that, would you say it's probably fine to track usage directly through stripe? or still control that ourselves and compare it based on the data stripe returns?

my main concern is if stripe were to have an outage of some sort, that it wouldn't impact our app, which makes me think it might be easier to do the event stuff internally, and perhaps have a cron that sends usage data to strip every X hours for each customer

mental schooner
#

I think the key thing to note here is that any company can have an outage, you need to have contingency plans to be able to recover accordingly. For example, maybe your server goes down, that's also a possibility, but most companies would have a backup server to switch to asap as a contingency

#

and yes, what you mentioned does make sense, i.e. to do the event stuff internally, and have a cron that sends usage data to Stripe at specific intervals. It would be easier to recover in case there's an issue.

median herald
#

makes sense, by chance do you guys have any examples of using the v2 stream method?

also hypothetically speaking if one was to be at the scale of 10s of thousands of customers and for some reason were to need higher than that 10k request limit, can one request a limit increase?

mental schooner
median herald
#

makes sense, I appreciate the assistance πŸ™‚ it's good to see stripe's still at the top all these years later, and glad to see you guys continuously improving

#

I'll shoot a ping in here if any other questions arise!

mental schooner
#

sure! this thread will be closed after a while, but you can open a new thread anytime

median herald
#

sounds like a plan, thanks again Alex!

median herald
#

hey @mental schooner apologies for the ping, If a parent company owns multiple products for example, how have you seen them work with stripe? Do they generally use a single stripe account, or an individual account for each product with the same company information provided for verification

mental schooner
#

typically you would just have a single Stripe account, and create multiple products in it

median herald
#

that's what I was thinking! Thanks πŸ™‚ wasn't sure if that would make billing complicated, more so in a scenario of let's say:

I owned Stripe as my parent company, but had Vercel and Twitch as products, wasn't sure if it typically means invoices would be billed as "Stripe, Inc" or if you should still invoice them like "Vercel, Inc" given the stripe account would be under the name Stripe

mental schooner
#

i think maybe you'll want to test things out just to see how things work

#

that'll probably clarify most of your doubts

median herald
#

sounds like a plan, thanks again and apologies for the ping!

mental schooner
#

no worries, we're here to help!

median herald
#

actually, one more thing came to mind, given discount codes/promo codes, do you have any suggestions on the best way to apply them automatically? I'd imagine we could do something like /checkout?plan=1&discount=test and just read the query parameter to apply at the checkout link right

mental schooner
#

it sounds like you're using the Payment Element?

median herald
#

we're actually loading the products on our pricing page from the stripe.products() and stripe.prices() respectfully, and clicking on the purchase button redirects you to the stripe checkout page

mental schooner
#

by stripe checkout page, are you referring to Stripe Checkout Sessions?

median herald
#

our own custom checkout page built in our app πŸ™‚

and we redirect to the stripe checkout page

mental schooner
#

okay, i'm quite confused cause Stripe (sadly) uses the term Checkout for many of our products. We'll need to be specific here so that I can understand how you're currently integrating with us.

Are you creating a Checkout Session? https://stripe.com/docs/api/checkout/sessions/create

median herald
#

yeah, apologies for the terminology lol, but yeah when you click "subscribe" on our pricing page we redirect to the stripe checkout

const session = await stripe.checkout.sessions.create({
    payment_method_types: ['card'],
    line_items: [
      {
        price: priceId,
        quantity: 1
      }
    ],
    mode: 'subscription',
    success_url: `${process.env.BASE_URL}/api/stripe/checkout?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.BASE_URL}/pricing`,
    customer: team.stripeCustomerId || undefined,
    client_reference_id: user.id.toString(),
    allow_promotion_codes: true,
    subscription_data: {
      trial_period_days: 14
    }
  });```

I know we can pass an `allow_promotional_codes` field to enable promo codes, but is there any way to automatically apply a promotional code if any are active
mental schooner
median herald
#

perfect, thank you!