#benjamin-fazli_checkout-subscriptions-saved-pms

1 messages · Page 1 of 1 (latest)

sly patrolBOT
#

👋 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/1349752132437282927

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

turbid falcon
#

Hello there

#

When you say "not available to use" what do you mean exactly?

pulsar kayak
#

Is not showing the card, it has on the cards, so when a new payment happens so he can use it

#

When I go to the customer portal, i see the cart, is set as default

#

But when I create a new subscription, the card is not showing

turbid falcon
#

How are you creating a new Subscription?

#

You can't create new Subscriptions via the Customer Portal.

#

So not exactly sure what you mean?

pulsar kayak
#

I'm doing it using create subscription api, not in portal

#
import type { StripePayloadType, SubscriptionBuilderFunctionProps } from '@/ts'

import { FREE_TRIAL_DAYS, PLAN_PERIODS } from '@/data/constants'
import { STRIPE_REDIRECT_URL } from '@/data/constants/Envs'

const SubscriptionBuilder = (props: SubscriptionBuilderFunctionProps): unknown => {
    const { 
        user,
        period,
        monthlyPlanId,
        yearlyPlanId,
        code
    } = props

    const planId = period === PLAN_PERIODS.MONTHLY ? monthlyPlanId : yearlyPlanId
    const usedTrial = user.Subscription?.UsedTrial

    const stripe_payload: StripePayloadType = {
        mode: 'subscription',
        payment_method_types: ['card'],
        success_url: `${STRIPE_REDIRECT_URL}/?success=true`,
        cancel_url: `${STRIPE_REDIRECT_URL}/?success=false`,
        customer: user.StripeCustomerId,
        allow_promotion_codes: true,
        line_items: [ 
            { 
                price: planId, 
                quantity: 1
            } 
        ]
    }

    if (code) {
        const codeFormatted = code?.toLocaleLowerCase().trim()

        if (!stripe_payload.metadata) stripe_payload.metadata = {}
        stripe_payload.metadata.referrer = codeFormatted
    }

    if (!usedTrial) {
        if (!stripe_payload.subscription_data) stripe_payload.subscription_data = {}
        stripe_payload.subscription_data.trial_period_days = FREE_TRIAL_DAYS
    }

    return stripe_payload
}

export default SubscriptionBuilder
turbid falcon
#

Ah

#

You are expecting that card to be prefilled into Checkout

pulsar kayak
#

I mean prefilled, or shown as an option to chose

#

Anything in this case 🙂

turbid falcon
pulsar kayak
#

Of course when the user has cards from before for some reaon

turbid falcon
#

So does the customer have a different card set as their default?

#

Unfortunately Checkout will never show a list of options

#

It will only pre-fill one card if applicable

pulsar kayak
#

No, its the same card

#

It has only one card, that previously used to do a subscription

#

Still is not showing that option

turbid falcon
#

Can you share the Customer ID and Checkout Session ID that you are testing with?

pulsar kayak
#

Yes, wait for me a little

#

For example I also want to pay an invoice

#

I click it and it doesnt show the default card below

#

Here then is the checkout with no card prefilled

#

Also when i try to do another subscription with the same user, that has the default card, is not showing it on the checkout

#

CustomerId: cus_Rt0E9j7Dbfvua4

#

Stripe Checkout: https://checkout.stripe.com/c/pay/cs_live_b1YcChckr3A3yDCI8sgj8dPfjMsiSY118HcqVjW9blyyPS0FE9GlNxKRc0#fid2cGd2ZndsdXFsamtQa2x0cGBrYHZ2QGtkZ2lgYSc%2FY2RpdmApJ2R1bE5gfCc%2FJ3VuWmlsc2BaMDRVNGprREJLVzxSPEpjS2hQMHd9ZEZfSUx0ZGx1bjY8SVxjTTVuTnZfdzFQdkxJZm1ia090VX9DTH9vbHVXNXNvVWhIb29tREBWXTZQbGI3YDZBVmRDTEo1NTc2alNwVEZmJyknY3dqaFZgd3Ngdyc%2FcXdwYCknaWR8anBxUXx1YCc%2FJ2hwaXFsWmxxYGgnKSdga2RnaWBVaWRmYG1qaWFgd3YnP3F3cGB4JSUl

