#crawl_code
1 messages · Page 1 of 1 (latest)
👋 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.
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
Hi! Looking into your question now.
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
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.
To test with a card that will fail the payment, you can update the test card to one fo these: https://docs.stripe.com/testing#declined-payments
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
Yes, you can use other cards to test it since your main requirement is to see a failed payment attempt.
This is a useful guide you can refer to: https://docs.stripe.com/billing/subscriptions/event-destinations#payment-failures
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.
got it
now
we cannot rely on webhooks for this flow
is there a response code or indication when doing the update call ?
Can I check why won't webhooks work?
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
Can't you grant access after getting the successful payment webhook?
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 ?
Let me check if there is a workaround.
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
Yes you are right. If automatic payment fails, the subscription updates to past_due and Stripe attempts to recover payment based on your retry rules.
Ref: https://docs.stripe.com/billing/subscriptions/overview#failed-payments
got it
so the status: "past_due",
should be in the object
this is correct, I just tested
Yes, it will be in the Subscription object.
ok I guess this will work for us
Another option is https://docs.stripe.com/billing/subscriptions/pending-updates#canceling-changing
You can look out for the pending_update hash. If the pending_update hash is populated, the payment has failed. Stripe will continue to retry but you can proceed to update the Subscription accordingly.
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 ?
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.
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
What do you mean by skip this?
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
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.
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
I am referring to my previous message:
Another option is https://docs.stripe.com/billing/subscriptions/pending-updates#canceling-changing
You can look out for the pending_update hash. If the pending_update hash is populated, the payment has failed. Stripe will continue to retry but you can proceed to update the Subscription accordingly.
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 ?
Invoice paid event os only created if there is a successful payment.
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
I can provide a feedback to our team on this 👍