#pattrn-subs-dup

1 messages · Page 1 of 1 (latest)

regal pelican
#

hello, you're the developer who built this integration?

can you share both sub IDs, one for the old past_due one and one for the duplicate/new one

agile geyser
#

Sure. One sec.

#

New subscription ID is sub_1JfGW2Lp3eWlIHUp3t9xGnRE. Old sub ID is sub_JC8RRpnv5bH88E.

#

It's probably something I've setup incorrectly on my end. Is there some way to guarantee a customer can only have one active subscription for a product?

regal pelican
#

thanks, looking

#

these were 2 distinct CheckoutSessions from what I'm seeing , the first one declined, the second one didnt

using Stripe's billing panel, and whenever a user has a past due subscription and then updates their card
how is your customer updating their card? your integration or Stripe's Customer Billing Portal

agile geyser
#

The customer is using Stripe's billing portal.

#

That's what's so confusing to me. We have very little custom code, due to using Stripe's out-of-the-box portals wherever possible.

regal pelican
#

ah ok ... that helps, thinking

agile geyser
#

We're using both the Stripe checkout portal and the billing portal.

#

If it helps, here's the entire code we're using on the server for generating checkout/billing portals:

createBillingPortal: async (
  customerId: string,
  returnUrl: string,
): Promise<string> => {
  const portalSession = await stripe.billingPortal.sessions.create({
    customer: customerId,
    return_url: returnUrl,
  });

  return portalSession.url;
},
createCheckoutPortal: async (
  customerId: string,
  packageName: keyof typeof SubscriptionPackage.all,
  returnUrl: string,
  cancelUrl: string,
  referralCode?: string,
  coupon?: string,
): Promise<string> => {
  const checkoutSession = await stripe.checkout.sessions.create({
    mode: 'subscription',
    customer: customerId,
    billing_address_collection: 'required',
    line_items: [
      {
        price: SubscriptionPackage.all[packageName].priceId,
        quantity: 1,
      },
    ],
    ...(coupon
      ? {
          subscription_data: {
            coupon,
          },
        }
      : {}),
    payment_method_types: ['card'],
    success_url: returnUrl,
    cancel_url: cancelUrl,
    ...(referralCode ? { client_reference_id: referralCode } : {}),
  });

  return checkoutSession.id;
},
#

There's some more code wrapping this (i.e. handling the request and performing validation/error handling), but this is pretty much it. Stripe does the rest.

#

We keep track of a customer ID for each user, which gets passed into these methods.

white mica
#

@agile geyser Hello! I'm hopping in as well to help, give me a few minutes to read back and get caught up

#

When your customer has a past due subscription, where do you direct them to do update their payment information?

white mica
#

@agile geyser Do you still need help?

agile geyser
#

Yeah -- sorry, didn't get the alert when you responded.

#

When they login, they open a new billing portal.

#

We don't actually send them an email. They get a message when they login.

white mica
#

Do you do anything specific to prevent them from going into a Checkout Session flow? From what I can see, both those subscriptions were created from Checkout Sessions

agile geyser
#

Bah, that's the problem. My apologies. I think the logic shows a link to the checkout page if they don't have an active subscription.

#

Which doesn't make sense if they have an expired subscription, because they wouldn't be creating a new subscription.