braintree / braintree-web-drop-in

Braintree Drop-in for the web
MIT License
200 stars 126 forks source link

`options.preselectVaultedPaymentMethod` does not preselect the active vaulted payment method #652

Closed adamhenson closed 3 years ago

adamhenson commented 4 years ago

General information

Issue description

When initializing with braintree.dropin.create with a token connected to a customer ID the preselectVaultedPaymentMethod is true by default, but a different card shows at the top of the UI and is selected than the users active payment method.

The below is what I would expect and to me this seems like an issue... or I'm doing something wrong. Would someone clarify if this is expected?

Expected: The users active payment method should show selected at the top of the UI list of payment methods.

Actual: A random payment method is selected and shown at the top of the list of payment methods in the UI.

payload from gateway.paymentMethod.find(token) https://developers.braintreepayments.com/reference/request/payment-method/find/node

Screen Shot 2020-08-22 at 2 13 25 PM

issue (note the text we add from the user's active payment method conflicting with the selected card.

Screen Shot 2020-08-22 at 2 13 51 PM
crookedneighbor commented 4 years ago

That's very odd and not what I would expect. I'll have to dig into this.

imkane commented 3 years ago

We're also seeing this. Any update, Braintree?

crookedneighbor commented 3 years ago

I have not had a chance to dig into this yet.

Question: is the default payment method expired by any chance?

imkane commented 3 years ago

Nope, this is in sandbox, too. The expiry dates are years away.

I have not had a chance to dig into this yet.

Question: is the default payment method expired by any chance?

crookedneighbor commented 3 years ago

We're definitely fetching with the intent to show the default first: https://github.com/braintree/braintree-web-drop-in/blob/8f0cecf750551a99e438a717c30a93de6ab9ffc9/src/dropin-model.js#L304

But one edge case where this could get messed up is if the default payment method is expired, and there's a duplicate payment method on the customer that is not the default, and is not expired. In that case, the payment methods returned would consolidate the expired and non-expired version and only show the non-expired version, which is not the default.

@imkane @adamhenson

Do y'all have staging sites that can reproduce the issue I can take a look at?

adamhenson commented 3 years ago

@crookedneighbor - I don't. I ended up just disabling this functionality altogether since it's broken with preselectVaultedPaymentMethod: false. I was able to reproduce this with any user in sandbox and production. I'd imagine you could reproduce this with a standard setup based on the "general information" I provided in the description.

imkane commented 3 years ago

@crookedneighbor We got it sorted! Just had to add the options field as shown below:

var result = await BTGateway.paymentMethod.create({
      customerId: customerId,
      paymentMethodNonce: nonce,
      options: {
        makeDefault: true,
      },
    });
crookedneighbor commented 3 years ago

@adamhenson I can't reproduce:

Screen Shot 2020-11-16 at 9 45 25 AM

Screen Shot 2020-11-16 at 9 45 15 AM

One question of clarification, when you say "active card", you mean the payment method that is marked as the customer's default, right?

adamhenson commented 3 years ago

Correct, @crookedneighbor - the one returned from gateway.paymentMethod.find. I would expect that to be the one last used, but maybe I need to do some extra legwork to make that happen? I'm looking at @imkane's example setting makeDefault: true, which I haven't seen before. Give me a week or so to test and get back.

crookedneighbor commented 3 years ago

@adamhenson OK, I think I see what the confusion is. There's a difference between the customer's default payment method and the last one used. If you never update the customer to change the default payment method, the default will be the customer's first payment method.

The underlying API endpoint for fetching payment methods does support showing the last payment method used, so it should be a very simple matter of updating Drop-in to allow that to be configured, instead of just always configuring it to show the default payment method.

https://github.com/braintree/braintree-web-drop-in/blob/8f0cecf750551a99e438a717c30a93de6ab9ffc9/src/dropin-model.js#L304

adamhenson commented 3 years ago

Thanks @crookedneighbor - then this seems like a confusion on my part. Closing. Thanks again for your help!

crookedneighbor commented 3 years ago

I think allowing it to be configured could still be valuable, so I opened a PR for it: https://github.com/braintree/braintree-web-drop-in/pull/675

With this PR, if you configure it to not show the default payment method first, then the API will decide, which will typically be the latest payment method added to the customer. I say typically because the order is not guaranteed.

I think for your use case in particular, I'd go ahead and just update the default payment method on your customer when your system adjusts the active payment method in your backend.

adamhenson commented 3 years ago

Thanks @crookedneighbor.

crookedneighbor commented 3 years ago

This was added in v1.26.0

adamhenson commented 3 years ago

675 helps with this by making the most recently added card the default, but if the user uses another card from the vault - it doesn't change. Intuitively, I think the most recently used card should be the default. I wouldn't expect any extra configuration for this to work out of the box, but it seems like in order to accomplish this - I'll need to build a server side flow to allow users to manage payment methods.