#jeff-sexton_unexpected

1 messages ยท Page 1 of 1 (latest)

glossy zodiacBOT
#

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

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

granite peak
#

Hi there! I'll be right with you

bright crest
#

I generated a script that will reproduce the issue as it occurred for one of our production subscriptions. I can share it if you would like.

#

I also noted in the documentation here that

Manage recurring payments through subscription lifecycles including creation, trials, invoice generation, payment collection, updates, and cancellations.

#

past_due Payment on the latest finalized invoice either failed or wasnโ€™t attempted. The subscription continues to create invoices. Your Dashboard subscription settings determine the subscriptionโ€™s next status. If the invoice is still unpaid after all attempted smart retries, you can configure the subscription to move to canceled, unpaid, or leave it as past_due. To reactivate the subscription, have your customer pay the most recent invoice. The subscription status becomes active regardless of whether the payment is done before or after the latest invoice due date.

#

This seems to indicate the status is expected when the latest invoice is voided but that leaves the customer in a weird state, potentially for a long time.

#

Bash script using the Stripe CLI to reproduce:

glossy zodiacBOT
#

๐Ÿง‘โ€๐Ÿ’ป How to format code on Discord

Inline code: wrap in single backticks (`)

This:

The variable `foo` contains the value `bar`.

Will turn into this:

The variable foo contains the value bar.

Code blocks: wrap in three backticks (```)

Also, you can specify the language after the first three backticks to get syntax highlighting.

This:

```javascript
function foo() {
return 'bar';
}
```

Will turn into this:

