Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot change the default payment option #1245

Closed
srikanthsrnvs opened this issue Jul 24, 2019 · 13 comments
Closed

Cannot change the default payment option #1245

srikanthsrnvs opened this issue Jul 24, 2019 · 13 comments
Assignees
Labels
triaged Issue has been reviewed by Stripe and is being tracked internally

Comments

@srikanthsrnvs
Copy link

srikanthsrnvs commented Jul 24, 2019

Summary

Prebuilt standard integration does not change default payment method.
Selecting a payment method on the paymentOptionsViewController results in a dismissal of the viewcontroller, but when examining the backend, the default card is not changed.
During the same session, if we re-open the paymentOptionsViewController, it shows the correct card being selected as the default option, but when killing the app and relaunching, it correctly pulls data from the backend, and shows no card being selected as a default payment method.

Code to reproduce

iOS version

iOS 13, Xcode 12 Beta

Installation method

Cocoapods

SDK version

16.0.0

Other information

@yuki-stripe
Copy link
Collaborator

Hi @srikanthsrnvs. The standard integration uses the new PaymentIntent+PaymentMethod API (as opposed to Sources), which does not have a concept of a default in general. You'll need to explicitly specify the PaymentMethod (https://stripe.com/docs/payments/payment-intents/migration#paying-saved-cards) when charging your customer using the PaymentIntent API.

That said, is this issue about which payment method is pre-selected in the UI by default? That seems like a valid thing the UI should be able to do - Stripe doesn't store the 'default' PaymentMethod, but we could expose an API to let you set which one is pre-selected by default. Let me know what you think!

@Ariandr
Copy link

Ariandr commented Jul 25, 2019

Hi @yuki-stripe
Yes, the new API is definitely needed in order to be able to show the default method, because without this feature the user experience will be deteriorated.

@srikanthsrnvs
Copy link
Author

@yuki-stripe Understood. However, we have had several customers complaining about this design, and currently dealing with it by using version 15.0.0 of the Stripe iOS component as a workaround.

Exposing such an API would be ideal for us to bake in our our code to handle this.

@yuki-stripe yuki-stripe added the triaged Issue has been reviewed by Stripe and is being tracked internally label Jul 25, 2019
@yuki-stripe
Copy link
Collaborator

@srikanthsrnvs Great! We're tracking this work internally.

@catt-stefano
Copy link

catt-stefano commented Jul 25, 2019

Having updated the Android version, and being in the middle of the iOS update. I can confirm that the user experience for the payment flow did deteriorate. We would really like to have a way to set a default payment method.

@gadget-man
Copy link

I agree. Currently the user can add a new payment method and the backend can set this as a default option for paying invoices etc, however there doesn't seem to be a way to reflect this in the iOS app without having a default payment option.

@gadget-man
Copy link

Not sure if it's related, but I need a way to change the invoice_settings.default_payment_method for a customer when they select a new card using the standard integration. Following a paymentContextDidChange can I return the payment_method ID that was selected so that I can update the customer details for a subscription?

@yuki-stripe
Copy link
Collaborator

@needlerp Yes, that sounds right.

I've merged #1252 which I believe addresses the issue.
Feel free to open a new one if it doesn't work for you.

@gadget-man
Copy link

I see 16.0.2 has been release. I've successfully retrieved the default payment method for invoices (saved to Stripe.PaymentMethod) but when I pass the variable as follows:
paymentContext.defaultPaymentMethod = Stripe.PaymentMethod
paymentContext.presentPaymentOptionsViewController()

The app crashes when I press the payment method button:
-[STPPaymentContext setDefaultPaymentMethod:]: unrecognized selector sent to instance 0x2803ffb80

Is it not working or am I mis-understanding the issue?

@rromanchuk
Copy link

I'm curious about the design arch departure from sources/default_source/customer to payment_methods/customer/invoice_settings.default_payment_method I understand a default_source may not always make contextual sense with SCA, but a payment_method with a off_session setup intent seems like a standard use case. I have business logic that relies on the existence of a default_source and has now gotten messy because of migrating, i now have to normalize legacy and new between default_source and invoice_settings.default_payment_method, additionally using webhooks to catch new attached payment methods as they won't have any defaults set on their own.

