#stiggz_api

1 messages ยท Page 1 of 1 (latest)

simple talonBOT
#

๐Ÿ‘‹ 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/1352037892347662448

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

verbal peak
#

Here's a code snippet that shows what I'm trying to do:

  1. Get the line items for the current subscription from stripe
  2. Create a map from a known enum of our products to the number on the subscription
  3. Convert any legacy products to modern products
  4. Preview the invoice, given the new line items
// handle the modern preview
      const lineItemsBefore: Partial<Record<Product, number>> = {}
      subscription.items.data.forEach((item) => {
        console.log('item', item)
        const quantity = item.quantity ?? 1
        const existing = StripeProduct.fromStripeId(item.plan.product as string)
        if (
          !desiredInterval &&
          ['month', 'year'].includes(item.plan.interval)
        ) {
          desiredInterval = item.plan.interval as IPricing.Interval
        }

        lineItemsBefore[existing.product] =
          (lineItemsBefore[existing.product] ?? 0) + quantity
      })

      if (!desiredInterval) {
        console.warn('No interval provided, defaulting to monthly')
        desiredInterval = IPricing.Interval.Monthly
      }

      const lineItemsAfter = this.convertLegacyProducts(lineItemsBefore)
      console.log('lineItemsBefore', lineItemsBefore)
      console.log('lineItemsAfter', lineItemsAfter)

      // construct final invoice line items

      const items = Object.entries(lineItemsAfter)
        .map(([item, quantity]) => ({
          price: new StripeProduct(item as Product).prices[desiredInterval!],
          quantity,
        }))
        .filter((s) => s.quantity > 0)
      console.log('final line items', items)

      const invoice = await Stripe.client.invoices.retrieveUpcoming({
        customer: subscription.customer.id,
        subscription: subscription.id,
        subscription_details: {
          proration_behavior: 'always_invoice',
          items,
        },
      })
#

The ideal thing might actually be to be able to set a fixed discount amount when calling retrieveUpcoming or the corresponding subscription.update. That way, I could do the following:

  1. Check the user's usage of their current subscription since the billing start date
  2. Calculate the appropriate discount, and manually apply it, resetting the billing period start date to today
green prism
#

Hi there, looking

verbal peak
#

Thanks!

green prism
verbal peak
#

One moment, browser doesn't like that cert

#

Yes, but from the docs it's somewhat unclear what the behavior of items is. The example shown there passes {id: string, price: string} for each item. Am I allowed to drop/add items? I.e., is the items parameter a comprehensive override of the existing items on the subscription?

#

It sort of appears that what might be happening is when I don't specify an {id}, it's interpreted as a new item. i.e., items can only be added, but not removed?

#

In the example I'm working with, a subscription has a single item (quantity 1), priced at $1000, and I'm trying to replace it with a new item (quantity 5), where each item is priced at $200. I would expect such a change to be effectively free, since the total price of the new subscription is equal to the total price of the old subscription

simple talonBOT
verbal peak
#

Yeah, in messing around a little further, if I specify the id of the previous item, it looks correct. If I don't specify an id, it's additive. Is there a way to preview with something like remove_item_ids: []?

fierce sparrow
#

Hi hi! Iโ€™m going to be taking over for my colleague here; can you please summarize your issue/question for me?

verbal peak
#

Sure, are you able to see the previous messages?

fierce sparrow
#

Yes, but often the original question morphs over time so I just wanted to find out where things were at.

verbal peak
#

Fair enough. The question is about the behavior of the subscription_details.items argument when calling invoices.retrieveUpcoming or subscription.update. What I'm wanting is to preview/update a subscription, removing some items, and adding others. But it looks like all I can do is update existing items or add more items

#

i.e., it seems like the behavior is items = merge(existingItems, newItems) rather than items = newItems.

#

(on your end)

#

Oh wait, maybe what I want is the deleted flag on items!

fierce sparrow
#

Yes. ๐Ÿ™‚

#

The ones you want removed, yes.

verbal peak
#

Ok that gets me most of the way there I think. The next question is about how to have more fine-grained control over the final invoice. If I wanted to apply a discount of say, exactly $10, but that discount is calculated on the fly when we call retrieveUpcoming, would that be possible?

#

The use case is that our subscriptions grant credits to users, which can then be consumed. If the user is halfway through their subscription, but all the way through their credits when they upgrade their subscription, the easiest thing would probably be to calculate a discount, issue it against the full price of the new subscription item, and reset their billing cycle

#

As an example, imagine we have 2 plans, standard and pro, which have 500 and 1000 monthly credits respectively, and are priced at $20 and $40/mo. If the user was on standard and exhausts all of their credit usage, then upgrades to pro, we'd want to charge them $20, the difference in price between standard and pro, regardless of where they are in the billing cycle

fierce sparrow
#

So, that call to see the 'upcoming invoice' will not actually change the Subscription - you're aware of that, right?

verbal peak
#

Yes, but the corresponding call to subscription.update which has a very similar method signature will

#

The idea is to show retrieveUpcoming and then call subscription.update a few moments later after the user confirms

fierce sparrow
verbal peak
#

That might pollute my stripe dashboard with a bunch of one-off programatically created coupons though

#

I suppose I could also manipulate proration_date to achieve a similar effect...

fierce sparrow
#

Does that answer your question? Or is there still the question of how to structure things given your usecase?

verbal peak
#

I think we're good! I'll follow up if I have more questions

#

Thanks so much!

fierce sparrow
#

Awesome! We do close idle threads, but if this is closed, just make a new one - the closed threads are always visible to you and to us. ๐Ÿ™‚