Stripe -- after confirmCardPayment, how to attach the new card to the customer? - stripe-payments

I am using a setupIntent to save a card to a customer for future use. I pass the client_secret from the setupIntent to the confirmCardSetup in js.
Later, I create a paymentIntent with that card. If it is declined and the status is requires_payment_method then I email the customer and give them a form to enter a new card, and subit that using confirmCardPayment in js. This works well and the charge succeeds (or becomes requires_capture).
How do I then attach that new payment method to the customer? If I do nothing, then their old saved card is still their primary payment method.
I only want to keep one card on file for each customer. I know I can detach the old card and then attach the new one, but then it will not have been done using a setupIntent, which is apparently more appropriate if I'm going to be charging the card in the future off session.

You can also save a card for future use during a payment using setup_future_usage=off_session by following this guide. The payment method will be automatically attached to the customer provided on the Payment Intent.
Your existing flow can be used, you'd just extend it by:
Prior to confirming the Payment Intent again with the new payment details, update it to set the setup_future_usage option.
After the payment succeeds, detach the old payment method like you mentioned and, if needed, update your internal reference to the payment method to use for that customer to be the new payment method id from the Payment Intent.

Related

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.

Stripe SetupIntent update flow for a new PaymentMethod

We are creating a site that allows users to attach a card to future payments.
At the first attempt, we're creating a SetupIntent with a PaymentMethod (card) - https://stripe.com/docs/payments/save-and-reuse.
Now let's say that user whats to remove the current card and attach a new one.
We can't change assigned payment method to SetupIntent or cancel SetupIntent, because
"You cannot cancel this SetupIntent because it has a status of succeeded."
Maybe I don't understand something, but how can I allow user to remove a card and attach a new one in save-and-reuse example?
Or maybe it was designed in such a way that SetupIntent only supports PaymentMethod authentication, and for a new card it is enough to disconnect (detach) the current PaymentMethod, leave SetupIntent unchanged and create a new SetupIntent + PaymentMethod pair?
Once you've setup a PaymentMethod via a SetupIntent, you no longer do anything through that SetupIntent (successful is a terminal state). You would detach the PaymentMethod from the Customer later, and/or you would follow the SetupIntent flow again (with a new SetupIntent) if you want to add a different/new PaymentMethod later.

Can I attach a Stripe PaymentMethod to a Customer several hours after creating the PaymentMethod?

When a user registers on my site, a pending registration object is created. The user must validate their email for an account object to be created.
I'd like to collect the user's payment information when they register but wait to create the Customer object until they actually validate their email and have an account. Is this possible? And is there a maximum amount of time that can elapse before I attach the PaymentMethod to a customer?
Yes this is definitely possible. The best option here is to create a SetupIntent that will let you collect their payment details securely. Once the SetupIntent is completed successfully you will get a valid PaymentMethod that you can then attach to a new customer in the future without a specific time limit.
You can read more about this in Stripe's docs: https://stripe.com/docs/payments/setup-intents

Stripe - Create subscriptions with a customer with PaymentMethod instead of Source (Token)

