#SteveW

1 messages · Page 1 of 1 (latest)

left juncoBOT
rancid idol
#

Do you have IDs for the Customer and the Payment that was created that we can look at?

balmy cosmos
#

yes, one second.

#

It's a test customer and payment:

cus_N6WouW1KRJLwvo

This is the part that succeeded:
pi_3MMJnzFskIL2Xzkf0q7s6Hui

This is the part that's incomplete:
pi_3MMJktFskIL2Xzkf1Xs8gDa1

ivory jetty
#

Hi 👋

balmy cosmos
#

hi

ivory jetty
#

I'm confused by what's going on here. You are talking about subscriptions and invoices but the first Payment Intent has no relation to any Invoice or Subscription. How are you creating these?

balmy cosmos
#

Everything is AWS Lambda and vanilla Javascript using the Stripe API. First I create the customer object with a Lambda. That works fine. Then I create a subscription passing in the priceId of a subscription that I set up in the dashboard.. That works, I guess. Then I take a payment using a card element. And with the secret returned I confirm the payment.

#

Here's how I create the subscription - with the price id and customer id

#

const subscription = await stripe.subscriptions.create({
customer: customerId,
items: [
{
price: priceId,
},
],
payment_behavior: "default_incomplete",
payment_settings: { save_default_payment_method: "on_subscription" },
expand: ["latest_invoice.payment_intent"],
});

ivory jetty
#

Okay so the first Payment Intent, the one that is successful, was created without a Customer ID. So while you did pass setup_future_usage, the Payment Method created didn't have a Customer to attach to. https://dashboard.stripe.com/test/logs/req_WHr1D6fIzFn5ID

That's why the payment method isn't attached to the Customer.

balmy cosmos
#

No i use the customer id

ivory jetty
#

Not in the successful Payment Intent you shared above

balmy cosmos
#

the customer id that I created in the first step

ivory jetty
#

The only parameters passed were amount, currency and setup_future_usage for pi_3MMJnzFskIL2Xzkf0q7s6Hui

balmy cosmos
#

In this?

#

