#gracine

1 messages ยท Page 1 of 1 (latest)

limpid coveBOT
summer crescent
#

It is because I receive both event when a user upgrade to a new subscription and that causes my code to try to call Stripe::Subscription.cancel on the same sub id twice

#

and from my test the update is always called and I have a sync subscription function that is called for both event, so its a create or update function

#

So I wonder if I could just drop the customer.subscription.created from my webhook listener

exotic linden
#

Hi ๐Ÿ‘‹

How are you creating subscriptions

#

?

#

And why would you cancel if the user updated?

summer crescent
#

I create the subscription by the Stripe Checkout portal

#

I have a Premium subscription & Pro Subscription

#

When a Premium user change plan to Pro, I cancel the premium subscription

#

At first I tried to simply update the existing subscription with the new Pro price but I ended up with too much corner cases to handle. Ex: user is on a free coupon so the API call fails due to no payment method. I found its way easier and robust to simply let the user go to the stripe checkout page and on the webhook simply cancel any remaining subscription

exotic linden
#

Why don't' you just update the Price associated with the Subscription object instead of canceling?

summer crescent
#

I just explained it โ˜๏ธ

#

"At first ..."

exotic linden
#

So if your integration creates a new subscription rather than changes the old one, why would you cancel an existing subscription on the .updated event?

summer crescent
#

only be cause I have a generic sync function

#

does not care if created,updated or delete

#

it sync my db, create or update

#

that is how it has been implemented, works quite well so far

#

I just have this specific case

#

but again, it not because I have a .created event that the subscription is necessary valid

#

the status a mean

#

my question was only to understand if a .created is always followed by a .updated

#

or if I will miss some edge case

#

if I do not listen to .created

#

this is how it looks

desert hollow
#

๐Ÿ‘‹

#

Stepping in as Snufkin needs to step away

#

Catching up

summer crescent
#

ok ! Hi

#

this is how it looks at the webhook handler side

#

def handle_event(event)

      logger.info("On stripe webhooks - : #{event.type}")

      case event.type

      when 'invoice.paid', 'invoice.payment_failed'
        invoice = event.data.object
        ::Billing::StripeEntitiesSynchronizer.new.update_billing_subscription_from_invoice(stripe_invoice: invoice)

      when 'customer.subscription.created', 'customer.subscription.updated', 'customer.subscription.deleted'
        stripe_subscription_id = event.data.object.id
        # Refetch the subscription simply because the events can come out of order so we do not want to overwrite subscription with out of sync data
        subscription = Stripe::Subscription.retrieve(stripe_subscription_id)

        ::Billing::StripeEntitiesSynchronizer.new.update_billing_subscription(subscription: subscription)
desert hollow
#

When you receive the updated event after the created event what is in the previous_attributes of the updated event?

summer crescent
#

I have to test I don't know, want me to find it ?

desert hollow
#

Yes that would be helpful

summer crescent
#

ok hold on

#

"previous_attributes"=>{"default_payment_method"=>nil, "status"=>"incomplete"}

desert hollow
#

Yep so that's the reason.

#

After you create the Subscription you are immediately charging that first invoice

#

When that is successful that changes the status and sets the default_payment_method

#

So that fires the customer.subscription.updated

#

The issue is that if that initial payment fails, neither of these things will change

#

I can't remember if you will see something else with the Sub change. I'd recommend testing if you fail that initial payment due to a decline

summer crescent
#

So, going back to my original question, can I safely drop the customer.subscription.created event ?

#

is it safe to only listen to the .updated

#

to have a robusting synching mechanism between Stripe & my database

desert hollow
#

Right

#

So you want to test what happens on a declined payment with how your integration is set up

summer crescent
#

in other words, is there a case where I will not have the .updated event fired

#

given all possible scenarios

desert hollow
#

I think you won't see a .updated event if the initial payment is declined, until either a retry succeeds or the Subscription moves to incomplete_expired

#

But if you are only ingesting data on a successful Subscription start (when the initial payment is successful) then yes you can just use the .updated event

summer crescent
#

ok, I do have this explicit listner though :

#

when 'invoice.paid', 'invoice.payment_failed'

#

I do call the same sync fonction

desert hollow
#

Ah okay then yeah that should work fine

summer crescent
#

ok

#

great! thanks I know it was not that clear

#

have a good day