braintree / braintree-web

A suite of tools for integrating Braintree in the browser
https://developer.paypal.com/braintree/docs/start/hello-client/javascript/v3
MIT License
438 stars 131 forks source link

Allowing customer to choose previously saved default payment method when using hosted fields #269

Closed mrjoes closed 7 years ago

mrjoes commented 7 years ago

This is not strictly a bug report, but more of the question. I'm trying to figure out how to show previously stored payment methods for the customer in the web app that's using v3 JS SDK. While that's easy with the drop-in UI, I was not able to find anything in the documentation for the hosted fields approach.

There are two ways that I found:

  1. Send a list of payment methods associated with the customer from the server.
    • I'm not sure this is secure, as CreditCard object on the server-side returns reusable token and not a nonce.
  2. Upon reading the drop-in v3 plugin source code, I found this:
    this._client.request({
      endpoint: 'payment_methods',
      method: 'get',
      data: {
        defaultFirst: 1
      }
    }, function (err, paymentMethodsPayload) {
      ...
    });

Thank you.

lilaconlee commented 7 years ago

At the moment we don't have a public method just to retrieve payment methods, but it is something we've discussed. In the meantime, we recommend using a request from the client shown in this CodePen, which is the same method we use in Drop-in. There are not any compliance issues using the client to retrieve this data.

crookedneighbor commented 7 years ago

We just released a vault-manager component to assist with this:

<script src="https://js.braintreegateway.com/web/3.11.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.11.0/js/vault-manager.min.js"></script>
<script>
braintree.client.create({authorization: 'your-client-token-with-customer-id'}, function (err, client) {
  braintree.vaultManager.create({client: client}, function (err, vm) {
    vm.fetchPaymentMethods(function (err, paymentMethods) {
       paymentMethods // an array of payment methods
    })
  })
})

See http://braintree.github.io/braintree-web/current/VaultManager.html for docs

psavard commented 7 years ago

Maybe I have missed something but I don't understand how I can pre-fill the hosted fields with the payment methods I have fetch with the vault manager.

crookedneighbor commented 7 years ago

You cannot pre-fill Hosted Fields.

What you can do is use vault manager to get a list of saved payment method nonces and create a UI for your customer to choose from a list of saved payment methods. If they'd like to add a new credit card instead, you then use Hosted Fields to capture the new card.

If you'd like a pre-made UI, you can use Drop-in, which uses Hosted Fields.

AndriusCTR commented 7 years ago

@crookedneighbor paymentMethod.details returns an object which has two properties: cardType and lastTwo. Is it possible to include third property - expiration date? (if it's card)

This is a useful bit of information for the users, because they can immediately see when their card expires or if it has already expired and they can update their payment method accordingly. That's probably one of the reasons why current payment method should be shown at all, right?

Thanks

psavard commented 6 years ago

Thank you for your answer @crookedneighbor, I understand how to work with the vaulted cards now.

crookedneighbor commented 6 years ago

@AndriusCTR That's not information available in the client API.

You can retrieve it from the server SDKs though by fetching the payment methods on the customer object and create a UI with that data.

AndriusCTR commented 6 years ago

@crookedneighbor yes, i know it's not available in the client API. That's why I suggested to consider including it into client API. Then you would't have to make separate API request, add additional code, etc.

simeyla commented 5 years ago

It's really a shame that expiration date isn't available in the fetchPaymentMethods call.

But what would be even nicer is if the vault would support the concept of a 'Nickname' for a credit card. Then the UI wouldn't look so 'naked' without an expiration date.