#lumen - accounts

1 messages ยท Page 1 of 1 (latest)

knotty isle
#

Hey, the server is still a bit busy and I am getting caught up but we are happy to advise.

#

One thing to keep in mind is that Customer objects in our system don't require you to make an account for them. It may make sense to make a Customer object and delete/reuse it if payment isn't made and simply fill out the details after the payment.

#

I forget if you can retroactively assosciate a payment with a Customer but if you can that may be a much more straightforward way to address your issue. Just try to take the payment, collect the details, create a customer, and update the payment intent with the relevant customer ID

dawn rover
#

Thank you for the reply!

The problem with the first approach is that I want to display the payment form on many pages on my website, show it to anyone who looks at the course. So I would have to create and delete a customer for every single user who ever visits our website, whether they decide to purchase the course or not. So if the website has 10,000 page views, I'd have to create and then delete 10,000 customers. That can't be right, right?

I will try out the 2nd approach and get back to you.

Ugh, having to create a payment intent in order to display the form makes my life so much more complicated. I really wish there was some way to render <PaymentElement/> without needing the Payment Intent first, kind of like you can do with <CardElement/>.

dawn rover
#

If I'm using the 2nd approach, I need to somehow pass the user's email and the courseSlug along with my payment, so that in my webhooks I could create an account for them, and then add the course to the list of purchased courses.

Currently I'm doing it when I create the payment intent like so:

  const paymentIntent = await stripe.paymentIntents.create({
    metadata: {
      courseSlug,
      email: profile.email,
      stripeCustomerId: profile.stripeCustomerId,
      profileId: profile.id,
    },
    amount: courses[courseSlug].price * 100,
    currency: "usd",
    // automatically detect the payment methods relevant to your customer.
    automatic_payment_methods: { enabled: true }, 
    description: `Purchase ${courseSlug}`,
    // After the PaymentIntent succeeds, save payment method on customer
    customer: profile.stripeCustomerId,
    setup_future_usage: "off_session",
  });

But for the non-authenticated users I will not know their email at the time of creating the Payment Intent. I need to show them the form, and then wait for them to type in their email.

What's the correct way to pass along this information?

I can see that you can pass along the email inside the

  stripe.confirmPayment({
    elements,
    confirmParams: {
      return_url: 'https://example.com',
      payment_method_data: {
        billing_details: {
          name: 'Jenny Rosen',
          email: 'jenny.rosen@example.com',
        }
      },
    },
  })

But I'm not sure this is the correct approach, and I don't think I'll be able to pass along the courseSlug this way. Can you recommend the best way to handle this?

knotty isle
#

Hey sorry just getting back to this thread and reading up

#

Those both look like reasonable ways to pass that info along. In the webhook event for the payment intent succeeding you can look up the name and email on the PaymentMethod object and the metadata should still have the course slug.

#

Can you tell me more about why you don't think you can pass the course slug that way?

#

Also I have confirmed that you can attach a Customer object after the fact. To me, setting the course slug when creating the payment intent and then using the customer info in payment_intent.succeeded sounds like a viable plan. Happy to hear any concerns you have though

dawn rover
#

I can no longer pass metadata along with the PaymentIntent because I have to create the payment intent before I show the user the form, and at that point I don't know the user's email yet.

knotty isle
#

I am a bit confused here. Your code seems to show passing in course specific things like the ID and price on creation. You will have to create the payment intent or at least update it with that ID before showing the payment form correct?

dawn rover
#

My code above works for the authenticated user. I am creating the payment intent when I'm loading the page, and if the user is authenticated, I already know all the information I need - the course slug and price, user's email and id in the database.

If the user is not authenticated, I can create the payment intent and pass it the courseSlug, because I know that information when the page loads. But I can't pass it the email, because I don't know it yet. I have to wait for the user to type in their email into the form. And the form can only be displayed after the payment intent has been created.

knotty isle
#

Right. So you can pass the course slug on creation and then pass in the email in the confirmPayment call like you showed in your snippet

#

And then create the customer/update the payment intent with the customer ID on your backend

#

I am going to step out but my colleague @coarse remnant can help if you still need clarificaiton

coarse remnant
#

๐Ÿ‘‹

dawn rover
#

Huzzah! That worked, I can pass along both the email and the courseSlug now. Thanks a lot!

Is it ok if we keep this thread open for now? I might have more questions as I'm implementing this (or I can ask them separately in #dev-help later).

coarse remnant
#

We'll keep this thread open for ~ 1hour but it will likely get closed after that.

#

But I'm happy to hear it's working for you ๐Ÿ™‚