Stripe webhooks to monitor whether customer has an active payment method - stripe-payments

Customers on my site use the Stripe Billing portal on user sign up to enter a payment method (card or ACH). What webhook can I use to monitor whether they have at least one active payment method?
I know I can use customer.source.created when a payment method is created and customer.source.deleted when a source is deleted. However a user can initially create two methods and delete one but still have an active method. I just need to know whether they have at least one available

Whenever you receive customer.source.created OR customer.source.deleted events, you typically receive card object as the payload. Since the customer property on the card object is expandable, you may not see it included by default on the card object.
In which case, you'd likely need to retrieve the card object again by calling the API and expanding customer property on it. Once you get the customer ID, you can call this API to list customer's payment methods. This should allow you to see if they have any other PaymentMethods or not.

Related

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 customers with attached cards, but no default payment method

I am doing a migration for a customer from one platform to another both of which use a Stripe account.
Both platforms only support card payments.
I have noticed, however, that the customers of the existing platform all have a card attached on the Stripe dashboard, but it is not marked as their default payment source. If I retrieve the customers from the API, both their default_source, invoice_settings. default_payment_method and sources.data attributes are null or empty array respectively.
It doesn't sound likely that I'll be able to charge a customer without a default source. I would like to run some tests on data that looks like the production environment, but no matter how I attach a card to a customer, it automatically gets registered as the customer's default source (if they don't already have another). I have in fact no idea how the previous platform manages to end up in a state where a customer has a card attached on the dashboard, but an empty sources-array.
Do any of you know how I can replicate this behaviour using either the API or the dashboard?
When working with Payment Methods, such as attaching a payment method, you must set the customer invoice_settings.default_payment_method explicitly (API ref). With the older Sources API, the default_source was set automatically.
If you attached one of the test payment methods, you can recreate the behaviour you describe: you'd have an attached payment method but no defaults set.

With Stripe, how to attach a single payment method created from Setup Intent API for multiple customers

With Stripe, how to use the payment method created from setup intent for multiple customers?
According tp the Create Setup Intent API, it only let us define one customer ID.
param name: customer (optional)
description of this param:
attached to the Customer on successful setup. Payment methods attached
to other Customers cannot be used with this SetupIntent.ID of the Customer this SetupIntent belongs to, ifone exists. If present, the SetupIntent’s payment method will be
TLDR
I want to let the same user to reuse same payment method to subscribe items with different presentment currencies,
I assume I should solve this requirement by directly creating multiple customer objects for a single user, and using create Setup Intent API to attach his/her same payment method for multiple "customer objects".
But, I am not sure if this is possible, therefore I welcome any recommendation for alternative approaches, such as using attach payment method to customers API, or any workarounds.
PS: Detail info (for why I am interested to ask this question)
Business requirement:
My business requirement is that customers have to subscribe to international services that must be presented with different presentment currencies. To makes thing even harder, each customer has to use the same list of saved payment methods to subscribe to services with different presentment currencies in the future. In other words, users should not have to re-enter card info again if they subscribe to items in different presentment currencies.
Limitation of the Stripe API:
Why not just use single customer object for subscribing to services (aka "price" objects) with multiple presentment currency?
I tried and it results in an error. According to this Stripe documentation, it indeed says that each customer can only be used for transactions in single currency.
If the user in my app want to subscribe to another service with another
currency, I need to create new "Customer" object in Stripe.
Why not just use /v1/payment_methods/:pm_id/attach api to attch payment method to multiple customer object?
Because according to this Attact payment method to customer API doc, Stripe does not recommend, yet I do not fully understand the risk of not performing any necessary steps as it warns. Therefore, it is just my risk averse instinct to avoid this.
To attach a new PaymentMethod to a customer for future payments, we
recommend you use a SetupIntent or a PaymentIntent with
setup_future_usage. These approaches will perform any necessary steps
to ensure that the PaymentMethod can be used in a future payment.
This is not supported. A payment method can only be consumed once if not attached, and attaching to a customer counts as a consumption. A PM can only be attached to a single customer, so you'll need to collect the payment details for each.
Stripe recommends using that customer's currency for all presentment to optimize for their experience, though that may not be suitable for all use cases.

Stripe API - How To Get When A Payment Method Is Added To A Customer's Account?

I am currently using the allSources() (https://stripe.com/docs/api/cards/list) method to get a list of credit cards associated with a user. This method does not return the date for which each individual card was added to the user's account.
Is there a way to get this info from Stripe? The idea being I want to display payment cards to a user in the order which the user added them to their account.
The Card object does not have a created property today. What you could do here is rely on the order in the sources sub-collection as it's always ordered by most recent first. The exception is that the current default source (the one set in default_source) is always the first in the collection even if it's not the most recently created.
Alternatively, what you could do is move to the PaymentMethod APIs instead. This is the most recent abstraction from Stripe which replaces Card and Source entirely. This object does have a created property. You can use the List PaymentMethod API to list them for a specific customer.
When Stripe built that new API they made it compatible with existing, and now considered legacy, objects. What this means is that you can have a Card object with the id card_123 and that will also work via the PaymentMethod API moving forward. The id stays the same and you don't need to do anything. If you list the PaymentMethods on your customer you will "magically" get the old card objects as PaymentMethod objects which means they will have a created property.

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.

Resources