I'm integrating Stripe Subscriptions in our workflow, but when creating a subscription with a Customer created with a paymentMethod instead of source I receive the error This customer has no attached payment source.
If I call in the browser createToken() and attach it to the customer in the source field it works.
We integrated one-time payments using the new docs with SCA that use createPaymentMethod() and not createToken(), so our customers are saved with paymentMethod, not source, like explained here:
https://stripe.com/docs/payments/cards/saving-cards-after-payment#save-payment-method
curl https://api.stripe.com/v1/customers \
-u sk_test_secret_token \
-d payment_method="{{PAYMENT_METHOD_ID}}"
Furthermore, in the migration guide it says to replace createToken() with createPaymentMethod().
In Scenario 2: Charging customers off-session for their initial payment, I saw the following:
To create subscriptions and charge customers off-session for their
initial payment, you need to:
1) Use CreatePaymentMethod to collect payment information
2) Create a customer using the ID of the PaymentMethod you created
3) Create the subscription
4) Set up error handling using handleCardSetup for authentication failures and handleCardPayment for authorization failures
I followed those steps. I don't create a SetupIntent (just like I don't create it in one-time payments and it works in these cases), and receive the error I said before when trying to create subscriptions.
Is it possible to create subscriptions with a customer with paymentMethod instead of source?
(We reuse cards using the customers created with paymentMethod for one-time payments, so it would be very important to be able to reuse the same customer/card for subscriptions, without the need for the user input data in stripe elements or anything of the sort, because it would break our flow for reusing cards)
I was able to solve it by including the payment method in the field default_payment_method.
This field is described as follows:
ID of the default payment method for the subscription. It must belong
to the customer associated with the subscription. If not set, invoices
will use the default payment method in the customer’s invoice
settings.
So I assumed that it would use the payment method I associated with the customer when not defined. It seems it is not happening, tough, so I needed to pass it explicitly (is it a Stripe bug? or creating the customer with paymentMethod doesn't make it the default payment method in the customer’s invoice settings? I will contact Stripe to make sure).
Update (2019-09-23)
I contacted Stripe asking if this was a bug and they replied:
[...] With that being said though, this wouldn't be a bug on our end, rather
expected behavior.
If you're wanting for the Payment Method that you're adding to the
customer object to be used on subscriptions, or invoices, by default
without specifying the default_payment_method when creating the
subscription then you would want to attach the Payment Method and
specify the invoice_settings.default_payment_method parameter when
updating the customer. This information can be found within our API
reference here:
https://stripe.com/docs/api/payment_methods/attach
The parameter to use when updating this can be found on the customer
object itself, here:
https://stripe.com/docs/api/customers/update#update_customer-invoice_settings-default_payment_method
This can also be specified upon customer creation, which can be seen
here:
https://stripe.com/docs/api/customers/create#create_customer-invoice_settings-default_payment_method
Specifying this parameter would indicate that the card being added
would be the default for subscriptions, as well as invoices, so that
the default_payment_method wouldn't need to be specified upon the
subscription, or invoice, creation.

save card to customer with Stripe.js

How do I save a card to a customer with Stripe.js?
I don't want to change them at this point. I just want to save the credit card info to their stripe account so I can use it later.
It seems like I'd need to use createToken from Stipe.js. But my understanding is that this is a one time use token. I want to save the credit card info for later use.
This seems to be a similar question: Stripe Payment: Save token and customer and make payment later from token
but the solution isn't clear. I'm not sure if it means for the customer I need to save card=token and everything will work fine.
Though the question is an old one and solution of this problem is now pretty straightforward in the current Stripe API, I'm just answering for those who accidentally reached or will reach here without reading the Official Stripe Doc properly(like me) searching for this question.
To make a stripe payment You first need to make a call to the Stripe API(Using Stripe's Checkout widget, Elements or Mobile SDKs) with the User's card information. As a response, you will get a token. Then you can charge your customer immediately using Stripe's Charge API. This is for just one-time payment. You will find an example here.
If you want to save customer's information for later payment, you need to create a 'Customer' first using Stripe's API and then using that customer's ID (returned as a response from the previous API call) you can charge this customer. Example here.
I just described the process briefly to show the idea at a glance. But you should really need to read this quickstart guide in Stripe's documentation. This explains the process very well.
I just want to save the credit card info to their stripe account so I
can use it later.
Then that's exactly what you can do!
If you're already passing the token back into your server-side code, you just need to update that server-side code to retrieve the customer and create the card on that customer record using the token.
Not knowing what language you're using I can't provide relevant sample code, but the Stripe API reference has functional examples for Ruby, Python, PHP, Java, and Node.js.
Note that if the customer has any outstanding invoices, this card will be used the next time they attempt to settle—so while simply adding the card won't create a charge by itself, it's possible the card may still be billed.
A key point that the prior answers seems to dance around but do not explicitly state is that you can't simply save the credit card (token) in Stripe. Stripe's API's don't save credit cards per se, however, they can save a customer and attached to the customer you can save one more credit cards (or payment sources). So a credit card (or payment source) is not a stand alone entity in the Stripe storage system, it's a child entity of a Customer.

Resources