For example, lets say an account is in bad standing for NSF, in the past they could remedy the situation by retrying/ adding new source, and it becomes the new default. It allows for very easy state tracking, the backend can now attempt to bring the account into good standing and re-run any pending invoices. I just ran into the issue where new intents users were trying to recover their accounts by adding working cards, but were left bricked because it was using old defaults, which is used to mean "i want to pay for things with this thing". This lead users to believe their new cards were being declined, so they generated even more payment methods. When i caught it, now i have a collection of payment methods without really any idea of what the user intended.

Other problem i now have to deal with is existing users that utilized default_source, upgraded and added a new payment method(s) that are essentially orphaned. So i ended up having to add a bunch of branching to normalize, new webhooks to intercept and set defaults, so the business logic can continue to function just until i can roll out my own default payment state tracking.

Hopefully that makes sense, it's N/A for on_session but pretty valuable for off_session by very nature of being off session.

@rromanchuk
Copy link

If i'm creating an intent with customer and payment method supplied I really need a way to tell stripe to make it the default payment method for the customer. This would solve all of my headaches. That's literally what the customer believes they are doing with the intent i'm creating.

let setupIntentParams = STPSetupIntentConfirmParams(clientSecret: setupIntent.clientSecret)
setupIntentParams.paymentMethodID = paymentMethod.stripeId
setupIntent.usage = "off_session"
setupIntent.customer = customerID
setupIntent.defaultPaymentMethod = true // <------ i really need this!!

@rromanchuk
Copy link

Also I would actually be a little careful with this language https://github.com/stripe/stripe-ios/blob/v16.0.6/Stripe/PublicHeaders/STPPaymentContext.h#L143 as it could cause confusion. Customer objects actually do have native support for "Default payment methods" it's just named a bit confusing. If Invoice.create and Subscription.create aren't provided with a payment_method it waterfalls down to the customer object.

https://stripe.com/docs/api/invoices/create#create_invoice-default_payment_method

ID of the default payment method for the invoice. It must belong to the customer associated with the invoice. If not set, defaults to the subscription’s default payment method, if any, or to the default payment method in the customer’s invoice settings.

Similarly for default_source
https://stripe.com/docs/api/invoices/create#create_invoice-default_source

ID of the default payment source for the invoice. It must belong to the customer associated with the invoice and be in a chargeable state. If not set, defaults to the subscription’s default source, if any, or to the customer’s default source.

When I create invoices i do not pass these properties, i let stripe take what ever is assigned on the customer object. Remember these are off session.

Here's a question, what if a legacy customer have both a default_source and now also a invoice_settings.default_payment_method, what happens?

@samar-gul
Copy link

I'm curious about the design arch departure from sources/default_source/customer to payment_methods/customer/invoice_settings.default_payment_method I understand a default_source may not always make contextual sense with SCA, but a payment_method with a off_session setup intent seems like a standard use case. I have business logic that relies on the existence of a default_source and has now gotten messy because of migrating, i now have to normalize legacy and new between default_source and invoice_settings.default_payment_method, additionally using webhooks to catch new attached payment methods as they won't have any defaults set on their own.

For example, lets say an account is in bad standing for NSF, in the past they could remedy the situation by retrying/ adding new source, and it becomes the new default. It allows for very easy state tracking, the backend can now attempt to bring the account into good standing and re-run any pending invoices. I just ran into the issue where new intents users were trying to recover their accounts by adding working cards, but were left bricked because it was using old defaults, which is used to mean "i want to pay for things with this thing". This lead users to believe their new cards were being declined, so they generated even more payment methods. When i caught it, now i have a collection of payment methods without really any idea of what the user intended.

Other problem i now have to deal with is existing users that utilized default_source, upgraded and added a new payment method(s) that are essentially orphaned. So i ended up having to add a bunch of branching to normalize, new webhooks to intercept and set defaults, so the business logic can continue to function just until i can roll out my own default payment state tracking.

Hopefully that makes sense, it's N/A for on_session but pretty valuable for off_session by very nature of being off session.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triaged Issue has been reviewed by Stripe and is being tracked internally
Projects
None yet
Development

No branches or pull requests

7 participants