turbid falcon
#

Looking

#

Ah okay from the doc I shared above:

A valid billing address, billing name and billing email are required on the payment method for Checkout to prefill the customer’s card details.

#

That PaymentMethod does not have a billing address collected

#

So it can't be prefilled

pulsar kayak
#

Okay sure

#

thanks then

#

I have

#

Another question, can i ask it here

#

But is not that much related with this one i had

turbid falcon
#

Yeah you can ask here

pulsar kayak
#

subscription_data: {
payment_behavior: 'error_if_incomplete'
},

error: Invalid subscription_data[payment_behavior]: must be allow_incomplete

#

is not allowing me to set this opton, so if a payment is failed to not show as incomplete, or payable invoice

turbid falcon
#

In the example you provided you used payment_behavior: 'default_incomplete' which is the correct behavior to use here.

#

Why are you trying to use error_if_incomplete?

#

Ah sorry!

#

I mixed up with another thread.

pulsar kayak
#

because its creating subscriptions, even if the payment fails

#

I don't want that behaviour

#

If a payment fails, I want to consider its as failed without creaitng a bill nor susbcription

turbid falcon
#

Using the pre-collected PaymentMethod still, yes?

#

You are not talking about Checkout here

pulsar kayak
#

import { FREE_TRIAL_DAYS, PLAN_PERIODS } from '@/data/constants'
import { STRIPE_REDIRECT_URL } from '@/data/constants/Envs'

const SubscriptionBuilder = (props: SubscriptionBuilderFunctionProps): unknown => {
    const { 
        user,
        period,
        monthlyPlanId,
        yearlyPlanId,
        code
    } = props

    const planId = period === PLAN_PERIODS.MONTHLY ? monthlyPlanId : yearlyPlanId
    const usedTrial = user.Subscription?.UsedTrial

    const stripe_payload: StripePayloadType = {
        mode: 'subscription',
        payment_method_types: ['card'],
        success_url: `${STRIPE_REDIRECT_URL}/?success=true`,
        cancel_url: `${STRIPE_REDIRECT_URL}/?success=false`,
        customer: user.StripeCustomerId,
        allow_promotion_codes: true,
        subscription_data: {
            payment_behavior: 'error_if_incomplete'
        },
        line_items: [ 
            { 
                price: planId, 
                quantity: 1
            } 
        ]
    }

    if (code) {
        const codeFormatted = code?.toLocaleLowerCase().trim()

        if (!stripe_payload.metadata) stripe_payload.metadata = {}
        stripe_payload.metadata.referrer = codeFormatted
    }

    if (!usedTrial) stripe_payload.subscription_data.trial_period_days = FREE_TRIAL_DAYS

    return stripe_payload
}

export default SubscriptionBuilder
#

i read that i need to add it on the checkout, when the checkout its inicalized

turbid falcon
#

With Stripe Checkout you don't control payment_behavior

pulsar kayak
turbid falcon
#

You can't prevent a Subscription from being created if you are using Stripe Checkout

pulsar kayak
#

but here in docs it says that

#

im using the same api

turbid falcon
#

That is for the Subscriptions API

#

The code you provided above is for the Checkout Session API

pulsar kayak
#

and what is the difference?

#

im creating the session in that form

turbid falcon
#

The Subscriptions API creates the Subscription directly and you use a pre-collected PaymentMethod to charge the initial invoice or you use a custom flow using Stripe Elements to collect a payment method.

Stripe Checkout is our hosted solution where you just redirect your customer to the checkout page and we both start the Subscription and collect the payment method.

pulsar kayak
#

okay makes sense

#

but how can i manage this on checkout then

#

as this is how we do currently

#

and we do not want that behaviour

turbid falcon
#

You can't

pulsar kayak
#

what

turbid falcon
#

A Subscription is always created if you use Stripe Checkout

pulsar kayak
#

why that 😦

turbid falcon
#

It will expire in 23 hours if the initial payment fails