function foo() {
  return 'bar';
}```

Notes about **code blocks**:
- Specifying the language is optional (e.g., you can omit `javascript` in the example above)
  - If you don't specify the language you won't get syntax highlighting
- When you're inside a code block (after you type \`\`\`) the `Return`/`Enter` key will add a new line instead of sending your message
  - Once you end the code block `Return`/`Enter` works normally again

You can [read more about message formatting on Discord's website.](https://support.discord.com/hc/en-us/articles/210298617)
bright crest
granite peak
#

Thanks for waiting. I'm happy to take a look at a specific Subscription, but you found the right docs page and this is (likely) expected behavior. When a new Invoice is generated on the Subscription and is paid, then the Subscription's status will transition back to active

bright crest
#

That same documentation also indicates:

#

Invoices marked as uncollectable keep the underlying subscription active. Stripe ignores voided invoices when determining subscription status and uses the most recent non-voided invoice instead.

#

Depending on how I squint at different parts of the docs, it looks like either this is the expected state or that the voided invoice should be ignored and the latest non-voided invoice (which is paid) should be used to determine status.

#

Here's an example case on our Dev instance Resources Created:
Customer: cus_TPcXfY2TXBspU6
Subscription: sub_1SSnITDAWTp2PXOwkcV57KYe (Quantity: 2)
First Invoice: in_1SSnIeDAWTp2PXOwZxWZ4tHR [PAID]
Second Invoice: in_1SSnIkDAWTp2PXOwqz5eSqhG [VOIDED]

View in Stripe Dashboard:
Subscription: https://dashboard.stripe.com/test/subscriptions/sub_1SSnITDAWTp2PXOwkcV57KYe
Customer: https://dashboard.stripe.com/test/customers/cus_TPcXfY2TXBspU6
First Invoice: https://dashboard.stripe.com/test/invoices/in_1SSnIeDAWTp2PXOwZxWZ4tHR
Second Invoice: https://dashboard.stripe.com/test/invoices/in_1SSnIkDAWTp2PXOwqz5eSqhG

#

That's on account: acct_1GIGBBDAWTp2PXOw

granite peak
#

looking

#

(sorry for the delay - helping other folks as well)

bright crest
#

No worries

granite peak
#

by the way, are you aware of our Test Clocks feature? I highly recommend it for testing Subscriptions

bright crest
#

I am. In this case, the scenario I'm trying to match was for two immediate prorated invoices as opposed to scheduled subscription invoices.

granite peak
#

Gotcha

#

at least you're using them! It amazes me how many people live without them

bright crest
#

They are very useful. I even integrated them into our dev test environment so we can continue to calculate proration dates correctly when a Test Clock is in use.

#

Ah! Interesting. With this scenario, if I change the order of the open invoice processing, I'm able to end up in an Active state

granite peak
#

I think what happened here is that in_1SSnIkDAWTp2PXOwqz5eSqhG was voided and in_1SSnIeDAWTp2PXOwZxWZ4tHR was paid nearly concurrently

bright crest
#

Hmmm, could be. I can add a delay and re-generate the scenario. The test case definitely matches what happened in our Production example and, in that case, the operations were minutes apart.

#

A new example scenario with 3 second delays between the steps:

Resources Created:
Customer: cus_TPcu3fI9sL3ZPA
Subscription: sub_1SSnfCDAWTp2PXOwwSpYsGJT (Quantity: 2)
First Invoice: in_1SSnfKDAWTp2PXOw0usXXX3R [PAID]
Second Invoice: in_1SSnfRDAWTp2PXOwFXIEaM3b [VOIDED]

View in Stripe Dashboard:
Subscription: https://dashboard.stripe.com/test/subscriptions/sub_1SSnfCDAWTp2PXOwwSpYsGJT
Customer: https://dashboard.stripe.com/test/customers/cus_TPcu3fI9sL3ZPA
First Invoice: https://dashboard.stripe.com/test/invoices/in_1SSnfKDAWTp2PXOw0usXXX3R
Second Invoice: https://dashboard.stripe.com/test/invoices/in_1SSnfRDAWTp2PXOwFXIEaM3b

Has the same result

granite peak
#

and can I have a look at the change you made that left the subscription in "active" status?

#

that is - the Subscription where that happened

bright crest
#

Sure. It just changes the order of the operations performed. i.e. FIRST, update the credit card & pay the first invoice, THEN change the subscription to remove a license and void the associated invoice.

#

It should be this one as an example:

Resources Created:
Customer: cus_TPck3KViqH4lJt
Subscription: sub_1SSnUyDAWTp2PXOwKuOBvT88 (Quantity: 2)
First Invoice: in_1SSnViDAWTp2PXOwcKjUW4XV [PAID]
Second Invoice: in_1SSnVoDAWTp2PXOwXmiGiu20 [VOIDED]

View in Stripe Dashboard:
Subscription: https://dashboard.stripe.com/test/subscriptions/sub_1SSnUyDAWTp2PXOwKuOBvT88
Customer: https://dashboard.stripe.com/test/customers/cus_TPck3KViqH4lJt
First Invoice: https://dashboard.stripe.com/test/invoices/in_1SSnViDAWTp2PXOwcKjUW4XV
Second Invoice: https://dashboard.stripe.com/test/invoices/in_1SSnVoDAWTp2PXOwXmiGiu20

#

I can send you the script changes as well. Just need to unstash them

granite peak
#

that part doesn't matter so much

#

Just the objects is enough - I have records of the API calls

bright crest
#

Perfect!

#

So it seems like a SOP change for our Subscription Services staff could avoid this issue but I don't think that the approach they used was unreasonable. i.e. it makes sense to clean up and remove unwanted changes & invoices before getting the updated credit card from the customer and getting them into a paid state. We wouldn't want to accidentally change the customer for the invoice we are planning to void.

granite peak
#

Yeah - I mean I think if you have n Invoices on a Subscription and one is going to be paid, it should always be the most recent

#

if you care about the Subscription's status moving back to active

bright crest
#

Not always though. In this scenario, the first invoice (older) was a valid invoice for services that the customer actually wanted. The second invoice (latest) was for additional changes layered on top of the first one that the customer did not want.

#

It wouldn't make sense to charge the second one as that would immediately require a follow up refund.

granite peak
#

Yes, sorry, should have added "all else being equal"

glossy zodiacBOT
granite peak
#

I have to step away but my colleague will follow up with you here

bright crest
#

Sounds good. Thanks for your help!

wind sage
#

๐Ÿ‘‹ catching up here

bright crest
#

I'm at end of day in about 15 minutes. The customer this is impacting is technically in a good state so I don't think we need to fix this tonight. i.e. they can access our product but there subscription state will just look incorrect until the next invoice is created and paid.

#

Is there anything I can clarify with you before I go or should I just pick this up tomorrow morning?

wind sage
#

Thank you. No I also just want to understand this correctly. Is the following correct?

This moved the Subscription back to active, example: sub_1SSnUyDAWTp2PXOwKuOBvT88

FIRST, update the credit card & pay the first invoice, THEN change the subscription to remove a license and void the associated invoice.

While this doesn't, example: sub_1SSnfCDAWTp2PXOwwSpYsGJT
"FIRST, void the last Invoice, THEN update credit card & pay the first invoice"

bright crest
#

Yes, that's correct. For the same scenario performing the same steps in different orders have different end results in terms of the subscription state.

wind sage
#

Alright. I will try to reproduce and will report here if I found anything. When you are back tomorrow, feel free to create a new thread, we will have it refer back to this one and you can continue ๐Ÿ™‚

#

Thank you for the thoughtful investigation and the codes, and the IDs in very clear manner

bright crest
#

No problem.

#

Do you want my updated reproduction scripts?

wind sage
#

Yes please

#

The one which made it work?

bright crest
#

I also added delays to the first "past_due" result example so I'll give you both updated files.

wind sage
#

Awesome

bright crest
#

If you figure anything out, just update this thread. I'll start a new one tomorrow if I haven't heard anything. Thanks so much for the help!

wind sage
#

It's on us to thank you. You are a great dev. The investigation quality is awesome

bright crest
#

Thank you so much! Have a good evening ๐Ÿ‘‹

wind sage
#

๐Ÿ‘‹ I have found that this is a known issue, where "Void then Pay" let the Subscription in a weird state. However this should be self-resolved when the Sub advance to its next billing cycle with keeping a valid Payment Method.

For next handling Stripe: Looks at Slack's note