#tudor-subs-testing

1 messages · Page 1 of 1 (latest)

safe sableBOT
#

Hello! We'll be with you shortly. Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.

finite nebula
#

Hello

#

i have some problems

#

i want to do subscriptions with stripe for my mern app

#

i try to build a saas platform where users can have premium account (i keep on my mongodb per user isPremium boolean)

#

and for subscription paymenth i have this webhook logic


case 'invoice.payment_succeeded':
        if (dataObject['billing_reason'] == 'subscription_create') {
          // The subscription automatically activates after successful payment
          // Set the payment method used to pay the first invoice
          // as the default payment method for that subscription
          const subscription_id = dataObject['subscription']
          const payment_intent_id = dataObject['payment_intent']

          // Retrieve the payment intent used to pay the subscription
          const payment_intent = await stripe.paymentIntents.retrieve(payment_intent_id);

          try {
            const subscription = await stripe.subscriptions.update(
              subscription_id,
              {
                default_payment_method: payment_intent.payment_method,
              },
            );

            console.log("Default payment method set for subscription:" + payment_intent.payment_method);
            const dbUser = await User.findOne({ email: dataObject.customer_email })

            dbUser.isPremium = true;
            dbUser.subscriptionId = subscription.id;

            await dbUser.save();

          } catch (err) {
            console.log(err);
            console.log(`⚠️  Falied to update the default payment method for subscription: ${subscription_id}`);
          }
        };

        break;```
#

are you there?

#

i really need your help to check my flow

teal ridge
#

Yup I'm here - I'm just waiting for you to give all the context

finite nebula
#

ok so

#

with the code from above the subscription will automatically renew for the user?

#

(i create the customer on user registration)

teal ridge
#

The Subscription will automatically renew/cycle even without the code you have above - the code you have is specifically for making sure that the Subscription can automatically attempt payment on each renewal

finite nebula
#

ok and lets say it renew and the user dont have money on the card anymore

#

how i can check this to remove the premium from my db

#

?

#

i read the docs but is not clear to me

teal ridge
#

You'd listen for the invoice.payment_failed to know that they weren't able to pay for the renewal invoice

finite nebula
#

i have this in my code

case 'invoice.payment_failed':
// TODO: handle case where subscription renew fails
// If the payment fails or the customer does not have a valid payment method,
// an invoice.payment_failed event is sent, the subscription becomes past_due.
// Use this webhook to notify your user that their payment has
// failed and to retrieve new card details.
break;

#

but

#

how i can see what arrives here

#

to test my logic?

#

using testclocks?

teal ridge
#

Yeah test clocks would be one way to test this

finite nebula
#

and other way?

#

i was not able to use them

#

i think my iq is too low

#

:)))

teal ridge
#

The other way would be to create a Subscription with a short (few second) trial_end or billing_cycle_anchor so that the renewal Invoice happens quickly

finite nebula
#

and how i can know what will happen? how i can make it fail or succeed?

teal ridge
#

You'd just want for a few minutes until the Subscription is automatically transitioned

#

Do you have specifics on why test clocks didn't work for you? It's more precise to use test clocks and if you're going to be doing a lot of tests it may be worth getting it up and running to save you time down the line

finite nebula
#

2 seconds to test again

safe sableBOT
#

tudor-subs-testing

finite nebula
#

i found other problem in my code that was not there some time ago

#

when i simulate a subscription from ui

#

from my app ui

#

my backend crash with this error

/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:99
throw new Error(Stripe: Argument "${param}" must be a string, but got: ${arg} (on API request to \${requestMethod} ${path}`)`);
^

Error: Stripe: Argument "intent" must be a string, but got: null (on API request to GET /v1/payment_intents/{intent})
at /Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:99:23
at Array.reduce (<anonymous>)
at Constructor._getRequestOpts (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:96:35)
at /Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:143:29
at new Promise (<anonymous>)
at Constructor._makeRequest (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:139:16)
at Constructor.retrieve (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeMethod.js:31:83)
at /Users/tudorang/Desktop/DevReadyFrontend-Backend/index.js:83:62
at Layer.handle [as handle_request] (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/express/lib/router/route.js:144:13)

Node.js v18.17.1
[nodemon] app crashed - waiting for file changes before starting...

#

the subscription in stripe dashboard is active but in my db ispremium is false because the backend crash

#

and now i send again and it worked

teal ridge
#

Ah, if you were testing with a trial then the first invoice of the subscription won't have a payment_intent ID so you need to account for that

finite nebula
#

what?

#

and how i can make this work

#

i dont want to have a free trial on the subscription

teal ridge
#

Not all paid Invoices have a payment_intent (because they may not need any payment because it's a trial or the amount owed is too low)

finite nebula
#

and how i can make it not crash

teal ridge
#

All you'd need to is add an if statement to only retrieve the PaymentIntent and set default_payment_method if the Invoice has a PaymentIntent

safe sableBOT
finite nebula
#

i am not able to make it work

#

hmm

neon sable
#

Hello! I'm taking over and catching up...

#

What part are you stuck on?

finite nebula
#

on the last part

#

of makeing it work

#

solving that error

#

with the intent

neon sable
#

The Error: Stripe: Argument "intent" must be a string, but got: null error?

finite nebula
#

can you help me please?

#

yeah

neon sable
#

Yeah, the issue is that you're passing nothing there instead of an Intent ID.

finite nebula
#

yeah i understand that

#

but why

#

?

neon sable
#

Why what? Why is causing the error? Why are you passing nothing? Something else?

finite nebula
#

yeah

#

how i can solve it

neon sable
#

The more specific your questions the more helpful I can be. 🙂

finite nebula
#

i dont understand

#

i make a subscription from my ui

neon sable
#

What specifically don't you understand?

finite nebula
#

and first time sends this error

#

if i send the second time works

#

can you help me?

#

please

#

i also dont understand what karbi said here

"All you'd need to is add an if statement to only retrieve the PaymentIntent and set default_payment_method if the Invoice has a PaymentIntent
And stepping back a bit -you could remove the code that sets default_payment_method in your webhook entirely if you create the Subscription with payment_settings.save_default_payment_method: on_subscription instead (see "

neon sable
#

The key thing to understand is that Subscriptions won't always have a Payment Intent. Your code is currently assuming they will always have a Payment Intent.

finite nebula
#

yeah i understand this

#

but i dont understand what is the intent

#

for what is this used

#

?

neon sable
finite nebula
#

and if i dont have this how subscription should work?

neon sable
#

If the Subscription doesn't need an immediate payment (like if there's a trial) there's no need for it to create a Payment Intent, so it doesn't.

#

Is that the case? Are you creating the Subscription with a trial?

finite nebula
#

i dont want to have any free trial

neon sable
#

Okay, does the Subscription not require a payment initially?

finite nebula
#

needs

#

i want when the user subscribe to to pay the first month

#

and then renew each month

#

thats my workflow that i want

neon sable
#

Okay, what line of code is throwing that error?

finite nebula
#

Default payment method set for subscription:pm_1OUvEVFi8oKxdd7KxuuLrxUf
/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:99
throw new Error(Stripe: Argument "${param}" must be a string, but got: ${arg} (on API request to \${requestMethod} ${path}`)`);
^

Error: Stripe: Argument "intent" must be a string, but got: null (on API request to GET /v1/payment_intents/{intent})
at /Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:99:23
at Array.reduce (<anonymous>)
at Constructor._getRequestOpts (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:96:35)
at /Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:143:29
at new Promise (<anonymous>)
at Constructor._makeRequest (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeResource.js:139:16)
at Constructor.retrieve (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/stripe/cjs/StripeMethod.js:31:83)
at /Users/tudorang/Desktop/DevReadyFrontend-Backend/index.js:83:62
at Layer.handle [as handle_request] (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/tudorang/Desktop/DevReadyFrontend-Backend/node_modules/express/lib/router/route.js:144:13)

Node.js v18.17.1

#

thats the error

#

and here is my logic for the subscription

case 'invoice.payment_succeeded':
if (dataObject['billing_reason'] == 'subscription_create') {
// The subscription automatically activates after successful payment
// Set the payment method used to pay the first invoice
// as the default payment method for that subscription
const subscription_id = dataObject['subscription']
const payment_intent_id = dataObject['payment_intent']

      // Retrieve the payment intent used to pay the subscription
      const payment_intent = await stripe.paymentIntents.retrieve(payment_intent_id);

      try {
        const subscription = await stripe.subscriptions.update(
          subscription_id,
          {
            default_payment_method: payment_intent.payment_method,
          },
        );

        console.log("Default payment method set for subscription:" + payment_intent.payment_method);
        const dbUser = await User.findOne({ email: dataObject.customer_email })

        dbUser.isPremium = true;
        dbUser.subscriptionId = subscription.id;

        await dbUser.save();

      } catch (err) {
        console.log(err);
        console.log(`⚠️  Falied to update the default payment method for subscription: ${subscription_id}`);
      }
    };
neon sable
#

Which specific line though?

finite nebula
#

i am not sure about that

neon sable
#

What's line 99 in StripeResource.js?

#

Err, wait...

finite nebula
#

i dont have any StripeResource in my project

neon sable
#

I don't think that's the right code.

finite nebula
#

what?

neon sable
#

I don't think that error is coming from that code. Can you check to see where you're setting intent?

finite nebula
#

thats my full stripe logic

#

app.post(
'/webhooks',
bodyParser.raw({ type: 'application/json' }),
async (req, res) => {
// Retrieve the event by verifying the signature using the raw body and secret.
let event;

try {
  event = stripe.webhooks.constructEvent(
    req.body,
    req.header('Stripe-Signature'),
    endpointSecret
  );
} catch (err) {
  console.log(err);
  console.log(`⚠️  Webhook signature verification failed.`);
  console.log(
    `⚠️  Check the env file and enter the correct webhook secret.`
  );
  return res.sendStatus(400);
}

// Extract the object from the event.
const dataObject = event.data.object;

// Handle the event
// Review important events for Billing webhooks
// https://stripe.com/docs/billing/webhooks
// Remove comment to see the various objects sent for this sample
switch (event.type) {
  case 'invoice.payment_succeeded':
    if (dataObject['billing_reason'] == 'subscription_create') {
      // The subscription automatically activates after successful payment
      // Set the payment method used to pay the first invoice
      // as the default payment method for that subscription
      const subscription_id = dataObject['subscription']
      const payment_intent_id = dataObject['payment_intent']

      // Retrieve the payment intent used to pay the subscription
      const payment_intent = await stripe.paymentIntents.retrieve(payment_intent_id);

      try {

Learn to use webhooks to receive notifications of subscription activity.

#

const subscription = await stripe.subscriptions.update(
subscription_id,
{
default_payment_method: payment_intent.payment_method,
},
);

        console.log("Default payment method set for subscription:" + payment_intent.payment_method);
        const dbUser = await User.findOne({ email: dataObject.customer_email })

        dbUser.isPremium = true;
        dbUser.subscriptionId = subscription.id;

        await dbUser.save();

      } catch (err) {
        console.log(err);
        console.log(`⚠️  Falied to update the default payment method for subscription: ${subscription_id}`);
      }
    };

    break;
  case 'invoice.payment_failed':
    // TODO: handle case where subscription renew fails 
    // If the payment fails or the customer does not have a valid payment method,
    //  an invoice.payment_failed event is sent, the subscription becomes past_due.
    // Use this webhook to notify your user that their payment has
    // failed and to retrieve new card details.
    break;
  case 'invoice.finalized':
    // If you want to manually send out invoices to your customers
    // or store them locally to reference to avoid hitting Stripe rate limits.
    break;
  case 'customer.subscription.deleted':
    if (event.request != null) {
      // handle a subscription cancelled by your request
      // from above.
    } else {
      // handle subscription cancelled automatically based
      // upon your subscription settings.
    }
    break;
  case 'customer.subscription.trial_will_end':
    // Send notification to your user that the trial will end
    break;
  default:
  // Unexpected event type
}
res.sendStatus(200);

}
);

#

thats all i have

#

and on user registration i have this

// generate stripe customer id
const newStripeCustomer = await stripe.customers.create({
email: email,
});

stripeCustomer = newStripeCustomer.id
#

to keep stripecustomerid in my mongodb

neon sable
#

Ah, it must be this line then:

const payment_intent = await stripe.paymentIntents.retrieve(payment_intent_id);
finite nebula
#

yeha \

neon sable
#

You're not checking to see if payment_intent_id is empty or not.

finite nebula
#

and how i can do this?

#

if i put an if

#

this will not brake my logic?

#

and if not exist what should i put?

neon sable
#

You need to adjust your logic to account for there not being a Payment Intent ID at that point.

#

If there's not a Payment Intent ID at that point you need to decide what your code should do about it.

finite nebula
#

can you give me some tips on how i can do it?

#

i want to user to pay at the start the first month and then automatically renew each month

neon sable
finite nebula
#

yeah

#

so if i completly remove that intent

#

what will happen?

neon sable
#

You should give it a try and see.

#

I can't run your code for you, or explain how it will behave.

finite nebula
#

i will not have a defaul paymenth method

#

so will not renew

#

right?

neon sable
#

Yes, unless there's a default set elsewhere.

finite nebula
#

is not

#

hmm

#

and how i can do it

#

i dont understand

#

if i dont have the intent but i need it to automatically renew

#

how i can do it

#

?

neon sable
#

You need to figure out why you don't have the Intent.

finite nebula
#

i removed it

#

and like this is looking my customer

#

on stripe

#

this will automatically renew?

#

i think yes

#

right?

#

because the card is there

neon sable
finite nebula
#

can you help me set up some test clocks please?

#

i am not able to make them work

#

with the docs

#

sorry for my big thread of problems

neon sable
#

What help do you need? Do you have a specific question?

#

Like what specific thing is preventing you from using them?

finite nebula
#

i dont know how to run a testclock for this customer

neon sable
#

You don't. Test Clocks aren't for use with existing Customers. You create the Test Clock, then you create a new Customer for that Test Clock.

finite nebula
#

yeah but in my terminal

#

2024-01-04 20:49:31 --> test_helpers.test_clock.advancing [evt_1OUvyxFi8oKxdd7KLnQ1oxz5]
2024-01-04 20:49:31 <-- [200] POST http://localhost:3001/webhooks [evt_1OUvyxFi8oKxdd7KLnQ1oxz5]
2024-01-04 20:49:32 --> test_helpers.test_clock.ready [evt_1OUvyyFi8oKxdd7KdNbRtYxu]
2024-01-04 20:49:32 <-- [200] POST http://localhost:3001/webhooks [evt_1OUvyyFi8oKxdd7KdNbRtYxu]

w

#

i made the testclock

#

but the webhook with invoice.payment_succeeded was not triggered again

#

on stripe the invoice was paid

#

but this was not reach to my backend

#

so how ik if i have to remove user premium in my db or not

neon sable
#

According to those logs your local code did get them and returned a 200 (success) status back.

#

That's what the <-- [200] POST http://localhost:3001/webhooks lines mean.

finite nebula
#

invoice.payment_succeeded was not triggered

neon sable
#

Yes, tha'ts not one of the events listed above.

#

You should have received test_helpers.test_clock.advancing and test_helpers.test_clock.ready.

finite nebula
#

can you explain why please?

#

yeah

neon sable
#

Probably because you didn't advance time far enough?

finite nebula
#

i did

#

hmm

#

now was triggered

#

i dont understand

#

why sometimes is sometimes not

neon sable
#

After you created the Test Clock you added a new Customer for it and set them up with a Subscription, then advanced time?

finite nebula
#

yeah

neon sable
#

It does looks like things are working, the Events are being generated.

finite nebula
#

but if is working like this what was the thing with that intent id

#

can you expalin please?

neon sable
#

I don't understand your question. Can you provide more details?

finite nebula
#

for what that intent id is used if you dont have to use it

#

🙂

neon sable
#

Payment Intents are used for accepting payments.

#

I don't understand... are you asking me why your code used them?

finite nebula
#

my code no longer use them

#

how is this possible

neon sable
#

It's possible because it sounds like you removed the code?

#

How is what possible?

finite nebula
#

yeah

#

how my code works without them

neon sable
#

You need to be specific. Can you give me the ID of a Subscription where it worked?

#

Or the ID of an Invoice?

finite nebula
#

now is working

#

and i no longer have that intent code

#

default_payment_method: payment_intent.payment_method,

#

this

#

i no longer have

#

and is working

#

how

#

?

neon sable
#

I don't know. Give me the ID for a Subscription or Invoice so I can look and see.

#

Do you have an ID for one I can take a look at?

finite nebula
#

no

neon sable
#

Why?

finite nebula
#

let me find one

neon sable
#

I'd be happy to tell you how it's working, but I need to be able to see it.

finite nebula
#

where can i find it?

neon sable
#

In your logs, in the Events, in your Dashboard.

#

Like when you got the invoice.* Events there should be an in_ ID in there.

finite nebula
#

why in left

#

at spent is 0

#

but he paid one invoice?

neon sable
#

I don't know, please give me the ID so I can look.

finite nebula
#

cus_PJZRMZP4uWr922

#

thats the customer

neon sable
#

I need the Subscription or Invoice ID.

#

sub_ or in_

#

It should be right there in the Dashboard.

finite nebula
#

in_1OUwJgFi8oKxdd7KtLQnSuAn

neon sable
#

Looking...

finite nebula
#

this was a 0 lei invoice

#

but my susbcription is 1 leu

neon sable
#

The Customer had an existing balance that was used to pay the Invoice.

finite nebula
#

where was this balance?

neon sable
#

Looking...

#

Oh... I think the amount was below our minimum charge amount, so we applied the -1 to the balance to charge later.

#

Yeah, that's what it was.

#

You need to increase the amount so it's above the minimum charge amount.

finite nebula
#

was the same subscription price

#

1 ron

#

like allways

neon sable
#

Yeah, but that's below our minimum charge amount, so an Invoice with a total of 1 ron isn't going to create a payment.

#

When you go and do the second Invoice for the same amount, the 1 fromt he Invoice and the 1 from the customer balance are combined to 2 and that does meet the minimum so that one works.

#

That's why you were seeing some go through and some not.

finite nebula
#

oh ok

#

so in production with 25 ron will work

#

?

neon sable
#

You should try 25 in test mode to see if it works as expected.

#

It should, but you should always test.

finite nebula
#

i have one more problem on the same customer

#

i run the clock

#

and the defautl card

#

should expire on apr 2024

#

and now i am in may and still succedd the paymenth

neon sable
#

Expiration dates are ignored. They often get updated transparently or still work after being expried.

finite nebula
#

and how i can test a fail case?

neon sable
#

Attaching this card to a Customer object succeeds, but attempts to charge the customer fail.

finite nebula
#

when i try to attach it i get Your card has insufficient funds.

#

on stripe dashboard

neon sable
#

You're trying to attach 4000000000000341?

finite nebula
#

yeah

#

ow no

#

i try 4000000000009995

neon sable
#

That one won't work.

#

It needs to be the specific one I mentioned above.

finite nebula
#

yeah i tried with yours and the paymenth fails

#

thank you

#

i think the integration looks good

#

this is my webhooks

#

try {
event = stripe.webhooks.constructEvent(
req.body,
req.header('Stripe-Signature'),
endpointSecret
);
} catch (err) {
console.log(err);
console.log(⚠️ Webhook signature verification failed.);
console.log(
⚠️ Check the env file and enter the correct webhook secret.
);
return res.sendStatus(400);
}

// Extract the object from the event.
const dataObject = event.data.object;

// Handle the event
// Review important events for Billing webhooks
// https://stripe.com/docs/billing/webhooks
// Remove comment to see the various objects sent for this sample
switch (event.type) {
  case 'invoice.payment_succeeded':
    if (dataObject['billing_reason'] == 'subscription_create') {
      // The subscription automatically activates after successful payment
      // Set the payment method used to pay the first invoice
      // as the default payment method for that subscription
      const subscription_id = dataObject['subscription']
      // const payment_intent_id = dataObject['payment_intent']

      // Retrieve the payment intent used to pay the subscription
      // const payment_intent = await stripe.paymentIntents.retrieve(payment_intent_id);

Learn to use webhooks to receive notifications of subscription activity.

#

try {
const subscription = await stripe.subscriptions.update(
subscription_id,
// {
// default_payment_method: payment_intent.payment_method,
// },
);

        // console.log("Default payment method set for subscription:" + payment_intent.payment_method);
        const dbUser = await User.findOne({ email: dataObject.customer_email })

        dbUser.isPremium = true;
        dbUser.subscriptionId = subscription.id;

        await dbUser.save();

      } catch (err) {
        console.log(err);
        console.log(`⚠️  Falied to update the default payment method for subscription: ${subscription_id}`);
      }
    };

    break;
    case 'invoice.payment_failed':
    // TODO: handle case where subscription renew fails 
    const dbUser = await User.findOne({ email: dataObject.customer_email })
    dbUser.isPremium = false;
    await dbUser.save();
    break;
  case 'invoice.finalized':
    // If you want to manually send out invoices to your customers
    // or store them locally to reference to avoid hitting Stripe rate limits.
    break;
  case 'customer.subscription.deleted':
    if (event.request != null) {
      // handle a subscription cancelled by your request
      // from above.
    } else {
      // handle subscription cancelled automatically based
      // upon your subscription settings.
    }
    break;
  case 'customer.subscription.trial_will_end':
    // Send notification to your user that the trial will end
    break;
  default:
  // Unexpected event type
}
res.sendStatus(200);

}

#

you see smth that i dont cover?

neon sable
#

We can't provide code reviews here, sorry.

#

Happy to answer specific questions and get you unblocked, but testing and reviewing your code is up to you.

finite nebula
#

i dont think thats a code review

#

what edge cases i have to cover for this subscription app model?

neon sable
finite nebula
#

i still dont understand that intents

#

and how without it works

neon sable
#

From that earlier example you added a card to that Customer via the Dashboard, and that card was used to pay for the Subscription.

finite nebula
#

yeah but if i add a card from the checkout page

#

still works

neon sable
#

Okay.

finite nebula
#

oh if i create fro mthe checkout page is not marked as default

neon sable
#

Okay.

finite nebula
#

and how i can make it default

#

?

neon sable
#

What's the ID of that Customer?

finite nebula
#

cus_PJZsmfXpUOf3Ff

#

if is not default i dont think the subscription will renew from it

#

right?

neon sable
finite nebula
#

i am not sure how i can do this

#

i dont understand this docs

#

where i set setup_future_usage in this checkout

neon sable
#

You need to set payment_intent_data.setup_future_usage in that request.

finite nebula
#

in the headers of the req?

safe sableBOT
finite nebula
#

hello hanzo

neon sable
#

No, it's in the body of the request.

#

You set it alongside things like success_url and customer.

finite nebula
#

is not clear to me what i have to set

neon sable
#

I don't think so? That doesn't seem to be the correct code.

#

This would be in your server-side code.

#

Where you create the Checkout Session.

finite nebula
#

oh yeah here

app.post('/create_checkout_link', async (request, response) => {
const priceId = request.body.priceId;

// Retrieve user's stripeCustomerId based on the provided email
const user = await User.findOne({ email: request.body.email });

if (!user) {
return response.status(400).json({ error: "User not found." });
}

console.log(user)

const session = await stripe.checkout.sessions.create({
billing_address_collection: 'auto',
// email: request.body.email, // TODO: add validation to my middleware email have the same mail from this body else redirect in a err page
customer: user.stripeCustomerId,
line_items: [
{
price: priceId,
quantity: 1,
},
],
mode: 'subscription',
success_url: http://localhost:3000/?success=true,
cancel_url: http://localhost:3000?canceled=true,
});
response.send({
url: session.url
});
});

#

sorry i am tired

neon sable
#

Yeah, that's it.

finite nebula
#

is not clear to me what i have to set there

#

tbh

neon sable
finite nebula
#

yeah

neon sable
finite nebula
#

i dont know whats that property

neon sable
#

So use that info in the API reference to add that to your code.

#

If you had to guess, what do you think the code would look like if you tried to add that property?

finite nebula
#

idk what property

#

is

#

for setting the default card

#

this docs are so bad

neon sable
#

I linked you directly to it. It's payment_intent_data.setup_future_usage.

#

So it's a top-level payment_intent_data property that contains an object, and that object has a setup_future_usage property which has a value that's a string.

#

If you take the time to learn how to translate your code to and from the API reference things are going to be a lot easier for you.

#

I have to run, but hanzo can help you further!

finite nebula
#

payment_intent_data: [

],
#

idk what to set there

#

@marble nova

#

hello

#

i want the card from checkout to be set as default paymenth

#

and i am not able to wfind out how

marble nova
#

Hello 👋
give me a moment to catch up

finite nebula
#

sure

#

so can you help me please?

marble nova
#

So there's no way to set the payment method to be default directly from a checkout session.

You can configure checkout session to set up and attach the payment method to a customer by setting payment_intent_data.setup_future_usage parameter

Once attached, you'd need to update the customer object by calling the Update Customer API separately

finite nebula
#

can you help me to do this please

#

?

#

how i can set payment_intent_data.setup_future_usage

#

this is not clear to me

marble nova
finite nebula
#

whats that payment intent for

#

i have const session = await stripe.checkout.sessions.create({

marble nova
#

PaymentIntent is a separate API, I don't want you to focus on that API but how it's setting setup_future_usage

finite nebula
#

const session = await stripe.checkout.sessions.create({
billing_address_collection: 'auto',
// email: request.body.email, // TODO: add validation to my middleware email have the same mail from this body else redirect in a err page
customer: user.stripeCustomerId,
setup_future_usage: 'off_session',
line_items: [
{
price: priceId,
quantity: 1,
},
],
mode: 'subscription',
success_url: http://localhost:3000/?success=true,
cancel_url: http://localhost:3000?canceled=true,
});

#

this is what i have

#

to what to set this setup_future_usage?

marble nova
finite nebula
#

what do you mean as child

#

what this should be in a programming languge

#

lol

#

?

#

i dont understand

#

can you please say how i send this

marble nova
#

My colleague and I have both tried to explain how you'd be able to add setup_future_usage parameter multiple times, we're just short of writing your code for you (which we won't do).

See:
#1192523624331100220 message

finite nebula
#

yeah

#

but i dont understand

#

so i have to set this inside const session = await stripe.checkout.sessions.create({

#

right?

marble nova
#

so i have to set this inside const session = await stripe.checkout.sessions.create({
This meaning what exactly?

finite nebula
#

where i have to set this

#

here?

#

const session = await stripe.checkout.sessions.create({
billing_address_collection: 'auto',
// email: request.body.email, // TODO: add validation to my middleware email have the same mail from this body else redirect in a err page
customer: user.stripeCustomerId,
line_items: [
{
price: priceId,
quantity: 1,
},
],
mode: 'subscription',
success_url: http://localhost:3000/?success=true,
cancel_url: http://localhost:3000?canceled=true,
});
response.send({
url: session.url
});
});

#

ok so i added this

line_items: [
{
price: priceId,
quantity: 1,
},
],

payment_intent_data: [
  
]
#

and what exactly i have to add to it?

#

to set the card as default

#

for the customer

#

can you respond please

marble nova
#

Please be patient, there are multiple people I am helping.

finite nebula
#

i have this and is not working

customer: user.stripeCustomerId,
line_items: [
  {
    price: priceId,
    quantity: 1,
  },
],
payment_intent_data: {
  setup_future_usage: "off_session"
},
#

the card is not set as default

marble nova
#

#1192523624331100220 message

So there's no way to set the payment method to be default directly from a checkout session.

You can configure checkout session to set up and attach the payment method to a customer by setting payment_intent_data.setup_future_usage parameter

Once attached, you'd need to update the customer object by calling the Update Customer API separately

finite nebula
#

how i can do this

#

i am not able

marble nova
#

That parameter attaches the payment method to a customer
You need a separate api request to make it default

finite nebula
#

and when this should be called

#

if the card is not default

#

the subscription will renew from it?

#

if is just added

#

?

marble nova
finite nebula
#

yeah

#

when i subscrbe from checkout the card is added but is not set as default

#

my question is

#

when the subscription for that user will renew

#

next month

#

will charge the card

#

even if is not default?

marble nova
#

I believe the payment method is set as default on the subscription when created via checkout session, so yeah renewal payment should go through fine.

finite nebula
#

is nott

marble nova
#

You're looking at the customer details page
open the subscription page

finite nebula
#

to see what

#

i want to see

#

when the subscription

#

on the customer

#

renew

#

if

#

he

#

is

#

chared

#

on the credit card

#

even if is not default

#

thats all

#

i want to see

marble nova
#

that's all subscriptions, you need to look at the subscription that you created for that specific customer

finite nebula
#

here

#

?

marble nova
#

yes, look at the payment method there

#

and billing method

#

it says "charge specific payment method" followed by the actual payment method used in checkout

#

meaning it isn't looking for customer's default payment method to charge

finite nebula
#

thats the current billing

#

here is the upcoming

#

and guess what

#

will charge the default card

#

that is not set

#

wow

marble nova
#

Can you share the subscription ID you're looking at?
sub_xxx

finite nebula
#

you can take it from the url please

#

because is upcomming_invoice

marble nova
#

I believe the dashboard upcoming invoice view is showing the wrong info there.
I checked the subscription and it has the payment method set correctly

finite nebula
#

yeah

#

but

#

the next

#

invoice

#

in 1 month

#

when this user will be charged

#

this will not work

marble nova
finite nebula
#

because he has no default card

marble nova
#

Well technically, the upcoming invoice details page says "charging default payment method"

It doesn't say anything about default payment method on subscription or customer

#

and I double checked that the subscription HAS a default payment method

finite nebula
#

how i can test if this works

#

if i do a testclock the card will be set as default

#

so?

marble nova
#

When you create subscription using a checkout session, the payment method is set as default on the Subscription meaning that payment method will be used for renewal automatically.

Testing a checkout session based flow with a test clock would be challenging as you can't create a checkout session linked to a test clock.

You'll need to create a test clock customer, a test clock subscription separately while setting a default payment method on the subscription