#crawl_code

1 messages · Page 1 of 1 (latest)

winter yokeBOT
#

👋 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/1313674541783846982

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

tidal wolf
#

also, how do we test this ourselves locally ? and replicate
because we already subscribed successfully with the 424242 card
so all update will work in test env

outer moth
#

Hi! Looking into your question now.

tidal wolf
#

Like going into the dashboard, we cannot replicate this issue by changing the card to a insuficient fund for ex
the ui will not let the card pass

#

so best scenario would be that we have test card that have fund but not ALL the fund needed

#

so that a small initial purchase go through, but not a bigger one

Here's what happen for our customers :
Initial purchase success > then want to upgrade to yearly because of black friday, but some do not have the funds

outer moth
#

When there is an update (upgrade / downgrade), we will update the subscription first and attempt to charge. You should listen for invoice payment events. We will send invoice_paid for succesful payments and invoice.payment_failed for unsuccessful ones.

tidal wolf
#

into the dashboard, we cannot replicate this issue by changing the card to a insuficient fund for ex

#

so basically we cannot add it manually from the dashboard

#

we would need a card that have a limit of fund for example

#

oh i guess this one works

4000000000000341

outer moth
#

Yes, you can use other cards to test it since your main requirement is to see a failed payment attempt.

#

You should use the same invoice failure handing for all the subscription charges. When the subscription payment fails, Stripe will change the subscription status according to the billing configuration page after exhausting all the retries. So you won’t be able to get any status change on the subscription itself in the update api.

tidal wolf
#

got it

#

now

#

we cannot rely on webhooks for this flow
is there a response code or indication when doing the update call ?

outer moth
#

Can I check why won't webhooks work?

tidal wolf
#

because we update with a custom UI with a press of a button, when user give consent
then we await on the operation (loader) until completion

having a webhook will mean that this would be decoupled, and I guess we'll have to listen async

#

that means that if we grant the access to the upgrade, and then wait for the webhook to confirm
user can exploit in the meantime

#

like an optimistic upgrade I guess

outer moth
#

Can't you grant access after getting the successful payment webhook?

tidal wolf
#

unfornutaly with my current requirement I can't :/
we would have to refactor our whole upgrade/downgrade backend

is there a quick fix available in the meantime ?

outer moth
#

Let me check if there is a workaround.

tidal wolf
#

like either an error code when calling
const subscription = await this.stripeClient.subscriptions.update(

#

or another function to check if the status is not in past due or something

#

because I guess also that when payment is in failure mode, stripe will reattempt right ?
and after 2-3days another webhook will be sent, and cancel the subscription
so it's resolving by itself

#

and if payment is successfull a success webhook will be sent too right ?

#

so just need to prevent those 2-3 of grey area where payement is failed after an upgrade, to prevent us loosing on our margins

outer moth
tidal wolf
#

got it

so the status: "past_due",
should be in the object

#

this is correct, I just tested

outer moth
#

Yes, it will be in the Subscription object.

tidal wolf
#

ok I guess this will work for us

outer moth
tidal wolf
#

nice everything works as expected

#

shipping to prod, thanks so much for your help on this!

#

last question, when receiving an invoice paid webhook

#

do we have a trace that this was previously in failed state, and now is resolved ?

#

like something that differentiate a first successful payment, with a failed then resolved payment

#

for exemple when a payment is resolved we see a billing_reason: subscription_update
but is there a way to see that this was previously unpaid ?

outer moth
#

The only way to see if an invoice was previously unpaid is via the events. The successful event itself doesn't have any information about previous failed status.

tidal wolf
#

can we retreive this ?

#

because what we have is that
user payment will fail, so subscription will not be granted
user will go in stripe billing portal and update his credit card, payment will go through
and we'll receive an event invoice paid success with billing_reason : subscription_update

and we'll recover the sub for user

but

when a regular user update successfully (with the funds) there is nothing to recover, everything is good, so we want to skip this

#

but we still receive the exact same event object for both

outer moth
#

What do you mean by skip this?

tidal wolf
#

when a regular user update successfully (with the funds), we already make the changes for him, without waiting on the webhooks, because its faster for our user experience

#

but when user with insufficient fund try to update, we do not make any changes
we will wait for the webhook for payment success, and then unlock ressources

#

so we are just missing one tiny piece, to differenciate both

#

previous_attributes maybe ?

#

but "previous_attributes": null

outer moth
#

We always recommend to listen to webhooks to ensure that a payment is successful or has failed.

There is no way to differentiate between a subscription that was paid successfully within the first attempt vs one that failed and then was successful.

when a regular user update successfully (with the funds), we already make the changes for him, without waiting on the webhooks, because its faster for our user experience
If you don't wish to listen to webhooks for above, you can use the pending_update instead. If there is no pending_update has the payment was successful.

tidal wolf
#

not sure for pending_update
what do you mean ?

I have

status: "past_due",
pending_invoice_item_interval: null,
pending_setup_intent: null,
pending_update: null,

in the same update object

#

so during an update, the only differenciator, is the status

outer moth
tidal wolf
#

ok, I see

#

and in the stripe setting
if an invoice payment fail, during update for exemple
can we prevent sending invoice paid, but still try to attempt the charge cycle ?

outer moth
#

Invoice paid event os only created if there is a successful payment.

tidal wolf
#

ah true true, okok sorry to bother I think I'll keep the status recovery or not in my db

#

to differentiate, and align with marketing (attribution, emails, etc..)

#

would be nice to have this handle by stripe, I guess that would be a feature request

#

to have one tiny flag, that indicate if this is a recovered payment or not, in the invoice paid object

outer moth
#

I can provide a feedback to our team on this 👍