try {
paymentIntent = await stripe.paymentIntents.create({
amount,
currency,
setup_future_usage: "off_session",
});

#

I see, so I need to pass the customer id in this - I was wondering about that. The documentation didn't show to pass in a customer id.

#

Do I need to pass in something returned from the subscription creation as well?

ivory jetty
#

It depends when in your process you want to save the customer information.

#

You could do this a different way using webhooks instead.

balmy cosmos
#

I'd like to have the customer make an initial payment for the subscription and also save the payment method to be used for the subscription

ivory jetty
#

Where you save the payment method to the Customer after the first invoice is paid successfully

balmy cosmos
#

I want to onboard them immediately and can't wait for an invoice

ivory jetty
#

You can update the Payment Intent generated by the Subscription's first Invoice to setup_future_usage. That Payment Intent is already linked to the Customer

balmy cosmos
#

I've got two scenarios. A subscription with a free trial (one month) where no payment is made. Another where there's a first payment and they continue to pay the same amount monthly.

It would be great if I could handle them the same way. Webhooks is a little trickier with AWS and would prefer to just handle it at the time they sign up and I create the customer and subscription. What I've done is almost working. I'd love to be able to just tweak it to complete it.

ivory jetty
#

Wait wait wait, I'm an idiot

#

This does exactly what you are looking for. It saves the Payment Method to the Customer and makes it the default when the Payment succeeds

balmy cosmos
#

Here's my code for Subscriptions. Seems similar:

#

try {
const subscription = await stripe.subscriptions.create({
customer: customerId,
items: [
{
price: priceId,
},
],
payment_behavior: "default_incomplete",
payment_settings: { save_default_payment_method: "on_subscription" },
expand: ["latest_invoice.payment_intent"],
});

#

similar

ivory jetty
#

Okay but are you using the Payment Element to collect card information for the Payment Intent on that first invoice?

balmy cosmos
#

Yes, I read that you need to do that if you want to get the first payment from them.

#

at the time of signup

#

and also to store their card

ivory jetty
#

Okay so what you need to do is use the second Payment Intent pi_3MMJktFskIL2Xzkf1Xs8gDa1 and it's client secret to collect payment data

balmy cosmos
#

I'm only doing one payment intent

ivory jetty
#

That's where I was confused. This Payment Intent is never attempted to be confirmed

balmy cosmos
#

I create the subscription. Is that considered a payment intent? I just do the one payment intent where they enter a card.

ivory jetty
#

No you shouldn't create the Payment Intent yourself.. That's the problem

balmy cosmos
#

How do I get their payment and to store it?

ivory jetty
#

You create the Subscription. That creates the Invoice. The Invoice creates the Payment Intent. You use that Payment Intent to collect their payment information

#

Returns a Subscription object with an invoice.payment_intent

balmy cosmos
#

Is there a node js equivalent of that

ivory jetty
#

You use that client_secret to create the Payment Element

balmy cosmos
#

That looks a lot like my code here:

#

try {
const subscription = await stripe.subscriptions.create({
customer: customerId,
items: [
{
price: priceId,
},
],
payment_behavior: "default_incomplete",
payment_settings: { save_default_payment_method: "on_subscription" },
expand: ["latest_invoice.payment_intent"],
});

#

Maybe I'm just creating something extra. Could that be the problem.

ivory jetty
#

That is just one snippet. I think you need to review the whole process because the Payment Intent your customer completes isn't the one that is associated with the Subscription.

#

I think you have an extra step that is actually stopping you from saving the Payment Method to the Customer

balmy cosmos
#

Here's what's confusing to me. In stripe connect, which I've used in the past succesfully, I first put up a form with a card element, and when that's submitted I get a secret and then I confirm that secret.

In this instance, when I create a subscription, I get a secret. But then I want to get their payment method and confirm that too.

#

So I put up a form and get their card, but that's not working. I read docs and stack exchanges and they seemed to suggest that's what I needed to do.

ivory jetty
#

Connect has nothing to do with payments directly. What you are describing is something else.

balmy cosmos
#

direct charges

ivory jetty
#

That is still just any kind of charge

#

You can use direct charges with subscriptions.

balmy cosmos
#

I know I"m not using direct charges here, but just that I've used the stripe api before succesfully

ivory jetty
#

Direct Charges isn't an API

#

I would take a step back and review the whole document I shared

balmy cosmos
#

you can make direct charges with the stripe api

ivory jetty
#

Direct charges are just making payments on another account. They aren't their own type of payment.

#

But that's not important here

balmy cosmos
#

I agree

ivory jetty
#

The doc I linked covers all the steps necessary to create a Subscription that saves a Payment Method to a Customer

#

But it's more than just one code snippet

#

You need to coordinate when you create the Subscription and when you collect payment information

balmy cosmos
#

I've got 3 NodeJS functions (Lambdas) that do the whole process, so I know that it's a multi step process

#

Is there a way to pass the payment info into the create subscription? I didn't see that documented that way.

#

It seems that the payment info is collected after the subscription returns a secret, which is what I did

ivory jetty
#

No, you need to do it the other way

#

You get the Payment info after you create the Subscription

balmy cosmos
#

That's what I did

ivory jetty
#

No, you never confirmed the Payment Intent that is associated with the Subscription

balmy cosmos
#

OK.

ivory jetty
#

So the problem I am seeing is the Payment Intent you are using to create the form where the user provides their payment information is not the one created by the Subscripton.

balmy cosmos
#

OK, that's helpful. I'm going to see if I can fix. I see that I'm not passing in the secret returned from the subscription creation.

ivory jetty
#

Yeah, I think that's the issue. Hopefully it will be easy to find and change since all you need to do is return the secret from the subscripton.latest_invoice.payment_intent

balmy cosmos
#

yes, I"m already return it. I'm just not using it when I collect the payment card.

ivory jetty
#

Okay so if you can use that secret instead of the other one it should work

balmy cosmos
#

Here's why I brought up direct charges. I've used the api to create direct charges and regular charges in the past. To do that I bring up the stripe card element, submit it and I get a secret. I'm not sure how to do this when I already have the secret.

#

How I attach the secret to the card submission.

ivory jetty
#

And the doc I provided about handling the Subscription does cover how to handle this on your front-end

balmy cosmos
#

Ok, Thank you very much!