#brandon_webhooks

1 messages ยท Page 1 of 1 (latest)

teal turretBOT
#

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

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

iron prairie
#

hello! not sure off the top of my head to be honest, it's been a while since i looked into that status. lemme look for ya

stoic vigil
#

Hello! Thanks, I appreciate it

iron prairie
#

ok, so testing a bit on this, i know for a fact that you see it when doing a checkout session in "mode": "setup"

#

i think it might still count as "paid" for subscriptions with a free trial because we still generate a $0 invoice that's "paid" automatically, but lemme confirm that

#

ok yep confirmed from looking at the code that this status will only show in instances where absolutely no invoice is generated, so if you're doing a free trial then paid is the expected value because of the $0 invoice

stoic vigil
#

Okay gotcha, that makes sense. So in "mode": "purchase", if there's a 100% discount or something and the order ends up being free, would we see no_payment_required in that case?

iron prairie
#

i think so! let me test

#

ok weirdly that one is still showing payment_status: "paid" , so perhaps my explanation above is oversimplifying things

stoic vigil
#

Oh interesting. Definitely gonna have to update our logic in that case.

#

Not sure if this is something you can do, but it might be worth calling this out in the docs. Unless it's there somewhere and I missed it (totally possible lol)

Just my 2 cents ๐Ÿ™‚

iron prairie
#

yeah i can poke around in the docs to validate exactly what we cover here, the existing description is pretty clearly insufficient ๐Ÿ˜…

#

testing another case with subscriptions now

stoic vigil
#

I really appreciate your input though!

For what it's worth, we're trying to grab and store payment detail summaries (total amounts, payment method type, card brand, last 4, etc) for completed orders/subscriptions.

Our expansion paths/API calls differ based on whether a session actually has a payment intent (or invoice payment) attached to it. That's what started me down the rabbit hole

iron prairie
#

ok this is a fun one, looks like this results in payment_status: "no_payment_required" (because no invoice is generated)

  success_url: "[my success url]",
  line_items: [
    {
      price: "[my price id]",
      quantity: 1,
    },
  ],
  mode: "subscription",
  subscription_data: {
    billing_cycle_anchor: new Date("May 31 2026 09:13").getTime() / 1000,  // some date in the future 
    proration_behavior: "none",
  },
}```
stoic vigil
#

Ah future dated, that one definitely makes sense

iron prairie
#

ok so i am reasonably confident that payment_status: "no_payment_required" is never returned in payment mode

stoic vigil
#

Oh wow, no kidding

iron prairie
#

as far as i can tell it's always returned in setup mode

#

and conditionally returned in subscription mode, based on whether or not we generate an invoice of any value

stoic vigil
#

Okay, that's very helpful! Thanks again for doing the research.

Kinda unrelated, but I have an API feature request based on this adventure. Is that something that I'm able to submit anywhere?

iron prairie
#

here! as with all feature requests i can't guarantee that it will be implemented, but we take suggestions here as well as our other support channels

stoic vigil
#

Awesome! But yeah, of course; just a request, not a demand ๐Ÿ˜… Give me just a minute to type it up

stoic vigil
#

Background

So as I mentioned, we were trying to store "payment summaries" for completed orders (ie, completed checkout sessions). We're specifically interested in:

  1. Subtotal, discount, tax, and total amounts (can grab right from the checkout.session)
  2. Application fee amount (Connect integration, requires a payment_intent)
  3. Payment intent ID (requires a payment_intent or object that references it)
  4. Payment method type and, if applicable, card brand, last 4, etc (requires a payment_method or charge)

What We've Tried

When we handle checkout.session.completed or checkout.session.async_payment_succeeded, we have several conditional branches that we follow to fetch the data.

First we branch based on the session's mode, then we go from there:

Setup Mode

  • GET /v1/setup_intents/:id and expand payment_method

Payment Mode

  • GET /v1/checkout/sessions/:id and expand payment_intent.payment_method
  • Haven't confirmed whether the payment intent exists for zero-cost sessions

Subscription Mode

  • GET /v1/checkout/sessions/:id and expand subscription.default_payment_method
  • If subscription.status == "trialing" return without a payment intent
  • Else, GET /v1/invoice_payments with subscription.latest_invoice_id and expand data.payment.payment_intent
  • Grab payments.data[0].payment.payment_intent and hope for the best

Suggestion

Maybe our use case is unusual, but it would be great if all of this payment summary info was accessible directly from the checkout session object. For example:

  • An invoice_payment_intent property alongside the existing payment_intent property
  • A payment_method property

Being able to do GET /v1/checkout/sessions/:id and expand [payment_intent, invoice_payment_intent, payment_method] would eliminate lots of branching and simplify our flow quite a bit.

#

Sorry for the novel. Hopefully that's alright though. Thanks again for your help!

iron prairie
#

hahahahaha no worries

#

i appreciate the thoroughness, digesting now

#

still digesting, gonna ask some potentially naive questions. first, for the setup mode use case, can you not expand: ["setup_intent.payment_method"] when retrieving the checkout session? that should get you the payment_method info

stoic vigil
#

We could, yeah. We have the base session object from the webhook event, but I think /sessions, expand: ["setup_intent.payment_method"] or /setup_intents, expand: ["payment_method"] would be equivalent

iron prairie
#

ok cool

stoic vigil
#

But to be fair, I think setup mode is our easiest case. Seems like there are way fewer edge cases to worry about

iron prairie
#

ahhh was checking which API version you're on, if you were on an older version then you would be able to get the payment intent pretty easily by expanding the invoice.payment_intent on the session too

#

but alas, you're living in the present where we nest the payment intent too deeply to get that

stoic vigil
#

Yeah we upgraded recently and I noticed we lost that... I assume because of the new split invoices functionality? Not sure of the exact terminology

iron prairie
#

multiple invoice payments! it's a neat feature but it adds complexity which is unfortunate

stoic vigil
#

Story of my life as a developer lol

iron prairie
#

ok i think i understand your request well enough, and i don't think i have any other recommendations to make your life easier in the meantime

stoic vigil
#

No problem! Thanks for taking the time to read through it

#

Hey, one last totally unrelated question then I'll stop bothering you haha...

Do you happen to know if Stripe is still hiring engineers, or if everything is frozen because of the whole AI situation? I think you guys solve really cool problems and I'd like to be involved

teal turretBOT
iron prairie
#

last time i checked we had plenty of engineering roles open! 1 sec

velvet magnet
iron prairie
#

hey you beat me