Stripe Elements update subscriber payment method - stripe-payments

How to enable users to update their subscription's payment method using Stripe Elements?
I couldn't find any reference to this neither in the docs nor on Stackoverflow.
This is how I'm currently setting the default payment method when the user first subscribes to our service.
Create a Stripe subscription object
Render the React CardElement component.
On submit, I call the browser's side Stripe library with stripe.confirmCardPayment(cardElement)
This then triggers a invoice.payment_succeeded webhook event.
In the webhook event, I get the payment intent ID which I use to retrieve the payment intent object which has the ID of the payment_method attached to it.
I then update Stripe's subscription object to use the successful payment_method's ID as the default payment method.
Is there a way to update the subscription's payment method without making a payment_intent first? Link to docs would be appreciated.
Thank you

You can use SetupIntents to save a customer’s card without an initial payment : https://stripe.com/docs/payments/save-and-reuse-cards-only [until step 4]
Listen for the setup_intent.succeeded webhook event to know when the SetupIntent is successful since the customer could close the browser window or quit the app before the stripe.confirmPayment callback executes.
Update the Subscription to use the resulting PaymentMethod ID as the default payment method.
Alternatively, you could also make use of the Customer Portal to allow customers to update their payment method for a subscription : https://stripe.com/docs/billing/subscriptions/customer-portal

Related

Trying to link a stripe payment page to passion.io via webhooks

So I have a stripe payment page that allows customers to subscribe to a membership platform I use called passion.io.
I am trying to trigger on zapier that when the customer checks out using the stripe payment page, it fills an order on passion.io as a new customer and goes through the new customer process.
Currently Zapier doesnt let the check out of a specific payment page be its own unique trigger so they suggested I use webhooks as a work around but I know nothing about webhooks and am so confused on which event to use and how to set this up.
Any insight?

How to save card details (payment method) in Stripe using backend?

The docs only covers the case where the payment method is created by the frontend (JS). But there is a risk that the user leaves the website before the frontend sends the information to the backend that the card has been added (and its ID).
In order to make a payment, I need ID of the payment method. I don't want to query Stripe's API for user cards IDs every time before making a payment, so I want to save the payment method ID in my local database. I also want to allow the user to define more payment methods and choose the default one.
Is there a reason you are using the non-recommended workflow you linked to? The most up-to-date version can be found here
Have you checked out using webhook listeners? I use them to create/update my local records.
In the workflow you reference, 3 webhook events potentially fire. First the setup_intent.created event is triggered when your server code generates the SetupIntent and its client_secret. Then, when the user fills out whatever Payment or Card element you instantiate and your frontend code calls the stripe.confirmCardSetup() (or stripe.confirmSetup() in the case of a PaymentElement), both the setup_intent.succeeded and payment_method.attached events will fire.
This last one will POST the payment_method object that was just attached to your customer back to your system. This object will have both the Payment Method ID as well as the associated Customer ID. You can use these to update your local records to map payment methods to customers in your server and avoid unnecessary API calls.

Stripe APi paymentIntent and sessions object

I am having trouble finding out the difference between payment Intent and a session.
Assuming I a customer logs into a page and goes to domain.com/register how can I create session and check if customer has already visited page by using customer email address to get the customer object?
What are the difference between paymentIntent and session and how do they help? I see that session is created on Checkout but not when accepting one time payments.
Current I create a payment intent and it works find but my 'url' has no session
PaymentIntents
A PaymentIntent is an API object in Stripe's API that create encapsulates a lifecycle of a one-time payment.
You typically create your own form on your webpage when using PaymentIntents, create a PaymentIntent using the Stripe API, then confirm it using the cardElement from Stripe Elements (the frontend UI elements for collecting card details).
Checkout
Checkout is a full page "hosted UI" that creates its own PaymentIntent and provides all the UI that a customer needs to enter their card details and takes a payment. It also supports many other payment methods automatically without you having to manually add support for each one.
So a CheckoutSession under the hood uses a Subscription or a PaymentIntent object, depending on whether it was used in subscription or payment mode.

payment intent is null in a subscription checkout session

I am integrating stripe using php by following this tutorial:
https://phppot.com/php/manage-recurring-payments-using-stripe-billing-in-php/
(my website has some subscription plans and redirects to the stripe checkout form ) . however, for the last step, I decided not to use webhooks, I chose to store the info like in this tutorial https://www.codexworld.com/stripe-checkout-payment-gateway-integration-php/ (I know it is not for subscription but I just use the success.php code from this tutorial to collect the customer info and payment intent details).
I tested it, gone throught the stripe checkout form , and on success I printed the checkout session object and noticed that the payment_intent field of that object is empty ! so i cannot load the payment intent object and get its info although the payment is successfully made and it is showing on the dashboard . any idea why ??
EDIT :
According to the documenttaion of a checkout session (https://stripe.com/docs/api/checkout/sessions/object), the payment_intent field stores the ID of the PaymentIntent for Checkout Sessions in payment mode. In my case I have a subscription mode not a payment one. however,if I still want to get the $intent->status , can I use the payment_status field of the session object $checkout_session->payment_status?
And if subcription payments really don't have paymentintents , then why did the payment appear in the payments section on the dashboard?
Based on the mode you passed in, either one of payment_intent, subscription or setup_intent will be populated, the rest will be null.
When a Subscription is made, your user is invoiced so it is considered a payment and will appear in the Payments dashboard. You can retrieve the Subscription and access the latest_invoice field to obtain the Invoice object. The Invoice object contains the payment_intent field. This is likely what you're looking for.
Using webhook would simplify the process, since you could listen to invoice.payment_suceeded to retrieve the PaymentIntent ID.

How to get the charge Id after subscribing a customer to a plan with recurring payment?

I have successfully created a customer in stripe with a subscription of plan .After successful payment I am not able to get the charge Id because after subscribing a customer to a plan.It automatically generates an invoice.So what is the way that I can get that particular charge stripe Id from stripe and store it in my system database.
Getting the charge ID for a subscription (or an invoice) can be done via their webhooks integration. You need to expose an API in your app where Stripe can fire these requests. You can subscribe to various events there, but in your case you'd need to do so on charge.succeeded. The charge ID will be in the data structure of the event object.
Take a look at the various other lifecycle events you can use with webhooks.

Resources