#Steven P

1 messages · Page 1 of 1 (latest)

harsh cedarBOT
bright quail
#

Hi there. Did you specify a customer when creating a checkout session?

hidden drift
#

I did not no

bright quail
hidden drift
#

I'm following the node version of this:
https://stripe.com/docs/billing/quickstart

  const prices = await stripe.prices.list({
    lookup_keys: [req.body.lookup_key],
    expand: ['data.product'],
  });
  const session = await stripe.checkout.sessions.create({
    billing_address_collection: 'auto',
    line_items: [
      {
        price: prices.data[0].id,
        // For metered billing, do not pass quantity
        quantity: 1,

      },
    ],
    mode: 'subscription',
    success_url: `${YOUR_DOMAIN}/success.html?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${YOUR_DOMAIN}/cancel.html`,
  });

Which doesn't set the value or customer_creation anywhere it looks like, so just whatever the default value is, I suppose..?

bright quail
#

Ok, the default value for customer_creation is if_required, which means Stripe won't create a customer if it's not needed for the checkout session.

#

If your integration requires a customer, you can set customer_creation to always. Alternatively you can create a customer upfront and pass it in when creating a checkout session

hidden drift
#
The Checkout Session will only create a Customer if it is required for Session confirmation. Currently, only subscription mode Sessions require a Customer.

I am using a subscription mode so perhaps it's default to always?

bright quail
#

Yes, but for payment mode checkout session, no customer will be created

hidden drift
#

Got it, so a customer is definitely being created for my checkout sessions given they are subscription mode, correct?
I can see the customer being returned on the webhook which later fires, just not when the checkout url is getting passed to my frontend, so I don't have a chance to save the customer ID to my local DB so I can later track the webhook and match it

bright quail
#

The customer will be created after the checkout session is completed.

hidden drift
#

ok, then how do i match my checkout session to the later fired webhook, if i dont have the customer id yet when the checkout session is created?

bright quail
#

You can put some custom data in the checkout session's metadata, so that you can use it to reconcile later when receiving the webhook

hidden drift
#

That is quite clever

#

what would that look like in the call to the sessions.create?

bright quail
#
const session = await stripe.checkout.sessions.create({
    billing_address_collection: 'auto',
    line_items: [
      {
        price: prices.data[0].id,
        // For metered billing, do not pass quantity
        quantity: 1,

      },
    ],
    mode: 'subscription',
    metadata: {key: 'value' },
    success_url: `${YOUR_DOMAIN}/success.html?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${YOUR_DOMAIN}/cancel.html`,
  });
#

Something like this

hidden drift
#

Thank you

#

it doesnt look like the webhook returns the metadata of the checkout

#
       let event = try decoder.decode(StripeEvent.self, from: bodyData)

        switch (event.type, event.data?.object) {
        case (.paymentIntentSucceeded, .paymentIntent(let paymentIntent)):
            print(paymentIntent.metadata)
            return .ok
#

in the webhook this gets logged as [:]

#
        let session = try stripe.sessions.create(
            cancelUrl: "http://localhost:4201/cancel.html",
            paymentMethodTypes: [.card],
            successUrl: "http://localhost:4201/success.html",
            allowPromotionCodes: nil,
            billingAddressCollection: .auto,
            customerEmail: email,
            lineItems: [[
                "price": "price_1M6nvrBzVKLzv39btdZHTKJd",
                "quantity": 1,
                
            ]],
            metadata: ["key": "value1"],
```
bright quail
#

That's because you set the metadata to checkout session, but try to get it from a payment_intent.

hidden drift
#

right

bright quail
#

You can set the metadata to checkout session's payment_intent_data

hidden drift
bright quail
#

and you will get it in the payment_intent_succeeded

#
    billing_address_collection: 'auto',
    line_items: [
      {
        price: prices.data[0].id,
        // For metered billing, do not pass quantity
        quantity: 1,

      },
    ],
    mode: 'subscription',
    payment_intent_data: {
      metadata: {key: 'value' },
    }
    success_url: `${YOUR_DOMAIN}/success.html?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${YOUR_DOMAIN}/cancel.html`,
  });
hidden drift
#

tyty

hidden drift
#

@bright quail
StripeInvalidRequestError: You can not pass payment_intent_data in subscription mode.

#

back to the drawing board

bright quail
#

Oh right. In that case you might want to listen to checkout.session.completed

hidden drift
#

could you explain that more please?

bright quail
#

Sure, checkout.session.completed is fired when you customer has completed a checkout. And you can get the checkout session object form this event and use the metadata to reconcile.

hidden drift
#

as in they completed the checkout successfully?

bright quail
#

Yes you are right