#ironbeard_api

1 messages ยท Page 1 of 1 (latest)

proper otterBOT
#

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

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

wet mesa
#

Can you share the code snippet?

plain python
#

Hmm, well. There's a model/class for Subscription that mirror's stripes (e.g., most of the same fields), and there's a method that serializes our db Subscription models to what Stripe API expects.

That serializing code always sets proration_behavior to always_invoice and then, if the subscription status is active, it sets billing_cycle_anchor to now.

But I think that's an issue, since simply updating a subscription with e.g. a different value for cancel_at_period_end would reset the biling cycle anchor, which I don't think is good.

#
def serialize(self, **kwargs) -> dict:
    data = {
      'cancel_at_period_end': self.cancel_at_period_end,
      'metadata': self.metadata,
      'payment_behavior': 'default_incomplete',
      'payment_settings': {
        'save_default_payment_method': 'on_subscription',
      },
      'proration_behavior': self.PRORATION_BEHAVIOR,
    }

    if self.id:
      # Only specify new SubscriptionItems if updating
      data['items'] = [
        item.serialize()
        for item in self.items.filter(id=None)
      ]
    else:
      # Specify all SubscriptionItems if creating
      data['items'] = [
        item.serialize()
        for item in self.items.all()
      ]

    if self.promotion_code:
      data['promotion_code'] = self.promotion_code.id

    if self.default_payment_method:
      data['default_payment_method'] = self.default_payment_method.id

    if not self.id:
      # Creation requires Customer
      data.update({
        'customer': self.customer.id,  # Creation requires Customer
      })
    elif self.status == 'incomplete':
      # Can't update attributes while incomplete
      data = {'metadata': self.metadata}
    elif self.status == 'active':
      # Can't specify BILLING_CYCLE_ANCHOR during creation, only update
      data.update({
        'billing_cycle_anchor': self.BILLING_CYCLE_ANCHOR,
      })

    data.update(kwargs)
    return data
wet mesa
#

So this is for storing a Subscription to your database?

#

Not calling our api?

#

My understanding is these values should only be used when trying to upgrade/downgrade a subscription, is that correct?
But to answer this, you're correct

#

billing_cycle_anchor can also be set on creation though

plain python
#

The serializing is for converting our db objects to what Stripe API expects

#

I think I'm running into issues because billng_cycle_anchor = now is being set on every update request, but I probably shoud only set it when a Customer is Checking Out and their cart contains an upgrade

wet mesa
#

that will just switch the date/time the subscription is billed on each update

#

which may or may not be what you want

plain python
#

If a user is upgrading, we want them to pay the balance immediately, I think that's why those values were originally coded this way. But I think what I'm realizing is that really they only should be set during the Subscription update call that is involved during checkout, not during any random update (which might not involve an ugprade)

wet mesa
#

proration_behavior=always_invoice is for billing user immediately. passing billing_cycle_anchor is optional. you'd only pass billing_cycle_anchor if you also want to change the date/time that the subscription is billed on a recurring basis

#

so up to you really and your integration's requirements

plain python
#

Gotcha!

#

But, if I want to allow the customer to toggle "cancel_at_period_end," I probably shouldn't send either of those, right?

wet mesa
#

Correct

#

That wouldn't make much sense to me

plain python
#

Thanks! Have a great day!

wet mesa
#

No problem. Same to you!

plain python
#

wait, one last question lol

#

Is there any reason to set proration_behavior = always_invoice on a brand new subscription?

wet mesa
#

In the creation request?

#

If you also set billing_cycle_anchor, then yeah

wet mesa
plain python
#

Right, I just noticed that

wet mesa
#

So basically either prorations will be added to first invoice or no prorations will be created. There's no ability to create a separate invoice for prorations on creation

plain python
#

But, I guess biling_cycle_anchor wasn't being sent in the Subscription creation requests, so the fact that proration_behavior = always_invoice was being sent might have been a no op

#

I think we only want prorations done for upgrades, so probably won't send either of those on creation

#

Okay, thanks again ๐Ÿ™‚