#SteveW
1 messages · Page 1 of 1 (latest)
Do you have IDs for the Customer and the Payment that was created that we can look at?
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
Hi 👋
hi
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?
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"],
});
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.
No i use the customer id
Not in the successful Payment Intent you shared above
the customer id that I created in the first step
The only parameters passed were amount, currency and setup_future_usage for pi_3MMJnzFskIL2Xzkf0q7s6Hui
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?
In that case we are talking about this flow: https://stripe.com/docs/payments/save-during-payment
It depends when in your process you want to save the customer information.
You could do this a different way using webhooks instead.
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
Where you save the payment method to the Customer after the first invoice is paid successfully
I want to onboard them immediately and can't wait for an invoice
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
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.
Wait wait wait, I'm an idiot
Why aren't you using the following setting? https://stripe.com/docs/api/subscriptions/create#create_subscription-payment_settings-save_default_payment_method
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
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
Okay but are you using the Payment Element to collect card information for the Payment Intent on that first invoice?
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
Okay so what you need to do is use the second Payment Intent pi_3MMJktFskIL2Xzkf1Xs8gDa1 and it's client secret to collect payment data
I'm only doing one payment intent
That's where I was confused. This Payment Intent is never attempted to be confirmed
I create the subscription. Is that considered a payment intent? I just do the one payment intent where they enter a card.
No you shouldn't create the Payment Intent yourself.. That's the problem
How do I get their payment and to store it?
You create the Subscription. That creates the Invoice. The Invoice creates the Payment Intent. You use that Payment Intent to collect their payment information
This API call you make: https://dashboard.stripe.com/test/logs/req_TcH6RuNZsaKGQ7
Returns a Subscription object with an invoice.payment_intent
Is there a node js equivalent of that
You use that client_secret to create the Payment Element
You can see both Node.js back-end and front-end code for this here: https://stripe.com/docs/billing/subscriptions/build-subscriptions
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.
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
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.
Connect has nothing to do with payments directly. What you are describing is something else.
direct charges
That is still just any kind of charge
You can use direct charges with subscriptions.
I know I"m not using direct charges here, but just that I've used the stripe api before succesfully
Direct Charges isn't an API
I would take a step back and review the whole document I shared
you can make direct charges with the stripe api
Direct charges are just making payments on another account. They aren't their own type of payment.
But that's not important here
I agree
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
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
No, you need to do it the other way
You get the Payment info after you create the Subscription
That's what I did
No, you never confirmed the Payment Intent that is associated with the Subscription
THis payment intent has nothing to do with a Customer or a Subscription: https://dashboard.stripe.com/test/logs/req_WHr1D6fIzFn5ID
OK.
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.
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.
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
yes, I"m already return it. I'm just not using it when I collect the payment card.
Okay so if you can use that secret instead of the other one it should work
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.
Regular charges do you mean the Charge API? https://stripe.com/docs/api/charges
Or Payment Intents? https://stripe.com/docs/api/payment_intents
And the doc I provided about handling the Subscription does cover how to handle this on your front-end
This section is specific to how to create the Payment form: https://stripe.com/docs/billing/subscriptions/build-subscriptions?ui=elements#collect-payment
Ok, Thank you very much!