pulsar kayak
#

yes but i don't want that behaviour

#

is there any altnerative?

#

in the sense to handle this

#

to delete this inital payment

#

on fail

#

or soemthing?

turbid falcon
#

Yes if you use the Subscriptions API directly.

#

But no not if you use Stripe Checkout

pulsar kayak
#

Yes but

#

There should be an alentavie

#

Can i delete the inital payment fail?

#

so to listen wehen that fails and the ndelete it

#

so its kinda the same effect?

turbid falcon
#

Yes you can cancel the Subscription, sure.

#

And then also void the initial Invoice

pulsar kayak
#

Thanks, is there

#

A custom event that triggers? on this incomplete period

#

So i can cancel that subscription and also void the same invoice attached to it?

turbid falcon
#

Why do you want to do this immediately instead of just waiting the 23 hours for this to happen automatically?

#

If you do this immediately then your customer could still be on the checkout page trying to pay with a different payment method

pulsar kayak
#

Its fine

#

I cancel all the tries

#

If all fail then i dont mind it, if it pays i dont touch those

#

I also think this should be an option on checkout, same as it is on the stripe create

turbid falcon
#

Sure I can file some feedback internally about that.

pulsar kayak
#

Also what about

#

That webook

#

I asked, that triggers specificlyt on this case

turbid falcon
#

You would need to listen for eithe payment_intent.payment_failed or invoice.payment_failed

#

But neither of these are unique to this situation.

#

So when you receive that Event you need to check if the Subscription is in an incomplete status

#

I highly recommend you don't do this

#

You just let the Subscription expire if payment fails

pulsar kayak
#

Okay makes sense

#

I will do because I don't want Stripe to try to charge the user again after 24 hours, nor show invoices due to pay on Stripe Portal.

#

Does payment_Failed invoice includes in the object if it was incomplete? or we need to do another request to check the subscription?

turbid falcon
#

The Subscription would move to incomplete_expired after 23 hours and the Invoice would be automatically voided at that point as well... we already do this for you.

turbid falcon
pulsar kayak
#

you mean retirve the subscription, not the object

#

because the object its included on the event that comes from stripe, right?

turbid falcon
#

You retrieve the object within the Event and expand the necessary properties to get to the Subscription. See: https://stripe.com/docs/expand for how expansion works

pulsar kayak
#
    try {
        const customerId = event.data.object?.customer```
#

for example here i get the customerId

#

can you help me clarify more?

turbid falcon
pulsar kayak
#

Yes, so its not included in the default object, we need to retrive the invoice, then vodi it

#

But what about that specific subscription it created, it is included on the invoice or in the default event that comes on payment_failed webook

turbid falcon
#

When you receive Webhooks properties are never expanded.

pulsar kayak
#

Sorry, I'm trying to understand you dont be harsh to me hehe

turbid falcon
#

So you need to make a separate request to retrieve the object and expand those properties that you care about (in this case, subscription)

#

Best thing to do at this point is test it out!

pulsar kayak
#

okay so i need to get the invoice object, then the subscrption object, then cancel the subscription with the id, and also void the invoice with the id

#

but if i have the invoice id, and subscription id on the default event, then i dont need to exctend just call the methods to do those two operaitons

#

this is what i mean

#

t

turbid falcon
#

Yep, so 3 requests after receiving the Webhook.

  1. Retrieve Invoice (and expand subscription to check the Subscription status)
    Then if Subscription is in a status: incomplete
  2. Cancel Subscription
  3. Void Invoice
pulsar kayak
#

Thanks much, you really helped me alot

turbid falcon
#

Happy to help!

sly patrolBOT
maiden forge
#

hello i need help not even stripe support can help me. what is this? it says contact support. support can't help me

sly patrolBOT
#

@maiden forge looks like you're in the wrong place, this thread is for someone else's question.

Note that posting inappropriate messages in other people's threads is against the rules. No worries if this was just an honest mistake, but anyone who violates the rules multiple times will be removed from this server.

rare sandal
#

@maiden forge this is not your thread. Please stop posting here.

maiden forge
#

ok